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/cs_types.h>
55 #include <pcmcia/cs.h>
56 #include <pcmcia/cistpl.h>
57 #include <pcmcia/cisreg.h>
58 #include <pcmcia/ds.h>
62 MODULE_AUTHOR("YOKOTA Hiroshi <yokota@netlab.is.tsukuba.ac.jp>");
63 MODULE_DESCRIPTION("WorkBit NinjaSCSI-3 / NinjaSCSI-32Bi(16bit) PCMCIA SCSI host adapter module $Revision: 1.23 $");
64 MODULE_SUPPORTED_DEVICE("sd,sr,sg,st");
66 MODULE_LICENSE("GPL");
71 /*====================================================================*/
72 /* Parameters that can be set with 'insmod' */
74 static int nsp_burst_mode = BURST_MEM32;
75 module_param(nsp_burst_mode, int, 0);
76 MODULE_PARM_DESC(nsp_burst_mode, "Burst transfer mode (0=io8, 1=io32, 2=mem32(default))");
78 /* Release IO ports after configuration? */
79 static int free_ports = 0;
80 module_param(free_ports, bool, 0);
81 MODULE_PARM_DESC(free_ports, "Release IO ports after configuration? (default: 0 (=no))");
83 /* /usr/src/linux/drivers/scsi/hosts.h */
84 static struct scsi_host_template nsp_driver_template = {
85 .proc_name = "nsp_cs",
86 .proc_info = nsp_proc_info,
87 .name = "WorkBit NinjaSCSI-3/32Bi(16bit)",
88 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
89 .detect = nsp_detect_old,
90 .release = nsp_release_old,
93 .queuecommand = nsp_queuecommand,
94 /* .eh_abort_handler = nsp_eh_abort,*/
95 .eh_bus_reset_handler = nsp_eh_bus_reset,
96 .eh_host_reset_handler = nsp_eh_host_reset,
98 .this_id = NSP_INITIATOR_ID,
99 .sg_tablesize = SG_ALL,
101 .use_clustering = DISABLE_CLUSTERING,
102 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,2))
103 .use_new_eh_code = 1,
107 static dev_info_t dev_info = {"nsp_cs"};
109 static nsp_hw_data nsp_data_base; /* attach <-> detect glue */
117 # define NSP_DEBUG_MASK 0x000000
118 # define nsp_msg(type, args...) nsp_cs_message("", 0, (type), args)
119 # define nsp_dbg(mask, args...) /* */
121 # define NSP_DEBUG_MASK 0xffffff
122 # define nsp_msg(type, args...) \
123 nsp_cs_message (__FUNCTION__, __LINE__, (type), args)
124 # define nsp_dbg(mask, args...) \
125 nsp_cs_dmessage(__FUNCTION__, __LINE__, (mask), args)
128 #define NSP_DEBUG_QUEUECOMMAND BIT(0)
129 #define NSP_DEBUG_REGISTER BIT(1)
130 #define NSP_DEBUG_AUTOSCSI BIT(2)
131 #define NSP_DEBUG_INTR BIT(3)
132 #define NSP_DEBUG_SGLIST BIT(4)
133 #define NSP_DEBUG_BUSFREE BIT(5)
134 #define NSP_DEBUG_CDB_CONTENTS BIT(6)
135 #define NSP_DEBUG_RESELECTION BIT(7)
136 #define NSP_DEBUG_MSGINOCCUR BIT(8)
137 #define NSP_DEBUG_EEPROM BIT(9)
138 #define NSP_DEBUG_MSGOUTOCCUR BIT(10)
139 #define NSP_DEBUG_BUSRESET BIT(11)
140 #define NSP_DEBUG_RESTART BIT(12)
141 #define NSP_DEBUG_SYNC BIT(13)
142 #define NSP_DEBUG_WAIT BIT(14)
143 #define NSP_DEBUG_TARGETFLAG BIT(15)
144 #define NSP_DEBUG_PROC BIT(16)
145 #define NSP_DEBUG_INIT BIT(17)
146 #define NSP_DEBUG_DATA_IO BIT(18)
147 #define NSP_SPECIAL_PRINT_REGISTER BIT(20)
149 #define NSP_DEBUG_BUF_LEN 150
151 static void nsp_cs_message(const char *func, int line, char *type, char *fmt, ...)
154 char buf[NSP_DEBUG_BUF_LEN];
157 vsnprintf(buf, sizeof(buf), fmt, args);
161 printk("%snsp_cs: %s\n", type, buf);
163 printk("%snsp_cs: %s (%d): %s\n", type, func, line, buf);
168 static void nsp_cs_dmessage(const char *func, int line, int mask, char *fmt, ...)
171 char buf[NSP_DEBUG_BUF_LEN];
174 vsnprintf(buf, sizeof(buf), fmt, args);
177 if (mask & NSP_DEBUG_MASK) {
178 printk("nsp_cs-debug: 0x%x %s (%d): %s\n", mask, func, line, buf);
183 /***********************************************************/
185 /*====================================================
186 * Clenaup parameters and call done() functions.
187 * You must be set SCpnt->result before call this function.
189 static void nsp_scsi_done(Scsi_Cmnd *SCpnt)
191 nsp_hw_data *data = (nsp_hw_data *)SCpnt->device->host->hostdata;
193 data->CurrentSC = NULL;
195 SCpnt->scsi_done(SCpnt);
198 static int nsp_queuecommand(Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *))
201 /*unsigned int host_id = SCpnt->device->host->this_id;*/
202 /*unsigned int base = SCpnt->device->host->io_port;*/
203 unsigned char target = scmd_id(SCpnt);
205 nsp_hw_data *data = (nsp_hw_data *)SCpnt->device->host->hostdata;
207 nsp_dbg(NSP_DEBUG_QUEUECOMMAND, "SCpnt=0x%p target=%d lun=%d buff=0x%p bufflen=%d use_sg=%d",
208 SCpnt, target, SCpnt->device->lun, SCpnt->request_buffer, SCpnt->request_bufflen, SCpnt->use_sg);
209 //nsp_dbg(NSP_DEBUG_QUEUECOMMAND, "before CurrentSC=0x%p", data->CurrentSC);
211 SCpnt->scsi_done = done;
213 if (data->CurrentSC != NULL) {
214 nsp_msg(KERN_DEBUG, "CurrentSC!=NULL this can't be happen");
215 SCpnt->result = DID_BAD_TARGET << 16;
216 nsp_scsi_done(SCpnt);
221 /* XXX: pcmcia-cs generates SCSI command with "scsi_info" utility.
222 This makes kernel crash when suspending... */
223 if (data->ScsiInfo->stop != 0) {
224 nsp_msg(KERN_INFO, "suspending device. reject command.");
225 SCpnt->result = DID_BAD_TARGET << 16;
226 nsp_scsi_done(SCpnt);
227 return SCSI_MLQUEUE_HOST_BUSY;
233 data->CurrentSC = SCpnt;
235 SCpnt->SCp.Status = CHECK_CONDITION;
236 SCpnt->SCp.Message = 0;
237 SCpnt->SCp.have_data_in = IO_UNKNOWN;
238 SCpnt->SCp.sent_command = 0;
239 SCpnt->SCp.phase = PH_UNDETERMINED;
240 SCpnt->resid = SCpnt->request_bufflen;
242 /* setup scratch area
243 SCp.ptr : buffer pointer
244 SCp.this_residual : buffer length
245 SCp.buffer : next buffer
246 SCp.buffers_residual : left buffers in list
247 SCp.phase : current state of the command */
249 SCpnt->SCp.buffer = (struct scatterlist *) SCpnt->request_buffer;
250 SCpnt->SCp.ptr = BUFFER_ADDR;
251 SCpnt->SCp.this_residual = SCpnt->SCp.buffer->length;
252 SCpnt->SCp.buffers_residual = SCpnt->use_sg - 1;
254 SCpnt->SCp.ptr = (char *) SCpnt->request_buffer;
255 SCpnt->SCp.this_residual = SCpnt->request_bufflen;
256 SCpnt->SCp.buffer = NULL;
257 SCpnt->SCp.buffers_residual = 0;
260 if (nsphw_start_selection(SCpnt) == FALSE) {
261 nsp_dbg(NSP_DEBUG_QUEUECOMMAND, "selection fail");
262 SCpnt->result = DID_BUS_BUSY << 16;
263 nsp_scsi_done(SCpnt);
268 //nsp_dbg(NSP_DEBUG_QUEUECOMMAND, "out");
276 * setup PIO FIFO transfer mode and enable/disable to data out
278 static void nsp_setup_fifo(nsp_hw_data *data, int enabled)
280 unsigned int base = data->BaseAddress;
281 unsigned char transfer_mode_reg;
283 //nsp_dbg(NSP_DEBUG_DATA_IO, "enabled=%d", enabled);
285 if (enabled != FALSE) {
286 transfer_mode_reg = TRANSFER_GO | BRAIND;
288 transfer_mode_reg = 0;
291 transfer_mode_reg |= data->TransferMode;
293 nsp_index_write(base, TRANSFERMODE, transfer_mode_reg);
296 static void nsphw_init_sync(nsp_hw_data *data)
298 sync_data tmp_sync = { .SyncNegotiation = SYNC_NOT_YET,
304 /* setup sync data */
305 for ( i = 0; i < ARRAY_SIZE(data->Sync); i++ ) {
306 data->Sync[i] = tmp_sync;
311 * Initialize Ninja hardware
313 static int nsphw_init(nsp_hw_data *data)
315 unsigned int base = data->BaseAddress;
317 nsp_dbg(NSP_DEBUG_INIT, "in base=0x%x", base);
319 data->ScsiClockDiv = CLOCK_40M | FAST_20;
320 data->CurrentSC = NULL;
322 data->TransferMode = MODE_IO8;
324 nsphw_init_sync(data);
326 /* block all interrupts */
327 nsp_write(base, IRQCONTROL, IRQCONTROL_ALLMASK);
329 /* setup SCSI interface */
330 nsp_write(base, IFSELECT, IF_IFSEL);
332 nsp_index_write(base, SCSIIRQMODE, 0);
334 nsp_index_write(base, TRANSFERMODE, MODE_IO8);
335 nsp_index_write(base, CLOCKDIV, data->ScsiClockDiv);
337 nsp_index_write(base, PARITYCTRL, 0);
338 nsp_index_write(base, POINTERCLR, POINTER_CLEAR |
343 /* setup fifo asic */
344 nsp_write(base, IFSELECT, IF_REGSEL);
345 nsp_index_write(base, TERMPWRCTRL, 0);
346 if ((nsp_index_read(base, OTHERCONTROL) & TPWR_SENSE) == 0) {
347 nsp_msg(KERN_INFO, "terminator power on");
348 nsp_index_write(base, TERMPWRCTRL, POWER_ON);
351 nsp_index_write(base, TIMERCOUNT, 0);
352 nsp_index_write(base, TIMERCOUNT, 0); /* requires 2 times!! */
354 nsp_index_write(base, SYNCREG, 0);
355 nsp_index_write(base, ACKWIDTH, 0);
357 /* enable interrupts and ack them */
358 nsp_index_write(base, SCSIIRQMODE, SCSI_PHASE_CHANGE_EI |
361 nsp_write(base, IRQCONTROL, IRQCONTROL_ALLCLEAR);
363 nsp_setup_fifo(data, FALSE);
369 * Start selection phase
371 static int nsphw_start_selection(Scsi_Cmnd *SCpnt)
373 unsigned int host_id = SCpnt->device->host->this_id;
374 unsigned int base = SCpnt->device->host->io_port;
375 unsigned char target = scmd_id(SCpnt);
376 nsp_hw_data *data = (nsp_hw_data *)SCpnt->device->host->hostdata;
378 unsigned char phase, arbit;
380 //nsp_dbg(NSP_DEBUG_RESELECTION, "in");
382 phase = nsp_index_read(base, SCSIBUSMON);
383 if(phase != BUSMON_BUS_FREE) {
384 //nsp_dbg(NSP_DEBUG_RESELECTION, "bus busy");
388 /* start arbitration */
389 //nsp_dbg(NSP_DEBUG_RESELECTION, "start arbit");
390 SCpnt->SCp.phase = PH_ARBSTART;
391 nsp_index_write(base, SETARBIT, ARBIT_GO);
395 /* XXX: what a stupid chip! */
396 arbit = nsp_index_read(base, ARBITSTATUS);
397 //nsp_dbg(NSP_DEBUG_RESELECTION, "arbit=%d, wait_count=%d", arbit, wait_count);
398 udelay(1); /* hold 1.2us */
399 } while((arbit & (ARBIT_WIN | ARBIT_FAIL)) == 0 &&
402 if (!(arbit & ARBIT_WIN)) {
403 //nsp_dbg(NSP_DEBUG_RESELECTION, "arbit fail");
404 nsp_index_write(base, SETARBIT, ARBIT_FLAG_CLEAR);
408 /* assert select line */
409 //nsp_dbg(NSP_DEBUG_RESELECTION, "assert SEL line");
410 SCpnt->SCp.phase = PH_SELSTART;
411 udelay(3); /* wait 2.4us */
412 nsp_index_write(base, SCSIDATALATCH, BIT(host_id) | BIT(target));
413 nsp_index_write(base, SCSIBUSCTRL, SCSI_SEL | SCSI_BSY | SCSI_ATN);
414 udelay(2); /* wait >1.2us */
415 nsp_index_write(base, SCSIBUSCTRL, SCSI_SEL | SCSI_BSY | SCSI_DATAOUT_ENB | SCSI_ATN);
416 nsp_index_write(base, SETARBIT, ARBIT_FLAG_CLEAR);
417 /*udelay(1);*/ /* wait >90ns */
418 nsp_index_write(base, SCSIBUSCTRL, SCSI_SEL | SCSI_DATAOUT_ENB | SCSI_ATN);
420 /* check selection timeout */
421 nsp_start_timer(SCpnt, 1000/51);
422 data->SelectionTimeOut = 1;
427 struct nsp_sync_table {
428 unsigned int min_period;
429 unsigned int max_period;
430 unsigned int chip_period;
431 unsigned int ack_width;
434 static struct nsp_sync_table nsp_sync_table_40M[] = {
435 {0x0c, 0x0c, 0x1, 0}, /* 20MB 50ns*/
436 {0x19, 0x19, 0x3, 1}, /* 10MB 100ns*/
437 {0x1a, 0x25, 0x5, 2}, /* 7.5MB 150ns*/
438 {0x26, 0x32, 0x7, 3}, /* 5MB 200ns*/
442 static struct nsp_sync_table nsp_sync_table_20M[] = {
443 {0x19, 0x19, 0x1, 0}, /* 10MB 100ns*/
444 {0x1a, 0x25, 0x2, 0}, /* 7.5MB 150ns*/
445 {0x26, 0x32, 0x3, 1}, /* 5MB 200ns*/
450 * setup synchronous data transfer mode
452 static int nsp_analyze_sdtr(Scsi_Cmnd *SCpnt)
454 unsigned char target = scmd_id(SCpnt);
455 // unsigned char lun = SCpnt->device->lun;
456 nsp_hw_data *data = (nsp_hw_data *)SCpnt->device->host->hostdata;
457 sync_data *sync = &(data->Sync[target]);
458 struct nsp_sync_table *sync_table;
459 unsigned int period, offset;
463 nsp_dbg(NSP_DEBUG_SYNC, "in");
465 period = sync->SyncPeriod;
466 offset = sync->SyncOffset;
468 nsp_dbg(NSP_DEBUG_SYNC, "period=0x%x, offset=0x%x", period, offset);
470 if ((data->ScsiClockDiv & (BIT(0)|BIT(1))) == CLOCK_20M) {
471 sync_table = nsp_sync_table_20M;
473 sync_table = nsp_sync_table_40M;
476 for ( i = 0; sync_table->max_period != 0; i++, sync_table++) {
477 if ( period >= sync_table->min_period &&
478 period <= sync_table->max_period ) {
483 if (period != 0 && sync_table->max_period == 0) {
485 * No proper period/offset found
487 nsp_dbg(NSP_DEBUG_SYNC, "no proper period/offset");
489 sync->SyncPeriod = 0;
490 sync->SyncOffset = 0;
491 sync->SyncRegister = 0;
497 sync->SyncRegister = (sync_table->chip_period << SYNCREG_PERIOD_SHIFT) |
498 (offset & SYNCREG_OFFSET_MASK);
499 sync->AckWidth = sync_table->ack_width;
501 nsp_dbg(NSP_DEBUG_SYNC, "sync_reg=0x%x, ack_width=0x%x", sync->SyncRegister, sync->AckWidth);
508 * start ninja hardware timer
510 static void nsp_start_timer(Scsi_Cmnd *SCpnt, int time)
512 unsigned int base = SCpnt->device->host->io_port;
513 nsp_hw_data *data = (nsp_hw_data *)SCpnt->device->host->hostdata;
515 //nsp_dbg(NSP_DEBUG_INTR, "in SCpnt=0x%p, time=%d", SCpnt, time);
516 data->TimerCount = time;
517 nsp_index_write(base, TIMERCOUNT, time);
521 * wait for bus phase change
523 static int nsp_negate_signal(Scsi_Cmnd *SCpnt, unsigned char mask, char *str)
525 unsigned int base = SCpnt->device->host->io_port;
529 //nsp_dbg(NSP_DEBUG_INTR, "in");
534 reg = nsp_index_read(base, SCSIBUSMON);
538 } while ((time_out-- != 0) && (reg & mask) != 0);
541 nsp_msg(KERN_DEBUG, " %s signal off timeut", str);
550 static int nsp_expect_signal(Scsi_Cmnd *SCpnt,
551 unsigned char current_phase,
554 unsigned int base = SCpnt->device->host->io_port;
556 unsigned char phase, i_src;
558 //nsp_dbg(NSP_DEBUG_INTR, "current_phase=0x%x, mask=0x%x", current_phase, mask);
562 phase = nsp_index_read(base, SCSIBUSMON);
564 //nsp_dbg(NSP_DEBUG_INTR, "ret -1");
567 i_src = nsp_read(base, IRQSTATUS);
568 if (i_src & IRQSTATUS_SCSI) {
569 //nsp_dbg(NSP_DEBUG_INTR, "ret 0 found scsi signal");
572 if ((phase & mask) != 0 && (phase & BUSMON_PHASE_MASK) == current_phase) {
573 //nsp_dbg(NSP_DEBUG_INTR, "ret 1 phase=0x%x", phase);
576 } while(time_out-- != 0);
578 //nsp_dbg(NSP_DEBUG_INTR, "timeout");
583 * transfer SCSI message
585 static int nsp_xfer(Scsi_Cmnd *SCpnt, int phase)
587 unsigned int base = SCpnt->device->host->io_port;
588 nsp_hw_data *data = (nsp_hw_data *)SCpnt->device->host->hostdata;
589 char *buf = data->MsgBuffer;
590 int len = min(MSGBUF_SIZE, data->MsgLen);
594 //nsp_dbg(NSP_DEBUG_DATA_IO, "in");
595 for (ptr = 0; len > 0; len--, ptr++) {
597 ret = nsp_expect_signal(SCpnt, phase, BUSMON_REQ);
599 nsp_dbg(NSP_DEBUG_DATA_IO, "xfer quit");
603 /* if last byte, negate ATN */
604 if (len == 1 && SCpnt->SCp.phase == PH_MSG_OUT) {
605 nsp_index_write(base, SCSIBUSCTRL, AUTODIRECTION | ACKENB);
608 /* read & write message */
609 if (phase & BUSMON_IO) {
610 nsp_dbg(NSP_DEBUG_DATA_IO, "read msg");
611 buf[ptr] = nsp_index_read(base, SCSIDATAWITHACK);
613 nsp_dbg(NSP_DEBUG_DATA_IO, "write msg");
614 nsp_index_write(base, SCSIDATAWITHACK, buf[ptr]);
616 nsp_negate_signal(SCpnt, BUSMON_ACK, "xfer<ack>");
623 * get extra SCSI data from fifo
625 static int nsp_dataphase_bypass(Scsi_Cmnd *SCpnt)
627 nsp_hw_data *data = (nsp_hw_data *)SCpnt->device->host->hostdata;
630 //nsp_dbg(NSP_DEBUG_DATA_IO, "in");
632 if (SCpnt->SCp.have_data_in != IO_IN) {
636 count = nsp_fifo_count(SCpnt);
637 if (data->FifoCount == count) {
638 //nsp_dbg(NSP_DEBUG_DATA_IO, "not use bypass quirk");
644 * data phase skip only occures in case of SCSI_LOW_READ
646 nsp_dbg(NSP_DEBUG_DATA_IO, "use bypass quirk");
647 SCpnt->SCp.phase = PH_DATA;
649 nsp_setup_fifo(data, FALSE);
657 static int nsp_reselected(Scsi_Cmnd *SCpnt)
659 unsigned int base = SCpnt->device->host->io_port;
660 unsigned int host_id = SCpnt->device->host->this_id;
661 //nsp_hw_data *data = (nsp_hw_data *)SCpnt->device->host->hostdata;
662 unsigned char bus_reg;
663 unsigned char id_reg, tmp;
666 nsp_dbg(NSP_DEBUG_RESELECTION, "in");
668 id_reg = nsp_index_read(base, RESELECTID);
669 tmp = id_reg & (~BIT(host_id));
679 if (scmd_id(SCpnt) != target) {
680 nsp_msg(KERN_ERR, "XXX: reselect ID must be %d in this implementation.", target);
683 nsp_negate_signal(SCpnt, BUSMON_SEL, "reselect<SEL>");
686 bus_reg = nsp_index_read(base, SCSIBUSCTRL) & ~(SCSI_BSY | SCSI_ATN);
687 nsp_index_write(base, SCSIBUSCTRL, bus_reg);
688 nsp_index_write(base, SCSIBUSCTRL, bus_reg | AUTODIRECTION | ACKENB);
694 * count how many data transferd
696 static int nsp_fifo_count(Scsi_Cmnd *SCpnt)
698 unsigned int base = SCpnt->device->host->io_port;
700 unsigned int l, m, h, dummy;
702 nsp_index_write(base, POINTERCLR, POINTER_CLEAR | ACK_COUNTER);
704 l = nsp_index_read(base, TRANSFERCOUNT);
705 m = nsp_index_read(base, TRANSFERCOUNT);
706 h = nsp_index_read(base, TRANSFERCOUNT);
707 dummy = nsp_index_read(base, TRANSFERCOUNT); /* required this! */
709 count = (h << 16) | (m << 8) | (l << 0);
711 //nsp_dbg(NSP_DEBUG_DATA_IO, "count=0x%x", count);
717 #define RFIFO_CRIT 64
718 #define WFIFO_CRIT 64
721 * read data in DATA IN phase
723 static void nsp_pio_read(Scsi_Cmnd *SCpnt)
725 unsigned int base = SCpnt->device->host->io_port;
726 unsigned long mmio_base = SCpnt->device->host->base;
727 nsp_hw_data *data = (nsp_hw_data *)SCpnt->device->host->hostdata;
730 unsigned char stat, fifo_stat;
732 ocount = data->FifoCount;
734 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",
735 SCpnt, SCpnt->resid, ocount, SCpnt->SCp.ptr, SCpnt->SCp.this_residual, SCpnt->SCp.buffer, SCpnt->SCp.buffers_residual);
739 while ((time_out-- != 0) &&
740 (SCpnt->SCp.this_residual > 0 || SCpnt->SCp.buffers_residual > 0 ) ) {
742 stat = nsp_index_read(base, SCSIBUSMON);
743 stat &= BUSMON_PHASE_MASK;
746 res = nsp_fifo_count(SCpnt) - ocount;
747 //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);
748 if (res == 0) { /* if some data avilable ? */
749 if (stat == BUSPHASE_DATA_IN) { /* phase changed? */
750 //nsp_dbg(NSP_DEBUG_DATA_IO, " wait for data this=%d", SCpnt->SCp.this_residual);
753 nsp_dbg(NSP_DEBUG_DATA_IO, "phase changed stat=0x%x", stat);
758 fifo_stat = nsp_read(base, FIFOSTATUS);
759 if ((fifo_stat & FIFOSTATUS_FULL_EMPTY) == 0 &&
760 stat == BUSPHASE_DATA_IN) {
764 res = min(res, SCpnt->SCp.this_residual);
766 switch (data->TransferMode) {
768 res &= ~(BIT(1)|BIT(0)); /* align 4 */
769 nsp_fifo32_read(base, SCpnt->SCp.ptr, res >> 2);
772 nsp_fifo8_read (base, SCpnt->SCp.ptr, res );
776 res &= ~(BIT(1)|BIT(0)); /* align 4 */
777 nsp_mmio_fifo32_read(mmio_base, SCpnt->SCp.ptr, res >> 2);
781 nsp_dbg(NSP_DEBUG_DATA_IO, "unknown read mode");
786 SCpnt->SCp.ptr += res;
787 SCpnt->SCp.this_residual -= res;
789 //nsp_dbg(NSP_DEBUG_DATA_IO, "ptr=0x%p this_residual=0x%x ocount=0x%x", SCpnt->SCp.ptr, SCpnt->SCp.this_residual, ocount);
791 /* go to next scatter list if available */
792 if (SCpnt->SCp.this_residual == 0 &&
793 SCpnt->SCp.buffers_residual != 0 ) {
794 //nsp_dbg(NSP_DEBUG_DATA_IO, "scatterlist next timeout=%d", time_out);
795 SCpnt->SCp.buffers_residual--;
797 SCpnt->SCp.ptr = BUFFER_ADDR;
798 SCpnt->SCp.this_residual = SCpnt->SCp.buffer->length;
801 //nsp_dbg(NSP_DEBUG_DATA_IO, "page: 0x%p, off: 0x%x", SCpnt->SCp.buffer->page, SCpnt->SCp.buffer->offset);
805 data->FifoCount = ocount;
808 nsp_msg(KERN_DEBUG, "pio read timeout resid=%d this_residual=%d buffers_residual=%d",
809 SCpnt->resid, SCpnt->SCp.this_residual, SCpnt->SCp.buffers_residual);
811 nsp_dbg(NSP_DEBUG_DATA_IO, "read ocount=0x%x", ocount);
812 nsp_dbg(NSP_DEBUG_DATA_IO, "r cmd=%d resid=0x%x\n", data->CmdId, SCpnt->resid);
816 * write data in DATA OUT phase
818 static void nsp_pio_write(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;
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, SCpnt->SCp.buffer, SCpnt->SCp.buffers_residual, SCpnt->resid);
834 while ((time_out-- != 0) &&
835 (SCpnt->SCp.this_residual > 0 || SCpnt->SCp.buffers_residual > 0)) {
836 stat = nsp_index_read(base, SCSIBUSMON);
837 stat &= BUSMON_PHASE_MASK;
839 if (stat != BUSPHASE_DATA_OUT) {
840 res = ocount - nsp_fifo_count(SCpnt);
842 nsp_dbg(NSP_DEBUG_DATA_IO, "phase changed stat=0x%x, res=%d\n", stat, res);
843 /* Put back pointer */
845 SCpnt->SCp.ptr -= res;
846 SCpnt->SCp.this_residual += res;
852 res = ocount - nsp_fifo_count(SCpnt);
853 if (res > 0) { /* write all data? */
854 nsp_dbg(NSP_DEBUG_DATA_IO, "wait for all data out. ocount=0x%x res=%d", ocount, res);
858 res = min(SCpnt->SCp.this_residual, WFIFO_CRIT);
860 //nsp_dbg(NSP_DEBUG_DATA_IO, "ptr=0x%p this=0x%x res=0x%x", SCpnt->SCp.ptr, SCpnt->SCp.this_residual, res);
861 switch (data->TransferMode) {
863 res &= ~(BIT(1)|BIT(0)); /* align 4 */
864 nsp_fifo32_write(base, SCpnt->SCp.ptr, res >> 2);
867 nsp_fifo8_write (base, SCpnt->SCp.ptr, res );
871 res &= ~(BIT(1)|BIT(0)); /* align 4 */
872 nsp_mmio_fifo32_write(mmio_base, SCpnt->SCp.ptr, res >> 2);
876 nsp_dbg(NSP_DEBUG_DATA_IO, "unknown write mode");
881 SCpnt->SCp.ptr += res;
882 SCpnt->SCp.this_residual -= res;
885 /* go to next scatter list if available */
886 if (SCpnt->SCp.this_residual == 0 &&
887 SCpnt->SCp.buffers_residual != 0 ) {
888 //nsp_dbg(NSP_DEBUG_DATA_IO, "scatterlist next");
889 SCpnt->SCp.buffers_residual--;
891 SCpnt->SCp.ptr = BUFFER_ADDR;
892 SCpnt->SCp.this_residual = SCpnt->SCp.buffer->length;
897 data->FifoCount = ocount;
900 nsp_msg(KERN_DEBUG, "pio write timeout resid=0x%x", SCpnt->resid);
902 nsp_dbg(NSP_DEBUG_DATA_IO, "write ocount=0x%x", ocount);
903 nsp_dbg(NSP_DEBUG_DATA_IO, "w cmd=%d resid=0x%x\n", data->CmdId, SCpnt->resid);
909 * setup synchronous/asynchronous data transfer mode
911 static int nsp_nexus(Scsi_Cmnd *SCpnt)
913 unsigned int base = SCpnt->device->host->io_port;
914 unsigned char target = scmd_id(SCpnt);
915 // unsigned char lun = SCpnt->device->lun;
916 nsp_hw_data *data = (nsp_hw_data *)SCpnt->device->host->hostdata;
917 sync_data *sync = &(data->Sync[target]);
919 //nsp_dbg(NSP_DEBUG_DATA_IO, "in SCpnt=0x%p", SCpnt);
921 /* setup synch transfer registers */
922 nsp_index_write(base, SYNCREG, sync->SyncRegister);
923 nsp_index_write(base, ACKWIDTH, sync->AckWidth);
925 if (SCpnt->use_sg == 0 ||
926 SCpnt->resid % 4 != 0 ||
927 SCpnt->resid <= PAGE_SIZE ) {
928 data->TransferMode = MODE_IO8;
929 } else if (nsp_burst_mode == BURST_MEM32) {
930 data->TransferMode = MODE_MEM32;
931 } else if (nsp_burst_mode == BURST_IO32) {
932 data->TransferMode = MODE_IO32;
934 data->TransferMode = MODE_IO8;
937 /* setup pdma fifo */
938 nsp_setup_fifo(data, TRUE);
940 /* clear ack counter */
942 nsp_index_write(base, POINTERCLR, POINTER_CLEAR |
950 #include "nsp_message.c"
954 static irqreturn_t nspintr(int irq, void *dev_id, struct pt_regs *regs)
957 unsigned char irq_status, irq_phase, phase;
959 unsigned char target, lun;
960 unsigned int *sync_neg;
965 //nsp_dbg(NSP_DEBUG_INTR, "dev_id=0x%p", dev_id);
966 //nsp_dbg(NSP_DEBUG_INTR, "host=0x%p", ((scsi_info_t *)dev_id)->host);
968 if ( dev_id != NULL &&
969 ((scsi_info_t *)dev_id)->host != NULL ) {
970 scsi_info_t *info = (scsi_info_t *)dev_id;
972 data = (nsp_hw_data *)info->host->hostdata;
974 nsp_dbg(NSP_DEBUG_INTR, "host data wrong");
978 //nsp_dbg(NSP_DEBUG_INTR, "&nsp_data_base=0x%p, dev_id=0x%p", &nsp_data_base, dev_id);
980 base = data->BaseAddress;
981 //nsp_dbg(NSP_DEBUG_INTR, "base=0x%x", base);
986 nsp_write(base, IRQCONTROL, IRQCONTROL_IRQDISABLE);
987 irq_status = nsp_read(base, IRQSTATUS);
988 //nsp_dbg(NSP_DEBUG_INTR, "irq_status=0x%x", irq_status);
989 if ((irq_status == 0xff) || ((irq_status & IRQSTATUS_MASK) == 0)) {
990 nsp_write(base, IRQCONTROL, 0);
991 //nsp_dbg(NSP_DEBUG_INTR, "no irq/shared irq");
996 * Do not read an irq_phase register if no scsi phase interrupt.
997 * Unless, you should lose a scsi phase interrupt.
999 phase = nsp_index_read(base, SCSIBUSMON);
1000 if((irq_status & IRQSTATUS_SCSI) != 0) {
1001 irq_phase = nsp_index_read(base, IRQPHASESENCE);
1006 //nsp_dbg(NSP_DEBUG_INTR, "irq_phase=0x%x", irq_phase);
1009 * timer interrupt handler (scsi vs timer interrupts)
1011 //nsp_dbg(NSP_DEBUG_INTR, "timercount=%d", data->TimerCount);
1012 if (data->TimerCount != 0) {
1013 //nsp_dbg(NSP_DEBUG_INTR, "stop timer");
1014 nsp_index_write(base, TIMERCOUNT, 0);
1015 nsp_index_write(base, TIMERCOUNT, 0);
1016 data->TimerCount = 0;
1019 if ((irq_status & IRQSTATUS_MASK) == IRQSTATUS_TIMER &&
1020 data->SelectionTimeOut == 0) {
1021 //nsp_dbg(NSP_DEBUG_INTR, "timer start");
1022 nsp_write(base, IRQCONTROL, IRQCONTROL_TIMER_CLEAR);
1026 nsp_write(base, IRQCONTROL, IRQCONTROL_TIMER_CLEAR | IRQCONTROL_FIFO_CLEAR);
1028 if ((irq_status & IRQSTATUS_SCSI) &&
1029 (irq_phase & SCSI_RESET_IRQ)) {
1030 nsp_msg(KERN_ERR, "bus reset (power off?)");
1033 nsp_bus_reset(data);
1035 if(data->CurrentSC != NULL) {
1036 tmpSC = data->CurrentSC;
1037 tmpSC->result = (DID_RESET << 16) |
1038 ((tmpSC->SCp.Message & 0xff) << 8) |
1039 ((tmpSC->SCp.Status & 0xff) << 0);
1040 nsp_scsi_done(tmpSC);
1045 if (data->CurrentSC == NULL) {
1046 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);
1048 nsp_bus_reset(data);
1052 tmpSC = data->CurrentSC;
1053 target = tmpSC->device->id;
1054 lun = tmpSC->device->lun;
1055 sync_neg = &(data->Sync[target].SyncNegotiation);
1058 * parse hardware SCSI irq reasons register
1060 if (irq_status & IRQSTATUS_SCSI) {
1061 if (irq_phase & RESELECT_IRQ) {
1062 nsp_dbg(NSP_DEBUG_INTR, "reselect");
1063 nsp_write(base, IRQCONTROL, IRQCONTROL_RESELECT_CLEAR);
1064 if (nsp_reselected(tmpSC) != FALSE) {
1069 if ((irq_phase & (PHASE_CHANGE_IRQ | LATCHED_BUS_FREE)) == 0) {
1074 //show_phase(tmpSC);
1076 switch(tmpSC->SCp.phase) {
1078 // *sync_neg = SYNC_NOT_YET;
1079 if ((phase & BUSMON_BSY) == 0) {
1080 //nsp_dbg(NSP_DEBUG_INTR, "selection count=%d", data->SelectionTimeOut);
1081 if (data->SelectionTimeOut >= NSP_SELTIMEOUT) {
1082 nsp_dbg(NSP_DEBUG_INTR, "selection time out");
1083 data->SelectionTimeOut = 0;
1084 nsp_index_write(base, SCSIBUSCTRL, 0);
1086 tmpSC->result = DID_TIME_OUT << 16;
1087 nsp_scsi_done(tmpSC);
1091 data->SelectionTimeOut += 1;
1092 nsp_start_timer(tmpSC, 1000/51);
1096 /* attention assert */
1097 //nsp_dbg(NSP_DEBUG_INTR, "attention assert");
1098 data->SelectionTimeOut = 0;
1099 tmpSC->SCp.phase = PH_SELECTED;
1100 nsp_index_write(base, SCSIBUSCTRL, SCSI_ATN);
1102 nsp_index_write(base, SCSIBUSCTRL, SCSI_ATN | AUTODIRECTION | ACKENB);
1108 //nsp_dbg(NSP_DEBUG_INTR, "phase reselect");
1109 // *sync_neg = SYNC_NOT_YET;
1110 if ((phase & BUSMON_PHASE_MASK) != BUSPHASE_MESSAGE_IN) {
1112 tmpSC->result = DID_ABORT << 16;
1113 nsp_scsi_done(tmpSC);
1118 if ((irq_status & (IRQSTATUS_SCSI | IRQSTATUS_FIFO)) == 0) {
1127 //nsp_dbg(NSP_DEBUG_INTR, "start scsi seq");
1129 /* normal disconnect */
1130 if (((tmpSC->SCp.phase == PH_MSG_IN) || (tmpSC->SCp.phase == PH_MSG_OUT)) &&
1131 (irq_phase & LATCHED_BUS_FREE) != 0 ) {
1132 nsp_dbg(NSP_DEBUG_INTR, "normal disconnect irq_status=0x%x, phase=0x%x, irq_phase=0x%x", irq_status, phase, irq_phase);
1134 //*sync_neg = SYNC_NOT_YET;
1136 if ((tmpSC->SCp.Message == MSG_COMMAND_COMPLETE)) { /* all command complete and return status */
1137 tmpSC->result = (DID_OK << 16) |
1138 ((tmpSC->SCp.Message & 0xff) << 8) |
1139 ((tmpSC->SCp.Status & 0xff) << 0);
1140 nsp_dbg(NSP_DEBUG_INTR, "command complete result=0x%x", tmpSC->result);
1141 nsp_scsi_done(tmpSC);
1150 /* check unexpected bus free state */
1152 nsp_msg(KERN_DEBUG, "unexpected bus free. irq_status=0x%x, phase=0x%x, irq_phase=0x%x", irq_status, phase, irq_phase);
1154 *sync_neg = SYNC_NG;
1155 tmpSC->result = DID_ERROR << 16;
1156 nsp_scsi_done(tmpSC);
1160 switch (phase & BUSMON_PHASE_MASK) {
1161 case BUSPHASE_COMMAND:
1162 nsp_dbg(NSP_DEBUG_INTR, "BUSPHASE_COMMAND");
1163 if ((phase & BUSMON_REQ) == 0) {
1164 nsp_dbg(NSP_DEBUG_INTR, "REQ == 0");
1168 tmpSC->SCp.phase = PH_COMMAND;
1172 /* write scsi command */
1173 nsp_dbg(NSP_DEBUG_INTR, "cmd_len=%d", tmpSC->cmd_len);
1174 nsp_index_write(base, COMMANDCTRL, CLEAR_COMMAND_POINTER);
1175 for (i = 0; i < tmpSC->cmd_len; i++) {
1176 nsp_index_write(base, COMMANDDATA, tmpSC->cmnd[i]);
1178 nsp_index_write(base, COMMANDCTRL, CLEAR_COMMAND_POINTER | AUTO_COMMAND_GO);
1181 case BUSPHASE_DATA_OUT:
1182 nsp_dbg(NSP_DEBUG_INTR, "BUSPHASE_DATA_OUT");
1184 tmpSC->SCp.phase = PH_DATA;
1185 tmpSC->SCp.have_data_in = IO_OUT;
1187 nsp_pio_write(tmpSC);
1191 case BUSPHASE_DATA_IN:
1192 nsp_dbg(NSP_DEBUG_INTR, "BUSPHASE_DATA_IN");
1194 tmpSC->SCp.phase = PH_DATA;
1195 tmpSC->SCp.have_data_in = IO_IN;
1197 nsp_pio_read(tmpSC);
1201 case BUSPHASE_STATUS:
1202 nsp_dataphase_bypass(tmpSC);
1203 nsp_dbg(NSP_DEBUG_INTR, "BUSPHASE_STATUS");
1205 tmpSC->SCp.phase = PH_STATUS;
1207 tmpSC->SCp.Status = nsp_index_read(base, SCSIDATAWITHACK);
1208 nsp_dbg(NSP_DEBUG_INTR, "message=0x%x status=0x%x", tmpSC->SCp.Message, tmpSC->SCp.Status);
1212 case BUSPHASE_MESSAGE_OUT:
1213 nsp_dbg(NSP_DEBUG_INTR, "BUSPHASE_MESSAGE_OUT");
1214 if ((phase & BUSMON_REQ) == 0) {
1218 tmpSC->SCp.phase = PH_MSG_OUT;
1220 //*sync_neg = SYNC_NOT_YET;
1222 data->MsgLen = i = 0;
1223 data->MsgBuffer[i] = IDENTIFY(TRUE, lun); i++;
1225 if (*sync_neg == SYNC_NOT_YET) {
1226 data->Sync[target].SyncPeriod = 0;
1227 data->Sync[target].SyncOffset = 0;
1230 data->MsgBuffer[i] = MSG_EXTENDED; i++;
1231 data->MsgBuffer[i] = 3; i++;
1232 data->MsgBuffer[i] = MSG_EXT_SDTR; i++;
1233 data->MsgBuffer[i] = 0x0c; i++;
1234 data->MsgBuffer[i] = 15; i++;
1239 nsp_analyze_sdtr(tmpSC);
1241 nsp_message_out(tmpSC);
1244 case BUSPHASE_MESSAGE_IN:
1245 nsp_dataphase_bypass(tmpSC);
1246 nsp_dbg(NSP_DEBUG_INTR, "BUSPHASE_MESSAGE_IN");
1247 if ((phase & BUSMON_REQ) == 0) {
1251 tmpSC->SCp.phase = PH_MSG_IN;
1252 nsp_message_in(tmpSC);
1255 if (*sync_neg == SYNC_NOT_YET) {
1256 //nsp_dbg(NSP_DEBUG_INTR, "sync target=%d,lun=%d",target,lun);
1258 if (data->MsgLen >= 5 &&
1259 data->MsgBuffer[0] == MSG_EXTENDED &&
1260 data->MsgBuffer[1] == 3 &&
1261 data->MsgBuffer[2] == MSG_EXT_SDTR ) {
1262 data->Sync[target].SyncPeriod = data->MsgBuffer[3];
1263 data->Sync[target].SyncOffset = data->MsgBuffer[4];
1264 //nsp_dbg(NSP_DEBUG_INTR, "sync ok, %d %d", data->MsgBuffer[3], data->MsgBuffer[4]);
1265 *sync_neg = SYNC_OK;
1267 data->Sync[target].SyncPeriod = 0;
1268 data->Sync[target].SyncOffset = 0;
1269 *sync_neg = SYNC_NG;
1271 nsp_analyze_sdtr(tmpSC);
1275 /* search last messeage byte */
1277 for (i = 0; i < data->MsgLen; i++) {
1278 tmp = data->MsgBuffer[i];
1279 if (data->MsgBuffer[i] == MSG_EXTENDED) {
1280 i += (1 + data->MsgBuffer[i+1]);
1283 tmpSC->SCp.Message = tmp;
1285 nsp_dbg(NSP_DEBUG_INTR, "message=0x%x len=%d", tmpSC->SCp.Message, data->MsgLen);
1290 case BUSPHASE_SELECT:
1292 nsp_dbg(NSP_DEBUG_INTR, "BUSPHASE other");
1297 //nsp_dbg(NSP_DEBUG_INTR, "out");
1301 nsp_start_timer(tmpSC, 1000/102);
1306 #include "nsp_debug.c"
1307 #endif /* NSP_DEBUG */
1309 /*----------------------------------------------------------------*/
1310 /* look for ninja3 card and init if found */
1311 /*----------------------------------------------------------------*/
1312 static struct Scsi_Host *nsp_detect(struct scsi_host_template *sht)
1314 struct Scsi_Host *host; /* registered host structure */
1315 nsp_hw_data *data_b = &nsp_data_base, *data;
1317 nsp_dbg(NSP_DEBUG_INIT, "this_id=%d", sht->this_id);
1318 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,73))
1319 host = scsi_host_alloc(&nsp_driver_template, sizeof(nsp_hw_data));
1321 host = scsi_register(sht, sizeof(nsp_hw_data));
1324 nsp_dbg(NSP_DEBUG_INIT, "host failed");
1328 memcpy(host->hostdata, data_b, sizeof(nsp_hw_data));
1329 data = (nsp_hw_data *)host->hostdata;
1330 data->ScsiInfo->host = host;
1335 nsp_dbg(NSP_DEBUG_INIT, "irq=%d,%d", data_b->IrqNumber, ((nsp_hw_data *)host->hostdata)->IrqNumber);
1337 host->unique_id = data->BaseAddress;
1338 host->io_port = data->BaseAddress;
1339 host->n_io_port = data->NumAddress;
1340 host->irq = data->IrqNumber;
1341 host->base = data->MmioAddress;
1343 spin_lock_init(&(data->Lock));
1345 snprintf(data->nspinfo,
1346 sizeof(data->nspinfo),
1347 "NinjaSCSI-3/32Bi Driver $Revision: 1.23 $ IO:0x%04lx-0x%04lx MMIO(virt addr):0x%04lx IRQ:%02d",
1348 host->io_port, host->io_port + host->n_io_port - 1,
1351 sht->name = data->nspinfo;
1353 nsp_dbg(NSP_DEBUG_INIT, "end");
1356 return host; /* detect done. */
1359 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
1360 static int nsp_detect_old(struct scsi_host_template *sht)
1362 if (nsp_detect(sht) == NULL) {
1365 //MOD_INC_USE_COUNT;
1371 static int nsp_release_old(struct Scsi_Host *shpnt)
1373 //nsp_hw_data *data = (nsp_hw_data *)shpnt->hostdata;
1375 /* PCMCIA Card Service dose same things below. */
1376 /* So we do nothing. */
1378 // free_irq(shpnt->irq, data->ScsiInfo);
1380 //if (shpnt->io_port) {
1381 // release_region(shpnt->io_port, shpnt->n_io_port);
1384 //MOD_DEC_USE_COUNT;
1390 /*----------------------------------------------------------------*/
1391 /* return info string */
1392 /*----------------------------------------------------------------*/
1393 static const char *nsp_info(struct Scsi_Host *shpnt)
1395 nsp_hw_data *data = (nsp_hw_data *)shpnt->hostdata;
1397 return data->nspinfo;
1401 #define SPRINTF(args...) \
1403 if(length > (pos - buffer)) { \
1404 pos += snprintf(pos, length - (pos - buffer) + 1, ## args); \
1405 nsp_dbg(NSP_DEBUG_PROC, "buffer=0x%p pos=0x%p length=%d %d\n", buffer, pos, length, length - (pos - buffer));\
1410 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,73))
1411 struct Scsi_Host *host,
1417 #if !(LINUX_VERSION_CODE > KERNEL_VERSION(2,5,73))
1426 unsigned long flags;
1428 #if !(LINUX_VERSION_CODE > KERNEL_VERSION(2,5,73))
1429 struct Scsi_Host *host;
1437 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,73))
1438 hostno = host->host_no;
1440 /* search this HBA host */
1441 host = scsi_host_hn_get(hostno);
1446 data = (nsp_hw_data *)host->hostdata;
1449 SPRINTF("NinjaSCSI status\n\n");
1450 SPRINTF("Driver version: $Revision: 1.23 $\n");
1451 SPRINTF("SCSI host No.: %d\n", hostno);
1452 SPRINTF("IRQ: %d\n", host->irq);
1453 SPRINTF("IO: 0x%lx-0x%lx\n", host->io_port, host->io_port + host->n_io_port - 1);
1454 SPRINTF("MMIO(virtual address): 0x%lx-0x%lx\n", host->base, host->base + data->MmioLength - 1);
1455 SPRINTF("sg_tablesize: %d\n", host->sg_tablesize);
1457 SPRINTF("burst transfer mode: ");
1458 switch (nsp_burst_mode) {
1475 spin_lock_irqsave(&(data->Lock), flags);
1476 SPRINTF("CurrentSC: 0x%p\n\n", data->CurrentSC);
1477 spin_unlock_irqrestore(&(data->Lock), flags);
1479 SPRINTF("SDTR status\n");
1480 for(id = 0; id < ARRAY_SIZE(data->Sync); id++) {
1482 SPRINTF("id %d: ", id);
1484 if (id == host->this_id) {
1485 SPRINTF("----- NinjaSCSI-3 host adapter\n");
1489 switch(data->Sync[id].SyncNegotiation) {
1504 if (data->Sync[id].SyncPeriod != 0) {
1505 speed = 1000000 / (data->Sync[id].SyncPeriod * 4);
1507 SPRINTF(" transfer %d.%dMB/s, offset %d",
1510 data->Sync[id].SyncOffset
1516 thislength = pos - (buffer + offset);
1518 if(thislength < 0) {
1524 thislength = min(thislength, length);
1525 *start = buffer + offset;
1531 /*---------------------------------------------------------------*/
1533 /*---------------------------------------------------------------*/
1536 static int nsp_eh_abort(Scsi_Cmnd *SCpnt)
1538 nsp_dbg(NSP_DEBUG_BUSRESET, "SCpnt=0x%p", SCpnt);
1540 return nsp_eh_bus_reset(SCpnt);
1543 static int nsp_bus_reset(nsp_hw_data *data)
1545 unsigned int base = data->BaseAddress;
1548 nsp_write(base, IRQCONTROL, IRQCONTROL_ALLMASK);
1550 nsp_index_write(base, SCSIBUSCTRL, SCSI_RST);
1551 mdelay(100); /* 100ms */
1552 nsp_index_write(base, SCSIBUSCTRL, 0);
1553 for(i = 0; i < 5; i++) {
1554 nsp_index_read(base, IRQPHASESENCE); /* dummy read */
1557 nsphw_init_sync(data);
1559 nsp_write(base, IRQCONTROL, IRQCONTROL_ALLCLEAR);
1564 static int nsp_eh_bus_reset(Scsi_Cmnd *SCpnt)
1566 nsp_hw_data *data = (nsp_hw_data *)SCpnt->device->host->hostdata;
1568 nsp_dbg(NSP_DEBUG_BUSRESET, "SCpnt=0x%p", SCpnt);
1570 return nsp_bus_reset(data);
1573 static int nsp_eh_host_reset(Scsi_Cmnd *SCpnt)
1575 nsp_hw_data *data = (nsp_hw_data *)SCpnt->device->host->hostdata;
1577 nsp_dbg(NSP_DEBUG_BUSRESET, "in");
1585 /**********************************************************************
1587 **********************************************************************/
1589 /*======================================================================
1590 nsp_cs_attach() creates an "instance" of the driver, allocating
1591 local data structures for one device. The device is registered
1594 The dev_link structure is initialized, but we don't actually
1595 configure the card at this point -- we wait until we receive a
1596 card insertion event.
1597 ======================================================================*/
1598 static dev_link_t *nsp_cs_attach(void)
1601 client_reg_t client_reg;
1604 nsp_hw_data *data = &nsp_data_base;
1606 nsp_dbg(NSP_DEBUG_INIT, "in");
1608 /* Create new SCSI device */
1609 info = kmalloc(sizeof(*info), GFP_KERNEL);
1610 if (info == NULL) { return NULL; }
1611 memset(info, 0, sizeof(*info));
1614 data->ScsiInfo = info;
1616 nsp_dbg(NSP_DEBUG_INIT, "info=0x%p", info);
1618 /* The io structure describes IO port mapping */
1619 link->io.NumPorts1 = 0x10;
1620 link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
1621 link->io.IOAddrLines = 10; /* not used */
1623 /* Interrupt setup */
1624 link->irq.Attributes = IRQ_TYPE_EXCLUSIVE | IRQ_HANDLE_PRESENT;
1625 link->irq.IRQInfo1 = IRQ_LEVEL_ID;
1627 /* Interrupt handler */
1628 link->irq.Handler = &nspintr;
1629 link->irq.Instance = info;
1630 link->irq.Attributes |= (SA_SHIRQ | SA_SAMPLE_RANDOM);
1632 /* General socket configuration */
1633 link->conf.Attributes = CONF_ENABLE_IRQ;
1634 link->conf.Vcc = 50;
1635 link->conf.IntType = INT_MEMORY_AND_IO;
1636 link->conf.Present = PRESENT_OPTION;
1639 /* Register with Card Services */
1641 client_reg.dev_info = &dev_info;
1642 client_reg.Version = 0x0210;
1643 client_reg.event_callback_args.client_data = link;
1644 ret = pcmcia_register_client(&link->handle, &client_reg);
1645 if (ret != CS_SUCCESS) {
1646 cs_error(link->handle, RegisterClient, ret);
1647 nsp_cs_detach(link->handle);
1652 nsp_dbg(NSP_DEBUG_INIT, "link=0x%p", link);
1654 } /* nsp_cs_attach */
1657 /*======================================================================
1658 This deletes a driver "instance". The device is de-registered
1659 with Card Services. If it has been released, all local data
1660 structures are freed. Otherwise, the structures will be freed
1661 when the device is released.
1662 ======================================================================*/
1663 static void nsp_cs_detach(struct pcmcia_device *p_dev)
1665 dev_link_t *link = dev_to_instance(p_dev);
1667 nsp_dbg(NSP_DEBUG_INIT, "in, link=0x%p", link);
1669 if (link->state & DEV_CONFIG) {
1670 ((scsi_info_t *)link->priv)->stop = 1;
1671 nsp_cs_release(link);
1676 } /* nsp_cs_detach */
1679 /*======================================================================
1680 nsp_cs_config() is scheduled to run after a CARD_INSERTION event
1681 is received, to configure the PCMCIA socket, and to make the
1682 ethernet device available to the system.
1683 ======================================================================*/
1684 #define CS_CHECK(fn, ret) \
1685 do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
1686 /*====================================================================*/
1687 static void nsp_cs_config(dev_link_t *link)
1689 client_handle_t handle = link->handle;
1690 scsi_info_t *info = link->priv;
1693 int last_ret, last_fn;
1694 unsigned char tuple_data[64];
1698 cistpl_cftable_entry_t dflt = { 0 };
1699 struct Scsi_Host *host;
1700 nsp_hw_data *data = &nsp_data_base;
1701 #if !(LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,74))
1702 struct scsi_device *dev;
1703 dev_node_t **tail, *node;
1706 nsp_dbg(NSP_DEBUG_INIT, "in");
1708 tuple.DesiredTuple = CISTPL_CONFIG;
1709 tuple.Attributes = 0;
1710 tuple.TupleData = tuple_data;
1711 tuple.TupleDataMax = sizeof(tuple_data);
1712 tuple.TupleOffset = 0;
1713 CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(handle, &tuple));
1714 CS_CHECK(GetTupleData, pcmcia_get_tuple_data(handle, &tuple));
1715 CS_CHECK(ParseTuple, pcmcia_parse_tuple(handle, &tuple, &parse));
1716 link->conf.ConfigBase = parse.config.base;
1717 link->conf.Present = parse.config.rmask[0];
1719 /* Configure card */
1720 link->state |= DEV_CONFIG;
1722 /* Look up the current Vcc */
1723 CS_CHECK(GetConfigurationInfo, pcmcia_get_configuration_info(handle, &conf));
1724 link->conf.Vcc = conf.Vcc;
1726 tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
1727 CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(handle, &tuple));
1729 cistpl_cftable_entry_t *cfg = &(parse.cftable_entry);
1731 if (pcmcia_get_tuple_data(handle, &tuple) != 0 ||
1732 pcmcia_parse_tuple(handle, &tuple, &parse) != 0)
1735 if (cfg->flags & CISTPL_CFTABLE_DEFAULT) { dflt = *cfg; }
1736 if (cfg->index == 0) { goto next_entry; }
1737 link->conf.ConfigIndex = cfg->index;
1739 /* Does this card need audio output? */
1740 if (cfg->flags & CISTPL_CFTABLE_AUDIO) {
1741 link->conf.Attributes |= CONF_ENABLE_SPKR;
1742 link->conf.Status = CCSR_AUDIO_ENA;
1745 /* Use power settings for Vcc and Vpp if present */
1746 /* Note that the CIS values need to be rescaled */
1747 if (cfg->vcc.present & (1<<CISTPL_POWER_VNOM)) {
1748 if (conf.Vcc != cfg->vcc.param[CISTPL_POWER_VNOM]/10000) {
1751 } else if (dflt.vcc.present & (1<<CISTPL_POWER_VNOM)) {
1752 if (conf.Vcc != dflt.vcc.param[CISTPL_POWER_VNOM]/10000) {
1757 if (cfg->vpp1.present & (1 << CISTPL_POWER_VNOM)) {
1758 link->conf.Vpp1 = link->conf.Vpp2 =
1759 cfg->vpp1.param[CISTPL_POWER_VNOM] / 10000;
1760 } else if (dflt.vpp1.present & (1 << CISTPL_POWER_VNOM)) {
1761 link->conf.Vpp1 = link->conf.Vpp2 =
1762 dflt.vpp1.param[CISTPL_POWER_VNOM] / 10000;
1765 /* Do we need to allocate an interrupt? */
1766 if (cfg->irq.IRQInfo1 || dflt.irq.IRQInfo1) {
1767 link->conf.Attributes |= CONF_ENABLE_IRQ;
1770 /* IO window settings */
1771 link->io.NumPorts1 = link->io.NumPorts2 = 0;
1772 if ((cfg->io.nwin > 0) || (dflt.io.nwin > 0)) {
1773 cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt.io;
1774 link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
1775 if (!(io->flags & CISTPL_IO_8BIT))
1776 link->io.Attributes1 = IO_DATA_PATH_WIDTH_16;
1777 if (!(io->flags & CISTPL_IO_16BIT))
1778 link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
1779 link->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK;
1780 link->io.BasePort1 = io->win[0].base;
1781 link->io.NumPorts1 = io->win[0].len;
1783 link->io.Attributes2 = link->io.Attributes1;
1784 link->io.BasePort2 = io->win[1].base;
1785 link->io.NumPorts2 = io->win[1].len;
1787 /* This reserves IO space but doesn't actually enable it */
1788 if (pcmcia_request_io(link->handle, &link->io) != 0)
1792 if ((cfg->mem.nwin > 0) || (dflt.mem.nwin > 0)) {
1794 (cfg->mem.nwin) ? &cfg->mem : &dflt.mem;
1795 req.Attributes = WIN_DATA_WIDTH_16|WIN_MEMORY_TYPE_CM;
1796 req.Attributes |= WIN_ENABLE;
1797 req.Base = mem->win[0].host_addr;
1798 req.Size = mem->win[0].len;
1799 if (req.Size < 0x1000) {
1802 req.AccessSpeed = 0;
1803 if (pcmcia_request_window(&link->handle, &req, &link->win) != 0)
1805 map.Page = 0; map.CardOffset = mem->win[0].card_addr;
1806 if (pcmcia_map_mem_page(link->win, &map) != 0)
1809 data->MmioAddress = (unsigned long)ioremap_nocache(req.Base, req.Size);
1810 data->MmioLength = req.Size;
1812 /* If we got this far, we're cool! */
1816 nsp_dbg(NSP_DEBUG_INIT, "next");
1818 if (link->io.NumPorts1) {
1819 pcmcia_release_io(link->handle, &link->io);
1821 CS_CHECK(GetNextTuple, pcmcia_get_next_tuple(handle, &tuple));
1824 if (link->conf.Attributes & CONF_ENABLE_IRQ) {
1825 CS_CHECK(RequestIRQ, pcmcia_request_irq(link->handle, &link->irq));
1827 CS_CHECK(RequestConfiguration, pcmcia_request_configuration(handle, &link->conf));
1830 if (link->io.BasePort1) {
1831 release_region(link->io.BasePort1, link->io.NumPorts1);
1833 if (link->io.BasePort2) {
1834 release_region(link->io.BasePort2, link->io.NumPorts2);
1838 /* Set port and IRQ */
1839 data->BaseAddress = link->io.BasePort1;
1840 data->NumAddress = link->io.NumPorts1;
1841 data->IrqNumber = link->irq.AssignedIRQ;
1843 nsp_dbg(NSP_DEBUG_INIT, "I/O[0x%x+0x%x] IRQ %d",
1844 data->BaseAddress, data->NumAddress, data->IrqNumber);
1846 if(nsphw_init(data) == FALSE) {
1850 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,2))
1851 host = nsp_detect(&nsp_driver_template);
1853 scsi_register_host(&nsp_driver_template);
1854 for (host = scsi_host_get_next(NULL); host != NULL;
1855 host = scsi_host_get_next(host)) {
1856 if (host->hostt == &nsp_driver_template) {
1863 nsp_dbg(NSP_DEBUG_INIT, "detect failed");
1868 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,74))
1869 scsi_add_host (host, NULL);
1870 scsi_scan_host(host);
1872 snprintf(info->node.dev_name, sizeof(info->node.dev_name), "scsi%d", host->host_no);
1873 link->dev = &info->node;
1877 nsp_dbg(NSP_DEBUG_INIT, "GET_SCSI_INFO");
1881 nsp_dbg(NSP_DEBUG_INIT, "host=0x%p", host);
1883 for (dev = host->host_queue; dev != NULL; dev = dev->next) {
1885 id = (dev->id & 0x0f) + ((dev->lun & 0x0f) << 4) +
1886 ((dev->channel & 0x0f) << 8) +
1887 ((dev->host->host_no & 0x0f) << 12);
1888 node = &info->node[info->ndev];
1890 switch (dev->type) {
1892 node->major = SCSI_TAPE_MAJOR;
1893 snprintf(node->dev_name, sizeof(node->dev_name), "st#%04lx", id);
1897 node->major = SCSI_DISK0_MAJOR;
1898 snprintf(node->dev_name, sizeof(node->dev_name), "sd#%04lx", id);
1902 node->major = SCSI_CDROM_MAJOR;
1903 snprintf(node->dev_name, sizeof(node->dev_name), "sr#%04lx", id);
1906 node->major = SCSI_GENERIC_MAJOR;
1907 snprintf(node->dev_name, sizeof(node->dev_name), "sg#%04lx", id);
1910 *tail = node; tail = &node->next;
1912 info->host = dev->host;
1916 if (info->ndev == 0) {
1917 nsp_msg(KERN_INFO, "no SCSI devices found");
1919 nsp_dbg(NSP_DEBUG_INIT, "host=0x%p", host);
1922 /* Finally, report what we've done */
1923 printk(KERN_INFO "nsp_cs: index 0x%02x: Vcc %d.%d",
1924 link->conf.ConfigIndex,
1925 link->conf.Vcc/10, link->conf.Vcc%10);
1926 if (link->conf.Vpp1) {
1927 printk(", Vpp %d.%d", link->conf.Vpp1/10, link->conf.Vpp1%10);
1929 if (link->conf.Attributes & CONF_ENABLE_IRQ) {
1930 printk(", irq %d", link->irq.AssignedIRQ);
1932 if (link->io.NumPorts1) {
1933 printk(", io 0x%04x-0x%04x", link->io.BasePort1,
1934 link->io.BasePort1+link->io.NumPorts1-1);
1936 if (link->io.NumPorts2)
1937 printk(" & 0x%04x-0x%04x", link->io.BasePort2,
1938 link->io.BasePort2+link->io.NumPorts2-1);
1940 printk(", mem 0x%06lx-0x%06lx", req.Base,
1941 req.Base+req.Size-1);
1944 link->state &= ~DEV_CONFIG_PENDING;
1948 nsp_dbg(NSP_DEBUG_INIT, "config fail");
1949 cs_error(link->handle, last_fn, last_ret);
1950 nsp_cs_release(link);
1953 } /* nsp_cs_config */
1957 /*======================================================================
1958 After a card is removed, nsp_cs_release() will unregister the net
1959 device, and release the PCMCIA configuration. If the device is
1960 still open, this will be postponed until it is closed.
1961 ======================================================================*/
1962 static void nsp_cs_release(dev_link_t *link)
1964 scsi_info_t *info = link->priv;
1965 nsp_hw_data *data = NULL;
1967 if (info->host == NULL) {
1968 nsp_msg(KERN_DEBUG, "unexpected card release call.");
1970 data = (nsp_hw_data *)info->host->hostdata;
1973 nsp_dbg(NSP_DEBUG_INIT, "link=0x%p", link);
1975 /* Unlink the device chain */
1976 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,2))
1977 if (info->host != NULL) {
1978 scsi_remove_host(info->host);
1981 scsi_unregister_host(&nsp_driver_template);
1987 iounmap((void *)(data->MmioAddress));
1989 pcmcia_release_window(link->win);
1991 pcmcia_release_configuration(link->handle);
1992 if (link->io.NumPorts1) {
1993 pcmcia_release_io(link->handle, &link->io);
1995 if (link->irq.AssignedIRQ) {
1996 pcmcia_release_irq(link->handle, &link->irq);
1998 link->state &= ~DEV_CONFIG;
1999 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,2))
2000 if (info->host != NULL) {
2001 scsi_host_put(info->host);
2004 } /* nsp_cs_release */
2006 static int nsp_cs_suspend(struct pcmcia_device *dev)
2008 dev_link_t *link = dev_to_instance(dev);
2009 scsi_info_t *info = link->priv;
2012 link->state |= DEV_SUSPEND;
2014 nsp_dbg(NSP_DEBUG_INIT, "event: suspend");
2016 if (info->host != NULL) {
2017 nsp_msg(KERN_INFO, "clear SDTR status");
2019 data = (nsp_hw_data *)info->host->hostdata;
2021 nsphw_init_sync(data);
2026 if (link->state & DEV_CONFIG)
2027 pcmcia_release_configuration(link->handle);
2032 static int nsp_cs_resume(struct pcmcia_device *dev)
2034 dev_link_t *link = dev_to_instance(dev);
2035 scsi_info_t *info = link->priv;
2038 nsp_dbg(NSP_DEBUG_INIT, "event: resume");
2040 link->state &= ~DEV_SUSPEND;
2042 if (link->state & DEV_CONFIG)
2043 pcmcia_request_configuration(link->handle, &link->conf);
2047 if (info->host != NULL) {
2048 nsp_msg(KERN_INFO, "reset host and bus");
2050 data = (nsp_hw_data *)info->host->hostdata;
2053 nsp_bus_reset(data);
2059 /*======================================================================
2061 The card status event handler. Mostly, this schedules other
2062 stuff to run after an event is received. A CARD_REMOVAL event
2063 also sets some flags to discourage the net drivers from trying
2064 to talk to the card any more.
2066 When a CARD_REMOVAL event is received, we immediately set a flag
2067 to block future accesses to this device. All the functions that
2068 actually access the device should check this flag to make sure
2069 the card is still present.
2071 ======================================================================*/
2072 static int nsp_cs_event(event_t event,
2074 event_callback_args_t *args)
2076 dev_link_t *link = args->client_data;
2078 nsp_dbg(NSP_DEBUG_INIT, "in, event=0x%08x", event);
2081 case CS_EVENT_CARD_INSERTION:
2082 nsp_dbg(NSP_DEBUG_INIT, "event: insert");
2083 link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
2084 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,68))
2085 info->bus = args->bus;
2087 nsp_cs_config(link);
2090 nsp_dbg(NSP_DEBUG_INIT, "event: unknown");
2093 nsp_dbg(NSP_DEBUG_INIT, "end");
2095 } /* nsp_cs_event */
2097 /*======================================================================*
2098 * module entry point
2099 *====================================================================*/
2100 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,68))
2101 static struct pcmcia_device_id nsp_cs_ids[] = {
2102 PCMCIA_DEVICE_PROD_ID123("IO DATA", "CBSC16 ", "1", 0x547e66dc, 0x0d63a3fd, 0x51de003a),
2103 PCMCIA_DEVICE_PROD_ID123("KME ", "SCSI-CARD-001", "1", 0x534c02bc, 0x52008408, 0x51de003a),
2104 PCMCIA_DEVICE_PROD_ID123("KME ", "SCSI-CARD-002", "1", 0x534c02bc, 0xcb09d5b2, 0x51de003a),
2105 PCMCIA_DEVICE_PROD_ID123("KME ", "SCSI-CARD-003", "1", 0x534c02bc, 0xbc0ee524, 0x51de003a),
2106 PCMCIA_DEVICE_PROD_ID123("KME ", "SCSI-CARD-004", "1", 0x534c02bc, 0x226a7087, 0x51de003a),
2107 PCMCIA_DEVICE_PROD_ID123("WBT", "NinjaSCSI-3", "R1.0", 0xc7ba805f, 0xfdc7c97d, 0x6973710e),
2108 PCMCIA_DEVICE_PROD_ID123("WORKBIT", "UltraNinja-16", "1", 0x28191418, 0xb70f4b09, 0x51de003a),
2111 MODULE_DEVICE_TABLE(pcmcia, nsp_cs_ids);
2113 static struct pcmcia_driver nsp_driver = {
2114 .owner = THIS_MODULE,
2118 .attach = nsp_cs_attach,
2119 .event = nsp_cs_event,
2120 .remove = nsp_cs_detach,
2121 .id_table = nsp_cs_ids,
2122 .suspend = nsp_cs_suspend,
2123 .resume = nsp_cs_resume,
2127 static int __init nsp_cs_init(void)
2129 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,68))
2130 nsp_msg(KERN_INFO, "loading...");
2132 return pcmcia_register_driver(&nsp_driver);
2136 nsp_msg(KERN_INFO, "loading...");
2137 pcmcia_get_card_services_info(&serv);
2138 if (serv.Revision != CS_RELEASE_CODE) {
2139 nsp_msg(KERN_DEBUG, "Card Services release does not match!");
2142 register_pcmcia_driver(&dev_info, &nsp_cs_attach, &nsp_cs_detach);
2144 nsp_dbg(NSP_DEBUG_INIT, "out");
2149 static void __exit nsp_cs_exit(void)
2151 nsp_msg(KERN_INFO, "unloading...");
2153 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,68))
2154 pcmcia_unregister_driver(&nsp_driver);
2156 unregister_pcmcia_driver(&dev_info);
2157 /* XXX: this really needs to move into generic code.. */
2158 while (dev_list != NULL) {
2159 if (dev_list->state & DEV_CONFIG) {
2160 nsp_cs_release(dev_list);
2162 nsp_cs_detach(dev_list);
2168 module_init(nsp_cs_init)
2169 module_exit(nsp_cs_exit)