iwlwifi: introduce host commands callbacks
[linux/fpc-iii.git] / drivers / scsi / pcmcia / nsp_cs.c
blob5082ca3c6876035df3818035873a47f1e6d181f9
1 /*======================================================================
3 NinjaSCSI-3 / NinjaSCSI-32Bi PCMCIA SCSI host adapter card driver
4 By: YOKOTA Hiroshi <yokota@netlab.is.tsukuba.ac.jp>
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
13 This software may be used and distributed according to the terms of
14 the GNU General Public License.
16 ======================================================================*/
18 /***********************************************************************
19 This driver is for these PCcards.
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"
26 ***********************************************************************/
28 #include <linux/version.h>
29 #include <linux/module.h>
30 #include <linux/kernel.h>
31 #include <linux/init.h>
32 #include <linux/slab.h>
33 #include <linux/string.h>
34 #include <linux/timer.h>
35 #include <linux/ioport.h>
36 #include <linux/delay.h>
37 #include <linux/interrupt.h>
38 #include <linux/major.h>
39 #include <linux/blkdev.h>
40 #include <linux/stat.h>
42 #include <asm/io.h>
43 #include <asm/irq.h>
45 #include <../drivers/scsi/scsi.h>
46 #include <scsi/scsi_host.h>
48 #include <scsi/scsi.h>
49 #include <scsi/scsi_ioctl.h>
51 #include <pcmcia/cs_types.h>
52 #include <pcmcia/cs.h>
53 #include <pcmcia/cistpl.h>
54 #include <pcmcia/cisreg.h>
55 #include <pcmcia/ds.h>
57 #include "nsp_cs.h"
59 MODULE_AUTHOR("YOKOTA Hiroshi <yokota@netlab.is.tsukuba.ac.jp>");
60 MODULE_DESCRIPTION("WorkBit NinjaSCSI-3 / NinjaSCSI-32Bi(16bit) PCMCIA SCSI host adapter module");
61 MODULE_SUPPORTED_DEVICE("sd,sr,sg,st");
62 #ifdef MODULE_LICENSE
63 MODULE_LICENSE("GPL");
64 #endif
66 #include "nsp_io.h"
68 /*====================================================================*/
69 /* Parameters that can be set with 'insmod' */
71 static int nsp_burst_mode = BURST_MEM32;
72 module_param(nsp_burst_mode, int, 0);
73 MODULE_PARM_DESC(nsp_burst_mode, "Burst transfer mode (0=io8, 1=io32, 2=mem32(default))");
75 /* Release IO ports after configuration? */
76 static int free_ports = 0;
77 module_param(free_ports, bool, 0);
78 MODULE_PARM_DESC(free_ports, "Release IO ports after configuration? (default: 0 (=no))");
80 static struct scsi_host_template nsp_driver_template = {
81 .proc_name = "nsp_cs",
82 .proc_info = nsp_proc_info,
83 .name = "WorkBit NinjaSCSI-3/32Bi(16bit)",
84 .info = nsp_info,
85 .queuecommand = nsp_queuecommand,
86 /* .eh_abort_handler = nsp_eh_abort,*/
87 .eh_bus_reset_handler = nsp_eh_bus_reset,
88 .eh_host_reset_handler = nsp_eh_host_reset,
89 .can_queue = 1,
90 .this_id = NSP_INITIATOR_ID,
91 .sg_tablesize = SG_ALL,
92 .cmd_per_lun = 1,
93 .use_clustering = DISABLE_CLUSTERING,
96 static nsp_hw_data nsp_data_base; /* attach <-> detect glue */
101 * debug, error print
103 #ifndef NSP_DEBUG
104 # define NSP_DEBUG_MASK 0x000000
105 # define nsp_msg(type, args...) nsp_cs_message("", 0, (type), args)
106 # define nsp_dbg(mask, args...) /* */
107 #else
108 # define NSP_DEBUG_MASK 0xffffff
109 # define nsp_msg(type, args...) \
110 nsp_cs_message (__FUNCTION__, __LINE__, (type), args)
111 # define nsp_dbg(mask, args...) \
112 nsp_cs_dmessage(__FUNCTION__, __LINE__, (mask), args)
113 #endif
115 #define NSP_DEBUG_QUEUECOMMAND BIT(0)
116 #define NSP_DEBUG_REGISTER BIT(1)
117 #define NSP_DEBUG_AUTOSCSI BIT(2)
118 #define NSP_DEBUG_INTR BIT(3)
119 #define NSP_DEBUG_SGLIST BIT(4)
120 #define NSP_DEBUG_BUSFREE BIT(5)
121 #define NSP_DEBUG_CDB_CONTENTS BIT(6)
122 #define NSP_DEBUG_RESELECTION BIT(7)
123 #define NSP_DEBUG_MSGINOCCUR BIT(8)
124 #define NSP_DEBUG_EEPROM BIT(9)
125 #define NSP_DEBUG_MSGOUTOCCUR BIT(10)
126 #define NSP_DEBUG_BUSRESET BIT(11)
127 #define NSP_DEBUG_RESTART BIT(12)
128 #define NSP_DEBUG_SYNC BIT(13)
129 #define NSP_DEBUG_WAIT BIT(14)
130 #define NSP_DEBUG_TARGETFLAG BIT(15)
131 #define NSP_DEBUG_PROC BIT(16)
132 #define NSP_DEBUG_INIT BIT(17)
133 #define NSP_DEBUG_DATA_IO BIT(18)
134 #define NSP_SPECIAL_PRINT_REGISTER BIT(20)
136 #define NSP_DEBUG_BUF_LEN 150
138 static inline void nsp_inc_resid(struct scsi_cmnd *SCpnt, int residInc)
140 scsi_set_resid(SCpnt, scsi_get_resid(SCpnt) + residInc);
143 static void nsp_cs_message(const char *func, int line, char *type, char *fmt, ...)
145 va_list args;
146 char buf[NSP_DEBUG_BUF_LEN];
148 va_start(args, fmt);
149 vsnprintf(buf, sizeof(buf), fmt, args);
150 va_end(args);
152 #ifndef NSP_DEBUG
153 printk("%snsp_cs: %s\n", type, buf);
154 #else
155 printk("%snsp_cs: %s (%d): %s\n", type, func, line, buf);
156 #endif
159 #ifdef NSP_DEBUG
160 static void nsp_cs_dmessage(const char *func, int line, int mask, char *fmt, ...)
162 va_list args;
163 char buf[NSP_DEBUG_BUF_LEN];
165 va_start(args, fmt);
166 vsnprintf(buf, sizeof(buf), fmt, args);
167 va_end(args);
169 if (mask & NSP_DEBUG_MASK) {
170 printk("nsp_cs-debug: 0x%x %s (%d): %s\n", mask, func, line, buf);
173 #endif
175 /***********************************************************/
177 /*====================================================
178 * Clenaup parameters and call done() functions.
179 * You must be set SCpnt->result before call this function.
181 static void nsp_scsi_done(struct scsi_cmnd *SCpnt)
183 nsp_hw_data *data = (nsp_hw_data *)SCpnt->device->host->hostdata;
185 data->CurrentSC = NULL;
187 SCpnt->scsi_done(SCpnt);
190 static int nsp_queuecommand(struct scsi_cmnd *SCpnt,
191 void (*done)(struct scsi_cmnd *))
193 #ifdef NSP_DEBUG
194 /*unsigned int host_id = SCpnt->device->host->this_id;*/
195 /*unsigned int base = SCpnt->device->host->io_port;*/
196 unsigned char target = scmd_id(SCpnt);
197 #endif
198 nsp_hw_data *data = (nsp_hw_data *)SCpnt->device->host->hostdata;
200 nsp_dbg(NSP_DEBUG_QUEUECOMMAND,
201 "SCpnt=0x%p target=%d lun=%d sglist=0x%p bufflen=%d sg_count=%d",
202 SCpnt, target, SCpnt->device->lun, scsi_sglist(SCpnt),
203 scsi_bufflen(SCpnt), scsi_sg_count(SCpnt));
204 //nsp_dbg(NSP_DEBUG_QUEUECOMMAND, "before CurrentSC=0x%p", data->CurrentSC);
206 SCpnt->scsi_done = done;
208 if (data->CurrentSC != NULL) {
209 nsp_msg(KERN_DEBUG, "CurrentSC!=NULL this can't be happen");
210 SCpnt->result = DID_BAD_TARGET << 16;
211 nsp_scsi_done(SCpnt);
212 return 0;
215 #if 0
216 /* XXX: pcmcia-cs generates SCSI command with "scsi_info" utility.
217 This makes kernel crash when suspending... */
218 if (data->ScsiInfo->stop != 0) {
219 nsp_msg(KERN_INFO, "suspending device. reject command.");
220 SCpnt->result = DID_BAD_TARGET << 16;
221 nsp_scsi_done(SCpnt);
222 return SCSI_MLQUEUE_HOST_BUSY;
224 #endif
226 show_command(SCpnt);
228 data->CurrentSC = SCpnt;
230 SCpnt->SCp.Status = CHECK_CONDITION;
231 SCpnt->SCp.Message = 0;
232 SCpnt->SCp.have_data_in = IO_UNKNOWN;
233 SCpnt->SCp.sent_command = 0;
234 SCpnt->SCp.phase = PH_UNDETERMINED;
235 scsi_set_resid(SCpnt, scsi_bufflen(SCpnt));
237 /* setup scratch area
238 SCp.ptr : buffer pointer
239 SCp.this_residual : buffer length
240 SCp.buffer : next buffer
241 SCp.buffers_residual : left buffers in list
242 SCp.phase : current state of the command */
243 if (scsi_bufflen(SCpnt)) {
244 SCpnt->SCp.buffer = scsi_sglist(SCpnt);
245 SCpnt->SCp.ptr = BUFFER_ADDR;
246 SCpnt->SCp.this_residual = SCpnt->SCp.buffer->length;
247 SCpnt->SCp.buffers_residual = scsi_sg_count(SCpnt) - 1;
248 } else {
249 SCpnt->SCp.ptr = NULL;
250 SCpnt->SCp.this_residual = 0;
251 SCpnt->SCp.buffer = NULL;
252 SCpnt->SCp.buffers_residual = 0;
255 if (nsphw_start_selection(SCpnt) == FALSE) {
256 nsp_dbg(NSP_DEBUG_QUEUECOMMAND, "selection fail");
257 SCpnt->result = DID_BUS_BUSY << 16;
258 nsp_scsi_done(SCpnt);
259 return 0;
263 //nsp_dbg(NSP_DEBUG_QUEUECOMMAND, "out");
264 #ifdef NSP_DEBUG
265 data->CmdId++;
266 #endif
267 return 0;
271 * setup PIO FIFO transfer mode and enable/disable to data out
273 static void nsp_setup_fifo(nsp_hw_data *data, int enabled)
275 unsigned int base = data->BaseAddress;
276 unsigned char transfer_mode_reg;
278 //nsp_dbg(NSP_DEBUG_DATA_IO, "enabled=%d", enabled);
280 if (enabled != FALSE) {
281 transfer_mode_reg = TRANSFER_GO | BRAIND;
282 } else {
283 transfer_mode_reg = 0;
286 transfer_mode_reg |= data->TransferMode;
288 nsp_index_write(base, TRANSFERMODE, transfer_mode_reg);
291 static void nsphw_init_sync(nsp_hw_data *data)
293 sync_data tmp_sync = { .SyncNegotiation = SYNC_NOT_YET,
294 .SyncPeriod = 0,
295 .SyncOffset = 0
297 int i;
299 /* setup sync data */
300 for ( i = 0; i < ARRAY_SIZE(data->Sync); i++ ) {
301 data->Sync[i] = tmp_sync;
306 * Initialize Ninja hardware
308 static int nsphw_init(nsp_hw_data *data)
310 unsigned int base = data->BaseAddress;
312 nsp_dbg(NSP_DEBUG_INIT, "in base=0x%x", base);
314 data->ScsiClockDiv = CLOCK_40M | FAST_20;
315 data->CurrentSC = NULL;
316 data->FifoCount = 0;
317 data->TransferMode = MODE_IO8;
319 nsphw_init_sync(data);
321 /* block all interrupts */
322 nsp_write(base, IRQCONTROL, IRQCONTROL_ALLMASK);
324 /* setup SCSI interface */
325 nsp_write(base, IFSELECT, IF_IFSEL);
327 nsp_index_write(base, SCSIIRQMODE, 0);
329 nsp_index_write(base, TRANSFERMODE, MODE_IO8);
330 nsp_index_write(base, CLOCKDIV, data->ScsiClockDiv);
332 nsp_index_write(base, PARITYCTRL, 0);
333 nsp_index_write(base, POINTERCLR, POINTER_CLEAR |
334 ACK_COUNTER_CLEAR |
335 REQ_COUNTER_CLEAR |
336 HOST_COUNTER_CLEAR);
338 /* setup fifo asic */
339 nsp_write(base, IFSELECT, IF_REGSEL);
340 nsp_index_write(base, TERMPWRCTRL, 0);
341 if ((nsp_index_read(base, OTHERCONTROL) & TPWR_SENSE) == 0) {
342 nsp_msg(KERN_INFO, "terminator power on");
343 nsp_index_write(base, TERMPWRCTRL, POWER_ON);
346 nsp_index_write(base, TIMERCOUNT, 0);
347 nsp_index_write(base, TIMERCOUNT, 0); /* requires 2 times!! */
349 nsp_index_write(base, SYNCREG, 0);
350 nsp_index_write(base, ACKWIDTH, 0);
352 /* enable interrupts and ack them */
353 nsp_index_write(base, SCSIIRQMODE, SCSI_PHASE_CHANGE_EI |
354 RESELECT_EI |
355 SCSI_RESET_IRQ_EI );
356 nsp_write(base, IRQCONTROL, IRQCONTROL_ALLCLEAR);
358 nsp_setup_fifo(data, FALSE);
360 return TRUE;
364 * Start selection phase
366 static int nsphw_start_selection(struct scsi_cmnd *SCpnt)
368 unsigned int host_id = SCpnt->device->host->this_id;
369 unsigned int base = SCpnt->device->host->io_port;
370 unsigned char target = scmd_id(SCpnt);
371 nsp_hw_data *data = (nsp_hw_data *)SCpnt->device->host->hostdata;
372 int time_out;
373 unsigned char phase, arbit;
375 //nsp_dbg(NSP_DEBUG_RESELECTION, "in");
377 phase = nsp_index_read(base, SCSIBUSMON);
378 if(phase != BUSMON_BUS_FREE) {
379 //nsp_dbg(NSP_DEBUG_RESELECTION, "bus busy");
380 return FALSE;
383 /* start arbitration */
384 //nsp_dbg(NSP_DEBUG_RESELECTION, "start arbit");
385 SCpnt->SCp.phase = PH_ARBSTART;
386 nsp_index_write(base, SETARBIT, ARBIT_GO);
388 time_out = 1000;
389 do {
390 /* XXX: what a stupid chip! */
391 arbit = nsp_index_read(base, ARBITSTATUS);
392 //nsp_dbg(NSP_DEBUG_RESELECTION, "arbit=%d, wait_count=%d", arbit, wait_count);
393 udelay(1); /* hold 1.2us */
394 } while((arbit & (ARBIT_WIN | ARBIT_FAIL)) == 0 &&
395 (time_out-- != 0));
397 if (!(arbit & ARBIT_WIN)) {
398 //nsp_dbg(NSP_DEBUG_RESELECTION, "arbit fail");
399 nsp_index_write(base, SETARBIT, ARBIT_FLAG_CLEAR);
400 return FALSE;
403 /* assert select line */
404 //nsp_dbg(NSP_DEBUG_RESELECTION, "assert SEL line");
405 SCpnt->SCp.phase = PH_SELSTART;
406 udelay(3); /* wait 2.4us */
407 nsp_index_write(base, SCSIDATALATCH, BIT(host_id) | BIT(target));
408 nsp_index_write(base, SCSIBUSCTRL, SCSI_SEL | SCSI_BSY | SCSI_ATN);
409 udelay(2); /* wait >1.2us */
410 nsp_index_write(base, SCSIBUSCTRL, SCSI_SEL | SCSI_BSY | SCSI_DATAOUT_ENB | SCSI_ATN);
411 nsp_index_write(base, SETARBIT, ARBIT_FLAG_CLEAR);
412 /*udelay(1);*/ /* wait >90ns */
413 nsp_index_write(base, SCSIBUSCTRL, SCSI_SEL | SCSI_DATAOUT_ENB | SCSI_ATN);
415 /* check selection timeout */
416 nsp_start_timer(SCpnt, 1000/51);
417 data->SelectionTimeOut = 1;
419 return TRUE;
422 struct nsp_sync_table {
423 unsigned int min_period;
424 unsigned int max_period;
425 unsigned int chip_period;
426 unsigned int ack_width;
429 static struct nsp_sync_table nsp_sync_table_40M[] = {
430 {0x0c, 0x0c, 0x1, 0}, /* 20MB 50ns*/
431 {0x19, 0x19, 0x3, 1}, /* 10MB 100ns*/
432 {0x1a, 0x25, 0x5, 2}, /* 7.5MB 150ns*/
433 {0x26, 0x32, 0x7, 3}, /* 5MB 200ns*/
434 { 0, 0, 0, 0},
437 static struct nsp_sync_table nsp_sync_table_20M[] = {
438 {0x19, 0x19, 0x1, 0}, /* 10MB 100ns*/
439 {0x1a, 0x25, 0x2, 0}, /* 7.5MB 150ns*/
440 {0x26, 0x32, 0x3, 1}, /* 5MB 200ns*/
441 { 0, 0, 0, 0},
445 * setup synchronous data transfer mode
447 static int nsp_analyze_sdtr(struct scsi_cmnd *SCpnt)
449 unsigned char target = scmd_id(SCpnt);
450 // unsigned char lun = SCpnt->device->lun;
451 nsp_hw_data *data = (nsp_hw_data *)SCpnt->device->host->hostdata;
452 sync_data *sync = &(data->Sync[target]);
453 struct nsp_sync_table *sync_table;
454 unsigned int period, offset;
455 int i;
458 nsp_dbg(NSP_DEBUG_SYNC, "in");
460 period = sync->SyncPeriod;
461 offset = sync->SyncOffset;
463 nsp_dbg(NSP_DEBUG_SYNC, "period=0x%x, offset=0x%x", period, offset);
465 if ((data->ScsiClockDiv & (BIT(0)|BIT(1))) == CLOCK_20M) {
466 sync_table = nsp_sync_table_20M;
467 } else {
468 sync_table = nsp_sync_table_40M;
471 for ( i = 0; sync_table->max_period != 0; i++, sync_table++) {
472 if ( period >= sync_table->min_period &&
473 period <= sync_table->max_period ) {
474 break;
478 if (period != 0 && sync_table->max_period == 0) {
480 * No proper period/offset found
482 nsp_dbg(NSP_DEBUG_SYNC, "no proper period/offset");
484 sync->SyncPeriod = 0;
485 sync->SyncOffset = 0;
486 sync->SyncRegister = 0;
487 sync->AckWidth = 0;
489 return FALSE;
492 sync->SyncRegister = (sync_table->chip_period << SYNCREG_PERIOD_SHIFT) |
493 (offset & SYNCREG_OFFSET_MASK);
494 sync->AckWidth = sync_table->ack_width;
496 nsp_dbg(NSP_DEBUG_SYNC, "sync_reg=0x%x, ack_width=0x%x", sync->SyncRegister, sync->AckWidth);
498 return TRUE;
503 * start ninja hardware timer
505 static void nsp_start_timer(struct scsi_cmnd *SCpnt, int time)
507 unsigned int base = SCpnt->device->host->io_port;
508 nsp_hw_data *data = (nsp_hw_data *)SCpnt->device->host->hostdata;
510 //nsp_dbg(NSP_DEBUG_INTR, "in SCpnt=0x%p, time=%d", SCpnt, time);
511 data->TimerCount = time;
512 nsp_index_write(base, TIMERCOUNT, time);
516 * wait for bus phase change
518 static int nsp_negate_signal(struct scsi_cmnd *SCpnt, unsigned char mask,
519 char *str)
521 unsigned int base = SCpnt->device->host->io_port;
522 unsigned char reg;
523 int time_out;
525 //nsp_dbg(NSP_DEBUG_INTR, "in");
527 time_out = 100;
529 do {
530 reg = nsp_index_read(base, SCSIBUSMON);
531 if (reg == 0xff) {
532 break;
534 } while ((time_out-- != 0) && (reg & mask) != 0);
536 if (time_out == 0) {
537 nsp_msg(KERN_DEBUG, " %s signal off timeut", str);
540 return 0;
544 * expect Ninja Irq
546 static int nsp_expect_signal(struct scsi_cmnd *SCpnt,
547 unsigned char current_phase,
548 unsigned char mask)
550 unsigned int base = SCpnt->device->host->io_port;
551 int time_out;
552 unsigned char phase, i_src;
554 //nsp_dbg(NSP_DEBUG_INTR, "current_phase=0x%x, mask=0x%x", current_phase, mask);
556 time_out = 100;
557 do {
558 phase = nsp_index_read(base, SCSIBUSMON);
559 if (phase == 0xff) {
560 //nsp_dbg(NSP_DEBUG_INTR, "ret -1");
561 return -1;
563 i_src = nsp_read(base, IRQSTATUS);
564 if (i_src & IRQSTATUS_SCSI) {
565 //nsp_dbg(NSP_DEBUG_INTR, "ret 0 found scsi signal");
566 return 0;
568 if ((phase & mask) != 0 && (phase & BUSMON_PHASE_MASK) == current_phase) {
569 //nsp_dbg(NSP_DEBUG_INTR, "ret 1 phase=0x%x", phase);
570 return 1;
572 } while(time_out-- != 0);
574 //nsp_dbg(NSP_DEBUG_INTR, "timeout");
575 return -1;
579 * transfer SCSI message
581 static int nsp_xfer(struct scsi_cmnd *SCpnt, int phase)
583 unsigned int base = SCpnt->device->host->io_port;
584 nsp_hw_data *data = (nsp_hw_data *)SCpnt->device->host->hostdata;
585 char *buf = data->MsgBuffer;
586 int len = min(MSGBUF_SIZE, data->MsgLen);
587 int ptr;
588 int ret;
590 //nsp_dbg(NSP_DEBUG_DATA_IO, "in");
591 for (ptr = 0; len > 0; len--, ptr++) {
593 ret = nsp_expect_signal(SCpnt, phase, BUSMON_REQ);
594 if (ret <= 0) {
595 nsp_dbg(NSP_DEBUG_DATA_IO, "xfer quit");
596 return 0;
599 /* if last byte, negate ATN */
600 if (len == 1 && SCpnt->SCp.phase == PH_MSG_OUT) {
601 nsp_index_write(base, SCSIBUSCTRL, AUTODIRECTION | ACKENB);
604 /* read & write message */
605 if (phase & BUSMON_IO) {
606 nsp_dbg(NSP_DEBUG_DATA_IO, "read msg");
607 buf[ptr] = nsp_index_read(base, SCSIDATAWITHACK);
608 } else {
609 nsp_dbg(NSP_DEBUG_DATA_IO, "write msg");
610 nsp_index_write(base, SCSIDATAWITHACK, buf[ptr]);
612 nsp_negate_signal(SCpnt, BUSMON_ACK, "xfer<ack>");
615 return len;
619 * get extra SCSI data from fifo
621 static int nsp_dataphase_bypass(struct scsi_cmnd *SCpnt)
623 nsp_hw_data *data = (nsp_hw_data *)SCpnt->device->host->hostdata;
624 unsigned int count;
626 //nsp_dbg(NSP_DEBUG_DATA_IO, "in");
628 if (SCpnt->SCp.have_data_in != IO_IN) {
629 return 0;
632 count = nsp_fifo_count(SCpnt);
633 if (data->FifoCount == count) {
634 //nsp_dbg(NSP_DEBUG_DATA_IO, "not use bypass quirk");
635 return 0;
639 * XXX: NSP_QUIRK
640 * data phase skip only occures in case of SCSI_LOW_READ
642 nsp_dbg(NSP_DEBUG_DATA_IO, "use bypass quirk");
643 SCpnt->SCp.phase = PH_DATA;
644 nsp_pio_read(SCpnt);
645 nsp_setup_fifo(data, FALSE);
647 return 0;
651 * accept reselection
653 static int nsp_reselected(struct scsi_cmnd *SCpnt)
655 unsigned int base = SCpnt->device->host->io_port;
656 unsigned int host_id = SCpnt->device->host->this_id;
657 //nsp_hw_data *data = (nsp_hw_data *)SCpnt->device->host->hostdata;
658 unsigned char bus_reg;
659 unsigned char id_reg, tmp;
660 int target;
662 nsp_dbg(NSP_DEBUG_RESELECTION, "in");
664 id_reg = nsp_index_read(base, RESELECTID);
665 tmp = id_reg & (~BIT(host_id));
666 target = 0;
667 while(tmp != 0) {
668 if (tmp & BIT(0)) {
669 break;
671 tmp >>= 1;
672 target++;
675 if (scmd_id(SCpnt) != target) {
676 nsp_msg(KERN_ERR, "XXX: reselect ID must be %d in this implementation.", target);
679 nsp_negate_signal(SCpnt, BUSMON_SEL, "reselect<SEL>");
681 nsp_nexus(SCpnt);
682 bus_reg = nsp_index_read(base, SCSIBUSCTRL) & ~(SCSI_BSY | SCSI_ATN);
683 nsp_index_write(base, SCSIBUSCTRL, bus_reg);
684 nsp_index_write(base, SCSIBUSCTRL, bus_reg | AUTODIRECTION | ACKENB);
686 return TRUE;
690 * count how many data transferd
692 static int nsp_fifo_count(struct scsi_cmnd *SCpnt)
694 unsigned int base = SCpnt->device->host->io_port;
695 unsigned int count;
696 unsigned int l, m, h, dummy;
698 nsp_index_write(base, POINTERCLR, POINTER_CLEAR | ACK_COUNTER);
700 l = nsp_index_read(base, TRANSFERCOUNT);
701 m = nsp_index_read(base, TRANSFERCOUNT);
702 h = nsp_index_read(base, TRANSFERCOUNT);
703 dummy = nsp_index_read(base, TRANSFERCOUNT); /* required this! */
705 count = (h << 16) | (m << 8) | (l << 0);
707 //nsp_dbg(NSP_DEBUG_DATA_IO, "count=0x%x", count);
709 return count;
712 /* fifo size */
713 #define RFIFO_CRIT 64
714 #define WFIFO_CRIT 64
717 * read data in DATA IN phase
719 static void nsp_pio_read(struct scsi_cmnd *SCpnt)
721 unsigned int base = SCpnt->device->host->io_port;
722 unsigned long mmio_base = SCpnt->device->host->base;
723 nsp_hw_data *data = (nsp_hw_data *)SCpnt->device->host->hostdata;
724 long time_out;
725 int ocount, res;
726 unsigned char stat, fifo_stat;
728 ocount = data->FifoCount;
730 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",
731 SCpnt, scsi_get_resid(SCpnt), ocount, SCpnt->SCp.ptr,
732 SCpnt->SCp.this_residual, SCpnt->SCp.buffer,
733 SCpnt->SCp.buffers_residual);
735 time_out = 1000;
737 while ((time_out-- != 0) &&
738 (SCpnt->SCp.this_residual > 0 || SCpnt->SCp.buffers_residual > 0 ) ) {
740 stat = nsp_index_read(base, SCSIBUSMON);
741 stat &= BUSMON_PHASE_MASK;
744 res = nsp_fifo_count(SCpnt) - ocount;
745 //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);
746 if (res == 0) { /* if some data avilable ? */
747 if (stat == BUSPHASE_DATA_IN) { /* phase changed? */
748 //nsp_dbg(NSP_DEBUG_DATA_IO, " wait for data this=%d", SCpnt->SCp.this_residual);
749 continue;
750 } else {
751 nsp_dbg(NSP_DEBUG_DATA_IO, "phase changed stat=0x%x", stat);
752 break;
756 fifo_stat = nsp_read(base, FIFOSTATUS);
757 if ((fifo_stat & FIFOSTATUS_FULL_EMPTY) == 0 &&
758 stat == BUSPHASE_DATA_IN) {
759 continue;
762 res = min(res, SCpnt->SCp.this_residual);
764 switch (data->TransferMode) {
765 case MODE_IO32:
766 res &= ~(BIT(1)|BIT(0)); /* align 4 */
767 nsp_fifo32_read(base, SCpnt->SCp.ptr, res >> 2);
768 break;
769 case MODE_IO8:
770 nsp_fifo8_read (base, SCpnt->SCp.ptr, res );
771 break;
773 case MODE_MEM32:
774 res &= ~(BIT(1)|BIT(0)); /* align 4 */
775 nsp_mmio_fifo32_read(mmio_base, SCpnt->SCp.ptr, res >> 2);
776 break;
778 default:
779 nsp_dbg(NSP_DEBUG_DATA_IO, "unknown read mode");
780 return;
783 nsp_inc_resid(SCpnt, -res);
784 SCpnt->SCp.ptr += res;
785 SCpnt->SCp.this_residual -= res;
786 ocount += res;
787 //nsp_dbg(NSP_DEBUG_DATA_IO, "ptr=0x%p this_residual=0x%x ocount=0x%x", SCpnt->SCp.ptr, SCpnt->SCp.this_residual, ocount);
789 /* go to next scatter list if available */
790 if (SCpnt->SCp.this_residual == 0 &&
791 SCpnt->SCp.buffers_residual != 0 ) {
792 //nsp_dbg(NSP_DEBUG_DATA_IO, "scatterlist next timeout=%d", time_out);
793 SCpnt->SCp.buffers_residual--;
794 SCpnt->SCp.buffer++;
795 SCpnt->SCp.ptr = BUFFER_ADDR;
796 SCpnt->SCp.this_residual = SCpnt->SCp.buffer->length;
797 time_out = 1000;
799 //nsp_dbg(NSP_DEBUG_DATA_IO, "page: 0x%p, off: 0x%x", SCpnt->SCp.buffer->page, SCpnt->SCp.buffer->offset);
803 data->FifoCount = ocount;
805 if (time_out == 0) {
806 nsp_msg(KERN_DEBUG, "pio read timeout resid=%d this_residual=%d buffers_residual=%d",
807 scsi_get_resid(SCpnt), SCpnt->SCp.this_residual,
808 SCpnt->SCp.buffers_residual);
810 nsp_dbg(NSP_DEBUG_DATA_IO, "read ocount=0x%x", ocount);
811 nsp_dbg(NSP_DEBUG_DATA_IO, "r cmd=%d resid=0x%x\n", data->CmdId,
812 scsi_get_resid(SCpnt));
816 * write data in DATA OUT phase
818 static void nsp_pio_write(struct scsi_cmnd *SCpnt)
820 unsigned int base = SCpnt->device->host->io_port;
821 unsigned long mmio_base = SCpnt->device->host->base;
822 nsp_hw_data *data = (nsp_hw_data *)SCpnt->device->host->hostdata;
823 int time_out;
824 int ocount, res;
825 unsigned char stat;
827 ocount = data->FifoCount;
829 nsp_dbg(NSP_DEBUG_DATA_IO, "in fifocount=%d ptr=0x%p this_residual=%d buffers=0x%p nbuf=%d resid=0x%x",
830 data->FifoCount, SCpnt->SCp.ptr, SCpnt->SCp.this_residual,
831 SCpnt->SCp.buffer, SCpnt->SCp.buffers_residual,
832 scsi_get_resid(SCpnt));
834 time_out = 1000;
836 while ((time_out-- != 0) &&
837 (SCpnt->SCp.this_residual > 0 || SCpnt->SCp.buffers_residual > 0)) {
838 stat = nsp_index_read(base, SCSIBUSMON);
839 stat &= BUSMON_PHASE_MASK;
841 if (stat != BUSPHASE_DATA_OUT) {
842 res = ocount - nsp_fifo_count(SCpnt);
844 nsp_dbg(NSP_DEBUG_DATA_IO, "phase changed stat=0x%x, res=%d\n", stat, res);
845 /* Put back pointer */
846 nsp_inc_resid(SCpnt, res);
847 SCpnt->SCp.ptr -= res;
848 SCpnt->SCp.this_residual += res;
849 ocount -= res;
851 break;
854 res = ocount - nsp_fifo_count(SCpnt);
855 if (res > 0) { /* write all data? */
856 nsp_dbg(NSP_DEBUG_DATA_IO, "wait for all data out. ocount=0x%x res=%d", ocount, res);
857 continue;
860 res = min(SCpnt->SCp.this_residual, WFIFO_CRIT);
862 //nsp_dbg(NSP_DEBUG_DATA_IO, "ptr=0x%p this=0x%x res=0x%x", SCpnt->SCp.ptr, SCpnt->SCp.this_residual, res);
863 switch (data->TransferMode) {
864 case MODE_IO32:
865 res &= ~(BIT(1)|BIT(0)); /* align 4 */
866 nsp_fifo32_write(base, SCpnt->SCp.ptr, res >> 2);
867 break;
868 case MODE_IO8:
869 nsp_fifo8_write (base, SCpnt->SCp.ptr, res );
870 break;
872 case MODE_MEM32:
873 res &= ~(BIT(1)|BIT(0)); /* align 4 */
874 nsp_mmio_fifo32_write(mmio_base, SCpnt->SCp.ptr, res >> 2);
875 break;
877 default:
878 nsp_dbg(NSP_DEBUG_DATA_IO, "unknown write mode");
879 break;
882 nsp_inc_resid(SCpnt, -res);
883 SCpnt->SCp.ptr += res;
884 SCpnt->SCp.this_residual -= res;
885 ocount += res;
887 /* go to next scatter list if available */
888 if (SCpnt->SCp.this_residual == 0 &&
889 SCpnt->SCp.buffers_residual != 0 ) {
890 //nsp_dbg(NSP_DEBUG_DATA_IO, "scatterlist next");
891 SCpnt->SCp.buffers_residual--;
892 SCpnt->SCp.buffer++;
893 SCpnt->SCp.ptr = BUFFER_ADDR;
894 SCpnt->SCp.this_residual = SCpnt->SCp.buffer->length;
895 time_out = 1000;
899 data->FifoCount = ocount;
901 if (time_out == 0) {
902 nsp_msg(KERN_DEBUG, "pio write timeout resid=0x%x",
903 scsi_get_resid(SCpnt));
905 nsp_dbg(NSP_DEBUG_DATA_IO, "write ocount=0x%x", ocount);
906 nsp_dbg(NSP_DEBUG_DATA_IO, "w cmd=%d resid=0x%x\n", data->CmdId,
907 scsi_get_resid(SCpnt));
909 #undef RFIFO_CRIT
910 #undef WFIFO_CRIT
913 * setup synchronous/asynchronous data transfer mode
915 static int nsp_nexus(struct scsi_cmnd *SCpnt)
917 unsigned int base = SCpnt->device->host->io_port;
918 unsigned char target = scmd_id(SCpnt);
919 // unsigned char lun = SCpnt->device->lun;
920 nsp_hw_data *data = (nsp_hw_data *)SCpnt->device->host->hostdata;
921 sync_data *sync = &(data->Sync[target]);
923 //nsp_dbg(NSP_DEBUG_DATA_IO, "in SCpnt=0x%p", SCpnt);
925 /* setup synch transfer registers */
926 nsp_index_write(base, SYNCREG, sync->SyncRegister);
927 nsp_index_write(base, ACKWIDTH, sync->AckWidth);
929 if (scsi_get_resid(SCpnt) % 4 != 0 ||
930 scsi_get_resid(SCpnt) <= PAGE_SIZE ) {
931 data->TransferMode = MODE_IO8;
932 } else if (nsp_burst_mode == BURST_MEM32) {
933 data->TransferMode = MODE_MEM32;
934 } else if (nsp_burst_mode == BURST_IO32) {
935 data->TransferMode = MODE_IO32;
936 } else {
937 data->TransferMode = MODE_IO8;
940 /* setup pdma fifo */
941 nsp_setup_fifo(data, TRUE);
943 /* clear ack counter */
944 data->FifoCount = 0;
945 nsp_index_write(base, POINTERCLR, POINTER_CLEAR |
946 ACK_COUNTER_CLEAR |
947 REQ_COUNTER_CLEAR |
948 HOST_COUNTER_CLEAR);
950 return 0;
953 #include "nsp_message.c"
955 * interrupt handler
957 static irqreturn_t nspintr(int irq, void *dev_id)
959 unsigned int base;
960 unsigned char irq_status, irq_phase, phase;
961 struct scsi_cmnd *tmpSC;
962 unsigned char target, lun;
963 unsigned int *sync_neg;
964 int i, tmp;
965 nsp_hw_data *data;
968 //nsp_dbg(NSP_DEBUG_INTR, "dev_id=0x%p", dev_id);
969 //nsp_dbg(NSP_DEBUG_INTR, "host=0x%p", ((scsi_info_t *)dev_id)->host);
971 if ( dev_id != NULL &&
972 ((scsi_info_t *)dev_id)->host != NULL ) {
973 scsi_info_t *info = (scsi_info_t *)dev_id;
975 data = (nsp_hw_data *)info->host->hostdata;
976 } else {
977 nsp_dbg(NSP_DEBUG_INTR, "host data wrong");
978 return IRQ_NONE;
981 //nsp_dbg(NSP_DEBUG_INTR, "&nsp_data_base=0x%p, dev_id=0x%p", &nsp_data_base, dev_id);
983 base = data->BaseAddress;
984 //nsp_dbg(NSP_DEBUG_INTR, "base=0x%x", base);
987 * interrupt check
989 nsp_write(base, IRQCONTROL, IRQCONTROL_IRQDISABLE);
990 irq_status = nsp_read(base, IRQSTATUS);
991 //nsp_dbg(NSP_DEBUG_INTR, "irq_status=0x%x", irq_status);
992 if ((irq_status == 0xff) || ((irq_status & IRQSTATUS_MASK) == 0)) {
993 nsp_write(base, IRQCONTROL, 0);
994 //nsp_dbg(NSP_DEBUG_INTR, "no irq/shared irq");
995 return IRQ_NONE;
998 /* XXX: IMPORTANT
999 * Do not read an irq_phase register if no scsi phase interrupt.
1000 * Unless, you should lose a scsi phase interrupt.
1002 phase = nsp_index_read(base, SCSIBUSMON);
1003 if((irq_status & IRQSTATUS_SCSI) != 0) {
1004 irq_phase = nsp_index_read(base, IRQPHASESENCE);
1005 } else {
1006 irq_phase = 0;
1009 //nsp_dbg(NSP_DEBUG_INTR, "irq_phase=0x%x", irq_phase);
1012 * timer interrupt handler (scsi vs timer interrupts)
1014 //nsp_dbg(NSP_DEBUG_INTR, "timercount=%d", data->TimerCount);
1015 if (data->TimerCount != 0) {
1016 //nsp_dbg(NSP_DEBUG_INTR, "stop timer");
1017 nsp_index_write(base, TIMERCOUNT, 0);
1018 nsp_index_write(base, TIMERCOUNT, 0);
1019 data->TimerCount = 0;
1022 if ((irq_status & IRQSTATUS_MASK) == IRQSTATUS_TIMER &&
1023 data->SelectionTimeOut == 0) {
1024 //nsp_dbg(NSP_DEBUG_INTR, "timer start");
1025 nsp_write(base, IRQCONTROL, IRQCONTROL_TIMER_CLEAR);
1026 return IRQ_HANDLED;
1029 nsp_write(base, IRQCONTROL, IRQCONTROL_TIMER_CLEAR | IRQCONTROL_FIFO_CLEAR);
1031 if ((irq_status & IRQSTATUS_SCSI) &&
1032 (irq_phase & SCSI_RESET_IRQ)) {
1033 nsp_msg(KERN_ERR, "bus reset (power off?)");
1035 nsphw_init(data);
1036 nsp_bus_reset(data);
1038 if(data->CurrentSC != NULL) {
1039 tmpSC = data->CurrentSC;
1040 tmpSC->result = (DID_RESET << 16) |
1041 ((tmpSC->SCp.Message & 0xff) << 8) |
1042 ((tmpSC->SCp.Status & 0xff) << 0);
1043 nsp_scsi_done(tmpSC);
1045 return IRQ_HANDLED;
1048 if (data->CurrentSC == NULL) {
1049 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);
1050 nsphw_init(data);
1051 nsp_bus_reset(data);
1052 return IRQ_HANDLED;
1055 tmpSC = data->CurrentSC;
1056 target = tmpSC->device->id;
1057 lun = tmpSC->device->lun;
1058 sync_neg = &(data->Sync[target].SyncNegotiation);
1061 * parse hardware SCSI irq reasons register
1063 if (irq_status & IRQSTATUS_SCSI) {
1064 if (irq_phase & RESELECT_IRQ) {
1065 nsp_dbg(NSP_DEBUG_INTR, "reselect");
1066 nsp_write(base, IRQCONTROL, IRQCONTROL_RESELECT_CLEAR);
1067 if (nsp_reselected(tmpSC) != FALSE) {
1068 return IRQ_HANDLED;
1072 if ((irq_phase & (PHASE_CHANGE_IRQ | LATCHED_BUS_FREE)) == 0) {
1073 return IRQ_HANDLED;
1077 //show_phase(tmpSC);
1079 switch(tmpSC->SCp.phase) {
1080 case PH_SELSTART:
1081 // *sync_neg = SYNC_NOT_YET;
1082 if ((phase & BUSMON_BSY) == 0) {
1083 //nsp_dbg(NSP_DEBUG_INTR, "selection count=%d", data->SelectionTimeOut);
1084 if (data->SelectionTimeOut >= NSP_SELTIMEOUT) {
1085 nsp_dbg(NSP_DEBUG_INTR, "selection time out");
1086 data->SelectionTimeOut = 0;
1087 nsp_index_write(base, SCSIBUSCTRL, 0);
1089 tmpSC->result = DID_TIME_OUT << 16;
1090 nsp_scsi_done(tmpSC);
1092 return IRQ_HANDLED;
1094 data->SelectionTimeOut += 1;
1095 nsp_start_timer(tmpSC, 1000/51);
1096 return IRQ_HANDLED;
1099 /* attention assert */
1100 //nsp_dbg(NSP_DEBUG_INTR, "attention assert");
1101 data->SelectionTimeOut = 0;
1102 tmpSC->SCp.phase = PH_SELECTED;
1103 nsp_index_write(base, SCSIBUSCTRL, SCSI_ATN);
1104 udelay(1);
1105 nsp_index_write(base, SCSIBUSCTRL, SCSI_ATN | AUTODIRECTION | ACKENB);
1106 return IRQ_HANDLED;
1108 break;
1110 case PH_RESELECT:
1111 //nsp_dbg(NSP_DEBUG_INTR, "phase reselect");
1112 // *sync_neg = SYNC_NOT_YET;
1113 if ((phase & BUSMON_PHASE_MASK) != BUSPHASE_MESSAGE_IN) {
1115 tmpSC->result = DID_ABORT << 16;
1116 nsp_scsi_done(tmpSC);
1117 return IRQ_HANDLED;
1119 /* fall thru */
1120 default:
1121 if ((irq_status & (IRQSTATUS_SCSI | IRQSTATUS_FIFO)) == 0) {
1122 return IRQ_HANDLED;
1124 break;
1128 * SCSI sequencer
1130 //nsp_dbg(NSP_DEBUG_INTR, "start scsi seq");
1132 /* normal disconnect */
1133 if (((tmpSC->SCp.phase == PH_MSG_IN) || (tmpSC->SCp.phase == PH_MSG_OUT)) &&
1134 (irq_phase & LATCHED_BUS_FREE) != 0 ) {
1135 nsp_dbg(NSP_DEBUG_INTR, "normal disconnect irq_status=0x%x, phase=0x%x, irq_phase=0x%x", irq_status, phase, irq_phase);
1137 //*sync_neg = SYNC_NOT_YET;
1139 if ((tmpSC->SCp.Message == MSG_COMMAND_COMPLETE)) { /* all command complete and return status */
1140 tmpSC->result = (DID_OK << 16) |
1141 ((tmpSC->SCp.Message & 0xff) << 8) |
1142 ((tmpSC->SCp.Status & 0xff) << 0);
1143 nsp_dbg(NSP_DEBUG_INTR, "command complete result=0x%x", tmpSC->result);
1144 nsp_scsi_done(tmpSC);
1146 return IRQ_HANDLED;
1149 return IRQ_HANDLED;
1153 /* check unexpected bus free state */
1154 if (phase == 0) {
1155 nsp_msg(KERN_DEBUG, "unexpected bus free. irq_status=0x%x, phase=0x%x, irq_phase=0x%x", irq_status, phase, irq_phase);
1157 *sync_neg = SYNC_NG;
1158 tmpSC->result = DID_ERROR << 16;
1159 nsp_scsi_done(tmpSC);
1160 return IRQ_HANDLED;
1163 switch (phase & BUSMON_PHASE_MASK) {
1164 case BUSPHASE_COMMAND:
1165 nsp_dbg(NSP_DEBUG_INTR, "BUSPHASE_COMMAND");
1166 if ((phase & BUSMON_REQ) == 0) {
1167 nsp_dbg(NSP_DEBUG_INTR, "REQ == 0");
1168 return IRQ_HANDLED;
1171 tmpSC->SCp.phase = PH_COMMAND;
1173 nsp_nexus(tmpSC);
1175 /* write scsi command */
1176 nsp_dbg(NSP_DEBUG_INTR, "cmd_len=%d", tmpSC->cmd_len);
1177 nsp_index_write(base, COMMANDCTRL, CLEAR_COMMAND_POINTER);
1178 for (i = 0; i < tmpSC->cmd_len; i++) {
1179 nsp_index_write(base, COMMANDDATA, tmpSC->cmnd[i]);
1181 nsp_index_write(base, COMMANDCTRL, CLEAR_COMMAND_POINTER | AUTO_COMMAND_GO);
1182 break;
1184 case BUSPHASE_DATA_OUT:
1185 nsp_dbg(NSP_DEBUG_INTR, "BUSPHASE_DATA_OUT");
1187 tmpSC->SCp.phase = PH_DATA;
1188 tmpSC->SCp.have_data_in = IO_OUT;
1190 nsp_pio_write(tmpSC);
1192 break;
1194 case BUSPHASE_DATA_IN:
1195 nsp_dbg(NSP_DEBUG_INTR, "BUSPHASE_DATA_IN");
1197 tmpSC->SCp.phase = PH_DATA;
1198 tmpSC->SCp.have_data_in = IO_IN;
1200 nsp_pio_read(tmpSC);
1202 break;
1204 case BUSPHASE_STATUS:
1205 nsp_dataphase_bypass(tmpSC);
1206 nsp_dbg(NSP_DEBUG_INTR, "BUSPHASE_STATUS");
1208 tmpSC->SCp.phase = PH_STATUS;
1210 tmpSC->SCp.Status = nsp_index_read(base, SCSIDATAWITHACK);
1211 nsp_dbg(NSP_DEBUG_INTR, "message=0x%x status=0x%x", tmpSC->SCp.Message, tmpSC->SCp.Status);
1213 break;
1215 case BUSPHASE_MESSAGE_OUT:
1216 nsp_dbg(NSP_DEBUG_INTR, "BUSPHASE_MESSAGE_OUT");
1217 if ((phase & BUSMON_REQ) == 0) {
1218 goto timer_out;
1221 tmpSC->SCp.phase = PH_MSG_OUT;
1223 //*sync_neg = SYNC_NOT_YET;
1225 data->MsgLen = i = 0;
1226 data->MsgBuffer[i] = IDENTIFY(TRUE, lun); i++;
1228 if (*sync_neg == SYNC_NOT_YET) {
1229 data->Sync[target].SyncPeriod = 0;
1230 data->Sync[target].SyncOffset = 0;
1232 /**/
1233 data->MsgBuffer[i] = MSG_EXTENDED; i++;
1234 data->MsgBuffer[i] = 3; i++;
1235 data->MsgBuffer[i] = MSG_EXT_SDTR; i++;
1236 data->MsgBuffer[i] = 0x0c; i++;
1237 data->MsgBuffer[i] = 15; i++;
1238 /**/
1240 data->MsgLen = i;
1242 nsp_analyze_sdtr(tmpSC);
1243 show_message(data);
1244 nsp_message_out(tmpSC);
1245 break;
1247 case BUSPHASE_MESSAGE_IN:
1248 nsp_dataphase_bypass(tmpSC);
1249 nsp_dbg(NSP_DEBUG_INTR, "BUSPHASE_MESSAGE_IN");
1250 if ((phase & BUSMON_REQ) == 0) {
1251 goto timer_out;
1254 tmpSC->SCp.phase = PH_MSG_IN;
1255 nsp_message_in(tmpSC);
1257 /**/
1258 if (*sync_neg == SYNC_NOT_YET) {
1259 //nsp_dbg(NSP_DEBUG_INTR, "sync target=%d,lun=%d",target,lun);
1261 if (data->MsgLen >= 5 &&
1262 data->MsgBuffer[0] == MSG_EXTENDED &&
1263 data->MsgBuffer[1] == 3 &&
1264 data->MsgBuffer[2] == MSG_EXT_SDTR ) {
1265 data->Sync[target].SyncPeriod = data->MsgBuffer[3];
1266 data->Sync[target].SyncOffset = data->MsgBuffer[4];
1267 //nsp_dbg(NSP_DEBUG_INTR, "sync ok, %d %d", data->MsgBuffer[3], data->MsgBuffer[4]);
1268 *sync_neg = SYNC_OK;
1269 } else {
1270 data->Sync[target].SyncPeriod = 0;
1271 data->Sync[target].SyncOffset = 0;
1272 *sync_neg = SYNC_NG;
1274 nsp_analyze_sdtr(tmpSC);
1276 /**/
1278 /* search last messeage byte */
1279 tmp = -1;
1280 for (i = 0; i < data->MsgLen; i++) {
1281 tmp = data->MsgBuffer[i];
1282 if (data->MsgBuffer[i] == MSG_EXTENDED) {
1283 i += (1 + data->MsgBuffer[i+1]);
1286 tmpSC->SCp.Message = tmp;
1288 nsp_dbg(NSP_DEBUG_INTR, "message=0x%x len=%d", tmpSC->SCp.Message, data->MsgLen);
1289 show_message(data);
1291 break;
1293 case BUSPHASE_SELECT:
1294 default:
1295 nsp_dbg(NSP_DEBUG_INTR, "BUSPHASE other");
1297 break;
1300 //nsp_dbg(NSP_DEBUG_INTR, "out");
1301 return IRQ_HANDLED;
1303 timer_out:
1304 nsp_start_timer(tmpSC, 1000/102);
1305 return IRQ_HANDLED;
1308 #ifdef NSP_DEBUG
1309 #include "nsp_debug.c"
1310 #endif /* NSP_DEBUG */
1312 /*----------------------------------------------------------------*/
1313 /* look for ninja3 card and init if found */
1314 /*----------------------------------------------------------------*/
1315 static struct Scsi_Host *nsp_detect(struct scsi_host_template *sht)
1317 struct Scsi_Host *host; /* registered host structure */
1318 nsp_hw_data *data_b = &nsp_data_base, *data;
1320 nsp_dbg(NSP_DEBUG_INIT, "this_id=%d", sht->this_id);
1321 host = scsi_host_alloc(&nsp_driver_template, sizeof(nsp_hw_data));
1322 if (host == NULL) {
1323 nsp_dbg(NSP_DEBUG_INIT, "host failed");
1324 return NULL;
1327 memcpy(host->hostdata, data_b, sizeof(nsp_hw_data));
1328 data = (nsp_hw_data *)host->hostdata;
1329 data->ScsiInfo->host = host;
1330 #ifdef NSP_DEBUG
1331 data->CmdId = 0;
1332 #endif
1334 nsp_dbg(NSP_DEBUG_INIT, "irq=%d,%d", data_b->IrqNumber, ((nsp_hw_data *)host->hostdata)->IrqNumber);
1336 host->unique_id = data->BaseAddress;
1337 host->io_port = data->BaseAddress;
1338 host->n_io_port = data->NumAddress;
1339 host->irq = data->IrqNumber;
1340 host->base = data->MmioAddress;
1342 spin_lock_init(&(data->Lock));
1344 snprintf(data->nspinfo,
1345 sizeof(data->nspinfo),
1346 "NinjaSCSI-3/32Bi Driver $Revision: 1.23 $ IO:0x%04lx-0x%04lx MMIO(virt addr):0x%04lx IRQ:%02d",
1347 host->io_port, host->io_port + host->n_io_port - 1,
1348 host->base,
1349 host->irq);
1350 sht->name = data->nspinfo;
1352 nsp_dbg(NSP_DEBUG_INIT, "end");
1355 return host; /* detect done. */
1358 /*----------------------------------------------------------------*/
1359 /* return info string */
1360 /*----------------------------------------------------------------*/
1361 static const char *nsp_info(struct Scsi_Host *shpnt)
1363 nsp_hw_data *data = (nsp_hw_data *)shpnt->hostdata;
1365 return data->nspinfo;
1368 #undef SPRINTF
1369 #define SPRINTF(args...) \
1370 do { \
1371 if(length > (pos - buffer)) { \
1372 pos += snprintf(pos, length - (pos - buffer) + 1, ## args); \
1373 nsp_dbg(NSP_DEBUG_PROC, "buffer=0x%p pos=0x%p length=%d %d\n", buffer, pos, length, length - (pos - buffer));\
1375 } while(0)
1377 static int nsp_proc_info(struct Scsi_Host *host, char *buffer, char **start,
1378 off_t offset, int length, int inout)
1380 int id;
1381 char *pos = buffer;
1382 int thislength;
1383 int speed;
1384 unsigned long flags;
1385 nsp_hw_data *data;
1386 int hostno;
1388 if (inout) {
1389 return -EINVAL;
1392 hostno = host->host_no;
1393 data = (nsp_hw_data *)host->hostdata;
1396 SPRINTF("NinjaSCSI status\n\n");
1397 SPRINTF("Driver version: $Revision: 1.23 $\n");
1398 SPRINTF("SCSI host No.: %d\n", hostno);
1399 SPRINTF("IRQ: %d\n", host->irq);
1400 SPRINTF("IO: 0x%lx-0x%lx\n", host->io_port, host->io_port + host->n_io_port - 1);
1401 SPRINTF("MMIO(virtual address): 0x%lx-0x%lx\n", host->base, host->base + data->MmioLength - 1);
1402 SPRINTF("sg_tablesize: %d\n", host->sg_tablesize);
1404 SPRINTF("burst transfer mode: ");
1405 switch (nsp_burst_mode) {
1406 case BURST_IO8:
1407 SPRINTF("io8");
1408 break;
1409 case BURST_IO32:
1410 SPRINTF("io32");
1411 break;
1412 case BURST_MEM32:
1413 SPRINTF("mem32");
1414 break;
1415 default:
1416 SPRINTF("???");
1417 break;
1419 SPRINTF("\n");
1422 spin_lock_irqsave(&(data->Lock), flags);
1423 SPRINTF("CurrentSC: 0x%p\n\n", data->CurrentSC);
1424 spin_unlock_irqrestore(&(data->Lock), flags);
1426 SPRINTF("SDTR status\n");
1427 for(id = 0; id < ARRAY_SIZE(data->Sync); id++) {
1429 SPRINTF("id %d: ", id);
1431 if (id == host->this_id) {
1432 SPRINTF("----- NinjaSCSI-3 host adapter\n");
1433 continue;
1436 switch(data->Sync[id].SyncNegotiation) {
1437 case SYNC_OK:
1438 SPRINTF(" sync");
1439 break;
1440 case SYNC_NG:
1441 SPRINTF("async");
1442 break;
1443 case SYNC_NOT_YET:
1444 SPRINTF(" none");
1445 break;
1446 default:
1447 SPRINTF("?????");
1448 break;
1451 if (data->Sync[id].SyncPeriod != 0) {
1452 speed = 1000000 / (data->Sync[id].SyncPeriod * 4);
1454 SPRINTF(" transfer %d.%dMB/s, offset %d",
1455 speed / 1000,
1456 speed % 1000,
1457 data->Sync[id].SyncOffset
1460 SPRINTF("\n");
1463 thislength = pos - (buffer + offset);
1465 if(thislength < 0) {
1466 *start = NULL;
1467 return 0;
1471 thislength = min(thislength, length);
1472 *start = buffer + offset;
1474 return thislength;
1476 #undef SPRINTF
1478 /*---------------------------------------------------------------*/
1479 /* error handler */
1480 /*---------------------------------------------------------------*/
1483 static int nsp_eh_abort(struct scsi_cmnd *SCpnt)
1485 nsp_dbg(NSP_DEBUG_BUSRESET, "SCpnt=0x%p", SCpnt);
1487 return nsp_eh_bus_reset(SCpnt);
1490 static int nsp_bus_reset(nsp_hw_data *data)
1492 unsigned int base = data->BaseAddress;
1493 int i;
1495 nsp_write(base, IRQCONTROL, IRQCONTROL_ALLMASK);
1497 nsp_index_write(base, SCSIBUSCTRL, SCSI_RST);
1498 mdelay(100); /* 100ms */
1499 nsp_index_write(base, SCSIBUSCTRL, 0);
1500 for(i = 0; i < 5; i++) {
1501 nsp_index_read(base, IRQPHASESENCE); /* dummy read */
1504 nsphw_init_sync(data);
1506 nsp_write(base, IRQCONTROL, IRQCONTROL_ALLCLEAR);
1508 return SUCCESS;
1511 static int nsp_eh_bus_reset(struct scsi_cmnd *SCpnt)
1513 nsp_hw_data *data = (nsp_hw_data *)SCpnt->device->host->hostdata;
1515 nsp_dbg(NSP_DEBUG_BUSRESET, "SCpnt=0x%p", SCpnt);
1517 return nsp_bus_reset(data);
1520 static int nsp_eh_host_reset(struct scsi_cmnd *SCpnt)
1522 nsp_hw_data *data = (nsp_hw_data *)SCpnt->device->host->hostdata;
1524 nsp_dbg(NSP_DEBUG_BUSRESET, "in");
1526 nsphw_init(data);
1528 return SUCCESS;
1532 /**********************************************************************
1533 PCMCIA functions
1534 **********************************************************************/
1536 /*======================================================================
1537 nsp_cs_attach() creates an "instance" of the driver, allocating
1538 local data structures for one device. The device is registered
1539 with Card Services.
1541 The dev_link structure is initialized, but we don't actually
1542 configure the card at this point -- we wait until we receive a
1543 card insertion event.
1544 ======================================================================*/
1545 static int nsp_cs_probe(struct pcmcia_device *link)
1547 scsi_info_t *info;
1548 nsp_hw_data *data = &nsp_data_base;
1549 int ret;
1551 nsp_dbg(NSP_DEBUG_INIT, "in");
1553 /* Create new SCSI device */
1554 info = kzalloc(sizeof(*info), GFP_KERNEL);
1555 if (info == NULL) { return -ENOMEM; }
1556 info->p_dev = link;
1557 link->priv = info;
1558 data->ScsiInfo = info;
1560 nsp_dbg(NSP_DEBUG_INIT, "info=0x%p", info);
1562 /* The io structure describes IO port mapping */
1563 link->io.NumPorts1 = 0x10;
1564 link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
1565 link->io.IOAddrLines = 10; /* not used */
1567 /* Interrupt setup */
1568 link->irq.Attributes = IRQ_TYPE_EXCLUSIVE | IRQ_HANDLE_PRESENT;
1569 link->irq.IRQInfo1 = IRQ_LEVEL_ID;
1571 /* Interrupt handler */
1572 link->irq.Handler = &nspintr;
1573 link->irq.Instance = info;
1574 link->irq.Attributes |= IRQF_SHARED;
1576 /* General socket configuration */
1577 link->conf.Attributes = CONF_ENABLE_IRQ;
1578 link->conf.IntType = INT_MEMORY_AND_IO;
1580 ret = nsp_cs_config(link);
1582 nsp_dbg(NSP_DEBUG_INIT, "link=0x%p", link);
1583 return ret;
1584 } /* nsp_cs_attach */
1587 /*======================================================================
1588 This deletes a driver "instance". The device is de-registered
1589 with Card Services. If it has been released, all local data
1590 structures are freed. Otherwise, the structures will be freed
1591 when the device is released.
1592 ======================================================================*/
1593 static void nsp_cs_detach(struct pcmcia_device *link)
1595 nsp_dbg(NSP_DEBUG_INIT, "in, link=0x%p", link);
1597 ((scsi_info_t *)link->priv)->stop = 1;
1598 nsp_cs_release(link);
1600 kfree(link->priv);
1601 link->priv = NULL;
1602 } /* nsp_cs_detach */
1605 /*======================================================================
1606 nsp_cs_config() is scheduled to run after a CARD_INSERTION event
1607 is received, to configure the PCMCIA socket, and to make the
1608 ethernet device available to the system.
1609 ======================================================================*/
1610 #define CS_CHECK(fn, ret) \
1611 do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
1612 /*====================================================================*/
1613 static int nsp_cs_config(struct pcmcia_device *link)
1615 int ret;
1616 scsi_info_t *info = link->priv;
1617 tuple_t tuple;
1618 cisparse_t parse;
1619 int last_ret, last_fn;
1620 unsigned char tuple_data[64];
1621 config_info_t conf;
1622 win_req_t req;
1623 memreq_t map;
1624 cistpl_cftable_entry_t dflt = { 0 };
1625 struct Scsi_Host *host;
1626 nsp_hw_data *data = &nsp_data_base;
1628 nsp_dbg(NSP_DEBUG_INIT, "in");
1630 tuple.Attributes = 0;
1631 tuple.TupleData = tuple_data;
1632 tuple.TupleDataMax = sizeof(tuple_data);
1633 tuple.TupleOffset = 0;
1635 /* Look up the current Vcc */
1636 CS_CHECK(GetConfigurationInfo, pcmcia_get_configuration_info(link, &conf));
1638 tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
1639 CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple));
1640 while (1) {
1641 cistpl_cftable_entry_t *cfg = &(parse.cftable_entry);
1643 if (pcmcia_get_tuple_data(link, &tuple) != 0 ||
1644 pcmcia_parse_tuple(link, &tuple, &parse) != 0)
1645 goto next_entry;
1647 if (cfg->flags & CISTPL_CFTABLE_DEFAULT) { dflt = *cfg; }
1648 if (cfg->index == 0) { goto next_entry; }
1649 link->conf.ConfigIndex = cfg->index;
1651 /* Does this card need audio output? */
1652 if (cfg->flags & CISTPL_CFTABLE_AUDIO) {
1653 link->conf.Attributes |= CONF_ENABLE_SPKR;
1654 link->conf.Status = CCSR_AUDIO_ENA;
1657 /* Use power settings for Vcc and Vpp if present */
1658 /* Note that the CIS values need to be rescaled */
1659 if (cfg->vcc.present & (1<<CISTPL_POWER_VNOM)) {
1660 if (conf.Vcc != cfg->vcc.param[CISTPL_POWER_VNOM]/10000) {
1661 goto next_entry;
1663 } else if (dflt.vcc.present & (1<<CISTPL_POWER_VNOM)) {
1664 if (conf.Vcc != dflt.vcc.param[CISTPL_POWER_VNOM]/10000) {
1665 goto next_entry;
1669 if (cfg->vpp1.present & (1 << CISTPL_POWER_VNOM)) {
1670 link->conf.Vpp =
1671 cfg->vpp1.param[CISTPL_POWER_VNOM] / 10000;
1672 } else if (dflt.vpp1.present & (1 << CISTPL_POWER_VNOM)) {
1673 link->conf.Vpp =
1674 dflt.vpp1.param[CISTPL_POWER_VNOM] / 10000;
1677 /* Do we need to allocate an interrupt? */
1678 if (cfg->irq.IRQInfo1 || dflt.irq.IRQInfo1) {
1679 link->conf.Attributes |= CONF_ENABLE_IRQ;
1682 /* IO window settings */
1683 link->io.NumPorts1 = link->io.NumPorts2 = 0;
1684 if ((cfg->io.nwin > 0) || (dflt.io.nwin > 0)) {
1685 cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt.io;
1686 link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
1687 if (!(io->flags & CISTPL_IO_8BIT))
1688 link->io.Attributes1 = IO_DATA_PATH_WIDTH_16;
1689 if (!(io->flags & CISTPL_IO_16BIT))
1690 link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
1691 link->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK;
1692 link->io.BasePort1 = io->win[0].base;
1693 link->io.NumPorts1 = io->win[0].len;
1694 if (io->nwin > 1) {
1695 link->io.Attributes2 = link->io.Attributes1;
1696 link->io.BasePort2 = io->win[1].base;
1697 link->io.NumPorts2 = io->win[1].len;
1699 /* This reserves IO space but doesn't actually enable it */
1700 if (pcmcia_request_io(link, &link->io) != 0)
1701 goto next_entry;
1704 if ((cfg->mem.nwin > 0) || (dflt.mem.nwin > 0)) {
1705 cistpl_mem_t *mem =
1706 (cfg->mem.nwin) ? &cfg->mem : &dflt.mem;
1707 req.Attributes = WIN_DATA_WIDTH_16|WIN_MEMORY_TYPE_CM;
1708 req.Attributes |= WIN_ENABLE;
1709 req.Base = mem->win[0].host_addr;
1710 req.Size = mem->win[0].len;
1711 if (req.Size < 0x1000) {
1712 req.Size = 0x1000;
1714 req.AccessSpeed = 0;
1715 if (pcmcia_request_window(&link, &req, &link->win) != 0)
1716 goto next_entry;
1717 map.Page = 0; map.CardOffset = mem->win[0].card_addr;
1718 if (pcmcia_map_mem_page(link->win, &map) != 0)
1719 goto next_entry;
1721 data->MmioAddress = (unsigned long)ioremap_nocache(req.Base, req.Size);
1722 data->MmioLength = req.Size;
1724 /* If we got this far, we're cool! */
1725 break;
1727 next_entry:
1728 nsp_dbg(NSP_DEBUG_INIT, "next");
1729 pcmcia_disable_device(link);
1730 CS_CHECK(GetNextTuple, pcmcia_get_next_tuple(link, &tuple));
1733 if (link->conf.Attributes & CONF_ENABLE_IRQ) {
1734 CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq));
1736 CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link, &link->conf));
1738 if (free_ports) {
1739 if (link->io.BasePort1) {
1740 release_region(link->io.BasePort1, link->io.NumPorts1);
1742 if (link->io.BasePort2) {
1743 release_region(link->io.BasePort2, link->io.NumPorts2);
1747 /* Set port and IRQ */
1748 data->BaseAddress = link->io.BasePort1;
1749 data->NumAddress = link->io.NumPorts1;
1750 data->IrqNumber = link->irq.AssignedIRQ;
1752 nsp_dbg(NSP_DEBUG_INIT, "I/O[0x%x+0x%x] IRQ %d",
1753 data->BaseAddress, data->NumAddress, data->IrqNumber);
1755 if(nsphw_init(data) == FALSE) {
1756 goto cs_failed;
1759 host = nsp_detect(&nsp_driver_template);
1761 if (host == NULL) {
1762 nsp_dbg(NSP_DEBUG_INIT, "detect failed");
1763 goto cs_failed;
1767 ret = scsi_add_host (host, NULL);
1768 if (ret)
1769 goto cs_failed;
1771 scsi_scan_host(host);
1773 snprintf(info->node.dev_name, sizeof(info->node.dev_name), "scsi%d", host->host_no);
1774 link->dev_node = &info->node;
1775 info->host = host;
1777 /* Finally, report what we've done */
1778 printk(KERN_INFO "nsp_cs: index 0x%02x: ",
1779 link->conf.ConfigIndex);
1780 if (link->conf.Vpp) {
1781 printk(", Vpp %d.%d", link->conf.Vpp/10, link->conf.Vpp%10);
1783 if (link->conf.Attributes & CONF_ENABLE_IRQ) {
1784 printk(", irq %d", link->irq.AssignedIRQ);
1786 if (link->io.NumPorts1) {
1787 printk(", io 0x%04x-0x%04x", link->io.BasePort1,
1788 link->io.BasePort1+link->io.NumPorts1-1);
1790 if (link->io.NumPorts2)
1791 printk(" & 0x%04x-0x%04x", link->io.BasePort2,
1792 link->io.BasePort2+link->io.NumPorts2-1);
1793 if (link->win)
1794 printk(", mem 0x%06lx-0x%06lx", req.Base,
1795 req.Base+req.Size-1);
1796 printk("\n");
1798 return 0;
1800 cs_failed:
1801 nsp_dbg(NSP_DEBUG_INIT, "config fail");
1802 cs_error(link, last_fn, last_ret);
1803 nsp_cs_release(link);
1805 return -ENODEV;
1806 } /* nsp_cs_config */
1807 #undef CS_CHECK
1810 /*======================================================================
1811 After a card is removed, nsp_cs_release() will unregister the net
1812 device, and release the PCMCIA configuration. If the device is
1813 still open, this will be postponed until it is closed.
1814 ======================================================================*/
1815 static void nsp_cs_release(struct pcmcia_device *link)
1817 scsi_info_t *info = link->priv;
1818 nsp_hw_data *data = NULL;
1820 if (info->host == NULL) {
1821 nsp_msg(KERN_DEBUG, "unexpected card release call.");
1822 } else {
1823 data = (nsp_hw_data *)info->host->hostdata;
1826 nsp_dbg(NSP_DEBUG_INIT, "link=0x%p", link);
1828 /* Unlink the device chain */
1829 if (info->host != NULL) {
1830 scsi_remove_host(info->host);
1832 link->dev_node = NULL;
1834 if (link->win) {
1835 if (data != NULL) {
1836 iounmap((void *)(data->MmioAddress));
1839 pcmcia_disable_device(link);
1841 if (info->host != NULL) {
1842 scsi_host_put(info->host);
1844 } /* nsp_cs_release */
1846 static int nsp_cs_suspend(struct pcmcia_device *link)
1848 scsi_info_t *info = link->priv;
1849 nsp_hw_data *data;
1851 nsp_dbg(NSP_DEBUG_INIT, "event: suspend");
1853 if (info->host != NULL) {
1854 nsp_msg(KERN_INFO, "clear SDTR status");
1856 data = (nsp_hw_data *)info->host->hostdata;
1858 nsphw_init_sync(data);
1861 info->stop = 1;
1863 return 0;
1866 static int nsp_cs_resume(struct pcmcia_device *link)
1868 scsi_info_t *info = link->priv;
1869 nsp_hw_data *data;
1871 nsp_dbg(NSP_DEBUG_INIT, "event: resume");
1873 info->stop = 0;
1875 if (info->host != NULL) {
1876 nsp_msg(KERN_INFO, "reset host and bus");
1878 data = (nsp_hw_data *)info->host->hostdata;
1880 nsphw_init (data);
1881 nsp_bus_reset(data);
1884 return 0;
1887 /*======================================================================*
1888 * module entry point
1889 *====================================================================*/
1890 static struct pcmcia_device_id nsp_cs_ids[] = {
1891 PCMCIA_DEVICE_PROD_ID123("IO DATA", "CBSC16 ", "1", 0x547e66dc, 0x0d63a3fd, 0x51de003a),
1892 PCMCIA_DEVICE_PROD_ID123("KME ", "SCSI-CARD-001", "1", 0x534c02bc, 0x52008408, 0x51de003a),
1893 PCMCIA_DEVICE_PROD_ID123("KME ", "SCSI-CARD-002", "1", 0x534c02bc, 0xcb09d5b2, 0x51de003a),
1894 PCMCIA_DEVICE_PROD_ID123("KME ", "SCSI-CARD-003", "1", 0x534c02bc, 0xbc0ee524, 0x51de003a),
1895 PCMCIA_DEVICE_PROD_ID123("KME ", "SCSI-CARD-004", "1", 0x534c02bc, 0x226a7087, 0x51de003a),
1896 PCMCIA_DEVICE_PROD_ID123("WBT", "NinjaSCSI-3", "R1.0", 0xc7ba805f, 0xfdc7c97d, 0x6973710e),
1897 PCMCIA_DEVICE_PROD_ID123("WORKBIT", "UltraNinja-16", "1", 0x28191418, 0xb70f4b09, 0x51de003a),
1898 PCMCIA_DEVICE_NULL
1900 MODULE_DEVICE_TABLE(pcmcia, nsp_cs_ids);
1902 static struct pcmcia_driver nsp_driver = {
1903 .owner = THIS_MODULE,
1904 .drv = {
1905 .name = "nsp_cs",
1907 .probe = nsp_cs_probe,
1908 .remove = nsp_cs_detach,
1909 .id_table = nsp_cs_ids,
1910 .suspend = nsp_cs_suspend,
1911 .resume = nsp_cs_resume,
1914 static int __init nsp_cs_init(void)
1916 nsp_msg(KERN_INFO, "loading...");
1918 return pcmcia_register_driver(&nsp_driver);
1921 static void __exit nsp_cs_exit(void)
1923 nsp_msg(KERN_INFO, "unloading...");
1924 pcmcia_unregister_driver(&nsp_driver);
1928 module_init(nsp_cs_init)
1929 module_exit(nsp_cs_exit)
1931 /* end */