Merge remote-tracking branch 'spi/for-5.12' into spi-linus
[linux-2.6-block.git] / drivers / scsi / pcmcia / nsp_cs.c
CommitLineData
1da177e4
LT
1/*======================================================================
2
3 NinjaSCSI-3 / NinjaSCSI-32Bi PCMCIA SCSI host adapter card driver
4 By: YOKOTA Hiroshi <yokota@netlab.is.tsukuba.ac.jp>
5
6 Ver.2.8 Support 32bit MMIO mode
7 Support Synchronous Data Transfer Request (SDTR) mode
8 Ver.2.0 Support 32bit PIO mode
9 Ver.1.1.2 Fix for scatter list buffer exceeds
10 Ver.1.1 Support scatter list
11 Ver.0.1 Initial version
12
13 This software may be used and distributed according to the terms of
14 the GNU General Public License.
15
16======================================================================*/
17
18/***********************************************************************
19 This driver is for these PCcards.
20
21 I-O DATA PCSC-F (Workbit NinjaSCSI-3)
22 "WBT", "NinjaSCSI-3", "R1.0"
23 I-O DATA CBSC-II (Workbit NinjaSCSI-32Bi in 16bit mode)
24 "IO DATA", "CBSC16 ", "1"
25
26***********************************************************************/
27
1da177e4
LT
28#include <linux/module.h>
29#include <linux/kernel.h>
30#include <linux/init.h>
1da177e4
LT
31#include <linux/slab.h>
32#include <linux/string.h>
33#include <linux/timer.h>
34#include <linux/ioport.h>
35#include <linux/delay.h>
36#include <linux/interrupt.h>
37#include <linux/major.h>
38#include <linux/blkdev.h>
39#include <linux/stat.h>
40
41#include <asm/io.h>
42#include <asm/irq.h>
43
44#include <../drivers/scsi/scsi.h>
45#include <scsi/scsi_host.h>
46
47#include <scsi/scsi.h>
48#include <scsi/scsi_ioctl.h>
49
1da177e4
LT
50#include <pcmcia/cistpl.h>
51#include <pcmcia/cisreg.h>
52#include <pcmcia/ds.h>
53
54#include "nsp_cs.h"
55
56MODULE_AUTHOR("YOKOTA Hiroshi <yokota@netlab.is.tsukuba.ac.jp>");
774251ef 57MODULE_DESCRIPTION("WorkBit NinjaSCSI-3 / NinjaSCSI-32Bi(16bit) PCMCIA SCSI host adapter module");
1da177e4 58MODULE_LICENSE("GPL");
1da177e4
LT
59
60#include "nsp_io.h"
61
62/*====================================================================*/
63/* Parameters that can be set with 'insmod' */
64
65static int nsp_burst_mode = BURST_MEM32;
66module_param(nsp_burst_mode, int, 0);
67MODULE_PARM_DESC(nsp_burst_mode, "Burst transfer mode (0=io8, 1=io32, 2=mem32(default))");
68
69/* Release IO ports after configuration? */
90ab5ee9 70static bool free_ports = 0;
1da177e4
LT
71module_param(free_ports, bool, 0);
72MODULE_PARM_DESC(free_ports, "Release IO ports after configuration? (default: 0 (=no))");
73
d0be4a7d 74static struct scsi_host_template nsp_driver_template = {
1da177e4 75 .proc_name = "nsp_cs",
63fd57cb 76 .show_info = nsp_show_info,
1da177e4 77 .name = "WorkBit NinjaSCSI-3/32Bi(16bit)",
1da177e4
LT
78 .info = nsp_info,
79 .queuecommand = nsp_queuecommand,
1da177e4 80/* .eh_abort_handler = nsp_eh_abort,*/
1da177e4
LT
81 .eh_bus_reset_handler = nsp_eh_bus_reset,
82 .eh_host_reset_handler = nsp_eh_host_reset,
83 .can_queue = 1,
84 .this_id = NSP_INITIATOR_ID,
85 .sg_tablesize = SG_ALL,
4af14d11 86 .dma_boundary = PAGE_SIZE - 1,
1da177e4
LT
87};
88
1da177e4
LT
89static nsp_hw_data nsp_data_base; /* attach <-> detect glue */
90
91
92
93/*
94 * debug, error print
95 */
96#ifndef NSP_DEBUG
97# define NSP_DEBUG_MASK 0x000000
98# define nsp_msg(type, args...) nsp_cs_message("", 0, (type), args)
99# define nsp_dbg(mask, args...) /* */
100#else
101# define NSP_DEBUG_MASK 0xffffff
102# define nsp_msg(type, args...) \
cadbd4a5 103 nsp_cs_message (__func__, __LINE__, (type), args)
1da177e4 104# define nsp_dbg(mask, args...) \
cadbd4a5 105 nsp_cs_dmessage(__func__, __LINE__, (mask), args)
1da177e4
LT
106#endif
107
108#define NSP_DEBUG_QUEUECOMMAND BIT(0)
109#define NSP_DEBUG_REGISTER BIT(1)
110#define NSP_DEBUG_AUTOSCSI BIT(2)
111#define NSP_DEBUG_INTR BIT(3)
112#define NSP_DEBUG_SGLIST BIT(4)
113#define NSP_DEBUG_BUSFREE BIT(5)
114#define NSP_DEBUG_CDB_CONTENTS BIT(6)
115#define NSP_DEBUG_RESELECTION BIT(7)
116#define NSP_DEBUG_MSGINOCCUR BIT(8)
117#define NSP_DEBUG_EEPROM BIT(9)
118#define NSP_DEBUG_MSGOUTOCCUR BIT(10)
119#define NSP_DEBUG_BUSRESET BIT(11)
120#define NSP_DEBUG_RESTART BIT(12)
121#define NSP_DEBUG_SYNC BIT(13)
122#define NSP_DEBUG_WAIT BIT(14)
123#define NSP_DEBUG_TARGETFLAG BIT(15)
124#define NSP_DEBUG_PROC BIT(16)
125#define NSP_DEBUG_INIT BIT(17)
126#define NSP_DEBUG_DATA_IO BIT(18)
127#define NSP_SPECIAL_PRINT_REGISTER BIT(20)
128
129#define NSP_DEBUG_BUF_LEN 150
130
040cd232
BH
131static inline void nsp_inc_resid(struct scsi_cmnd *SCpnt, int residInc)
132{
133 scsi_set_resid(SCpnt, scsi_get_resid(SCpnt) + residInc);
134}
135
af0b55d0 136__printf(4, 5)
1da177e4
LT
137static void nsp_cs_message(const char *func, int line, char *type, char *fmt, ...)
138{
139 va_list args;
140 char buf[NSP_DEBUG_BUF_LEN];
141
142 va_start(args, fmt);
143 vsnprintf(buf, sizeof(buf), fmt, args);
144 va_end(args);
145
146#ifndef NSP_DEBUG
147 printk("%snsp_cs: %s\n", type, buf);
148#else
149 printk("%snsp_cs: %s (%d): %s\n", type, func, line, buf);
150#endif
151}
152
153#ifdef NSP_DEBUG
154static void nsp_cs_dmessage(const char *func, int line, int mask, char *fmt, ...)
155{
156 va_list args;
157 char buf[NSP_DEBUG_BUF_LEN];
158
159 va_start(args, fmt);
160 vsnprintf(buf, sizeof(buf), fmt, args);
161 va_end(args);
162
163 if (mask & NSP_DEBUG_MASK) {
164 printk("nsp_cs-debug: 0x%x %s (%d): %s\n", mask, func, line, buf);
165 }
166}
167#endif
168
169/***********************************************************/
170
171/*====================================================
172 * Clenaup parameters and call done() functions.
173 * You must be set SCpnt->result before call this function.
174 */
0fc82d5e 175static void nsp_scsi_done(struct scsi_cmnd *SCpnt)
1da177e4
LT
176{
177 nsp_hw_data *data = (nsp_hw_data *)SCpnt->device->host->hostdata;
178
179 data->CurrentSC = NULL;
180
181 SCpnt->scsi_done(SCpnt);
182}
183
f281233d 184static int nsp_queuecommand_lck(struct scsi_cmnd *SCpnt,
0fc82d5e 185 void (*done)(struct scsi_cmnd *))
1da177e4
LT
186{
187#ifdef NSP_DEBUG
188 /*unsigned int host_id = SCpnt->device->host->this_id;*/
189 /*unsigned int base = SCpnt->device->host->io_port;*/
422c0d61 190 unsigned char target = scmd_id(SCpnt);
1da177e4
LT
191#endif
192 nsp_hw_data *data = (nsp_hw_data *)SCpnt->device->host->hostdata;
193
040cd232 194 nsp_dbg(NSP_DEBUG_QUEUECOMMAND,
9cb78c16 195 "SCpnt=0x%p target=%d lun=%llu sglist=0x%p bufflen=%d sg_count=%d",
040cd232
BH
196 SCpnt, target, SCpnt->device->lun, scsi_sglist(SCpnt),
197 scsi_bufflen(SCpnt), scsi_sg_count(SCpnt));
1da177e4
LT
198 //nsp_dbg(NSP_DEBUG_QUEUECOMMAND, "before CurrentSC=0x%p", data->CurrentSC);
199
200 SCpnt->scsi_done = done;
201
202 if (data->CurrentSC != NULL) {
203 nsp_msg(KERN_DEBUG, "CurrentSC!=NULL this can't be happen");
204 SCpnt->result = DID_BAD_TARGET << 16;
205 nsp_scsi_done(SCpnt);
206 return 0;
207 }
208
209#if 0
210 /* XXX: pcmcia-cs generates SCSI command with "scsi_info" utility.
211 This makes kernel crash when suspending... */
212 if (data->ScsiInfo->stop != 0) {
213 nsp_msg(KERN_INFO, "suspending device. reject command.");
214 SCpnt->result = DID_BAD_TARGET << 16;
215 nsp_scsi_done(SCpnt);
216 return SCSI_MLQUEUE_HOST_BUSY;
217 }
218#endif
219
220 show_command(SCpnt);
221
222 data->CurrentSC = SCpnt;
223
224 SCpnt->SCp.Status = CHECK_CONDITION;
225 SCpnt->SCp.Message = 0;
226 SCpnt->SCp.have_data_in = IO_UNKNOWN;
227 SCpnt->SCp.sent_command = 0;
228 SCpnt->SCp.phase = PH_UNDETERMINED;
040cd232 229 scsi_set_resid(SCpnt, scsi_bufflen(SCpnt));
1da177e4
LT
230
231 /* setup scratch area
232 SCp.ptr : buffer pointer
233 SCp.this_residual : buffer length
234 SCp.buffer : next buffer
235 SCp.buffers_residual : left buffers in list
236 SCp.phase : current state of the command */
040cd232
BH
237 if (scsi_bufflen(SCpnt)) {
238 SCpnt->SCp.buffer = scsi_sglist(SCpnt);
1da177e4
LT
239 SCpnt->SCp.ptr = BUFFER_ADDR;
240 SCpnt->SCp.this_residual = SCpnt->SCp.buffer->length;
040cd232 241 SCpnt->SCp.buffers_residual = scsi_sg_count(SCpnt) - 1;
1da177e4 242 } else {
040cd232
BH
243 SCpnt->SCp.ptr = NULL;
244 SCpnt->SCp.this_residual = 0;
1da177e4
LT
245 SCpnt->SCp.buffer = NULL;
246 SCpnt->SCp.buffers_residual = 0;
247 }
248
249 if (nsphw_start_selection(SCpnt) == FALSE) {
250 nsp_dbg(NSP_DEBUG_QUEUECOMMAND, "selection fail");
251 SCpnt->result = DID_BUS_BUSY << 16;
252 nsp_scsi_done(SCpnt);
253 return 0;
254 }
255
256
257 //nsp_dbg(NSP_DEBUG_QUEUECOMMAND, "out");
258#ifdef NSP_DEBUG
259 data->CmdId++;
260#endif
261 return 0;
262}
263
f281233d
JG
264static DEF_SCSI_QCMD(nsp_queuecommand)
265
1da177e4
LT
266/*
267 * setup PIO FIFO transfer mode and enable/disable to data out
268 */
269static void nsp_setup_fifo(nsp_hw_data *data, int enabled)
270{
271 unsigned int base = data->BaseAddress;
272 unsigned char transfer_mode_reg;
273
274 //nsp_dbg(NSP_DEBUG_DATA_IO, "enabled=%d", enabled);
275
276 if (enabled != FALSE) {
277 transfer_mode_reg = TRANSFER_GO | BRAIND;
278 } else {
279 transfer_mode_reg = 0;
280 }
281
282 transfer_mode_reg |= data->TransferMode;
283
284 nsp_index_write(base, TRANSFERMODE, transfer_mode_reg);
285}
286
287static void nsphw_init_sync(nsp_hw_data *data)
288{
289 sync_data tmp_sync = { .SyncNegotiation = SYNC_NOT_YET,
290 .SyncPeriod = 0,
291 .SyncOffset = 0
292 };
293 int i;
294
295 /* setup sync data */
296 for ( i = 0; i < ARRAY_SIZE(data->Sync); i++ ) {
297 data->Sync[i] = tmp_sync;
298 }
299}
300
301/*
302 * Initialize Ninja hardware
303 */
304static int nsphw_init(nsp_hw_data *data)
305{
306 unsigned int base = data->BaseAddress;
307
308 nsp_dbg(NSP_DEBUG_INIT, "in base=0x%x", base);
309
310 data->ScsiClockDiv = CLOCK_40M | FAST_20;
311 data->CurrentSC = NULL;
312 data->FifoCount = 0;
313 data->TransferMode = MODE_IO8;
314
315 nsphw_init_sync(data);
316
317 /* block all interrupts */
318 nsp_write(base, IRQCONTROL, IRQCONTROL_ALLMASK);
319
320 /* setup SCSI interface */
321 nsp_write(base, IFSELECT, IF_IFSEL);
322
323 nsp_index_write(base, SCSIIRQMODE, 0);
324
325 nsp_index_write(base, TRANSFERMODE, MODE_IO8);
326 nsp_index_write(base, CLOCKDIV, data->ScsiClockDiv);
327
328 nsp_index_write(base, PARITYCTRL, 0);
329 nsp_index_write(base, POINTERCLR, POINTER_CLEAR |
330 ACK_COUNTER_CLEAR |
331 REQ_COUNTER_CLEAR |
332 HOST_COUNTER_CLEAR);
333
334 /* setup fifo asic */
335 nsp_write(base, IFSELECT, IF_REGSEL);
336 nsp_index_write(base, TERMPWRCTRL, 0);
337 if ((nsp_index_read(base, OTHERCONTROL) & TPWR_SENSE) == 0) {
338 nsp_msg(KERN_INFO, "terminator power on");
339 nsp_index_write(base, TERMPWRCTRL, POWER_ON);
340 }
341
342 nsp_index_write(base, TIMERCOUNT, 0);
343 nsp_index_write(base, TIMERCOUNT, 0); /* requires 2 times!! */
344
345 nsp_index_write(base, SYNCREG, 0);
346 nsp_index_write(base, ACKWIDTH, 0);
347
348 /* enable interrupts and ack them */
349 nsp_index_write(base, SCSIIRQMODE, SCSI_PHASE_CHANGE_EI |
350 RESELECT_EI |
351 SCSI_RESET_IRQ_EI );
352 nsp_write(base, IRQCONTROL, IRQCONTROL_ALLCLEAR);
353
354 nsp_setup_fifo(data, FALSE);
355
356 return TRUE;
357}
358
359/*
360 * Start selection phase
361 */
0fc82d5e 362static int nsphw_start_selection(struct scsi_cmnd *SCpnt)
1da177e4
LT
363{
364 unsigned int host_id = SCpnt->device->host->this_id;
365 unsigned int base = SCpnt->device->host->io_port;
422c0d61 366 unsigned char target = scmd_id(SCpnt);
1da177e4
LT
367 nsp_hw_data *data = (nsp_hw_data *)SCpnt->device->host->hostdata;
368 int time_out;
369 unsigned char phase, arbit;
370
371 //nsp_dbg(NSP_DEBUG_RESELECTION, "in");
372
373 phase = nsp_index_read(base, SCSIBUSMON);
374 if(phase != BUSMON_BUS_FREE) {
375 //nsp_dbg(NSP_DEBUG_RESELECTION, "bus busy");
376 return FALSE;
377 }
378
379 /* start arbitration */
380 //nsp_dbg(NSP_DEBUG_RESELECTION, "start arbit");
381 SCpnt->SCp.phase = PH_ARBSTART;
382 nsp_index_write(base, SETARBIT, ARBIT_GO);
383
384 time_out = 1000;
385 do {
386 /* XXX: what a stupid chip! */
387 arbit = nsp_index_read(base, ARBITSTATUS);
388 //nsp_dbg(NSP_DEBUG_RESELECTION, "arbit=%d, wait_count=%d", arbit, wait_count);
389 udelay(1); /* hold 1.2us */
390 } while((arbit & (ARBIT_WIN | ARBIT_FAIL)) == 0 &&
391 (time_out-- != 0));
392
393 if (!(arbit & ARBIT_WIN)) {
394 //nsp_dbg(NSP_DEBUG_RESELECTION, "arbit fail");
395 nsp_index_write(base, SETARBIT, ARBIT_FLAG_CLEAR);
396 return FALSE;
397 }
398
399 /* assert select line */
400 //nsp_dbg(NSP_DEBUG_RESELECTION, "assert SEL line");
401 SCpnt->SCp.phase = PH_SELSTART;
402 udelay(3); /* wait 2.4us */
403 nsp_index_write(base, SCSIDATALATCH, BIT(host_id) | BIT(target));
404 nsp_index_write(base, SCSIBUSCTRL, SCSI_SEL | SCSI_BSY | SCSI_ATN);
405 udelay(2); /* wait >1.2us */
406 nsp_index_write(base, SCSIBUSCTRL, SCSI_SEL | SCSI_BSY | SCSI_DATAOUT_ENB | SCSI_ATN);
407 nsp_index_write(base, SETARBIT, ARBIT_FLAG_CLEAR);
408 /*udelay(1);*/ /* wait >90ns */
409 nsp_index_write(base, SCSIBUSCTRL, SCSI_SEL | SCSI_DATAOUT_ENB | SCSI_ATN);
410
411 /* check selection timeout */
412 nsp_start_timer(SCpnt, 1000/51);
413 data->SelectionTimeOut = 1;
414
415 return TRUE;
416}
417
418struct nsp_sync_table {
419 unsigned int min_period;
420 unsigned int max_period;
421 unsigned int chip_period;
422 unsigned int ack_width;
423};
424
425static struct nsp_sync_table nsp_sync_table_40M[] = {
426 {0x0c, 0x0c, 0x1, 0}, /* 20MB 50ns*/
427 {0x19, 0x19, 0x3, 1}, /* 10MB 100ns*/
428 {0x1a, 0x25, 0x5, 2}, /* 7.5MB 150ns*/
429 {0x26, 0x32, 0x7, 3}, /* 5MB 200ns*/
430 { 0, 0, 0, 0},
431};
432
433static struct nsp_sync_table nsp_sync_table_20M[] = {
434 {0x19, 0x19, 0x1, 0}, /* 10MB 100ns*/
435 {0x1a, 0x25, 0x2, 0}, /* 7.5MB 150ns*/
436 {0x26, 0x32, 0x3, 1}, /* 5MB 200ns*/
437 { 0, 0, 0, 0},
438};
439
440/*
441 * setup synchronous data transfer mode
442 */
0fc82d5e 443static int nsp_analyze_sdtr(struct scsi_cmnd *SCpnt)
1da177e4 444{
422c0d61 445 unsigned char target = scmd_id(SCpnt);
1da177e4
LT
446// unsigned char lun = SCpnt->device->lun;
447 nsp_hw_data *data = (nsp_hw_data *)SCpnt->device->host->hostdata;
448 sync_data *sync = &(data->Sync[target]);
449 struct nsp_sync_table *sync_table;
450 unsigned int period, offset;
451 int i;
452
453
454 nsp_dbg(NSP_DEBUG_SYNC, "in");
455
456 period = sync->SyncPeriod;
457 offset = sync->SyncOffset;
458
459 nsp_dbg(NSP_DEBUG_SYNC, "period=0x%x, offset=0x%x", period, offset);
460
461 if ((data->ScsiClockDiv & (BIT(0)|BIT(1))) == CLOCK_20M) {
462 sync_table = nsp_sync_table_20M;
463 } else {
464 sync_table = nsp_sync_table_40M;
465 }
466
467 for ( i = 0; sync_table->max_period != 0; i++, sync_table++) {
468 if ( period >= sync_table->min_period &&
469 period <= sync_table->max_period ) {
470 break;
471 }
472 }
473
474 if (period != 0 && sync_table->max_period == 0) {
475 /*
476 * No proper period/offset found
477 */
478 nsp_dbg(NSP_DEBUG_SYNC, "no proper period/offset");
479
480 sync->SyncPeriod = 0;
481 sync->SyncOffset = 0;
482 sync->SyncRegister = 0;
483 sync->AckWidth = 0;
484
485 return FALSE;
486 }
487
488 sync->SyncRegister = (sync_table->chip_period << SYNCREG_PERIOD_SHIFT) |
489 (offset & SYNCREG_OFFSET_MASK);
490 sync->AckWidth = sync_table->ack_width;
491
492 nsp_dbg(NSP_DEBUG_SYNC, "sync_reg=0x%x, ack_width=0x%x", sync->SyncRegister, sync->AckWidth);
493
494 return TRUE;
495}
496
497
498/*
499 * start ninja hardware timer
500 */
0fc82d5e 501static void nsp_start_timer(struct scsi_cmnd *SCpnt, int time)
1da177e4
LT
502{
503 unsigned int base = SCpnt->device->host->io_port;
504 nsp_hw_data *data = (nsp_hw_data *)SCpnt->device->host->hostdata;
505
506 //nsp_dbg(NSP_DEBUG_INTR, "in SCpnt=0x%p, time=%d", SCpnt, time);
507 data->TimerCount = time;
508 nsp_index_write(base, TIMERCOUNT, time);
509}
510
511/*
512 * wait for bus phase change
513 */
0fc82d5e
HK
514static int nsp_negate_signal(struct scsi_cmnd *SCpnt, unsigned char mask,
515 char *str)
1da177e4
LT
516{
517 unsigned int base = SCpnt->device->host->io_port;
518 unsigned char reg;
519 int time_out;
520
521 //nsp_dbg(NSP_DEBUG_INTR, "in");
522
523 time_out = 100;
524
525 do {
526 reg = nsp_index_read(base, SCSIBUSMON);
527 if (reg == 0xff) {
528 break;
529 }
0454c740 530 } while ((--time_out != 0) && (reg & mask) != 0);
1da177e4
LT
531
532 if (time_out == 0) {
9b13494c 533 nsp_msg(KERN_DEBUG, " %s signal off timeout", str);
1da177e4
LT
534 }
535
536 return 0;
537}
538
539/*
540 * expect Ninja Irq
541 */
0fc82d5e
HK
542static int nsp_expect_signal(struct scsi_cmnd *SCpnt,
543 unsigned char current_phase,
544 unsigned char mask)
1da177e4
LT
545{
546 unsigned int base = SCpnt->device->host->io_port;
547 int time_out;
548 unsigned char phase, i_src;
549
550 //nsp_dbg(NSP_DEBUG_INTR, "current_phase=0x%x, mask=0x%x", current_phase, mask);
551
552 time_out = 100;
553 do {
554 phase = nsp_index_read(base, SCSIBUSMON);
555 if (phase == 0xff) {
556 //nsp_dbg(NSP_DEBUG_INTR, "ret -1");
557 return -1;
558 }
559 i_src = nsp_read(base, IRQSTATUS);
560 if (i_src & IRQSTATUS_SCSI) {
561 //nsp_dbg(NSP_DEBUG_INTR, "ret 0 found scsi signal");
562 return 0;
563 }
564 if ((phase & mask) != 0 && (phase & BUSMON_PHASE_MASK) == current_phase) {
565 //nsp_dbg(NSP_DEBUG_INTR, "ret 1 phase=0x%x", phase);
566 return 1;
567 }
568 } while(time_out-- != 0);
569
570 //nsp_dbg(NSP_DEBUG_INTR, "timeout");
571 return -1;
572}
573
574/*
575 * transfer SCSI message
576 */
0fc82d5e 577static int nsp_xfer(struct scsi_cmnd *SCpnt, int phase)
1da177e4
LT
578{
579 unsigned int base = SCpnt->device->host->io_port;
580 nsp_hw_data *data = (nsp_hw_data *)SCpnt->device->host->hostdata;
581 char *buf = data->MsgBuffer;
582 int len = min(MSGBUF_SIZE, data->MsgLen);
583 int ptr;
584 int ret;
585
586 //nsp_dbg(NSP_DEBUG_DATA_IO, "in");
587 for (ptr = 0; len > 0; len--, ptr++) {
588
589 ret = nsp_expect_signal(SCpnt, phase, BUSMON_REQ);
590 if (ret <= 0) {
591 nsp_dbg(NSP_DEBUG_DATA_IO, "xfer quit");
592 return 0;
593 }
594
595 /* if last byte, negate ATN */
596 if (len == 1 && SCpnt->SCp.phase == PH_MSG_OUT) {
597 nsp_index_write(base, SCSIBUSCTRL, AUTODIRECTION | ACKENB);
598 }
599
600 /* read & write message */
601 if (phase & BUSMON_IO) {
602 nsp_dbg(NSP_DEBUG_DATA_IO, "read msg");
603 buf[ptr] = nsp_index_read(base, SCSIDATAWITHACK);
604 } else {
605 nsp_dbg(NSP_DEBUG_DATA_IO, "write msg");
606 nsp_index_write(base, SCSIDATAWITHACK, buf[ptr]);
607 }
608 nsp_negate_signal(SCpnt, BUSMON_ACK, "xfer<ack>");
609
610 }
611 return len;
612}
613
614/*
615 * get extra SCSI data from fifo
616 */
0fc82d5e 617static int nsp_dataphase_bypass(struct scsi_cmnd *SCpnt)
1da177e4
LT
618{
619 nsp_hw_data *data = (nsp_hw_data *)SCpnt->device->host->hostdata;
620 unsigned int count;
621
622 //nsp_dbg(NSP_DEBUG_DATA_IO, "in");
623
624 if (SCpnt->SCp.have_data_in != IO_IN) {
625 return 0;
626 }
627
628 count = nsp_fifo_count(SCpnt);
629 if (data->FifoCount == count) {
630 //nsp_dbg(NSP_DEBUG_DATA_IO, "not use bypass quirk");
631 return 0;
632 }
633
634 /*
635 * XXX: NSP_QUIRK
636 * data phase skip only occures in case of SCSI_LOW_READ
637 */
638 nsp_dbg(NSP_DEBUG_DATA_IO, "use bypass quirk");
639 SCpnt->SCp.phase = PH_DATA;
640 nsp_pio_read(SCpnt);
641 nsp_setup_fifo(data, FALSE);
642
643 return 0;
644}
645
646/*
647 * accept reselection
648 */
0fc82d5e 649static int nsp_reselected(struct scsi_cmnd *SCpnt)
1da177e4
LT
650{
651 unsigned int base = SCpnt->device->host->io_port;
652 unsigned int host_id = SCpnt->device->host->this_id;
653 //nsp_hw_data *data = (nsp_hw_data *)SCpnt->device->host->hostdata;
654 unsigned char bus_reg;
655 unsigned char id_reg, tmp;
656 int target;
657
658 nsp_dbg(NSP_DEBUG_RESELECTION, "in");
659
660 id_reg = nsp_index_read(base, RESELECTID);
661 tmp = id_reg & (~BIT(host_id));
662 target = 0;
663 while(tmp != 0) {
664 if (tmp & BIT(0)) {
665 break;
666 }
667 tmp >>= 1;
668 target++;
669 }
670
422c0d61 671 if (scmd_id(SCpnt) != target) {
1da177e4
LT
672 nsp_msg(KERN_ERR, "XXX: reselect ID must be %d in this implementation.", target);
673 }
674
675 nsp_negate_signal(SCpnt, BUSMON_SEL, "reselect<SEL>");
676
677 nsp_nexus(SCpnt);
678 bus_reg = nsp_index_read(base, SCSIBUSCTRL) & ~(SCSI_BSY | SCSI_ATN);
679 nsp_index_write(base, SCSIBUSCTRL, bus_reg);
680 nsp_index_write(base, SCSIBUSCTRL, bus_reg | AUTODIRECTION | ACKENB);
681
682 return TRUE;
683}
684
685/*
686 * count how many data transferd
687 */
0fc82d5e 688static int nsp_fifo_count(struct scsi_cmnd *SCpnt)
1da177e4
LT
689{
690 unsigned int base = SCpnt->device->host->io_port;
691 unsigned int count;
97a33483 692 unsigned int l, m, h;
1da177e4
LT
693
694 nsp_index_write(base, POINTERCLR, POINTER_CLEAR | ACK_COUNTER);
695
696 l = nsp_index_read(base, TRANSFERCOUNT);
697 m = nsp_index_read(base, TRANSFERCOUNT);
698 h = nsp_index_read(base, TRANSFERCOUNT);
97a33483 699 nsp_index_read(base, TRANSFERCOUNT); /* required this! */
1da177e4
LT
700
701 count = (h << 16) | (m << 8) | (l << 0);
702
703 //nsp_dbg(NSP_DEBUG_DATA_IO, "count=0x%x", count);
704
705 return count;
706}
707
708/* fifo size */
709#define RFIFO_CRIT 64
710#define WFIFO_CRIT 64
711
712/*
713 * read data in DATA IN phase
714 */
0fc82d5e 715static void nsp_pio_read(struct scsi_cmnd *SCpnt)
1da177e4
LT
716{
717 unsigned int base = SCpnt->device->host->io_port;
718 unsigned long mmio_base = SCpnt->device->host->base;
719 nsp_hw_data *data = (nsp_hw_data *)SCpnt->device->host->hostdata;
720 long time_out;
721 int ocount, res;
722 unsigned char stat, fifo_stat;
723
724 ocount = data->FifoCount;
725
726 nsp_dbg(NSP_DEBUG_DATA_IO, "in SCpnt=0x%p resid=%d ocount=%d ptr=0x%p this_residual=%d buffers=0x%p nbuf=%d",
040cd232
BH
727 SCpnt, scsi_get_resid(SCpnt), ocount, SCpnt->SCp.ptr,
728 SCpnt->SCp.this_residual, SCpnt->SCp.buffer,
729 SCpnt->SCp.buffers_residual);
1da177e4
LT
730
731 time_out = 1000;
732
733 while ((time_out-- != 0) &&
734 (SCpnt->SCp.this_residual > 0 || SCpnt->SCp.buffers_residual > 0 ) ) {
735
736 stat = nsp_index_read(base, SCSIBUSMON);
737 stat &= BUSMON_PHASE_MASK;
738
739
740 res = nsp_fifo_count(SCpnt) - ocount;
741 //nsp_dbg(NSP_DEBUG_DATA_IO, "ptr=0x%p this=0x%x ocount=0x%x res=0x%x", SCpnt->SCp.ptr, SCpnt->SCp.this_residual, ocount, res);
25985edc 742 if (res == 0) { /* if some data available ? */
1da177e4
LT
743 if (stat == BUSPHASE_DATA_IN) { /* phase changed? */
744 //nsp_dbg(NSP_DEBUG_DATA_IO, " wait for data this=%d", SCpnt->SCp.this_residual);
745 continue;
746 } else {
747 nsp_dbg(NSP_DEBUG_DATA_IO, "phase changed stat=0x%x", stat);
748 break;
749 }
750 }
751
752 fifo_stat = nsp_read(base, FIFOSTATUS);
753 if ((fifo_stat & FIFOSTATUS_FULL_EMPTY) == 0 &&
754 stat == BUSPHASE_DATA_IN) {
755 continue;
756 }
757
758 res = min(res, SCpnt->SCp.this_residual);
759
760 switch (data->TransferMode) {
761 case MODE_IO32:
762 res &= ~(BIT(1)|BIT(0)); /* align 4 */
763 nsp_fifo32_read(base, SCpnt->SCp.ptr, res >> 2);
764 break;
765 case MODE_IO8:
766 nsp_fifo8_read (base, SCpnt->SCp.ptr, res );
767 break;
768
769 case MODE_MEM32:
770 res &= ~(BIT(1)|BIT(0)); /* align 4 */
771 nsp_mmio_fifo32_read(mmio_base, SCpnt->SCp.ptr, res >> 2);
772 break;
773
774 default:
775 nsp_dbg(NSP_DEBUG_DATA_IO, "unknown read mode");
776 return;
777 }
778
040cd232 779 nsp_inc_resid(SCpnt, -res);
1da177e4
LT
780 SCpnt->SCp.ptr += res;
781 SCpnt->SCp.this_residual -= res;
782 ocount += res;
783 //nsp_dbg(NSP_DEBUG_DATA_IO, "ptr=0x%p this_residual=0x%x ocount=0x%x", SCpnt->SCp.ptr, SCpnt->SCp.this_residual, ocount);
784
785 /* go to next scatter list if available */
786 if (SCpnt->SCp.this_residual == 0 &&
787 SCpnt->SCp.buffers_residual != 0 ) {
788 //nsp_dbg(NSP_DEBUG_DATA_IO, "scatterlist next timeout=%d", time_out);
789 SCpnt->SCp.buffers_residual--;
1b3a4640 790 SCpnt->SCp.buffer = sg_next(SCpnt->SCp.buffer);
1da177e4
LT
791 SCpnt->SCp.ptr = BUFFER_ADDR;
792 SCpnt->SCp.this_residual = SCpnt->SCp.buffer->length;
793 time_out = 1000;
794
795 //nsp_dbg(NSP_DEBUG_DATA_IO, "page: 0x%p, off: 0x%x", SCpnt->SCp.buffer->page, SCpnt->SCp.buffer->offset);
796 }
797 }
798
799 data->FifoCount = ocount;
800
0454c740 801 if (time_out < 0) {
1da177e4 802 nsp_msg(KERN_DEBUG, "pio read timeout resid=%d this_residual=%d buffers_residual=%d",
040cd232
BH
803 scsi_get_resid(SCpnt), SCpnt->SCp.this_residual,
804 SCpnt->SCp.buffers_residual);
1da177e4
LT
805 }
806 nsp_dbg(NSP_DEBUG_DATA_IO, "read ocount=0x%x", ocount);
040cd232
BH
807 nsp_dbg(NSP_DEBUG_DATA_IO, "r cmd=%d resid=0x%x\n", data->CmdId,
808 scsi_get_resid(SCpnt));
1da177e4
LT
809}
810
811/*
812 * write data in DATA OUT phase
813 */
0fc82d5e 814static void nsp_pio_write(struct scsi_cmnd *SCpnt)
1da177e4
LT
815{
816 unsigned int base = SCpnt->device->host->io_port;
817 unsigned long mmio_base = SCpnt->device->host->base;
818 nsp_hw_data *data = (nsp_hw_data *)SCpnt->device->host->hostdata;
819 int time_out;
820 int ocount, res;
821 unsigned char stat;
822
823 ocount = data->FifoCount;
824
825 nsp_dbg(NSP_DEBUG_DATA_IO, "in fifocount=%d ptr=0x%p this_residual=%d buffers=0x%p nbuf=%d resid=0x%x",
040cd232
BH
826 data->FifoCount, SCpnt->SCp.ptr, SCpnt->SCp.this_residual,
827 SCpnt->SCp.buffer, SCpnt->SCp.buffers_residual,
828 scsi_get_resid(SCpnt));
1da177e4
LT
829
830 time_out = 1000;
831
832 while ((time_out-- != 0) &&
833 (SCpnt->SCp.this_residual > 0 || SCpnt->SCp.buffers_residual > 0)) {
834 stat = nsp_index_read(base, SCSIBUSMON);
835 stat &= BUSMON_PHASE_MASK;
836
837 if (stat != BUSPHASE_DATA_OUT) {
838 res = ocount - nsp_fifo_count(SCpnt);
839
840 nsp_dbg(NSP_DEBUG_DATA_IO, "phase changed stat=0x%x, res=%d\n", stat, res);
841 /* Put back pointer */
040cd232 842 nsp_inc_resid(SCpnt, res);
1da177e4
LT
843 SCpnt->SCp.ptr -= res;
844 SCpnt->SCp.this_residual += res;
845 ocount -= res;
846
847 break;
848 }
849
850 res = ocount - nsp_fifo_count(SCpnt);
851 if (res > 0) { /* write all data? */
852 nsp_dbg(NSP_DEBUG_DATA_IO, "wait for all data out. ocount=0x%x res=%d", ocount, res);
853 continue;
854 }
855
856 res = min(SCpnt->SCp.this_residual, WFIFO_CRIT);
857
858 //nsp_dbg(NSP_DEBUG_DATA_IO, "ptr=0x%p this=0x%x res=0x%x", SCpnt->SCp.ptr, SCpnt->SCp.this_residual, res);
859 switch (data->TransferMode) {
860 case MODE_IO32:
861 res &= ~(BIT(1)|BIT(0)); /* align 4 */
862 nsp_fifo32_write(base, SCpnt->SCp.ptr, res >> 2);
863 break;
864 case MODE_IO8:
865 nsp_fifo8_write (base, SCpnt->SCp.ptr, res );
866 break;
867
868 case MODE_MEM32:
869 res &= ~(BIT(1)|BIT(0)); /* align 4 */
870 nsp_mmio_fifo32_write(mmio_base, SCpnt->SCp.ptr, res >> 2);
871 break;
872
873 default:
874 nsp_dbg(NSP_DEBUG_DATA_IO, "unknown write mode");
875 break;
876 }
877
040cd232 878 nsp_inc_resid(SCpnt, -res);
1da177e4
LT
879 SCpnt->SCp.ptr += res;
880 SCpnt->SCp.this_residual -= res;
881 ocount += res;
882
883 /* go to next scatter list if available */
884 if (SCpnt->SCp.this_residual == 0 &&
885 SCpnt->SCp.buffers_residual != 0 ) {
886 //nsp_dbg(NSP_DEBUG_DATA_IO, "scatterlist next");
887 SCpnt->SCp.buffers_residual--;
1b3a4640 888 SCpnt->SCp.buffer = sg_next(SCpnt->SCp.buffer);
1da177e4
LT
889 SCpnt->SCp.ptr = BUFFER_ADDR;
890 SCpnt->SCp.this_residual = SCpnt->SCp.buffer->length;
891 time_out = 1000;
892 }
893 }
894
895 data->FifoCount = ocount;
896
0454c740 897 if (time_out < 0) {
040cd232
BH
898 nsp_msg(KERN_DEBUG, "pio write timeout resid=0x%x",
899 scsi_get_resid(SCpnt));
1da177e4
LT
900 }
901 nsp_dbg(NSP_DEBUG_DATA_IO, "write ocount=0x%x", ocount);
040cd232
BH
902 nsp_dbg(NSP_DEBUG_DATA_IO, "w cmd=%d resid=0x%x\n", data->CmdId,
903 scsi_get_resid(SCpnt));
1da177e4
LT
904}
905#undef RFIFO_CRIT
906#undef WFIFO_CRIT
907
908/*
909 * setup synchronous/asynchronous data transfer mode
910 */
0fc82d5e 911static int nsp_nexus(struct scsi_cmnd *SCpnt)
1da177e4
LT
912{
913 unsigned int base = SCpnt->device->host->io_port;
422c0d61 914 unsigned char target = scmd_id(SCpnt);
1da177e4
LT
915// unsigned char lun = SCpnt->device->lun;
916 nsp_hw_data *data = (nsp_hw_data *)SCpnt->device->host->hostdata;
917 sync_data *sync = &(data->Sync[target]);
918
919 //nsp_dbg(NSP_DEBUG_DATA_IO, "in SCpnt=0x%p", SCpnt);
920
921 /* setup synch transfer registers */
922 nsp_index_write(base, SYNCREG, sync->SyncRegister);
923 nsp_index_write(base, ACKWIDTH, sync->AckWidth);
924
040cd232
BH
925 if (scsi_get_resid(SCpnt) % 4 != 0 ||
926 scsi_get_resid(SCpnt) <= PAGE_SIZE ) {
1da177e4
LT
927 data->TransferMode = MODE_IO8;
928 } else if (nsp_burst_mode == BURST_MEM32) {
929 data->TransferMode = MODE_MEM32;
930 } else if (nsp_burst_mode == BURST_IO32) {
931 data->TransferMode = MODE_IO32;
932 } else {
933 data->TransferMode = MODE_IO8;
934 }
935
936 /* setup pdma fifo */
937 nsp_setup_fifo(data, TRUE);
938
939 /* clear ack counter */
940 data->FifoCount = 0;
941 nsp_index_write(base, POINTERCLR, POINTER_CLEAR |
942 ACK_COUNTER_CLEAR |
943 REQ_COUNTER_CLEAR |
944 HOST_COUNTER_CLEAR);
945
946 return 0;
947}
948
949#include "nsp_message.c"
950/*
951 * interrupt handler
952 */
7d12e780 953static irqreturn_t nspintr(int irq, void *dev_id)
1da177e4
LT
954{
955 unsigned int base;
956 unsigned char irq_status, irq_phase, phase;
0fc82d5e 957 struct scsi_cmnd *tmpSC;
1da177e4
LT
958 unsigned char target, lun;
959 unsigned int *sync_neg;
960 int i, tmp;
961 nsp_hw_data *data;
962
963
964 //nsp_dbg(NSP_DEBUG_INTR, "dev_id=0x%p", dev_id);
965 //nsp_dbg(NSP_DEBUG_INTR, "host=0x%p", ((scsi_info_t *)dev_id)->host);
966
967 if ( dev_id != NULL &&
968 ((scsi_info_t *)dev_id)->host != NULL ) {
969 scsi_info_t *info = (scsi_info_t *)dev_id;
970
971 data = (nsp_hw_data *)info->host->hostdata;
972 } else {
973 nsp_dbg(NSP_DEBUG_INTR, "host data wrong");
974 return IRQ_NONE;
975 }
976
977 //nsp_dbg(NSP_DEBUG_INTR, "&nsp_data_base=0x%p, dev_id=0x%p", &nsp_data_base, dev_id);
978
979 base = data->BaseAddress;
980 //nsp_dbg(NSP_DEBUG_INTR, "base=0x%x", base);
981
982 /*
983 * interrupt check
984 */
985 nsp_write(base, IRQCONTROL, IRQCONTROL_IRQDISABLE);
986 irq_status = nsp_read(base, IRQSTATUS);
987 //nsp_dbg(NSP_DEBUG_INTR, "irq_status=0x%x", irq_status);
988 if ((irq_status == 0xff) || ((irq_status & IRQSTATUS_MASK) == 0)) {
989 nsp_write(base, IRQCONTROL, 0);
990 //nsp_dbg(NSP_DEBUG_INTR, "no irq/shared irq");
991 return IRQ_NONE;
992 }
993
994 /* XXX: IMPORTANT
995 * Do not read an irq_phase register if no scsi phase interrupt.
996 * Unless, you should lose a scsi phase interrupt.
997 */
998 phase = nsp_index_read(base, SCSIBUSMON);
999 if((irq_status & IRQSTATUS_SCSI) != 0) {
1000 irq_phase = nsp_index_read(base, IRQPHASESENCE);
1001 } else {
1002 irq_phase = 0;
1003 }
1004
1005 //nsp_dbg(NSP_DEBUG_INTR, "irq_phase=0x%x", irq_phase);
1006
1007 /*
1008 * timer interrupt handler (scsi vs timer interrupts)
1009 */
1010 //nsp_dbg(NSP_DEBUG_INTR, "timercount=%d", data->TimerCount);
1011 if (data->TimerCount != 0) {
1012 //nsp_dbg(NSP_DEBUG_INTR, "stop timer");
1013 nsp_index_write(base, TIMERCOUNT, 0);
1014 nsp_index_write(base, TIMERCOUNT, 0);
1015 data->TimerCount = 0;
1016 }
1017
1018 if ((irq_status & IRQSTATUS_MASK) == IRQSTATUS_TIMER &&
1019 data->SelectionTimeOut == 0) {
1020 //nsp_dbg(NSP_DEBUG_INTR, "timer start");
1021 nsp_write(base, IRQCONTROL, IRQCONTROL_TIMER_CLEAR);
1022 return IRQ_HANDLED;
1023 }
1024
1025 nsp_write(base, IRQCONTROL, IRQCONTROL_TIMER_CLEAR | IRQCONTROL_FIFO_CLEAR);
1026
1027 if ((irq_status & IRQSTATUS_SCSI) &&
1028 (irq_phase & SCSI_RESET_IRQ)) {
1029 nsp_msg(KERN_ERR, "bus reset (power off?)");
1030
1031 nsphw_init(data);
1032 nsp_bus_reset(data);
1033
1034 if(data->CurrentSC != NULL) {
1035 tmpSC = data->CurrentSC;
1036 tmpSC->result = (DID_RESET << 16) |
1037 ((tmpSC->SCp.Message & 0xff) << 8) |
1038 ((tmpSC->SCp.Status & 0xff) << 0);
1039 nsp_scsi_done(tmpSC);
1040 }
1041 return IRQ_HANDLED;
1042 }
1043
1044 if (data->CurrentSC == NULL) {
1045 nsp_msg(KERN_ERR, "CurrentSC==NULL irq_status=0x%x phase=0x%x irq_phase=0x%x this can't be happen. reset everything", irq_status, phase, irq_phase);
1046 nsphw_init(data);
1047 nsp_bus_reset(data);
1048 return IRQ_HANDLED;
1049 }
1050
1051 tmpSC = data->CurrentSC;
1052 target = tmpSC->device->id;
1053 lun = tmpSC->device->lun;
1054 sync_neg = &(data->Sync[target].SyncNegotiation);
1055
1056 /*
1057 * parse hardware SCSI irq reasons register
1058 */
1059 if (irq_status & IRQSTATUS_SCSI) {
1060 if (irq_phase & RESELECT_IRQ) {
1061 nsp_dbg(NSP_DEBUG_INTR, "reselect");
1062 nsp_write(base, IRQCONTROL, IRQCONTROL_RESELECT_CLEAR);
1063 if (nsp_reselected(tmpSC) != FALSE) {
1064 return IRQ_HANDLED;
1065 }
1066 }
1067
1068 if ((irq_phase & (PHASE_CHANGE_IRQ | LATCHED_BUS_FREE)) == 0) {
1069 return IRQ_HANDLED;
1070 }
1071 }
1072
1073 //show_phase(tmpSC);
1074
1075 switch(tmpSC->SCp.phase) {
1076 case PH_SELSTART:
1077 // *sync_neg = SYNC_NOT_YET;
1078 if ((phase & BUSMON_BSY) == 0) {
1079 //nsp_dbg(NSP_DEBUG_INTR, "selection count=%d", data->SelectionTimeOut);
1080 if (data->SelectionTimeOut >= NSP_SELTIMEOUT) {
1081 nsp_dbg(NSP_DEBUG_INTR, "selection time out");
1082 data->SelectionTimeOut = 0;
1083 nsp_index_write(base, SCSIBUSCTRL, 0);
1084
1085 tmpSC->result = DID_TIME_OUT << 16;
1086 nsp_scsi_done(tmpSC);
1087
1088 return IRQ_HANDLED;
1089 }
1090 data->SelectionTimeOut += 1;
1091 nsp_start_timer(tmpSC, 1000/51);
1092 return IRQ_HANDLED;
1093 }
1094
1095 /* attention assert */
1096 //nsp_dbg(NSP_DEBUG_INTR, "attention assert");
1097 data->SelectionTimeOut = 0;
1098 tmpSC->SCp.phase = PH_SELECTED;
1099 nsp_index_write(base, SCSIBUSCTRL, SCSI_ATN);
1100 udelay(1);
1101 nsp_index_write(base, SCSIBUSCTRL, SCSI_ATN | AUTODIRECTION | ACKENB);
1102 return IRQ_HANDLED;
1103
1da177e4
LT
1104 case PH_RESELECT:
1105 //nsp_dbg(NSP_DEBUG_INTR, "phase reselect");
1106 // *sync_neg = SYNC_NOT_YET;
1107 if ((phase & BUSMON_PHASE_MASK) != BUSPHASE_MESSAGE_IN) {
1108
1109 tmpSC->result = DID_ABORT << 16;
1110 nsp_scsi_done(tmpSC);
1111 return IRQ_HANDLED;
1112 }
df561f66 1113 fallthrough;
1da177e4
LT
1114 default:
1115 if ((irq_status & (IRQSTATUS_SCSI | IRQSTATUS_FIFO)) == 0) {
1116 return IRQ_HANDLED;
1117 }
1118 break;
1119 }
1120
1121 /*
1122 * SCSI sequencer
1123 */
1124 //nsp_dbg(NSP_DEBUG_INTR, "start scsi seq");
1125
1126 /* normal disconnect */
1127 if (((tmpSC->SCp.phase == PH_MSG_IN) || (tmpSC->SCp.phase == PH_MSG_OUT)) &&
1128 (irq_phase & LATCHED_BUS_FREE) != 0 ) {
1129 nsp_dbg(NSP_DEBUG_INTR, "normal disconnect irq_status=0x%x, phase=0x%x, irq_phase=0x%x", irq_status, phase, irq_phase);
1130
1131 //*sync_neg = SYNC_NOT_YET;
1132
7e1c99e5 1133 /* all command complete and return status */
1c9eb798 1134 if (tmpSC->SCp.Message == COMMAND_COMPLETE) {
1da177e4
LT
1135 tmpSC->result = (DID_OK << 16) |
1136 ((tmpSC->SCp.Message & 0xff) << 8) |
1137 ((tmpSC->SCp.Status & 0xff) << 0);
1138 nsp_dbg(NSP_DEBUG_INTR, "command complete result=0x%x", tmpSC->result);
1139 nsp_scsi_done(tmpSC);
1140
1141 return IRQ_HANDLED;
1142 }
1143
1144 return IRQ_HANDLED;
1145 }
1146
1147
1148 /* check unexpected bus free state */
1149 if (phase == 0) {
1150 nsp_msg(KERN_DEBUG, "unexpected bus free. irq_status=0x%x, phase=0x%x, irq_phase=0x%x", irq_status, phase, irq_phase);
1151
1152 *sync_neg = SYNC_NG;
1153 tmpSC->result = DID_ERROR << 16;
1154 nsp_scsi_done(tmpSC);
1155 return IRQ_HANDLED;
1156 }
1157
1158 switch (phase & BUSMON_PHASE_MASK) {
1159 case BUSPHASE_COMMAND:
1160 nsp_dbg(NSP_DEBUG_INTR, "BUSPHASE_COMMAND");
1161 if ((phase & BUSMON_REQ) == 0) {
1162 nsp_dbg(NSP_DEBUG_INTR, "REQ == 0");
1163 return IRQ_HANDLED;
1164 }
1165
1166 tmpSC->SCp.phase = PH_COMMAND;
1167
1168 nsp_nexus(tmpSC);
1169
1170 /* write scsi command */
1171 nsp_dbg(NSP_DEBUG_INTR, "cmd_len=%d", tmpSC->cmd_len);
1172 nsp_index_write(base, COMMANDCTRL, CLEAR_COMMAND_POINTER);
1173 for (i = 0; i < tmpSC->cmd_len; i++) {
1174 nsp_index_write(base, COMMANDDATA, tmpSC->cmnd[i]);
1175 }
1176 nsp_index_write(base, COMMANDCTRL, CLEAR_COMMAND_POINTER | AUTO_COMMAND_GO);
1177 break;
1178
1179 case BUSPHASE_DATA_OUT:
1180 nsp_dbg(NSP_DEBUG_INTR, "BUSPHASE_DATA_OUT");
1181
1182 tmpSC->SCp.phase = PH_DATA;
1183 tmpSC->SCp.have_data_in = IO_OUT;
1184
1185 nsp_pio_write(tmpSC);
1186
1187 break;
1188
1189 case BUSPHASE_DATA_IN:
1190 nsp_dbg(NSP_DEBUG_INTR, "BUSPHASE_DATA_IN");
1191
1192 tmpSC->SCp.phase = PH_DATA;
1193 tmpSC->SCp.have_data_in = IO_IN;
1194
1195 nsp_pio_read(tmpSC);
1196
1197 break;
1198
1199 case BUSPHASE_STATUS:
1200 nsp_dataphase_bypass(tmpSC);
1201 nsp_dbg(NSP_DEBUG_INTR, "BUSPHASE_STATUS");
1202
1203 tmpSC->SCp.phase = PH_STATUS;
1204
1205 tmpSC->SCp.Status = nsp_index_read(base, SCSIDATAWITHACK);
1206 nsp_dbg(NSP_DEBUG_INTR, "message=0x%x status=0x%x", tmpSC->SCp.Message, tmpSC->SCp.Status);
1207
1208 break;
1209
1210 case BUSPHASE_MESSAGE_OUT:
1211 nsp_dbg(NSP_DEBUG_INTR, "BUSPHASE_MESSAGE_OUT");
1212 if ((phase & BUSMON_REQ) == 0) {
1213 goto timer_out;
1214 }
1215
1216 tmpSC->SCp.phase = PH_MSG_OUT;
1217
1218 //*sync_neg = SYNC_NOT_YET;
1219
1220 data->MsgLen = i = 0;
1221 data->MsgBuffer[i] = IDENTIFY(TRUE, lun); i++;
1222
1223 if (*sync_neg == SYNC_NOT_YET) {
1224 data->Sync[target].SyncPeriod = 0;
1225 data->Sync[target].SyncOffset = 0;
1226
1227 /**/
1c9eb798 1228 data->MsgBuffer[i] = EXTENDED_MESSAGE; i++;
1da177e4 1229 data->MsgBuffer[i] = 3; i++;
1c9eb798 1230 data->MsgBuffer[i] = EXTENDED_SDTR; i++;
1da177e4
LT
1231 data->MsgBuffer[i] = 0x0c; i++;
1232 data->MsgBuffer[i] = 15; i++;
1233 /**/
1234 }
1235 data->MsgLen = i;
1236
1237 nsp_analyze_sdtr(tmpSC);
1238 show_message(data);
1239 nsp_message_out(tmpSC);
1240 break;
1241
1242 case BUSPHASE_MESSAGE_IN:
1243 nsp_dataphase_bypass(tmpSC);
1244 nsp_dbg(NSP_DEBUG_INTR, "BUSPHASE_MESSAGE_IN");
1245 if ((phase & BUSMON_REQ) == 0) {
1246 goto timer_out;
1247 }
1248
1249 tmpSC->SCp.phase = PH_MSG_IN;
1250 nsp_message_in(tmpSC);
1251
1252 /**/
1253 if (*sync_neg == SYNC_NOT_YET) {
1254 //nsp_dbg(NSP_DEBUG_INTR, "sync target=%d,lun=%d",target,lun);
1255
1256 if (data->MsgLen >= 5 &&
1c9eb798 1257 data->MsgBuffer[0] == EXTENDED_MESSAGE &&
1da177e4 1258 data->MsgBuffer[1] == 3 &&
1c9eb798 1259 data->MsgBuffer[2] == EXTENDED_SDTR ) {
1da177e4
LT
1260 data->Sync[target].SyncPeriod = data->MsgBuffer[3];
1261 data->Sync[target].SyncOffset = data->MsgBuffer[4];
1262 //nsp_dbg(NSP_DEBUG_INTR, "sync ok, %d %d", data->MsgBuffer[3], data->MsgBuffer[4]);
1263 *sync_neg = SYNC_OK;
1264 } else {
1265 data->Sync[target].SyncPeriod = 0;
1266 data->Sync[target].SyncOffset = 0;
1267 *sync_neg = SYNC_NG;
1268 }
1269 nsp_analyze_sdtr(tmpSC);
1270 }
1271 /**/
1272
1273 /* search last messeage byte */
1274 tmp = -1;
1275 for (i = 0; i < data->MsgLen; i++) {
1276 tmp = data->MsgBuffer[i];
1c9eb798 1277 if (data->MsgBuffer[i] == EXTENDED_MESSAGE) {
1da177e4
LT
1278 i += (1 + data->MsgBuffer[i+1]);
1279 }
1280 }
1281 tmpSC->SCp.Message = tmp;
1282
1283 nsp_dbg(NSP_DEBUG_INTR, "message=0x%x len=%d", tmpSC->SCp.Message, data->MsgLen);
1284 show_message(data);
1285
1286 break;
1287
1288 case BUSPHASE_SELECT:
1289 default:
1290 nsp_dbg(NSP_DEBUG_INTR, "BUSPHASE other");
1291
1292 break;
1293 }
1294
1295 //nsp_dbg(NSP_DEBUG_INTR, "out");
1296 return IRQ_HANDLED;
1297
1298timer_out:
1299 nsp_start_timer(tmpSC, 1000/102);
1300 return IRQ_HANDLED;
1301}
1302
1303#ifdef NSP_DEBUG
1304#include "nsp_debug.c"
1305#endif /* NSP_DEBUG */
1306
1307/*----------------------------------------------------------------*/
1308/* look for ninja3 card and init if found */
1309/*----------------------------------------------------------------*/
d0be4a7d 1310static struct Scsi_Host *nsp_detect(struct scsi_host_template *sht)
1da177e4
LT
1311{
1312 struct Scsi_Host *host; /* registered host structure */
1313 nsp_hw_data *data_b = &nsp_data_base, *data;
1314
1315 nsp_dbg(NSP_DEBUG_INIT, "this_id=%d", sht->this_id);
1da177e4 1316 host = scsi_host_alloc(&nsp_driver_template, sizeof(nsp_hw_data));
1da177e4
LT
1317 if (host == NULL) {
1318 nsp_dbg(NSP_DEBUG_INIT, "host failed");
1319 return NULL;
1320 }
1321
1322 memcpy(host->hostdata, data_b, sizeof(nsp_hw_data));
1323 data = (nsp_hw_data *)host->hostdata;
1324 data->ScsiInfo->host = host;
1325#ifdef NSP_DEBUG
1326 data->CmdId = 0;
1327#endif
1328
1329 nsp_dbg(NSP_DEBUG_INIT, "irq=%d,%d", data_b->IrqNumber, ((nsp_hw_data *)host->hostdata)->IrqNumber);
1330
1331 host->unique_id = data->BaseAddress;
1332 host->io_port = data->BaseAddress;
1333 host->n_io_port = data->NumAddress;
1334 host->irq = data->IrqNumber;
1335 host->base = data->MmioAddress;
1336
1337 spin_lock_init(&(data->Lock));
1338
1339 snprintf(data->nspinfo,
1340 sizeof(data->nspinfo),
1341 "NinjaSCSI-3/32Bi Driver $Revision: 1.23 $ IO:0x%04lx-0x%04lx MMIO(virt addr):0x%04lx IRQ:%02d",
1342 host->io_port, host->io_port + host->n_io_port - 1,
1343 host->base,
1344 host->irq);
1345 sht->name = data->nspinfo;
1346
1347 nsp_dbg(NSP_DEBUG_INIT, "end");
1348
1349
1350 return host; /* detect done. */
1351}
1352
1da177e4
LT
1353/*----------------------------------------------------------------*/
1354/* return info string */
1355/*----------------------------------------------------------------*/
1356static const char *nsp_info(struct Scsi_Host *shpnt)
1357{
1358 nsp_hw_data *data = (nsp_hw_data *)shpnt->hostdata;
1359
1360 return data->nspinfo;
1361}
1362
63fd57cb 1363static int nsp_show_info(struct seq_file *m, struct Scsi_Host *host)
1da177e4
LT
1364{
1365 int id;
1da177e4
LT
1366 int speed;
1367 unsigned long flags;
1368 nsp_hw_data *data;
1da177e4 1369 int hostno;
774251ef 1370
1da177e4 1371 hostno = host->host_no;
1da177e4
LT
1372 data = (nsp_hw_data *)host->hostdata;
1373
3d30079c
RV
1374 seq_puts(m, "NinjaSCSI status\n\n"
1375 "Driver version: $Revision: 1.23 $\n");
0c3de38f
RV
1376 seq_printf(m, "SCSI host No.: %d\n", hostno);
1377 seq_printf(m, "IRQ: %d\n", host->irq);
1378 seq_printf(m, "IO: 0x%lx-0x%lx\n", host->io_port, host->io_port + host->n_io_port - 1);
1379 seq_printf(m, "MMIO(virtual address): 0x%lx-0x%lx\n", host->base, host->base + data->MmioLength - 1);
1380 seq_printf(m, "sg_tablesize: %d\n", host->sg_tablesize);
1da177e4 1381
91c40f24 1382 seq_puts(m, "burst transfer mode: ");
1da177e4
LT
1383 switch (nsp_burst_mode) {
1384 case BURST_IO8:
91c40f24 1385 seq_puts(m, "io8");
1da177e4
LT
1386 break;
1387 case BURST_IO32:
91c40f24 1388 seq_puts(m, "io32");
1da177e4
LT
1389 break;
1390 case BURST_MEM32:
91c40f24 1391 seq_puts(m, "mem32");
1da177e4
LT
1392 break;
1393 default:
91c40f24 1394 seq_puts(m, "???");
1da177e4
LT
1395 break;
1396 }
f50332ff 1397 seq_putc(m, '\n');
1da177e4
LT
1398
1399
1400 spin_lock_irqsave(&(data->Lock), flags);
0c3de38f 1401 seq_printf(m, "CurrentSC: 0x%p\n\n", data->CurrentSC);
1da177e4
LT
1402 spin_unlock_irqrestore(&(data->Lock), flags);
1403
91c40f24 1404 seq_puts(m, "SDTR status\n");
1da177e4
LT
1405 for(id = 0; id < ARRAY_SIZE(data->Sync); id++) {
1406
0c3de38f 1407 seq_printf(m, "id %d: ", id);
1da177e4
LT
1408
1409 if (id == host->this_id) {
91c40f24 1410 seq_puts(m, "----- NinjaSCSI-3 host adapter\n");
1da177e4
LT
1411 continue;
1412 }
1413
1414 switch(data->Sync[id].SyncNegotiation) {
1415 case SYNC_OK:
91c40f24 1416 seq_puts(m, " sync");
1da177e4
LT
1417 break;
1418 case SYNC_NG:
91c40f24 1419 seq_puts(m, "async");
1da177e4
LT
1420 break;
1421 case SYNC_NOT_YET:
91c40f24 1422 seq_puts(m, " none");
1da177e4
LT
1423 break;
1424 default:
91c40f24 1425 seq_puts(m, "?????");
1da177e4
LT
1426 break;
1427 }
1428
1429 if (data->Sync[id].SyncPeriod != 0) {
1430 speed = 1000000 / (data->Sync[id].SyncPeriod * 4);
1431
0c3de38f 1432 seq_printf(m, " transfer %d.%dMB/s, offset %d",
1da177e4
LT
1433 speed / 1000,
1434 speed % 1000,
1435 data->Sync[id].SyncOffset
1436 );
1437 }
f50332ff 1438 seq_putc(m, '\n');
1da177e4 1439 }
63fd57cb 1440 return 0;
1da177e4 1441}
1da177e4
LT
1442
1443/*---------------------------------------------------------------*/
1444/* error handler */
1445/*---------------------------------------------------------------*/
1446
1da177e4 1447/*
0fc82d5e 1448static int nsp_eh_abort(struct scsi_cmnd *SCpnt)
1da177e4
LT
1449{
1450 nsp_dbg(NSP_DEBUG_BUSRESET, "SCpnt=0x%p", SCpnt);
1451
1452 return nsp_eh_bus_reset(SCpnt);
1453}*/
1454
1da177e4
LT
1455static int nsp_bus_reset(nsp_hw_data *data)
1456{
1457 unsigned int base = data->BaseAddress;
1458 int i;
1459
1460 nsp_write(base, IRQCONTROL, IRQCONTROL_ALLMASK);
1461
1462 nsp_index_write(base, SCSIBUSCTRL, SCSI_RST);
1463 mdelay(100); /* 100ms */
1464 nsp_index_write(base, SCSIBUSCTRL, 0);
1465 for(i = 0; i < 5; i++) {
1466 nsp_index_read(base, IRQPHASESENCE); /* dummy read */
1467 }
1468
1469 nsphw_init_sync(data);
1470
1471 nsp_write(base, IRQCONTROL, IRQCONTROL_ALLCLEAR);
1472
1473 return SUCCESS;
1474}
1475
0fc82d5e 1476static int nsp_eh_bus_reset(struct scsi_cmnd *SCpnt)
1da177e4
LT
1477{
1478 nsp_hw_data *data = (nsp_hw_data *)SCpnt->device->host->hostdata;
1479
1480 nsp_dbg(NSP_DEBUG_BUSRESET, "SCpnt=0x%p", SCpnt);
1481
1482 return nsp_bus_reset(data);
1483}
1484
0fc82d5e 1485static int nsp_eh_host_reset(struct scsi_cmnd *SCpnt)
1da177e4
LT
1486{
1487 nsp_hw_data *data = (nsp_hw_data *)SCpnt->device->host->hostdata;
1488
1489 nsp_dbg(NSP_DEBUG_BUSRESET, "in");
1490
1491 nsphw_init(data);
1492
1493 return SUCCESS;
1494}
1495
1496
1497/**********************************************************************
1498 PCMCIA functions
1499**********************************************************************/
1500
15b99ac1 1501static int nsp_cs_probe(struct pcmcia_device *link)
1da177e4
LT
1502{
1503 scsi_info_t *info;
1da177e4 1504 nsp_hw_data *data = &nsp_data_base;
15b99ac1 1505 int ret;
1da177e4
LT
1506
1507 nsp_dbg(NSP_DEBUG_INIT, "in");
1508
1509 /* Create new SCSI device */
dd00cc48 1510 info = kzalloc(sizeof(*info), GFP_KERNEL);
f8cfa618 1511 if (info == NULL) { return -ENOMEM; }
fba395ee 1512 info->p_dev = link;
1da177e4
LT
1513 link->priv = info;
1514 data->ScsiInfo = info;
1515
1516 nsp_dbg(NSP_DEBUG_INIT, "info=0x%p", info);
1517
15b99ac1 1518 ret = nsp_cs_config(link);
1da177e4
LT
1519
1520 nsp_dbg(NSP_DEBUG_INIT, "link=0x%p", link);
15b99ac1 1521 return ret;
1da177e4
LT
1522} /* nsp_cs_attach */
1523
1524
fba395ee 1525static void nsp_cs_detach(struct pcmcia_device *link)
1da177e4 1526{
1da177e4
LT
1527 nsp_dbg(NSP_DEBUG_INIT, "in, link=0x%p", link);
1528
e2d40963
DB
1529 ((scsi_info_t *)link->priv)->stop = 1;
1530 nsp_cs_release(link);
1da177e4 1531
1da177e4
LT
1532 kfree(link->priv);
1533 link->priv = NULL;
1da177e4
LT
1534} /* nsp_cs_detach */
1535
1536
00990e7c 1537static int nsp_cs_config_check(struct pcmcia_device *p_dev, void *priv_data)
0e6f9d27 1538{
cdb13808 1539 nsp_hw_data *data = priv_data;
1da177e4 1540
00990e7c 1541 if (p_dev->config_index == 0)
0e6f9d27 1542 return -ENODEV;
1da177e4 1543
00990e7c
DB
1544 /* This reserves IO space but doesn't actually enable it */
1545 if (pcmcia_request_io(p_dev) != 0)
1546 goto next_entry;
1da177e4 1547
00990e7c 1548 if (resource_size(p_dev->resource[2])) {
440eed43
DB
1549 p_dev->resource[2]->flags |= (WIN_DATA_WIDTH_16 |
1550 WIN_MEMORY_TYPE_CM |
1551 WIN_ENABLE);
440eed43
DB
1552 if (p_dev->resource[2]->end < 0x1000)
1553 p_dev->resource[2]->end = 0x1000;
1554 if (pcmcia_request_window(p_dev, p_dev->resource[2], 0) != 0)
1555 goto next_entry;
1556 if (pcmcia_map_mem_page(p_dev, p_dev->resource[2],
00990e7c 1557 p_dev->card_addr) != 0)
440eed43
DB
1558 goto next_entry;
1559
1560 data->MmioAddress = (unsigned long)
4bdc0d67 1561 ioremap(p_dev->resource[2]->start,
cdb13808 1562 resource_size(p_dev->resource[2]));
440eed43 1563 data->MmioLength = resource_size(p_dev->resource[2]);
1da177e4 1564 }
440eed43
DB
1565 /* If we got this far, we're cool! */
1566 return 0;
1da177e4 1567
0e6f9d27
DB
1568next_entry:
1569 nsp_dbg(NSP_DEBUG_INIT, "next");
1570 pcmcia_disable_device(p_dev);
1571 return -ENODEV;
1572}
1573
1574static int nsp_cs_config(struct pcmcia_device *link)
1575{
1576 int ret;
1577 scsi_info_t *info = link->priv;
0e6f9d27
DB
1578 struct Scsi_Host *host;
1579 nsp_hw_data *data = &nsp_data_base;
1580
1581 nsp_dbg(NSP_DEBUG_INIT, "in");
1582
440eed43 1583 link->config_flags |= CONF_ENABLE_IRQ | CONF_AUTO_CHECK_VCC |
00990e7c
DB
1584 CONF_AUTO_SET_VPP | CONF_AUTO_AUDIO | CONF_AUTO_SET_IOMEM |
1585 CONF_AUTO_SET_IO;
440eed43 1586
cdb13808 1587 ret = pcmcia_loop_config(link, nsp_cs_config_check, data);
e794c01b 1588 if (ret)
0e6f9d27
DB
1589 goto cs_failed;
1590
eb14120f
DB
1591 if (pcmcia_request_irq(link, nspintr))
1592 goto cs_failed;
0e6f9d27 1593
1ac71e5a 1594 ret = pcmcia_enable_device(link);
0e6f9d27
DB
1595 if (ret)
1596 goto cs_failed;
1da177e4
LT
1597
1598 if (free_ports) {
9a017a91
DB
1599 if (link->resource[0]) {
1600 release_region(link->resource[0]->start,
1601 resource_size(link->resource[0]));
1da177e4 1602 }
9a017a91
DB
1603 if (link->resource[1]) {
1604 release_region(link->resource[1]->start,
1605 resource_size(link->resource[1]));
1da177e4
LT
1606 }
1607 }
1608
1609 /* Set port and IRQ */
9a017a91
DB
1610 data->BaseAddress = link->resource[0]->start;
1611 data->NumAddress = resource_size(link->resource[0]);
eb14120f 1612 data->IrqNumber = link->irq;
1da177e4
LT
1613
1614 nsp_dbg(NSP_DEBUG_INIT, "I/O[0x%x+0x%x] IRQ %d",
1615 data->BaseAddress, data->NumAddress, data->IrqNumber);
1616
1617 if(nsphw_init(data) == FALSE) {
1618 goto cs_failed;
1619 }
1620
1da177e4 1621 host = nsp_detect(&nsp_driver_template);
1da177e4
LT
1622
1623 if (host == NULL) {
1624 nsp_dbg(NSP_DEBUG_INIT, "detect failed");
1625 goto cs_failed;
1626 }
1627
1628
15b99ac1
DB
1629 ret = scsi_add_host (host, NULL);
1630 if (ret)
1631 goto cs_failed;
1632
1da177e4
LT
1633 scsi_scan_host(host);
1634
1da177e4
LT
1635 info->host = host;
1636
15b99ac1 1637 return 0;
1da177e4
LT
1638
1639 cs_failed:
1640 nsp_dbg(NSP_DEBUG_INIT, "config fail");
1da177e4
LT
1641 nsp_cs_release(link);
1642
15b99ac1 1643 return -ENODEV;
1da177e4 1644} /* nsp_cs_config */
1da177e4
LT
1645
1646
fba395ee 1647static void nsp_cs_release(struct pcmcia_device *link)
1da177e4
LT
1648{
1649 scsi_info_t *info = link->priv;
1650 nsp_hw_data *data = NULL;
1651
1652 if (info->host == NULL) {
1653 nsp_msg(KERN_DEBUG, "unexpected card release call.");
1654 } else {
1655 data = (nsp_hw_data *)info->host->hostdata;
1656 }
1657
1658 nsp_dbg(NSP_DEBUG_INIT, "link=0x%p", link);
1659
1660 /* Unlink the device chain */
1da177e4
LT
1661 if (info->host != NULL) {
1662 scsi_remove_host(info->host);
1663 }
1da177e4 1664
cdb13808 1665 if (resource_size(link->resource[2])) {
1da177e4
LT
1666 if (data != NULL) {
1667 iounmap((void *)(data->MmioAddress));
1668 }
1da177e4 1669 }
fba395ee 1670 pcmcia_disable_device(link);
5f2a71fc 1671
1da177e4
LT
1672 if (info->host != NULL) {
1673 scsi_host_put(info->host);
1674 }
1da177e4
LT
1675} /* nsp_cs_release */
1676
fba395ee 1677static int nsp_cs_suspend(struct pcmcia_device *link)
98e4c28b 1678{
98e4c28b
DB
1679 scsi_info_t *info = link->priv;
1680 nsp_hw_data *data;
1681
98e4c28b
DB
1682 nsp_dbg(NSP_DEBUG_INIT, "event: suspend");
1683
1684 if (info->host != NULL) {
1685 nsp_msg(KERN_INFO, "clear SDTR status");
1686
1687 data = (nsp_hw_data *)info->host->hostdata;
1688
1689 nsphw_init_sync(data);
1690 }
1691
1692 info->stop = 1;
1693
98e4c28b
DB
1694 return 0;
1695}
1696
fba395ee 1697static int nsp_cs_resume(struct pcmcia_device *link)
98e4c28b 1698{
98e4c28b
DB
1699 scsi_info_t *info = link->priv;
1700 nsp_hw_data *data;
1701
1702 nsp_dbg(NSP_DEBUG_INIT, "event: resume");
1703
98e4c28b
DB
1704 info->stop = 0;
1705
1706 if (info->host != NULL) {
1707 nsp_msg(KERN_INFO, "reset host and bus");
1708
1709 data = (nsp_hw_data *)info->host->hostdata;
1710
1711 nsphw_init (data);
1712 nsp_bus_reset(data);
1713 }
1714
1715 return 0;
1716}
1717
1da177e4
LT
1718/*======================================================================*
1719 * module entry point
1720 *====================================================================*/
25f8f54f 1721static const struct pcmcia_device_id nsp_cs_ids[] = {
aba14100
DB
1722 PCMCIA_DEVICE_PROD_ID123("IO DATA", "CBSC16 ", "1", 0x547e66dc, 0x0d63a3fd, 0x51de003a),
1723 PCMCIA_DEVICE_PROD_ID123("KME ", "SCSI-CARD-001", "1", 0x534c02bc, 0x52008408, 0x51de003a),
1724 PCMCIA_DEVICE_PROD_ID123("KME ", "SCSI-CARD-002", "1", 0x534c02bc, 0xcb09d5b2, 0x51de003a),
1725 PCMCIA_DEVICE_PROD_ID123("KME ", "SCSI-CARD-003", "1", 0x534c02bc, 0xbc0ee524, 0x51de003a),
1726 PCMCIA_DEVICE_PROD_ID123("KME ", "SCSI-CARD-004", "1", 0x534c02bc, 0x226a7087, 0x51de003a),
1727 PCMCIA_DEVICE_PROD_ID123("WBT", "NinjaSCSI-3", "R1.0", 0xc7ba805f, 0xfdc7c97d, 0x6973710e),
1728 PCMCIA_DEVICE_PROD_ID123("WORKBIT", "UltraNinja-16", "1", 0x28191418, 0xb70f4b09, 0x51de003a),
1729 PCMCIA_DEVICE_NULL
1730};
1731MODULE_DEVICE_TABLE(pcmcia, nsp_cs_ids);
1732
1da177e4 1733static struct pcmcia_driver nsp_driver = {
1e212f36 1734 .owner = THIS_MODULE,
2e9b981a 1735 .name = "nsp_cs",
15b99ac1 1736 .probe = nsp_cs_probe,
cc3b4866 1737 .remove = nsp_cs_detach,
aba14100 1738 .id_table = nsp_cs_ids,
98e4c28b
DB
1739 .suspend = nsp_cs_suspend,
1740 .resume = nsp_cs_resume,
1da177e4 1741};
dc245cfa 1742module_pcmcia_driver(nsp_driver);
1da177e4
LT
1743
1744/* end */