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 /* $Id: nsp_cs.c,v 1.23 2003/08/18 11:09:19 elca Exp $ */
30 #include <linux/version.h>
31 #include <linux/module.h>
32 #include <linux/kernel.h>
33 #include <linux/init.h>
34 #include <linux/sched.h>
35 #include <linux/slab.h>
36 #include <linux/string.h>
37 #include <linux/timer.h>
38 #include <linux/ioport.h>
39 #include <linux/delay.h>
40 #include <linux/interrupt.h>
41 #include <linux/major.h>
42 #include <linux/blkdev.h>
43 #include <linux/stat.h>
48 #include <../drivers/scsi/scsi.h>
49 #include <scsi/scsi_host.h>
51 #include <scsi/scsi.h>
52 #include <scsi/scsi_ioctl.h>
54 #include <pcmcia/version.h>
55 #include <pcmcia/cs_types.h>
56 #include <pcmcia/cs.h>
57 #include <pcmcia/cistpl.h>
58 #include <pcmcia/cisreg.h>
59 #include <pcmcia/ds.h>
63 MODULE_AUTHOR("YOKOTA Hiroshi <yokota@netlab.is.tsukuba.ac.jp>");
64 MODULE_DESCRIPTION("WorkBit NinjaSCSI-3 / NinjaSCSI-32Bi(16bit) PCMCIA SCSI host adapter module $Revision: 1.23 $");
65 MODULE_SUPPORTED_DEVICE("sd,sr,sg,st");
67 MODULE_LICENSE("GPL");
72 /*====================================================================*/
73 /* Parameters that can be set with 'insmod' */
75 static int nsp_burst_mode = BURST_MEM32;
76 module_param(nsp_burst_mode, int, 0);
77 MODULE_PARM_DESC(nsp_burst_mode, "Burst transfer mode (0=io8, 1=io32, 2=mem32(default))");
79 /* Release IO ports after configuration? */
80 static int free_ports = 0;
81 module_param(free_ports, bool, 0);
82 MODULE_PARM_DESC(free_ports, "Release IO ports after configuration? (default: 0 (=no))");
84 /* /usr/src/linux/drivers/scsi/hosts.h */
85 static Scsi_Host_Template nsp_driver_template = {
86 .proc_name = "nsp_cs",
87 .proc_info = nsp_proc_info,
88 .name = "WorkBit NinjaSCSI-3/32Bi(16bit)",
89 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
90 .detect = nsp_detect_old,
91 .release = nsp_release_old,
94 .queuecommand = nsp_queuecommand,
95 /* .eh_strategy_handler = nsp_eh_strategy,*/
96 /* .eh_abort_handler = nsp_eh_abort,*/
97 /* .eh_device_reset_handler = nsp_eh_device_reset,*/
98 .eh_bus_reset_handler = nsp_eh_bus_reset,
99 .eh_host_reset_handler = nsp_eh_host_reset,
101 .this_id = NSP_INITIATOR_ID,
102 .sg_tablesize = SG_ALL,
104 .use_clustering = DISABLE_CLUSTERING,
105 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,2))
106 .use_new_eh_code = 1,
110 static dev_link_t *dev_list = NULL;
111 static dev_info_t dev_info = {"nsp_cs"};
113 static nsp_hw_data nsp_data_base; /* attach <-> detect glue */
121 # define NSP_DEBUG_MASK 0x000000
122 # define nsp_msg(type, args...) nsp_cs_message("", 0, (type), args)
123 # define nsp_dbg(mask, args...) /* */
125 # define NSP_DEBUG_MASK 0xffffff
126 # define nsp_msg(type, args...) \
127 nsp_cs_message (__FUNCTION__, __LINE__, (type), args)
128 # define nsp_dbg(mask, args...) \
129 nsp_cs_dmessage(__FUNCTION__, __LINE__, (mask), args)
132 #define NSP_DEBUG_QUEUECOMMAND BIT(0)
133 #define NSP_DEBUG_REGISTER BIT(1)
134 #define NSP_DEBUG_AUTOSCSI BIT(2)
135 #define NSP_DEBUG_INTR BIT(3)
136 #define NSP_DEBUG_SGLIST BIT(4)
137 #define NSP_DEBUG_BUSFREE BIT(5)
138 #define NSP_DEBUG_CDB_CONTENTS BIT(6)
139 #define NSP_DEBUG_RESELECTION BIT(7)
140 #define NSP_DEBUG_MSGINOCCUR BIT(8)
141 #define NSP_DEBUG_EEPROM BIT(9)
142 #define NSP_DEBUG_MSGOUTOCCUR BIT(10)
143 #define NSP_DEBUG_BUSRESET BIT(11)
144 #define NSP_DEBUG_RESTART BIT(12)
145 #define NSP_DEBUG_SYNC BIT(13)
146 #define NSP_DEBUG_WAIT BIT(14)
147 #define NSP_DEBUG_TARGETFLAG BIT(15)
148 #define NSP_DEBUG_PROC BIT(16)
149 #define NSP_DEBUG_INIT BIT(17)
150 #define NSP_DEBUG_DATA_IO BIT(18)
151 #define NSP_SPECIAL_PRINT_REGISTER BIT(20)
153 #define NSP_DEBUG_BUF_LEN 150
155 static void nsp_cs_message(const char *func, int line, char *type, char *fmt, ...)
158 char buf[NSP_DEBUG_BUF_LEN];
161 vsnprintf(buf, sizeof(buf), fmt, args);
165 printk("%snsp_cs: %s\n", type, buf);
167 printk("%snsp_cs: %s (%d): %s\n", type, func, line, buf);
172 static void nsp_cs_dmessage(const char *func, int line, int mask, char *fmt, ...)
175 char buf[NSP_DEBUG_BUF_LEN];
178 vsnprintf(buf, sizeof(buf), fmt, args);
181 if (mask & NSP_DEBUG_MASK) {
182 printk("nsp_cs-debug: 0x%x %s (%d): %s\n", mask, func, line, buf);
187 /***********************************************************/
189 /*====================================================
190 * Clenaup parameters and call done() functions.
191 * You must be set SCpnt->result before call this function.
193 static void nsp_scsi_done(Scsi_Cmnd *SCpnt)
195 nsp_hw_data *data = (nsp_hw_data *)SCpnt->device->host->hostdata;
197 data->CurrentSC = NULL;
199 SCpnt->scsi_done(SCpnt);
202 static int nsp_queuecommand(Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *))
205 /*unsigned int host_id = SCpnt->device->host->this_id;*/
206 /*unsigned int base = SCpnt->device->host->io_port;*/
207 unsigned char target = SCpnt->device->id;
209 nsp_hw_data *data = (nsp_hw_data *)SCpnt->device->host->hostdata;
211 nsp_dbg(NSP_DEBUG_QUEUECOMMAND, "SCpnt=0x%p target=%d lun=%d buff=0x%p bufflen=%d use_sg=%d",
212 SCpnt, target, SCpnt->device->lun, SCpnt->request_buffer, SCpnt->request_bufflen, SCpnt->use_sg);
213 //nsp_dbg(NSP_DEBUG_QUEUECOMMAND, "before CurrentSC=0x%p", data->CurrentSC);
215 SCpnt->scsi_done = done;
217 if (data->CurrentSC != NULL) {
218 nsp_msg(KERN_DEBUG, "CurrentSC!=NULL this can't be happen");
219 SCpnt->result = DID_BAD_TARGET << 16;
220 nsp_scsi_done(SCpnt);
225 /* XXX: pcmcia-cs generates SCSI command with "scsi_info" utility.
226 This makes kernel crash when suspending... */
227 if (data->ScsiInfo->stop != 0) {
228 nsp_msg(KERN_INFO, "suspending device. reject command.");
229 SCpnt->result = DID_BAD_TARGET << 16;
230 nsp_scsi_done(SCpnt);
231 return SCSI_MLQUEUE_HOST_BUSY;
237 data->CurrentSC = SCpnt;
239 SCpnt->SCp.Status = CHECK_CONDITION;
240 SCpnt->SCp.Message = 0;
241 SCpnt->SCp.have_data_in = IO_UNKNOWN;
242 SCpnt->SCp.sent_command = 0;
243 SCpnt->SCp.phase = PH_UNDETERMINED;
244 SCpnt->resid = SCpnt->request_bufflen;
246 /* setup scratch area
247 SCp.ptr : buffer pointer
248 SCp.this_residual : buffer length
249 SCp.buffer : next buffer
250 SCp.buffers_residual : left buffers in list
251 SCp.phase : current state of the command */
253 SCpnt->SCp.buffer = (struct scatterlist *) SCpnt->request_buffer;
254 SCpnt->SCp.ptr = BUFFER_ADDR;
255 SCpnt->SCp.this_residual = SCpnt->SCp.buffer->length;
256 SCpnt->SCp.buffers_residual = SCpnt->use_sg - 1;
258 SCpnt->SCp.ptr = (char *) SCpnt->request_buffer;
259 SCpnt->SCp.this_residual = SCpnt->request_bufflen;
260 SCpnt->SCp.buffer = NULL;
261 SCpnt->SCp.buffers_residual = 0;
264 if (nsphw_start_selection(SCpnt) == FALSE) {
265 nsp_dbg(NSP_DEBUG_QUEUECOMMAND, "selection fail");
266 SCpnt->result = DID_BUS_BUSY << 16;
267 nsp_scsi_done(SCpnt);
272 //nsp_dbg(NSP_DEBUG_QUEUECOMMAND, "out");
280 * setup PIO FIFO transfer mode and enable/disable to data out
282 static void nsp_setup_fifo(nsp_hw_data *data, int enabled)
284 unsigned int base = data->BaseAddress;
285 unsigned char transfer_mode_reg;
287 //nsp_dbg(NSP_DEBUG_DATA_IO, "enabled=%d", enabled);
289 if (enabled != FALSE) {
290 transfer_mode_reg = TRANSFER_GO | BRAIND;
292 transfer_mode_reg = 0;
295 transfer_mode_reg |= data->TransferMode;
297 nsp_index_write(base, TRANSFERMODE, transfer_mode_reg);
300 static void nsphw_init_sync(nsp_hw_data *data)
302 sync_data tmp_sync = { .SyncNegotiation = SYNC_NOT_YET,
308 /* setup sync data */
309 for ( i = 0; i < ARRAY_SIZE(data->Sync); i++ ) {
310 data->Sync[i] = tmp_sync;
315 * Initialize Ninja hardware
317 static int nsphw_init(nsp_hw_data *data)
319 unsigned int base = data->BaseAddress;
321 nsp_dbg(NSP_DEBUG_INIT, "in base=0x%x", base);
323 data->ScsiClockDiv = CLOCK_40M | FAST_20;
324 data->CurrentSC = NULL;
326 data->TransferMode = MODE_IO8;
328 nsphw_init_sync(data);
330 /* block all interrupts */
331 nsp_write(base, IRQCONTROL, IRQCONTROL_ALLMASK);
333 /* setup SCSI interface */
334 nsp_write(base, IFSELECT, IF_IFSEL);
336 nsp_index_write(base, SCSIIRQMODE, 0);
338 nsp_index_write(base, TRANSFERMODE, MODE_IO8);
339 nsp_index_write(base, CLOCKDIV, data->ScsiClockDiv);
341 nsp_index_write(base, PARITYCTRL, 0);
342 nsp_index_write(base, POINTERCLR, POINTER_CLEAR |
347 /* setup fifo asic */
348 nsp_write(base, IFSELECT, IF_REGSEL);
349 nsp_index_write(base, TERMPWRCTRL, 0);
350 if ((nsp_index_read(base, OTHERCONTROL) & TPWR_SENSE) == 0) {
351 nsp_msg(KERN_INFO, "terminator power on");
352 nsp_index_write(base, TERMPWRCTRL, POWER_ON);
355 nsp_index_write(base, TIMERCOUNT, 0);
356 nsp_index_write(base, TIMERCOUNT, 0); /* requires 2 times!! */
358 nsp_index_write(base, SYNCREG, 0);
359 nsp_index_write(base, ACKWIDTH, 0);
361 /* enable interrupts and ack them */
362 nsp_index_write(base, SCSIIRQMODE, SCSI_PHASE_CHANGE_EI |
365 nsp_write(base, IRQCONTROL, IRQCONTROL_ALLCLEAR);
367 nsp_setup_fifo(data, FALSE);
373 * Start selection phase
375 static int nsphw_start_selection(Scsi_Cmnd *SCpnt)
377 unsigned int host_id = SCpnt->device->host->this_id;
378 unsigned int base = SCpnt->device->host->io_port;
379 unsigned char target = SCpnt->device->id;
380 nsp_hw_data *data = (nsp_hw_data *)SCpnt->device->host->hostdata;
382 unsigned char phase, arbit;
384 //nsp_dbg(NSP_DEBUG_RESELECTION, "in");
386 phase = nsp_index_read(base, SCSIBUSMON);
387 if(phase != BUSMON_BUS_FREE) {
388 //nsp_dbg(NSP_DEBUG_RESELECTION, "bus busy");
392 /* start arbitration */
393 //nsp_dbg(NSP_DEBUG_RESELECTION, "start arbit");
394 SCpnt->SCp.phase = PH_ARBSTART;
395 nsp_index_write(base, SETARBIT, ARBIT_GO);
399 /* XXX: what a stupid chip! */
400 arbit = nsp_index_read(base, ARBITSTATUS);
401 //nsp_dbg(NSP_DEBUG_RESELECTION, "arbit=%d, wait_count=%d", arbit, wait_count);
402 udelay(1); /* hold 1.2us */
403 } while((arbit & (ARBIT_WIN | ARBIT_FAIL)) == 0 &&
406 if (!(arbit & ARBIT_WIN)) {
407 //nsp_dbg(NSP_DEBUG_RESELECTION, "arbit fail");
408 nsp_index_write(base, SETARBIT, ARBIT_FLAG_CLEAR);
412 /* assert select line */
413 //nsp_dbg(NSP_DEBUG_RESELECTION, "assert SEL line");
414 SCpnt->SCp.phase = PH_SELSTART;
415 udelay(3); /* wait 2.4us */
416 nsp_index_write(base, SCSIDATALATCH, BIT(host_id) | BIT(target));
417 nsp_index_write(base, SCSIBUSCTRL, SCSI_SEL | SCSI_BSY | SCSI_ATN);
418 udelay(2); /* wait >1.2us */
419 nsp_index_write(base, SCSIBUSCTRL, SCSI_SEL | SCSI_BSY | SCSI_DATAOUT_ENB | SCSI_ATN);
420 nsp_index_write(base, SETARBIT, ARBIT_FLAG_CLEAR);
421 /*udelay(1);*/ /* wait >90ns */
422 nsp_index_write(base, SCSIBUSCTRL, SCSI_SEL | SCSI_DATAOUT_ENB | SCSI_ATN);
424 /* check selection timeout */
425 nsp_start_timer(SCpnt, 1000/51);
426 data->SelectionTimeOut = 1;
431 struct nsp_sync_table {
432 unsigned int min_period;
433 unsigned int max_period;
434 unsigned int chip_period;
435 unsigned int ack_width;
438 static struct nsp_sync_table nsp_sync_table_40M[] = {
439 {0x0c, 0x0c, 0x1, 0}, /* 20MB 50ns*/
440 {0x19, 0x19, 0x3, 1}, /* 10MB 100ns*/
441 {0x1a, 0x25, 0x5, 2}, /* 7.5MB 150ns*/
442 {0x26, 0x32, 0x7, 3}, /* 5MB 200ns*/
446 static struct nsp_sync_table nsp_sync_table_20M[] = {
447 {0x19, 0x19, 0x1, 0}, /* 10MB 100ns*/
448 {0x1a, 0x25, 0x2, 0}, /* 7.5MB 150ns*/
449 {0x26, 0x32, 0x3, 1}, /* 5MB 200ns*/
454 * setup synchronous data transfer mode
456 static int nsp_analyze_sdtr(Scsi_Cmnd *SCpnt)
458 unsigned char target = SCpnt->device->id;
459 // unsigned char lun = SCpnt->device->lun;
460 nsp_hw_data *data = (nsp_hw_data *)SCpnt->device->host->hostdata;
461 sync_data *sync = &(data->Sync[target]);
462 struct nsp_sync_table *sync_table;
463 unsigned int period, offset;
467 nsp_dbg(NSP_DEBUG_SYNC, "in");
469 period = sync->SyncPeriod;
470 offset = sync->SyncOffset;
472 nsp_dbg(NSP_DEBUG_SYNC, "period=0x%x, offset=0x%x", period, offset);
474 if ((data->ScsiClockDiv & (BIT(0)|BIT(1))) == CLOCK_20M) {
475 sync_table = nsp_sync_table_20M;
477 sync_table = nsp_sync_table_40M;
480 for ( i = 0; sync_table->max_period != 0; i++, sync_table++) {
481 if ( period >= sync_table->min_period &&
482 period <= sync_table->max_period ) {
487 if (period != 0 && sync_table->max_period == 0) {
489 * No proper period/offset found
491 nsp_dbg(NSP_DEBUG_SYNC, "no proper period/offset");
493 sync->SyncPeriod = 0;
494 sync->SyncOffset = 0;
495 sync->SyncRegister = 0;
501 sync->SyncRegister = (sync_table->chip_period << SYNCREG_PERIOD_SHIFT) |
502 (offset & SYNCREG_OFFSET_MASK);
503 sync->AckWidth = sync_table->ack_width;
505 nsp_dbg(NSP_DEBUG_SYNC, "sync_reg=0x%x, ack_width=0x%x", sync->SyncRegister, sync->AckWidth);
512 * start ninja hardware timer
514 static void nsp_start_timer(Scsi_Cmnd *SCpnt, int time)
516 unsigned int base = SCpnt->device->host->io_port;
517 nsp_hw_data *data = (nsp_hw_data *)SCpnt->device->host->hostdata;
519 //nsp_dbg(NSP_DEBUG_INTR, "in SCpnt=0x%p, time=%d", SCpnt, time);
520 data->TimerCount = time;
521 nsp_index_write(base, TIMERCOUNT, time);
525 * wait for bus phase change
527 static int nsp_negate_signal(Scsi_Cmnd *SCpnt, unsigned char mask, char *str)
529 unsigned int base = SCpnt->device->host->io_port;
533 //nsp_dbg(NSP_DEBUG_INTR, "in");
538 reg = nsp_index_read(base, SCSIBUSMON);
542 } while ((time_out-- != 0) && (reg & mask) != 0);
545 nsp_msg(KERN_DEBUG, " %s signal off timeut", str);
554 static int nsp_expect_signal(Scsi_Cmnd *SCpnt,
555 unsigned char current_phase,
558 unsigned int base = SCpnt->device->host->io_port;
560 unsigned char phase, i_src;
562 //nsp_dbg(NSP_DEBUG_INTR, "current_phase=0x%x, mask=0x%x", current_phase, mask);
566 phase = nsp_index_read(base, SCSIBUSMON);
568 //nsp_dbg(NSP_DEBUG_INTR, "ret -1");
571 i_src = nsp_read(base, IRQSTATUS);
572 if (i_src & IRQSTATUS_SCSI) {
573 //nsp_dbg(NSP_DEBUG_INTR, "ret 0 found scsi signal");
576 if ((phase & mask) != 0 && (phase & BUSMON_PHASE_MASK) == current_phase) {
577 //nsp_dbg(NSP_DEBUG_INTR, "ret 1 phase=0x%x", phase);
580 } while(time_out-- != 0);
582 //nsp_dbg(NSP_DEBUG_INTR, "timeout");
587 * transfer SCSI message
589 static int nsp_xfer(Scsi_Cmnd *SCpnt, int phase)
591 unsigned int base = SCpnt->device->host->io_port;
592 nsp_hw_data *data = (nsp_hw_data *)SCpnt->device->host->hostdata;
593 char *buf = data->MsgBuffer;
594 int len = min(MSGBUF_SIZE, data->MsgLen);
598 //nsp_dbg(NSP_DEBUG_DATA_IO, "in");
599 for (ptr = 0; len > 0; len--, ptr++) {
601 ret = nsp_expect_signal(SCpnt, phase, BUSMON_REQ);
603 nsp_dbg(NSP_DEBUG_DATA_IO, "xfer quit");
607 /* if last byte, negate ATN */
608 if (len == 1 && SCpnt->SCp.phase == PH_MSG_OUT) {
609 nsp_index_write(base, SCSIBUSCTRL, AUTODIRECTION | ACKENB);
612 /* read & write message */
613 if (phase & BUSMON_IO) {
614 nsp_dbg(NSP_DEBUG_DATA_IO, "read msg");
615 buf[ptr] = nsp_index_read(base, SCSIDATAWITHACK);
617 nsp_dbg(NSP_DEBUG_DATA_IO, "write msg");
618 nsp_index_write(base, SCSIDATAWITHACK, buf[ptr]);
620 nsp_negate_signal(SCpnt, BUSMON_ACK, "xfer<ack>");
627 * get extra SCSI data from fifo
629 static int nsp_dataphase_bypass(Scsi_Cmnd *SCpnt)
631 nsp_hw_data *data = (nsp_hw_data *)SCpnt->device->host->hostdata;
634 //nsp_dbg(NSP_DEBUG_DATA_IO, "in");
636 if (SCpnt->SCp.have_data_in != IO_IN) {
640 count = nsp_fifo_count(SCpnt);
641 if (data->FifoCount == count) {
642 //nsp_dbg(NSP_DEBUG_DATA_IO, "not use bypass quirk");
648 * data phase skip only occures in case of SCSI_LOW_READ
650 nsp_dbg(NSP_DEBUG_DATA_IO, "use bypass quirk");
651 SCpnt->SCp.phase = PH_DATA;
653 nsp_setup_fifo(data, FALSE);
661 static int nsp_reselected(Scsi_Cmnd *SCpnt)
663 unsigned int base = SCpnt->device->host->io_port;
664 unsigned int host_id = SCpnt->device->host->this_id;
665 //nsp_hw_data *data = (nsp_hw_data *)SCpnt->device->host->hostdata;
666 unsigned char bus_reg;
667 unsigned char id_reg, tmp;
670 nsp_dbg(NSP_DEBUG_RESELECTION, "in");
672 id_reg = nsp_index_read(base, RESELECTID);
673 tmp = id_reg & (~BIT(host_id));
683 if (SCpnt->device->id != target) {
684 nsp_msg(KERN_ERR, "XXX: reselect ID must be %d in this implementation.", target);
687 nsp_negate_signal(SCpnt, BUSMON_SEL, "reselect<SEL>");
690 bus_reg = nsp_index_read(base, SCSIBUSCTRL) & ~(SCSI_BSY | SCSI_ATN);
691 nsp_index_write(base, SCSIBUSCTRL, bus_reg);
692 nsp_index_write(base, SCSIBUSCTRL, bus_reg | AUTODIRECTION | ACKENB);
698 * count how many data transferd
700 static int nsp_fifo_count(Scsi_Cmnd *SCpnt)
702 unsigned int base = SCpnt->device->host->io_port;
704 unsigned int l, m, h, dummy;
706 nsp_index_write(base, POINTERCLR, POINTER_CLEAR | ACK_COUNTER);
708 l = nsp_index_read(base, TRANSFERCOUNT);
709 m = nsp_index_read(base, TRANSFERCOUNT);
710 h = nsp_index_read(base, TRANSFERCOUNT);
711 dummy = nsp_index_read(base, TRANSFERCOUNT); /* required this! */
713 count = (h << 16) | (m << 8) | (l << 0);
715 //nsp_dbg(NSP_DEBUG_DATA_IO, "count=0x%x", count);
721 #define RFIFO_CRIT 64
722 #define WFIFO_CRIT 64
725 * read data in DATA IN phase
727 static void nsp_pio_read(Scsi_Cmnd *SCpnt)
729 unsigned int base = SCpnt->device->host->io_port;
730 unsigned long mmio_base = SCpnt->device->host->base;
731 nsp_hw_data *data = (nsp_hw_data *)SCpnt->device->host->hostdata;
734 unsigned char stat, fifo_stat;
736 ocount = data->FifoCount;
738 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",
739 SCpnt, SCpnt->resid, ocount, SCpnt->SCp.ptr, SCpnt->SCp.this_residual, SCpnt->SCp.buffer, SCpnt->SCp.buffers_residual);
743 while ((time_out-- != 0) &&
744 (SCpnt->SCp.this_residual > 0 || SCpnt->SCp.buffers_residual > 0 ) ) {
746 stat = nsp_index_read(base, SCSIBUSMON);
747 stat &= BUSMON_PHASE_MASK;
750 res = nsp_fifo_count(SCpnt) - ocount;
751 //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);
752 if (res == 0) { /* if some data avilable ? */
753 if (stat == BUSPHASE_DATA_IN) { /* phase changed? */
754 //nsp_dbg(NSP_DEBUG_DATA_IO, " wait for data this=%d", SCpnt->SCp.this_residual);
757 nsp_dbg(NSP_DEBUG_DATA_IO, "phase changed stat=0x%x", stat);
762 fifo_stat = nsp_read(base, FIFOSTATUS);
763 if ((fifo_stat & FIFOSTATUS_FULL_EMPTY) == 0 &&
764 stat == BUSPHASE_DATA_IN) {
768 res = min(res, SCpnt->SCp.this_residual);
770 switch (data->TransferMode) {
772 res &= ~(BIT(1)|BIT(0)); /* align 4 */
773 nsp_fifo32_read(base, SCpnt->SCp.ptr, res >> 2);
776 nsp_fifo8_read (base, SCpnt->SCp.ptr, res );
780 res &= ~(BIT(1)|BIT(0)); /* align 4 */
781 nsp_mmio_fifo32_read(mmio_base, SCpnt->SCp.ptr, res >> 2);
785 nsp_dbg(NSP_DEBUG_DATA_IO, "unknown read mode");
790 SCpnt->SCp.ptr += res;
791 SCpnt->SCp.this_residual -= res;
793 //nsp_dbg(NSP_DEBUG_DATA_IO, "ptr=0x%p this_residual=0x%x ocount=0x%x", SCpnt->SCp.ptr, SCpnt->SCp.this_residual, ocount);
795 /* go to next scatter list if available */
796 if (SCpnt->SCp.this_residual == 0 &&
797 SCpnt->SCp.buffers_residual != 0 ) {
798 //nsp_dbg(NSP_DEBUG_DATA_IO, "scatterlist next timeout=%d", time_out);
799 SCpnt->SCp.buffers_residual--;
801 SCpnt->SCp.ptr = BUFFER_ADDR;
802 SCpnt->SCp.this_residual = SCpnt->SCp.buffer->length;
805 //nsp_dbg(NSP_DEBUG_DATA_IO, "page: 0x%p, off: 0x%x", SCpnt->SCp.buffer->page, SCpnt->SCp.buffer->offset);
809 data->FifoCount = ocount;
812 nsp_msg(KERN_DEBUG, "pio read timeout resid=%d this_residual=%d buffers_residual=%d",
813 SCpnt->resid, SCpnt->SCp.this_residual, SCpnt->SCp.buffers_residual);
815 nsp_dbg(NSP_DEBUG_DATA_IO, "read ocount=0x%x", ocount);
816 nsp_dbg(NSP_DEBUG_DATA_IO, "r cmd=%d resid=0x%x\n", data->CmdId, SCpnt->resid);
820 * write data in DATA OUT phase
822 static void nsp_pio_write(Scsi_Cmnd *SCpnt)
824 unsigned int base = SCpnt->device->host->io_port;
825 unsigned long mmio_base = SCpnt->device->host->base;
826 nsp_hw_data *data = (nsp_hw_data *)SCpnt->device->host->hostdata;
831 ocount = data->FifoCount;
833 nsp_dbg(NSP_DEBUG_DATA_IO, "in fifocount=%d ptr=0x%p this_residual=%d buffers=0x%p nbuf=%d resid=0x%x",
834 data->FifoCount, SCpnt->SCp.ptr, SCpnt->SCp.this_residual, SCpnt->SCp.buffer, SCpnt->SCp.buffers_residual, SCpnt->resid);
838 while ((time_out-- != 0) &&
839 (SCpnt->SCp.this_residual > 0 || SCpnt->SCp.buffers_residual > 0)) {
840 stat = nsp_index_read(base, SCSIBUSMON);
841 stat &= BUSMON_PHASE_MASK;
843 if (stat != BUSPHASE_DATA_OUT) {
844 res = ocount - nsp_fifo_count(SCpnt);
846 nsp_dbg(NSP_DEBUG_DATA_IO, "phase changed stat=0x%x, res=%d\n", stat, res);
847 /* Put back pointer */
849 SCpnt->SCp.ptr -= res;
850 SCpnt->SCp.this_residual += res;
856 res = ocount - nsp_fifo_count(SCpnt);
857 if (res > 0) { /* write all data? */
858 nsp_dbg(NSP_DEBUG_DATA_IO, "wait for all data out. ocount=0x%x res=%d", ocount, res);
862 res = min(SCpnt->SCp.this_residual, WFIFO_CRIT);
864 //nsp_dbg(NSP_DEBUG_DATA_IO, "ptr=0x%p this=0x%x res=0x%x", SCpnt->SCp.ptr, SCpnt->SCp.this_residual, res);
865 switch (data->TransferMode) {
867 res &= ~(BIT(1)|BIT(0)); /* align 4 */
868 nsp_fifo32_write(base, SCpnt->SCp.ptr, res >> 2);
871 nsp_fifo8_write (base, SCpnt->SCp.ptr, res );
875 res &= ~(BIT(1)|BIT(0)); /* align 4 */
876 nsp_mmio_fifo32_write(mmio_base, SCpnt->SCp.ptr, res >> 2);
880 nsp_dbg(NSP_DEBUG_DATA_IO, "unknown write mode");
885 SCpnt->SCp.ptr += res;
886 SCpnt->SCp.this_residual -= res;
889 /* go to next scatter list if available */
890 if (SCpnt->SCp.this_residual == 0 &&
891 SCpnt->SCp.buffers_residual != 0 ) {
892 //nsp_dbg(NSP_DEBUG_DATA_IO, "scatterlist next");
893 SCpnt->SCp.buffers_residual--;
895 SCpnt->SCp.ptr = BUFFER_ADDR;
896 SCpnt->SCp.this_residual = SCpnt->SCp.buffer->length;
901 data->FifoCount = ocount;
904 nsp_msg(KERN_DEBUG, "pio write timeout resid=0x%x", SCpnt->resid);
906 nsp_dbg(NSP_DEBUG_DATA_IO, "write ocount=0x%x", ocount);
907 nsp_dbg(NSP_DEBUG_DATA_IO, "w cmd=%d resid=0x%x\n", data->CmdId, SCpnt->resid);
913 * setup synchronous/asynchronous data transfer mode
915 static int nsp_nexus(Scsi_Cmnd *SCpnt)
917 unsigned int base = SCpnt->device->host->io_port;
918 unsigned char target = SCpnt->device->id;
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 (SCpnt->use_sg == 0 ||
930 SCpnt->resid % 4 != 0 ||
931 SCpnt->resid <= PAGE_SIZE ) {
932 data->TransferMode = MODE_IO8;
933 } else if (nsp_burst_mode == BURST_MEM32) {
934 data->TransferMode = MODE_MEM32;
935 } else if (nsp_burst_mode == BURST_IO32) {
936 data->TransferMode = MODE_IO32;
938 data->TransferMode = MODE_IO8;
941 /* setup pdma fifo */
942 nsp_setup_fifo(data, TRUE);
944 /* clear ack counter */
946 nsp_index_write(base, POINTERCLR, POINTER_CLEAR |
954 #include "nsp_message.c"
958 static irqreturn_t nspintr(int irq, void *dev_id, struct pt_regs *regs)
961 unsigned char irq_status, irq_phase, phase;
963 unsigned char target, lun;
964 unsigned int *sync_neg;
969 //nsp_dbg(NSP_DEBUG_INTR, "dev_id=0x%p", dev_id);
970 //nsp_dbg(NSP_DEBUG_INTR, "host=0x%p", ((scsi_info_t *)dev_id)->host);
972 if ( dev_id != NULL &&
973 ((scsi_info_t *)dev_id)->host != NULL ) {
974 scsi_info_t *info = (scsi_info_t *)dev_id;
976 data = (nsp_hw_data *)info->host->hostdata;
978 nsp_dbg(NSP_DEBUG_INTR, "host data wrong");
982 //nsp_dbg(NSP_DEBUG_INTR, "&nsp_data_base=0x%p, dev_id=0x%p", &nsp_data_base, dev_id);
984 base = data->BaseAddress;
985 //nsp_dbg(NSP_DEBUG_INTR, "base=0x%x", base);
990 nsp_write(base, IRQCONTROL, IRQCONTROL_IRQDISABLE);
991 irq_status = nsp_read(base, IRQSTATUS);
992 //nsp_dbg(NSP_DEBUG_INTR, "irq_status=0x%x", irq_status);
993 if ((irq_status == 0xff) || ((irq_status & IRQSTATUS_MASK) == 0)) {
994 nsp_write(base, IRQCONTROL, 0);
995 //nsp_dbg(NSP_DEBUG_INTR, "no irq/shared irq");
1000 * Do not read an irq_phase register if no scsi phase interrupt.
1001 * Unless, you should lose a scsi phase interrupt.
1003 phase = nsp_index_read(base, SCSIBUSMON);
1004 if((irq_status & IRQSTATUS_SCSI) != 0) {
1005 irq_phase = nsp_index_read(base, IRQPHASESENCE);
1010 //nsp_dbg(NSP_DEBUG_INTR, "irq_phase=0x%x", irq_phase);
1013 * timer interrupt handler (scsi vs timer interrupts)
1015 //nsp_dbg(NSP_DEBUG_INTR, "timercount=%d", data->TimerCount);
1016 if (data->TimerCount != 0) {
1017 //nsp_dbg(NSP_DEBUG_INTR, "stop timer");
1018 nsp_index_write(base, TIMERCOUNT, 0);
1019 nsp_index_write(base, TIMERCOUNT, 0);
1020 data->TimerCount = 0;
1023 if ((irq_status & IRQSTATUS_MASK) == IRQSTATUS_TIMER &&
1024 data->SelectionTimeOut == 0) {
1025 //nsp_dbg(NSP_DEBUG_INTR, "timer start");
1026 nsp_write(base, IRQCONTROL, IRQCONTROL_TIMER_CLEAR);
1030 nsp_write(base, IRQCONTROL, IRQCONTROL_TIMER_CLEAR | IRQCONTROL_FIFO_CLEAR);
1032 if ((irq_status & IRQSTATUS_SCSI) &&
1033 (irq_phase & SCSI_RESET_IRQ)) {
1034 nsp_msg(KERN_ERR, "bus reset (power off?)");
1037 nsp_bus_reset(data);
1039 if(data->CurrentSC != NULL) {
1040 tmpSC = data->CurrentSC;
1041 tmpSC->result = (DID_RESET << 16) |
1042 ((tmpSC->SCp.Message & 0xff) << 8) |
1043 ((tmpSC->SCp.Status & 0xff) << 0);
1044 nsp_scsi_done(tmpSC);
1049 if (data->CurrentSC == NULL) {
1050 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);
1052 nsp_bus_reset(data);
1056 tmpSC = data->CurrentSC;
1057 target = tmpSC->device->id;
1058 lun = tmpSC->device->lun;
1059 sync_neg = &(data->Sync[target].SyncNegotiation);
1062 * parse hardware SCSI irq reasons register
1064 if (irq_status & IRQSTATUS_SCSI) {
1065 if (irq_phase & RESELECT_IRQ) {
1066 nsp_dbg(NSP_DEBUG_INTR, "reselect");
1067 nsp_write(base, IRQCONTROL, IRQCONTROL_RESELECT_CLEAR);
1068 if (nsp_reselected(tmpSC) != FALSE) {
1073 if ((irq_phase & (PHASE_CHANGE_IRQ | LATCHED_BUS_FREE)) == 0) {
1078 //show_phase(tmpSC);
1080 switch(tmpSC->SCp.phase) {
1082 // *sync_neg = SYNC_NOT_YET;
1083 if ((phase & BUSMON_BSY) == 0) {
1084 //nsp_dbg(NSP_DEBUG_INTR, "selection count=%d", data->SelectionTimeOut);
1085 if (data->SelectionTimeOut >= NSP_SELTIMEOUT) {
1086 nsp_dbg(NSP_DEBUG_INTR, "selection time out");
1087 data->SelectionTimeOut = 0;
1088 nsp_index_write(base, SCSIBUSCTRL, 0);
1090 tmpSC->result = DID_TIME_OUT << 16;
1091 nsp_scsi_done(tmpSC);
1095 data->SelectionTimeOut += 1;
1096 nsp_start_timer(tmpSC, 1000/51);
1100 /* attention assert */
1101 //nsp_dbg(NSP_DEBUG_INTR, "attention assert");
1102 data->SelectionTimeOut = 0;
1103 tmpSC->SCp.phase = PH_SELECTED;
1104 nsp_index_write(base, SCSIBUSCTRL, SCSI_ATN);
1106 nsp_index_write(base, SCSIBUSCTRL, SCSI_ATN | AUTODIRECTION | ACKENB);
1112 //nsp_dbg(NSP_DEBUG_INTR, "phase reselect");
1113 // *sync_neg = SYNC_NOT_YET;
1114 if ((phase & BUSMON_PHASE_MASK) != BUSPHASE_MESSAGE_IN) {
1116 tmpSC->result = DID_ABORT << 16;
1117 nsp_scsi_done(tmpSC);
1122 if ((irq_status & (IRQSTATUS_SCSI | IRQSTATUS_FIFO)) == 0) {
1131 //nsp_dbg(NSP_DEBUG_INTR, "start scsi seq");
1133 /* normal disconnect */
1134 if (((tmpSC->SCp.phase == PH_MSG_IN) || (tmpSC->SCp.phase == PH_MSG_OUT)) &&
1135 (irq_phase & LATCHED_BUS_FREE) != 0 ) {
1136 nsp_dbg(NSP_DEBUG_INTR, "normal disconnect irq_status=0x%x, phase=0x%x, irq_phase=0x%x", irq_status, phase, irq_phase);
1138 //*sync_neg = SYNC_NOT_YET;
1140 if ((tmpSC->SCp.Message == MSG_COMMAND_COMPLETE)) { /* all command complete and return status */
1141 tmpSC->result = (DID_OK << 16) |
1142 ((tmpSC->SCp.Message & 0xff) << 8) |
1143 ((tmpSC->SCp.Status & 0xff) << 0);
1144 nsp_dbg(NSP_DEBUG_INTR, "command complete result=0x%x", tmpSC->result);
1145 nsp_scsi_done(tmpSC);
1154 /* check unexpected bus free state */
1156 nsp_msg(KERN_DEBUG, "unexpected bus free. irq_status=0x%x, phase=0x%x, irq_phase=0x%x", irq_status, phase, irq_phase);
1158 *sync_neg = SYNC_NG;
1159 tmpSC->result = DID_ERROR << 16;
1160 nsp_scsi_done(tmpSC);
1164 switch (phase & BUSMON_PHASE_MASK) {
1165 case BUSPHASE_COMMAND:
1166 nsp_dbg(NSP_DEBUG_INTR, "BUSPHASE_COMMAND");
1167 if ((phase & BUSMON_REQ) == 0) {
1168 nsp_dbg(NSP_DEBUG_INTR, "REQ == 0");
1172 tmpSC->SCp.phase = PH_COMMAND;
1176 /* write scsi command */
1177 nsp_dbg(NSP_DEBUG_INTR, "cmd_len=%d", tmpSC->cmd_len);
1178 nsp_index_write(base, COMMANDCTRL, CLEAR_COMMAND_POINTER);
1179 for (i = 0; i < tmpSC->cmd_len; i++) {
1180 nsp_index_write(base, COMMANDDATA, tmpSC->cmnd[i]);
1182 nsp_index_write(base, COMMANDCTRL, CLEAR_COMMAND_POINTER | AUTO_COMMAND_GO);
1185 case BUSPHASE_DATA_OUT:
1186 nsp_dbg(NSP_DEBUG_INTR, "BUSPHASE_DATA_OUT");
1188 tmpSC->SCp.phase = PH_DATA;
1189 tmpSC->SCp.have_data_in = IO_OUT;
1191 nsp_pio_write(tmpSC);
1195 case BUSPHASE_DATA_IN:
1196 nsp_dbg(NSP_DEBUG_INTR, "BUSPHASE_DATA_IN");
1198 tmpSC->SCp.phase = PH_DATA;
1199 tmpSC->SCp.have_data_in = IO_IN;
1201 nsp_pio_read(tmpSC);
1205 case BUSPHASE_STATUS:
1206 nsp_dataphase_bypass(tmpSC);
1207 nsp_dbg(NSP_DEBUG_INTR, "BUSPHASE_STATUS");
1209 tmpSC->SCp.phase = PH_STATUS;
1211 tmpSC->SCp.Status = nsp_index_read(base, SCSIDATAWITHACK);
1212 nsp_dbg(NSP_DEBUG_INTR, "message=0x%x status=0x%x", tmpSC->SCp.Message, tmpSC->SCp.Status);
1216 case BUSPHASE_MESSAGE_OUT:
1217 nsp_dbg(NSP_DEBUG_INTR, "BUSPHASE_MESSAGE_OUT");
1218 if ((phase & BUSMON_REQ) == 0) {
1222 tmpSC->SCp.phase = PH_MSG_OUT;
1224 //*sync_neg = SYNC_NOT_YET;
1226 data->MsgLen = i = 0;
1227 data->MsgBuffer[i] = IDENTIFY(TRUE, lun); i++;
1229 if (*sync_neg == SYNC_NOT_YET) {
1230 data->Sync[target].SyncPeriod = 0;
1231 data->Sync[target].SyncOffset = 0;
1234 data->MsgBuffer[i] = MSG_EXTENDED; i++;
1235 data->MsgBuffer[i] = 3; i++;
1236 data->MsgBuffer[i] = MSG_EXT_SDTR; i++;
1237 data->MsgBuffer[i] = 0x0c; i++;
1238 data->MsgBuffer[i] = 15; i++;
1243 nsp_analyze_sdtr(tmpSC);
1245 nsp_message_out(tmpSC);
1248 case BUSPHASE_MESSAGE_IN:
1249 nsp_dataphase_bypass(tmpSC);
1250 nsp_dbg(NSP_DEBUG_INTR, "BUSPHASE_MESSAGE_IN");
1251 if ((phase & BUSMON_REQ) == 0) {
1255 tmpSC->SCp.phase = PH_MSG_IN;
1256 nsp_message_in(tmpSC);
1259 if (*sync_neg == SYNC_NOT_YET) {
1260 //nsp_dbg(NSP_DEBUG_INTR, "sync target=%d,lun=%d",target,lun);
1262 if (data->MsgLen >= 5 &&
1263 data->MsgBuffer[0] == MSG_EXTENDED &&
1264 data->MsgBuffer[1] == 3 &&
1265 data->MsgBuffer[2] == MSG_EXT_SDTR ) {
1266 data->Sync[target].SyncPeriod = data->MsgBuffer[3];
1267 data->Sync[target].SyncOffset = data->MsgBuffer[4];
1268 //nsp_dbg(NSP_DEBUG_INTR, "sync ok, %d %d", data->MsgBuffer[3], data->MsgBuffer[4]);
1269 *sync_neg = SYNC_OK;
1271 data->Sync[target].SyncPeriod = 0;
1272 data->Sync[target].SyncOffset = 0;
1273 *sync_neg = SYNC_NG;
1275 nsp_analyze_sdtr(tmpSC);
1279 /* search last messeage byte */
1281 for (i = 0; i < data->MsgLen; i++) {
1282 tmp = data->MsgBuffer[i];
1283 if (data->MsgBuffer[i] == MSG_EXTENDED) {
1284 i += (1 + data->MsgBuffer[i+1]);
1287 tmpSC->SCp.Message = tmp;
1289 nsp_dbg(NSP_DEBUG_INTR, "message=0x%x len=%d", tmpSC->SCp.Message, data->MsgLen);
1294 case BUSPHASE_SELECT:
1296 nsp_dbg(NSP_DEBUG_INTR, "BUSPHASE other");
1301 //nsp_dbg(NSP_DEBUG_INTR, "out");
1305 nsp_start_timer(tmpSC, 1000/102);
1310 #include "nsp_debug.c"
1311 #endif /* NSP_DEBUG */
1313 /*----------------------------------------------------------------*/
1314 /* look for ninja3 card and init if found */
1315 /*----------------------------------------------------------------*/
1316 static struct Scsi_Host *nsp_detect(Scsi_Host_Template *sht)
1318 struct Scsi_Host *host; /* registered host structure */
1319 nsp_hw_data *data_b = &nsp_data_base, *data;
1321 nsp_dbg(NSP_DEBUG_INIT, "this_id=%d", sht->this_id);
1322 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,73))
1323 host = scsi_host_alloc(&nsp_driver_template, sizeof(nsp_hw_data));
1325 host = scsi_register(sht, sizeof(nsp_hw_data));
1328 nsp_dbg(NSP_DEBUG_INIT, "host failed");
1332 memcpy(host->hostdata, data_b, sizeof(nsp_hw_data));
1333 data = (nsp_hw_data *)host->hostdata;
1334 data->ScsiInfo->host = host;
1339 nsp_dbg(NSP_DEBUG_INIT, "irq=%d,%d", data_b->IrqNumber, ((nsp_hw_data *)host->hostdata)->IrqNumber);
1341 host->unique_id = data->BaseAddress;
1342 host->io_port = data->BaseAddress;
1343 host->n_io_port = data->NumAddress;
1344 host->irq = data->IrqNumber;
1345 host->base = data->MmioAddress;
1347 spin_lock_init(&(data->Lock));
1349 snprintf(data->nspinfo,
1350 sizeof(data->nspinfo),
1351 "NinjaSCSI-3/32Bi Driver $Revision: 1.23 $ IO:0x%04lx-0x%04lx MMIO(virt addr):0x%04lx IRQ:%02d",
1352 host->io_port, host->io_port + host->n_io_port - 1,
1355 sht->name = data->nspinfo;
1357 nsp_dbg(NSP_DEBUG_INIT, "end");
1360 return host; /* detect done. */
1363 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
1364 static int nsp_detect_old(Scsi_Host_Template *sht)
1366 if (nsp_detect(sht) == NULL) {
1369 //MOD_INC_USE_COUNT;
1375 static int nsp_release_old(struct Scsi_Host *shpnt)
1377 //nsp_hw_data *data = (nsp_hw_data *)shpnt->hostdata;
1379 /* PCMCIA Card Service dose same things below. */
1380 /* So we do nothing. */
1382 // free_irq(shpnt->irq, data->ScsiInfo);
1384 //if (shpnt->io_port) {
1385 // release_region(shpnt->io_port, shpnt->n_io_port);
1388 //MOD_DEC_USE_COUNT;
1394 /*----------------------------------------------------------------*/
1395 /* return info string */
1396 /*----------------------------------------------------------------*/
1397 static const char *nsp_info(struct Scsi_Host *shpnt)
1399 nsp_hw_data *data = (nsp_hw_data *)shpnt->hostdata;
1401 return data->nspinfo;
1405 #define SPRINTF(args...) \
1407 if(length > (pos - buffer)) { \
1408 pos += snprintf(pos, length - (pos - buffer) + 1, ## args); \
1409 nsp_dbg(NSP_DEBUG_PROC, "buffer=0x%p pos=0x%p length=%d %d\n", buffer, pos, length, length - (pos - buffer));\
1414 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,73))
1415 struct Scsi_Host *host,
1421 #if !(LINUX_VERSION_CODE > KERNEL_VERSION(2,5,73))
1430 unsigned long flags;
1432 #if !(LINUX_VERSION_CODE > KERNEL_VERSION(2,5,73))
1433 struct Scsi_Host *host;
1441 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,73))
1442 hostno = host->host_no;
1444 /* search this HBA host */
1445 host = scsi_host_hn_get(hostno);
1450 data = (nsp_hw_data *)host->hostdata;
1453 SPRINTF("NinjaSCSI status\n\n");
1454 SPRINTF("Driver version: $Revision: 1.23 $\n");
1455 SPRINTF("SCSI host No.: %d\n", hostno);
1456 SPRINTF("IRQ: %d\n", host->irq);
1457 SPRINTF("IO: 0x%lx-0x%lx\n", host->io_port, host->io_port + host->n_io_port - 1);
1458 SPRINTF("MMIO(virtual address): 0x%lx-0x%lx\n", host->base, host->base + data->MmioLength - 1);
1459 SPRINTF("sg_tablesize: %d\n", host->sg_tablesize);
1461 SPRINTF("burst transfer mode: ");
1462 switch (nsp_burst_mode) {
1479 spin_lock_irqsave(&(data->Lock), flags);
1480 SPRINTF("CurrentSC: 0x%p\n\n", data->CurrentSC);
1481 spin_unlock_irqrestore(&(data->Lock), flags);
1483 SPRINTF("SDTR status\n");
1484 for(id = 0; id < ARRAY_SIZE(data->Sync); id++) {
1486 SPRINTF("id %d: ", id);
1488 if (id == host->this_id) {
1489 SPRINTF("----- NinjaSCSI-3 host adapter\n");
1493 switch(data->Sync[id].SyncNegotiation) {
1508 if (data->Sync[id].SyncPeriod != 0) {
1509 speed = 1000000 / (data->Sync[id].SyncPeriod * 4);
1511 SPRINTF(" transfer %d.%dMB/s, offset %d",
1514 data->Sync[id].SyncOffset
1520 thislength = pos - (buffer + offset);
1522 if(thislength < 0) {
1528 thislength = min(thislength, length);
1529 *start = buffer + offset;
1535 /*---------------------------------------------------------------*/
1537 /*---------------------------------------------------------------*/
1539 /*static int nsp_eh_strategy(struct Scsi_Host *Shost)
1545 static int nsp_eh_abort(Scsi_Cmnd *SCpnt)
1547 nsp_dbg(NSP_DEBUG_BUSRESET, "SCpnt=0x%p", SCpnt);
1549 return nsp_eh_bus_reset(SCpnt);
1553 static int nsp_eh_device_reset(Scsi_Cmnd *SCpnt)
1555 nsp_dbg(NSP_DEBUG_BUSRESET, "%s: SCpnt=0x%p", SCpnt);
1560 static int nsp_bus_reset(nsp_hw_data *data)
1562 unsigned int base = data->BaseAddress;
1565 nsp_write(base, IRQCONTROL, IRQCONTROL_ALLMASK);
1567 nsp_index_write(base, SCSIBUSCTRL, SCSI_RST);
1568 mdelay(100); /* 100ms */
1569 nsp_index_write(base, SCSIBUSCTRL, 0);
1570 for(i = 0; i < 5; i++) {
1571 nsp_index_read(base, IRQPHASESENCE); /* dummy read */
1574 nsphw_init_sync(data);
1576 nsp_write(base, IRQCONTROL, IRQCONTROL_ALLCLEAR);
1581 static int nsp_eh_bus_reset(Scsi_Cmnd *SCpnt)
1583 nsp_hw_data *data = (nsp_hw_data *)SCpnt->device->host->hostdata;
1585 nsp_dbg(NSP_DEBUG_BUSRESET, "SCpnt=0x%p", SCpnt);
1587 return nsp_bus_reset(data);
1590 static int nsp_eh_host_reset(Scsi_Cmnd *SCpnt)
1592 nsp_hw_data *data = (nsp_hw_data *)SCpnt->device->host->hostdata;
1594 nsp_dbg(NSP_DEBUG_BUSRESET, "in");
1602 /**********************************************************************
1604 **********************************************************************/
1606 /*======================================================================
1607 nsp_cs_attach() creates an "instance" of the driver, allocating
1608 local data structures for one device. The device is registered
1611 The dev_link structure is initialized, but we don't actually
1612 configure the card at this point -- we wait until we receive a
1613 card insertion event.
1614 ======================================================================*/
1615 static dev_link_t *nsp_cs_attach(void)
1618 client_reg_t client_reg;
1621 nsp_hw_data *data = &nsp_data_base;
1623 nsp_dbg(NSP_DEBUG_INIT, "in");
1625 /* Create new SCSI device */
1626 info = kmalloc(sizeof(*info), GFP_KERNEL);
1627 if (info == NULL) { return NULL; }
1628 memset(info, 0, sizeof(*info));
1631 data->ScsiInfo = info;
1633 nsp_dbg(NSP_DEBUG_INIT, "info=0x%p", info);
1635 /* The io structure describes IO port mapping */
1636 link->io.NumPorts1 = 0x10;
1637 link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
1638 link->io.IOAddrLines = 10; /* not used */
1640 /* Interrupt setup */
1641 link->irq.Attributes = IRQ_TYPE_EXCLUSIVE | IRQ_HANDLE_PRESENT;
1642 link->irq.IRQInfo1 = IRQ_LEVEL_ID;
1644 /* Interrupt handler */
1645 link->irq.Handler = &nspintr;
1646 link->irq.Instance = info;
1647 link->irq.Attributes |= (SA_SHIRQ | SA_SAMPLE_RANDOM);
1649 /* General socket configuration */
1650 link->conf.Attributes = CONF_ENABLE_IRQ;
1651 link->conf.Vcc = 50;
1652 link->conf.IntType = INT_MEMORY_AND_IO;
1653 link->conf.Present = PRESENT_OPTION;
1656 /* Register with Card Services */
1657 link->next = dev_list;
1659 client_reg.dev_info = &dev_info;
1660 client_reg.EventMask =
1661 CS_EVENT_CARD_INSERTION | CS_EVENT_CARD_REMOVAL |
1662 CS_EVENT_RESET_PHYSICAL | CS_EVENT_CARD_RESET |
1663 CS_EVENT_PM_SUSPEND | CS_EVENT_PM_RESUME ;
1664 client_reg.event_handler = &nsp_cs_event;
1665 client_reg.Version = 0x0210;
1666 client_reg.event_callback_args.client_data = link;
1667 ret = pcmcia_register_client(&link->handle, &client_reg);
1668 if (ret != CS_SUCCESS) {
1669 cs_error(link->handle, RegisterClient, ret);
1670 nsp_cs_detach(link);
1675 nsp_dbg(NSP_DEBUG_INIT, "link=0x%p", link);
1677 } /* nsp_cs_attach */
1680 /*======================================================================
1681 This deletes a driver "instance". The device is de-registered
1682 with Card Services. If it has been released, all local data
1683 structures are freed. Otherwise, the structures will be freed
1684 when the device is released.
1685 ======================================================================*/
1686 static void nsp_cs_detach(dev_link_t *link)
1690 nsp_dbg(NSP_DEBUG_INIT, "in, link=0x%p", link);
1692 /* Locate device structure */
1693 for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next) {
1694 if (*linkp == link) {
1698 if (*linkp == NULL) {
1702 if (link->state & DEV_CONFIG)
1703 nsp_cs_release(link);
1705 /* Break the link with Card Services */
1707 pcmcia_deregister_client(link->handle);
1710 /* Unlink device structure, free bits */
1711 *linkp = link->next;
1715 } /* nsp_cs_detach */
1718 /*======================================================================
1719 nsp_cs_config() is scheduled to run after a CARD_INSERTION event
1720 is received, to configure the PCMCIA socket, and to make the
1721 ethernet device available to the system.
1722 ======================================================================*/
1723 #define CS_CHECK(fn, ret) \
1724 do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
1725 /*====================================================================*/
1726 static void nsp_cs_config(dev_link_t *link)
1728 client_handle_t handle = link->handle;
1729 scsi_info_t *info = link->priv;
1732 int last_ret, last_fn;
1733 unsigned char tuple_data[64];
1737 cistpl_cftable_entry_t dflt = { 0 };
1738 struct Scsi_Host *host;
1739 nsp_hw_data *data = &nsp_data_base;
1740 #if !(LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,74))
1742 dev_node_t **tail, *node;
1745 nsp_dbg(NSP_DEBUG_INIT, "in");
1747 tuple.DesiredTuple = CISTPL_CONFIG;
1748 tuple.Attributes = 0;
1749 tuple.TupleData = tuple_data;
1750 tuple.TupleDataMax = sizeof(tuple_data);
1751 tuple.TupleOffset = 0;
1752 CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(handle, &tuple));
1753 CS_CHECK(GetTupleData, pcmcia_get_tuple_data(handle, &tuple));
1754 CS_CHECK(ParseTuple, pcmcia_parse_tuple(handle, &tuple, &parse));
1755 link->conf.ConfigBase = parse.config.base;
1756 link->conf.Present = parse.config.rmask[0];
1758 /* Configure card */
1759 link->state |= DEV_CONFIG;
1761 /* Look up the current Vcc */
1762 CS_CHECK(GetConfigurationInfo, pcmcia_get_configuration_info(handle, &conf));
1763 link->conf.Vcc = conf.Vcc;
1765 tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
1766 CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(handle, &tuple));
1768 cistpl_cftable_entry_t *cfg = &(parse.cftable_entry);
1770 if (pcmcia_get_tuple_data(handle, &tuple) != 0 ||
1771 pcmcia_parse_tuple(handle, &tuple, &parse) != 0)
1774 if (cfg->flags & CISTPL_CFTABLE_DEFAULT) { dflt = *cfg; }
1775 if (cfg->index == 0) { goto next_entry; }
1776 link->conf.ConfigIndex = cfg->index;
1778 /* Does this card need audio output? */
1779 if (cfg->flags & CISTPL_CFTABLE_AUDIO) {
1780 link->conf.Attributes |= CONF_ENABLE_SPKR;
1781 link->conf.Status = CCSR_AUDIO_ENA;
1784 /* Use power settings for Vcc and Vpp if present */
1785 /* Note that the CIS values need to be rescaled */
1786 if (cfg->vcc.present & (1<<CISTPL_POWER_VNOM)) {
1787 if (conf.Vcc != cfg->vcc.param[CISTPL_POWER_VNOM]/10000) {
1790 } else if (dflt.vcc.present & (1<<CISTPL_POWER_VNOM)) {
1791 if (conf.Vcc != dflt.vcc.param[CISTPL_POWER_VNOM]/10000) {
1796 if (cfg->vpp1.present & (1 << CISTPL_POWER_VNOM)) {
1797 link->conf.Vpp1 = link->conf.Vpp2 =
1798 cfg->vpp1.param[CISTPL_POWER_VNOM] / 10000;
1799 } else if (dflt.vpp1.present & (1 << CISTPL_POWER_VNOM)) {
1800 link->conf.Vpp1 = link->conf.Vpp2 =
1801 dflt.vpp1.param[CISTPL_POWER_VNOM] / 10000;
1804 /* Do we need to allocate an interrupt? */
1805 if (cfg->irq.IRQInfo1 || dflt.irq.IRQInfo1) {
1806 link->conf.Attributes |= CONF_ENABLE_IRQ;
1809 /* IO window settings */
1810 link->io.NumPorts1 = link->io.NumPorts2 = 0;
1811 if ((cfg->io.nwin > 0) || (dflt.io.nwin > 0)) {
1812 cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt.io;
1813 link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
1814 if (!(io->flags & CISTPL_IO_8BIT))
1815 link->io.Attributes1 = IO_DATA_PATH_WIDTH_16;
1816 if (!(io->flags & CISTPL_IO_16BIT))
1817 link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
1818 link->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK;
1819 link->io.BasePort1 = io->win[0].base;
1820 link->io.NumPorts1 = io->win[0].len;
1822 link->io.Attributes2 = link->io.Attributes1;
1823 link->io.BasePort2 = io->win[1].base;
1824 link->io.NumPorts2 = io->win[1].len;
1826 /* This reserves IO space but doesn't actually enable it */
1827 if (pcmcia_request_io(link->handle, &link->io) != 0)
1831 if ((cfg->mem.nwin > 0) || (dflt.mem.nwin > 0)) {
1833 (cfg->mem.nwin) ? &cfg->mem : &dflt.mem;
1834 req.Attributes = WIN_DATA_WIDTH_16|WIN_MEMORY_TYPE_CM;
1835 req.Attributes |= WIN_ENABLE;
1836 req.Base = mem->win[0].host_addr;
1837 req.Size = mem->win[0].len;
1838 if (req.Size < 0x1000) {
1841 req.AccessSpeed = 0;
1842 if (pcmcia_request_window(&link->handle, &req, &link->win) != 0)
1844 map.Page = 0; map.CardOffset = mem->win[0].card_addr;
1845 if (pcmcia_map_mem_page(link->win, &map) != 0)
1848 data->MmioAddress = (unsigned long)ioremap_nocache(req.Base, req.Size);
1849 data->MmioLength = req.Size;
1851 /* If we got this far, we're cool! */
1855 nsp_dbg(NSP_DEBUG_INIT, "next");
1857 if (link->io.NumPorts1) {
1858 pcmcia_release_io(link->handle, &link->io);
1860 CS_CHECK(GetNextTuple, pcmcia_get_next_tuple(handle, &tuple));
1863 if (link->conf.Attributes & CONF_ENABLE_IRQ) {
1864 CS_CHECK(RequestIRQ, pcmcia_request_irq(link->handle, &link->irq));
1866 CS_CHECK(RequestConfiguration, pcmcia_request_configuration(handle, &link->conf));
1869 if (link->io.BasePort1) {
1870 release_region(link->io.BasePort1, link->io.NumPorts1);
1872 if (link->io.BasePort2) {
1873 release_region(link->io.BasePort2, link->io.NumPorts2);
1877 /* Set port and IRQ */
1878 data->BaseAddress = link->io.BasePort1;
1879 data->NumAddress = link->io.NumPorts1;
1880 data->IrqNumber = link->irq.AssignedIRQ;
1882 nsp_dbg(NSP_DEBUG_INIT, "I/O[0x%x+0x%x] IRQ %d",
1883 data->BaseAddress, data->NumAddress, data->IrqNumber);
1885 if(nsphw_init(data) == FALSE) {
1889 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,2))
1890 host = nsp_detect(&nsp_driver_template);
1892 scsi_register_host(&nsp_driver_template);
1893 for (host = scsi_host_get_next(NULL); host != NULL;
1894 host = scsi_host_get_next(host)) {
1895 if (host->hostt == &nsp_driver_template) {
1902 nsp_dbg(NSP_DEBUG_INIT, "detect failed");
1907 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,74))
1908 scsi_add_host (host, NULL);
1909 scsi_scan_host(host);
1911 snprintf(info->node.dev_name, sizeof(info->node.dev_name), "scsi%d", host->host_no);
1912 link->dev = &info->node;
1916 nsp_dbg(NSP_DEBUG_INIT, "GET_SCSI_INFO");
1920 nsp_dbg(NSP_DEBUG_INIT, "host=0x%p", host);
1922 for (dev = host->host_queue; dev != NULL; dev = dev->next) {
1924 id = (dev->id & 0x0f) + ((dev->lun & 0x0f) << 4) +
1925 ((dev->channel & 0x0f) << 8) +
1926 ((dev->host->host_no & 0x0f) << 12);
1927 node = &info->node[info->ndev];
1929 switch (dev->type) {
1931 node->major = SCSI_TAPE_MAJOR;
1932 snprintf(node->dev_name, sizeof(node->dev_name), "st#%04lx", id);
1936 node->major = SCSI_DISK0_MAJOR;
1937 snprintf(node->dev_name, sizeof(node->dev_name), "sd#%04lx", id);
1941 node->major = SCSI_CDROM_MAJOR;
1942 snprintf(node->dev_name, sizeof(node->dev_name), "sr#%04lx", id);
1945 node->major = SCSI_GENERIC_MAJOR;
1946 snprintf(node->dev_name, sizeof(node->dev_name), "sg#%04lx", id);
1949 *tail = node; tail = &node->next;
1951 info->host = dev->host;
1955 if (info->ndev == 0) {
1956 nsp_msg(KERN_INFO, "no SCSI devices found");
1958 nsp_dbg(NSP_DEBUG_INIT, "host=0x%p", host);
1961 /* Finally, report what we've done */
1962 printk(KERN_INFO "nsp_cs: index 0x%02x: Vcc %d.%d",
1963 link->conf.ConfigIndex,
1964 link->conf.Vcc/10, link->conf.Vcc%10);
1965 if (link->conf.Vpp1) {
1966 printk(", Vpp %d.%d", link->conf.Vpp1/10, link->conf.Vpp1%10);
1968 if (link->conf.Attributes & CONF_ENABLE_IRQ) {
1969 printk(", irq %d", link->irq.AssignedIRQ);
1971 if (link->io.NumPorts1) {
1972 printk(", io 0x%04x-0x%04x", link->io.BasePort1,
1973 link->io.BasePort1+link->io.NumPorts1-1);
1975 if (link->io.NumPorts2)
1976 printk(" & 0x%04x-0x%04x", link->io.BasePort2,
1977 link->io.BasePort2+link->io.NumPorts2-1);
1979 printk(", mem 0x%06lx-0x%06lx", req.Base,
1980 req.Base+req.Size-1);
1983 link->state &= ~DEV_CONFIG_PENDING;
1987 nsp_dbg(NSP_DEBUG_INIT, "config fail");
1988 cs_error(link->handle, last_fn, last_ret);
1989 nsp_cs_release(link);
1992 } /* nsp_cs_config */
1996 /*======================================================================
1997 After a card is removed, nsp_cs_release() will unregister the net
1998 device, and release the PCMCIA configuration. If the device is
1999 still open, this will be postponed until it is closed.
2000 ======================================================================*/
2001 static void nsp_cs_release(dev_link_t *link)
2003 scsi_info_t *info = link->priv;
2004 nsp_hw_data *data = NULL;
2006 if (info->host == NULL) {
2007 nsp_msg(KERN_DEBUG, "unexpected card release call.");
2009 data = (nsp_hw_data *)info->host->hostdata;
2012 nsp_dbg(NSP_DEBUG_INIT, "link=0x%p", link);
2014 /* Unlink the device chain */
2015 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,2))
2016 if (info->host != NULL) {
2017 scsi_remove_host(info->host);
2020 scsi_unregister_host(&nsp_driver_template);
2026 iounmap((void *)(data->MmioAddress));
2028 pcmcia_release_window(link->win);
2030 pcmcia_release_configuration(link->handle);
2031 if (link->io.NumPorts1) {
2032 pcmcia_release_io(link->handle, &link->io);
2034 if (link->irq.AssignedIRQ) {
2035 pcmcia_release_irq(link->handle, &link->irq);
2037 link->state &= ~DEV_CONFIG;
2038 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,2))
2039 if (info->host != NULL) {
2040 scsi_host_put(info->host);
2043 } /* nsp_cs_release */
2045 /*======================================================================
2047 The card status event handler. Mostly, this schedules other
2048 stuff to run after an event is received. A CARD_REMOVAL event
2049 also sets some flags to discourage the net drivers from trying
2050 to talk to the card any more.
2052 When a CARD_REMOVAL event is received, we immediately set a flag
2053 to block future accesses to this device. All the functions that
2054 actually access the device should check this flag to make sure
2055 the card is still present.
2057 ======================================================================*/
2058 static int nsp_cs_event(event_t event,
2060 event_callback_args_t *args)
2062 dev_link_t *link = args->client_data;
2063 scsi_info_t *info = link->priv;
2066 nsp_dbg(NSP_DEBUG_INIT, "in, event=0x%08x", event);
2069 case CS_EVENT_CARD_REMOVAL:
2070 nsp_dbg(NSP_DEBUG_INIT, "event: remove");
2071 link->state &= ~DEV_PRESENT;
2072 if (link->state & DEV_CONFIG) {
2073 ((scsi_info_t *)link->priv)->stop = 1;
2074 nsp_cs_release(link);
2078 case CS_EVENT_CARD_INSERTION:
2079 nsp_dbg(NSP_DEBUG_INIT, "event: insert");
2080 link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
2081 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,68))
2082 info->bus = args->bus;
2084 nsp_cs_config(link);
2087 case CS_EVENT_PM_SUSPEND:
2088 nsp_dbg(NSP_DEBUG_INIT, "event: suspend");
2089 link->state |= DEV_SUSPEND;
2090 /* Fall through... */
2091 case CS_EVENT_RESET_PHYSICAL:
2092 /* Mark the device as stopped, to block IO until later */
2093 nsp_dbg(NSP_DEBUG_INIT, "event: reset physical");
2095 if (info->host != NULL) {
2096 nsp_msg(KERN_INFO, "clear SDTR status");
2098 data = (nsp_hw_data *)info->host->hostdata;
2100 nsphw_init_sync(data);
2104 if (link->state & DEV_CONFIG) {
2105 pcmcia_release_configuration(link->handle);
2109 case CS_EVENT_PM_RESUME:
2110 nsp_dbg(NSP_DEBUG_INIT, "event: resume");
2111 link->state &= ~DEV_SUSPEND;
2112 /* Fall through... */
2113 case CS_EVENT_CARD_RESET:
2114 nsp_dbg(NSP_DEBUG_INIT, "event: reset");
2115 if (link->state & DEV_CONFIG) {
2116 pcmcia_request_configuration(link->handle, &link->conf);
2120 if (info->host != NULL) {
2121 nsp_msg(KERN_INFO, "reset host and bus");
2123 data = (nsp_hw_data *)info->host->hostdata;
2126 nsp_bus_reset(data);
2132 nsp_dbg(NSP_DEBUG_INIT, "event: unknown");
2135 nsp_dbg(NSP_DEBUG_INIT, "end");
2137 } /* nsp_cs_event */
2139 /*======================================================================*
2140 * module entry point
2141 *====================================================================*/
2142 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,68))
2143 static struct pcmcia_driver nsp_driver = {
2144 .owner = THIS_MODULE,
2148 .attach = nsp_cs_attach,
2149 .detach = nsp_cs_detach,
2153 static int __init nsp_cs_init(void)
2155 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,68))
2156 nsp_msg(KERN_INFO, "loading...");
2158 return pcmcia_register_driver(&nsp_driver);
2162 nsp_msg(KERN_INFO, "loading...");
2163 pcmcia_get_card_services_info(&serv);
2164 if (serv.Revision != CS_RELEASE_CODE) {
2165 nsp_msg(KERN_DEBUG, "Card Services release does not match!");
2168 register_pcmcia_driver(&dev_info, &nsp_cs_attach, &nsp_cs_detach);
2170 nsp_dbg(NSP_DEBUG_INIT, "out");
2175 static void __exit nsp_cs_exit(void)
2177 nsp_msg(KERN_INFO, "unloading...");
2179 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,68))
2180 pcmcia_unregister_driver(&nsp_driver);
2181 BUG_ON(dev_list != NULL);
2183 unregister_pcmcia_driver(&dev_info);
2184 /* XXX: this really needs to move into generic code.. */
2185 while (dev_list != NULL) {
2186 if (dev_list->state & DEV_CONFIG) {
2187 nsp_cs_release(dev_list);
2189 nsp_cs_detach(dev_list);
2195 module_init(nsp_cs_init)
2196 module_exit(nsp_cs_exit)