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_abort_handler = nsp_eh_abort,*/
96 .eh_bus_reset_handler = nsp_eh_bus_reset,
97 .eh_host_reset_handler = nsp_eh_host_reset,
99 .this_id = NSP_INITIATOR_ID,
100 .sg_tablesize = SG_ALL,
102 .use_clustering = DISABLE_CLUSTERING,
103 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,2))
104 .use_new_eh_code = 1,
108 static dev_link_t *dev_list = NULL;
109 static dev_info_t dev_info = {"nsp_cs"};
111 static nsp_hw_data nsp_data_base; /* attach <-> detect glue */
119 # define NSP_DEBUG_MASK 0x000000
120 # define nsp_msg(type, args...) nsp_cs_message("", 0, (type), args)
121 # define nsp_dbg(mask, args...) /* */
123 # define NSP_DEBUG_MASK 0xffffff
124 # define nsp_msg(type, args...) \
125 nsp_cs_message (__FUNCTION__, __LINE__, (type), args)
126 # define nsp_dbg(mask, args...) \
127 nsp_cs_dmessage(__FUNCTION__, __LINE__, (mask), args)
130 #define NSP_DEBUG_QUEUECOMMAND BIT(0)
131 #define NSP_DEBUG_REGISTER BIT(1)
132 #define NSP_DEBUG_AUTOSCSI BIT(2)
133 #define NSP_DEBUG_INTR BIT(3)
134 #define NSP_DEBUG_SGLIST BIT(4)
135 #define NSP_DEBUG_BUSFREE BIT(5)
136 #define NSP_DEBUG_CDB_CONTENTS BIT(6)
137 #define NSP_DEBUG_RESELECTION BIT(7)
138 #define NSP_DEBUG_MSGINOCCUR BIT(8)
139 #define NSP_DEBUG_EEPROM BIT(9)
140 #define NSP_DEBUG_MSGOUTOCCUR BIT(10)
141 #define NSP_DEBUG_BUSRESET BIT(11)
142 #define NSP_DEBUG_RESTART BIT(12)
143 #define NSP_DEBUG_SYNC BIT(13)
144 #define NSP_DEBUG_WAIT BIT(14)
145 #define NSP_DEBUG_TARGETFLAG BIT(15)
146 #define NSP_DEBUG_PROC BIT(16)
147 #define NSP_DEBUG_INIT BIT(17)
148 #define NSP_DEBUG_DATA_IO BIT(18)
149 #define NSP_SPECIAL_PRINT_REGISTER BIT(20)
151 #define NSP_DEBUG_BUF_LEN 150
153 static void nsp_cs_message(const char *func, int line, char *type, char *fmt, ...)
156 char buf[NSP_DEBUG_BUF_LEN];
159 vsnprintf(buf, sizeof(buf), fmt, args);
163 printk("%snsp_cs: %s\n", type, buf);
165 printk("%snsp_cs: %s (%d): %s\n", type, func, line, buf);
170 static void nsp_cs_dmessage(const char *func, int line, int mask, char *fmt, ...)
173 char buf[NSP_DEBUG_BUF_LEN];
176 vsnprintf(buf, sizeof(buf), fmt, args);
179 if (mask & NSP_DEBUG_MASK) {
180 printk("nsp_cs-debug: 0x%x %s (%d): %s\n", mask, func, line, buf);
185 /***********************************************************/
187 /*====================================================
188 * Clenaup parameters and call done() functions.
189 * You must be set SCpnt->result before call this function.
191 static void nsp_scsi_done(Scsi_Cmnd *SCpnt)
193 nsp_hw_data *data = (nsp_hw_data *)SCpnt->device->host->hostdata;
195 data->CurrentSC = NULL;
197 SCpnt->scsi_done(SCpnt);
200 static int nsp_queuecommand(Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *))
203 /*unsigned int host_id = SCpnt->device->host->this_id;*/
204 /*unsigned int base = SCpnt->device->host->io_port;*/
205 unsigned char target = SCpnt->device->id;
207 nsp_hw_data *data = (nsp_hw_data *)SCpnt->device->host->hostdata;
209 nsp_dbg(NSP_DEBUG_QUEUECOMMAND, "SCpnt=0x%p target=%d lun=%d buff=0x%p bufflen=%d use_sg=%d",
210 SCpnt, target, SCpnt->device->lun, SCpnt->request_buffer, SCpnt->request_bufflen, SCpnt->use_sg);
211 //nsp_dbg(NSP_DEBUG_QUEUECOMMAND, "before CurrentSC=0x%p", data->CurrentSC);
213 SCpnt->scsi_done = done;
215 if (data->CurrentSC != NULL) {
216 nsp_msg(KERN_DEBUG, "CurrentSC!=NULL this can't be happen");
217 SCpnt->result = DID_BAD_TARGET << 16;
218 nsp_scsi_done(SCpnt);
223 /* XXX: pcmcia-cs generates SCSI command with "scsi_info" utility.
224 This makes kernel crash when suspending... */
225 if (data->ScsiInfo->stop != 0) {
226 nsp_msg(KERN_INFO, "suspending device. reject command.");
227 SCpnt->result = DID_BAD_TARGET << 16;
228 nsp_scsi_done(SCpnt);
229 return SCSI_MLQUEUE_HOST_BUSY;
235 data->CurrentSC = SCpnt;
237 SCpnt->SCp.Status = CHECK_CONDITION;
238 SCpnt->SCp.Message = 0;
239 SCpnt->SCp.have_data_in = IO_UNKNOWN;
240 SCpnt->SCp.sent_command = 0;
241 SCpnt->SCp.phase = PH_UNDETERMINED;
242 SCpnt->resid = SCpnt->request_bufflen;
244 /* setup scratch area
245 SCp.ptr : buffer pointer
246 SCp.this_residual : buffer length
247 SCp.buffer : next buffer
248 SCp.buffers_residual : left buffers in list
249 SCp.phase : current state of the command */
251 SCpnt->SCp.buffer = (struct scatterlist *) SCpnt->request_buffer;
252 SCpnt->SCp.ptr = BUFFER_ADDR;
253 SCpnt->SCp.this_residual = SCpnt->SCp.buffer->length;
254 SCpnt->SCp.buffers_residual = SCpnt->use_sg - 1;
256 SCpnt->SCp.ptr = (char *) SCpnt->request_buffer;
257 SCpnt->SCp.this_residual = SCpnt->request_bufflen;
258 SCpnt->SCp.buffer = NULL;
259 SCpnt->SCp.buffers_residual = 0;
262 if (nsphw_start_selection(SCpnt) == FALSE) {
263 nsp_dbg(NSP_DEBUG_QUEUECOMMAND, "selection fail");
264 SCpnt->result = DID_BUS_BUSY << 16;
265 nsp_scsi_done(SCpnt);
270 //nsp_dbg(NSP_DEBUG_QUEUECOMMAND, "out");
278 * setup PIO FIFO transfer mode and enable/disable to data out
280 static void nsp_setup_fifo(nsp_hw_data *data, int enabled)
282 unsigned int base = data->BaseAddress;
283 unsigned char transfer_mode_reg;
285 //nsp_dbg(NSP_DEBUG_DATA_IO, "enabled=%d", enabled);
287 if (enabled != FALSE) {
288 transfer_mode_reg = TRANSFER_GO | BRAIND;
290 transfer_mode_reg = 0;
293 transfer_mode_reg |= data->TransferMode;
295 nsp_index_write(base, TRANSFERMODE, transfer_mode_reg);
298 static void nsphw_init_sync(nsp_hw_data *data)
300 sync_data tmp_sync = { .SyncNegotiation = SYNC_NOT_YET,
306 /* setup sync data */
307 for ( i = 0; i < ARRAY_SIZE(data->Sync); i++ ) {
308 data->Sync[i] = tmp_sync;
313 * Initialize Ninja hardware
315 static int nsphw_init(nsp_hw_data *data)
317 unsigned int base = data->BaseAddress;
319 nsp_dbg(NSP_DEBUG_INIT, "in base=0x%x", base);
321 data->ScsiClockDiv = CLOCK_40M | FAST_20;
322 data->CurrentSC = NULL;
324 data->TransferMode = MODE_IO8;
326 nsphw_init_sync(data);
328 /* block all interrupts */
329 nsp_write(base, IRQCONTROL, IRQCONTROL_ALLMASK);
331 /* setup SCSI interface */
332 nsp_write(base, IFSELECT, IF_IFSEL);
334 nsp_index_write(base, SCSIIRQMODE, 0);
336 nsp_index_write(base, TRANSFERMODE, MODE_IO8);
337 nsp_index_write(base, CLOCKDIV, data->ScsiClockDiv);
339 nsp_index_write(base, PARITYCTRL, 0);
340 nsp_index_write(base, POINTERCLR, POINTER_CLEAR |
345 /* setup fifo asic */
346 nsp_write(base, IFSELECT, IF_REGSEL);
347 nsp_index_write(base, TERMPWRCTRL, 0);
348 if ((nsp_index_read(base, OTHERCONTROL) & TPWR_SENSE) == 0) {
349 nsp_msg(KERN_INFO, "terminator power on");
350 nsp_index_write(base, TERMPWRCTRL, POWER_ON);
353 nsp_index_write(base, TIMERCOUNT, 0);
354 nsp_index_write(base, TIMERCOUNT, 0); /* requires 2 times!! */
356 nsp_index_write(base, SYNCREG, 0);
357 nsp_index_write(base, ACKWIDTH, 0);
359 /* enable interrupts and ack them */
360 nsp_index_write(base, SCSIIRQMODE, SCSI_PHASE_CHANGE_EI |
363 nsp_write(base, IRQCONTROL, IRQCONTROL_ALLCLEAR);
365 nsp_setup_fifo(data, FALSE);
371 * Start selection phase
373 static int nsphw_start_selection(Scsi_Cmnd *SCpnt)
375 unsigned int host_id = SCpnt->device->host->this_id;
376 unsigned int base = SCpnt->device->host->io_port;
377 unsigned char target = SCpnt->device->id;
378 nsp_hw_data *data = (nsp_hw_data *)SCpnt->device->host->hostdata;
380 unsigned char phase, arbit;
382 //nsp_dbg(NSP_DEBUG_RESELECTION, "in");
384 phase = nsp_index_read(base, SCSIBUSMON);
385 if(phase != BUSMON_BUS_FREE) {
386 //nsp_dbg(NSP_DEBUG_RESELECTION, "bus busy");
390 /* start arbitration */
391 //nsp_dbg(NSP_DEBUG_RESELECTION, "start arbit");
392 SCpnt->SCp.phase = PH_ARBSTART;
393 nsp_index_write(base, SETARBIT, ARBIT_GO);
397 /* XXX: what a stupid chip! */
398 arbit = nsp_index_read(base, ARBITSTATUS);
399 //nsp_dbg(NSP_DEBUG_RESELECTION, "arbit=%d, wait_count=%d", arbit, wait_count);
400 udelay(1); /* hold 1.2us */
401 } while((arbit & (ARBIT_WIN | ARBIT_FAIL)) == 0 &&
404 if (!(arbit & ARBIT_WIN)) {
405 //nsp_dbg(NSP_DEBUG_RESELECTION, "arbit fail");
406 nsp_index_write(base, SETARBIT, ARBIT_FLAG_CLEAR);
410 /* assert select line */
411 //nsp_dbg(NSP_DEBUG_RESELECTION, "assert SEL line");
412 SCpnt->SCp.phase = PH_SELSTART;
413 udelay(3); /* wait 2.4us */
414 nsp_index_write(base, SCSIDATALATCH, BIT(host_id) | BIT(target));
415 nsp_index_write(base, SCSIBUSCTRL, SCSI_SEL | SCSI_BSY | SCSI_ATN);
416 udelay(2); /* wait >1.2us */
417 nsp_index_write(base, SCSIBUSCTRL, SCSI_SEL | SCSI_BSY | SCSI_DATAOUT_ENB | SCSI_ATN);
418 nsp_index_write(base, SETARBIT, ARBIT_FLAG_CLEAR);
419 /*udelay(1);*/ /* wait >90ns */
420 nsp_index_write(base, SCSIBUSCTRL, SCSI_SEL | SCSI_DATAOUT_ENB | SCSI_ATN);
422 /* check selection timeout */
423 nsp_start_timer(SCpnt, 1000/51);
424 data->SelectionTimeOut = 1;
429 struct nsp_sync_table {
430 unsigned int min_period;
431 unsigned int max_period;
432 unsigned int chip_period;
433 unsigned int ack_width;
436 static struct nsp_sync_table nsp_sync_table_40M[] = {
437 {0x0c, 0x0c, 0x1, 0}, /* 20MB 50ns*/
438 {0x19, 0x19, 0x3, 1}, /* 10MB 100ns*/
439 {0x1a, 0x25, 0x5, 2}, /* 7.5MB 150ns*/
440 {0x26, 0x32, 0x7, 3}, /* 5MB 200ns*/
444 static struct nsp_sync_table nsp_sync_table_20M[] = {
445 {0x19, 0x19, 0x1, 0}, /* 10MB 100ns*/
446 {0x1a, 0x25, 0x2, 0}, /* 7.5MB 150ns*/
447 {0x26, 0x32, 0x3, 1}, /* 5MB 200ns*/
452 * setup synchronous data transfer mode
454 static int nsp_analyze_sdtr(Scsi_Cmnd *SCpnt)
456 unsigned char target = SCpnt->device->id;
457 // unsigned char lun = SCpnt->device->lun;
458 nsp_hw_data *data = (nsp_hw_data *)SCpnt->device->host->hostdata;
459 sync_data *sync = &(data->Sync[target]);
460 struct nsp_sync_table *sync_table;
461 unsigned int period, offset;
465 nsp_dbg(NSP_DEBUG_SYNC, "in");
467 period = sync->SyncPeriod;
468 offset = sync->SyncOffset;
470 nsp_dbg(NSP_DEBUG_SYNC, "period=0x%x, offset=0x%x", period, offset);
472 if ((data->ScsiClockDiv & (BIT(0)|BIT(1))) == CLOCK_20M) {
473 sync_table = nsp_sync_table_20M;
475 sync_table = nsp_sync_table_40M;
478 for ( i = 0; sync_table->max_period != 0; i++, sync_table++) {
479 if ( period >= sync_table->min_period &&
480 period <= sync_table->max_period ) {
485 if (period != 0 && sync_table->max_period == 0) {
487 * No proper period/offset found
489 nsp_dbg(NSP_DEBUG_SYNC, "no proper period/offset");
491 sync->SyncPeriod = 0;
492 sync->SyncOffset = 0;
493 sync->SyncRegister = 0;
499 sync->SyncRegister = (sync_table->chip_period << SYNCREG_PERIOD_SHIFT) |
500 (offset & SYNCREG_OFFSET_MASK);
501 sync->AckWidth = sync_table->ack_width;
503 nsp_dbg(NSP_DEBUG_SYNC, "sync_reg=0x%x, ack_width=0x%x", sync->SyncRegister, sync->AckWidth);
510 * start ninja hardware timer
512 static void nsp_start_timer(Scsi_Cmnd *SCpnt, int time)
514 unsigned int base = SCpnt->device->host->io_port;
515 nsp_hw_data *data = (nsp_hw_data *)SCpnt->device->host->hostdata;
517 //nsp_dbg(NSP_DEBUG_INTR, "in SCpnt=0x%p, time=%d", SCpnt, time);
518 data->TimerCount = time;
519 nsp_index_write(base, TIMERCOUNT, time);
523 * wait for bus phase change
525 static int nsp_negate_signal(Scsi_Cmnd *SCpnt, unsigned char mask, char *str)
527 unsigned int base = SCpnt->device->host->io_port;
531 //nsp_dbg(NSP_DEBUG_INTR, "in");
536 reg = nsp_index_read(base, SCSIBUSMON);
540 } while ((time_out-- != 0) && (reg & mask) != 0);
543 nsp_msg(KERN_DEBUG, " %s signal off timeut", str);
552 static int nsp_expect_signal(Scsi_Cmnd *SCpnt,
553 unsigned char current_phase,
556 unsigned int base = SCpnt->device->host->io_port;
558 unsigned char phase, i_src;
560 //nsp_dbg(NSP_DEBUG_INTR, "current_phase=0x%x, mask=0x%x", current_phase, mask);
564 phase = nsp_index_read(base, SCSIBUSMON);
566 //nsp_dbg(NSP_DEBUG_INTR, "ret -1");
569 i_src = nsp_read(base, IRQSTATUS);
570 if (i_src & IRQSTATUS_SCSI) {
571 //nsp_dbg(NSP_DEBUG_INTR, "ret 0 found scsi signal");
574 if ((phase & mask) != 0 && (phase & BUSMON_PHASE_MASK) == current_phase) {
575 //nsp_dbg(NSP_DEBUG_INTR, "ret 1 phase=0x%x", phase);
578 } while(time_out-- != 0);
580 //nsp_dbg(NSP_DEBUG_INTR, "timeout");
585 * transfer SCSI message
587 static int nsp_xfer(Scsi_Cmnd *SCpnt, int phase)
589 unsigned int base = SCpnt->device->host->io_port;
590 nsp_hw_data *data = (nsp_hw_data *)SCpnt->device->host->hostdata;
591 char *buf = data->MsgBuffer;
592 int len = min(MSGBUF_SIZE, data->MsgLen);
596 //nsp_dbg(NSP_DEBUG_DATA_IO, "in");
597 for (ptr = 0; len > 0; len--, ptr++) {
599 ret = nsp_expect_signal(SCpnt, phase, BUSMON_REQ);
601 nsp_dbg(NSP_DEBUG_DATA_IO, "xfer quit");
605 /* if last byte, negate ATN */
606 if (len == 1 && SCpnt->SCp.phase == PH_MSG_OUT) {
607 nsp_index_write(base, SCSIBUSCTRL, AUTODIRECTION | ACKENB);
610 /* read & write message */
611 if (phase & BUSMON_IO) {
612 nsp_dbg(NSP_DEBUG_DATA_IO, "read msg");
613 buf[ptr] = nsp_index_read(base, SCSIDATAWITHACK);
615 nsp_dbg(NSP_DEBUG_DATA_IO, "write msg");
616 nsp_index_write(base, SCSIDATAWITHACK, buf[ptr]);
618 nsp_negate_signal(SCpnt, BUSMON_ACK, "xfer<ack>");
625 * get extra SCSI data from fifo
627 static int nsp_dataphase_bypass(Scsi_Cmnd *SCpnt)
629 nsp_hw_data *data = (nsp_hw_data *)SCpnt->device->host->hostdata;
632 //nsp_dbg(NSP_DEBUG_DATA_IO, "in");
634 if (SCpnt->SCp.have_data_in != IO_IN) {
638 count = nsp_fifo_count(SCpnt);
639 if (data->FifoCount == count) {
640 //nsp_dbg(NSP_DEBUG_DATA_IO, "not use bypass quirk");
646 * data phase skip only occures in case of SCSI_LOW_READ
648 nsp_dbg(NSP_DEBUG_DATA_IO, "use bypass quirk");
649 SCpnt->SCp.phase = PH_DATA;
651 nsp_setup_fifo(data, FALSE);
659 static int nsp_reselected(Scsi_Cmnd *SCpnt)
661 unsigned int base = SCpnt->device->host->io_port;
662 unsigned int host_id = SCpnt->device->host->this_id;
663 //nsp_hw_data *data = (nsp_hw_data *)SCpnt->device->host->hostdata;
664 unsigned char bus_reg;
665 unsigned char id_reg, tmp;
668 nsp_dbg(NSP_DEBUG_RESELECTION, "in");
670 id_reg = nsp_index_read(base, RESELECTID);
671 tmp = id_reg & (~BIT(host_id));
681 if (SCpnt->device->id != target) {
682 nsp_msg(KERN_ERR, "XXX: reselect ID must be %d in this implementation.", target);
685 nsp_negate_signal(SCpnt, BUSMON_SEL, "reselect<SEL>");
688 bus_reg = nsp_index_read(base, SCSIBUSCTRL) & ~(SCSI_BSY | SCSI_ATN);
689 nsp_index_write(base, SCSIBUSCTRL, bus_reg);
690 nsp_index_write(base, SCSIBUSCTRL, bus_reg | AUTODIRECTION | ACKENB);
696 * count how many data transferd
698 static int nsp_fifo_count(Scsi_Cmnd *SCpnt)
700 unsigned int base = SCpnt->device->host->io_port;
702 unsigned int l, m, h, dummy;
704 nsp_index_write(base, POINTERCLR, POINTER_CLEAR | ACK_COUNTER);
706 l = nsp_index_read(base, TRANSFERCOUNT);
707 m = nsp_index_read(base, TRANSFERCOUNT);
708 h = nsp_index_read(base, TRANSFERCOUNT);
709 dummy = nsp_index_read(base, TRANSFERCOUNT); /* required this! */
711 count = (h << 16) | (m << 8) | (l << 0);
713 //nsp_dbg(NSP_DEBUG_DATA_IO, "count=0x%x", count);
719 #define RFIFO_CRIT 64
720 #define WFIFO_CRIT 64
723 * read data in DATA IN phase
725 static void nsp_pio_read(Scsi_Cmnd *SCpnt)
727 unsigned int base = SCpnt->device->host->io_port;
728 unsigned long mmio_base = SCpnt->device->host->base;
729 nsp_hw_data *data = (nsp_hw_data *)SCpnt->device->host->hostdata;
732 unsigned char stat, fifo_stat;
734 ocount = data->FifoCount;
736 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",
737 SCpnt, SCpnt->resid, ocount, SCpnt->SCp.ptr, SCpnt->SCp.this_residual, SCpnt->SCp.buffer, SCpnt->SCp.buffers_residual);
741 while ((time_out-- != 0) &&
742 (SCpnt->SCp.this_residual > 0 || SCpnt->SCp.buffers_residual > 0 ) ) {
744 stat = nsp_index_read(base, SCSIBUSMON);
745 stat &= BUSMON_PHASE_MASK;
748 res = nsp_fifo_count(SCpnt) - ocount;
749 //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);
750 if (res == 0) { /* if some data avilable ? */
751 if (stat == BUSPHASE_DATA_IN) { /* phase changed? */
752 //nsp_dbg(NSP_DEBUG_DATA_IO, " wait for data this=%d", SCpnt->SCp.this_residual);
755 nsp_dbg(NSP_DEBUG_DATA_IO, "phase changed stat=0x%x", stat);
760 fifo_stat = nsp_read(base, FIFOSTATUS);
761 if ((fifo_stat & FIFOSTATUS_FULL_EMPTY) == 0 &&
762 stat == BUSPHASE_DATA_IN) {
766 res = min(res, SCpnt->SCp.this_residual);
768 switch (data->TransferMode) {
770 res &= ~(BIT(1)|BIT(0)); /* align 4 */
771 nsp_fifo32_read(base, SCpnt->SCp.ptr, res >> 2);
774 nsp_fifo8_read (base, SCpnt->SCp.ptr, res );
778 res &= ~(BIT(1)|BIT(0)); /* align 4 */
779 nsp_mmio_fifo32_read(mmio_base, SCpnt->SCp.ptr, res >> 2);
783 nsp_dbg(NSP_DEBUG_DATA_IO, "unknown read mode");
788 SCpnt->SCp.ptr += res;
789 SCpnt->SCp.this_residual -= res;
791 //nsp_dbg(NSP_DEBUG_DATA_IO, "ptr=0x%p this_residual=0x%x ocount=0x%x", SCpnt->SCp.ptr, SCpnt->SCp.this_residual, ocount);
793 /* go to next scatter list if available */
794 if (SCpnt->SCp.this_residual == 0 &&
795 SCpnt->SCp.buffers_residual != 0 ) {
796 //nsp_dbg(NSP_DEBUG_DATA_IO, "scatterlist next timeout=%d", time_out);
797 SCpnt->SCp.buffers_residual--;
799 SCpnt->SCp.ptr = BUFFER_ADDR;
800 SCpnt->SCp.this_residual = SCpnt->SCp.buffer->length;
803 //nsp_dbg(NSP_DEBUG_DATA_IO, "page: 0x%p, off: 0x%x", SCpnt->SCp.buffer->page, SCpnt->SCp.buffer->offset);
807 data->FifoCount = ocount;
810 nsp_msg(KERN_DEBUG, "pio read timeout resid=%d this_residual=%d buffers_residual=%d",
811 SCpnt->resid, SCpnt->SCp.this_residual, SCpnt->SCp.buffers_residual);
813 nsp_dbg(NSP_DEBUG_DATA_IO, "read ocount=0x%x", ocount);
814 nsp_dbg(NSP_DEBUG_DATA_IO, "r cmd=%d resid=0x%x\n", data->CmdId, SCpnt->resid);
818 * write data in DATA OUT phase
820 static void nsp_pio_write(Scsi_Cmnd *SCpnt)
822 unsigned int base = SCpnt->device->host->io_port;
823 unsigned long mmio_base = SCpnt->device->host->base;
824 nsp_hw_data *data = (nsp_hw_data *)SCpnt->device->host->hostdata;
829 ocount = data->FifoCount;
831 nsp_dbg(NSP_DEBUG_DATA_IO, "in fifocount=%d ptr=0x%p this_residual=%d buffers=0x%p nbuf=%d resid=0x%x",
832 data->FifoCount, SCpnt->SCp.ptr, SCpnt->SCp.this_residual, SCpnt->SCp.buffer, SCpnt->SCp.buffers_residual, SCpnt->resid);
836 while ((time_out-- != 0) &&
837 (SCpnt->SCp.this_residual > 0 || SCpnt->SCp.buffers_residual > 0)) {
838 stat = nsp_index_read(base, SCSIBUSMON);
839 stat &= BUSMON_PHASE_MASK;
841 if (stat != BUSPHASE_DATA_OUT) {
842 res = ocount - nsp_fifo_count(SCpnt);
844 nsp_dbg(NSP_DEBUG_DATA_IO, "phase changed stat=0x%x, res=%d\n", stat, res);
845 /* Put back pointer */
847 SCpnt->SCp.ptr -= res;
848 SCpnt->SCp.this_residual += res;
854 res = ocount - nsp_fifo_count(SCpnt);
855 if (res > 0) { /* write all data? */
856 nsp_dbg(NSP_DEBUG_DATA_IO, "wait for all data out. ocount=0x%x res=%d", ocount, res);
860 res = min(SCpnt->SCp.this_residual, WFIFO_CRIT);
862 //nsp_dbg(NSP_DEBUG_DATA_IO, "ptr=0x%p this=0x%x res=0x%x", SCpnt->SCp.ptr, SCpnt->SCp.this_residual, res);
863 switch (data->TransferMode) {
865 res &= ~(BIT(1)|BIT(0)); /* align 4 */
866 nsp_fifo32_write(base, SCpnt->SCp.ptr, res >> 2);
869 nsp_fifo8_write (base, SCpnt->SCp.ptr, res );
873 res &= ~(BIT(1)|BIT(0)); /* align 4 */
874 nsp_mmio_fifo32_write(mmio_base, SCpnt->SCp.ptr, res >> 2);
878 nsp_dbg(NSP_DEBUG_DATA_IO, "unknown write mode");
883 SCpnt->SCp.ptr += res;
884 SCpnt->SCp.this_residual -= res;
887 /* go to next scatter list if available */
888 if (SCpnt->SCp.this_residual == 0 &&
889 SCpnt->SCp.buffers_residual != 0 ) {
890 //nsp_dbg(NSP_DEBUG_DATA_IO, "scatterlist next");
891 SCpnt->SCp.buffers_residual--;
893 SCpnt->SCp.ptr = BUFFER_ADDR;
894 SCpnt->SCp.this_residual = SCpnt->SCp.buffer->length;
899 data->FifoCount = ocount;
902 nsp_msg(KERN_DEBUG, "pio write timeout resid=0x%x", SCpnt->resid);
904 nsp_dbg(NSP_DEBUG_DATA_IO, "write ocount=0x%x", ocount);
905 nsp_dbg(NSP_DEBUG_DATA_IO, "w cmd=%d resid=0x%x\n", data->CmdId, SCpnt->resid);
911 * setup synchronous/asynchronous data transfer mode
913 static int nsp_nexus(Scsi_Cmnd *SCpnt)
915 unsigned int base = SCpnt->device->host->io_port;
916 unsigned char target = SCpnt->device->id;
917 // unsigned char lun = SCpnt->device->lun;
918 nsp_hw_data *data = (nsp_hw_data *)SCpnt->device->host->hostdata;
919 sync_data *sync = &(data->Sync[target]);
921 //nsp_dbg(NSP_DEBUG_DATA_IO, "in SCpnt=0x%p", SCpnt);
923 /* setup synch transfer registers */
924 nsp_index_write(base, SYNCREG, sync->SyncRegister);
925 nsp_index_write(base, ACKWIDTH, sync->AckWidth);
927 if (SCpnt->use_sg == 0 ||
928 SCpnt->resid % 4 != 0 ||
929 SCpnt->resid <= PAGE_SIZE ) {
930 data->TransferMode = MODE_IO8;
931 } else if (nsp_burst_mode == BURST_MEM32) {
932 data->TransferMode = MODE_MEM32;
933 } else if (nsp_burst_mode == BURST_IO32) {
934 data->TransferMode = MODE_IO32;
936 data->TransferMode = MODE_IO8;
939 /* setup pdma fifo */
940 nsp_setup_fifo(data, TRUE);
942 /* clear ack counter */
944 nsp_index_write(base, POINTERCLR, POINTER_CLEAR |
952 #include "nsp_message.c"
956 static irqreturn_t nspintr(int irq, void *dev_id, struct pt_regs *regs)
959 unsigned char irq_status, irq_phase, phase;
961 unsigned char target, lun;
962 unsigned int *sync_neg;
967 //nsp_dbg(NSP_DEBUG_INTR, "dev_id=0x%p", dev_id);
968 //nsp_dbg(NSP_DEBUG_INTR, "host=0x%p", ((scsi_info_t *)dev_id)->host);
970 if ( dev_id != NULL &&
971 ((scsi_info_t *)dev_id)->host != NULL ) {
972 scsi_info_t *info = (scsi_info_t *)dev_id;
974 data = (nsp_hw_data *)info->host->hostdata;
976 nsp_dbg(NSP_DEBUG_INTR, "host data wrong");
980 //nsp_dbg(NSP_DEBUG_INTR, "&nsp_data_base=0x%p, dev_id=0x%p", &nsp_data_base, dev_id);
982 base = data->BaseAddress;
983 //nsp_dbg(NSP_DEBUG_INTR, "base=0x%x", base);
988 nsp_write(base, IRQCONTROL, IRQCONTROL_IRQDISABLE);
989 irq_status = nsp_read(base, IRQSTATUS);
990 //nsp_dbg(NSP_DEBUG_INTR, "irq_status=0x%x", irq_status);
991 if ((irq_status == 0xff) || ((irq_status & IRQSTATUS_MASK) == 0)) {
992 nsp_write(base, IRQCONTROL, 0);
993 //nsp_dbg(NSP_DEBUG_INTR, "no irq/shared irq");
998 * Do not read an irq_phase register if no scsi phase interrupt.
999 * Unless, you should lose a scsi phase interrupt.
1001 phase = nsp_index_read(base, SCSIBUSMON);
1002 if((irq_status & IRQSTATUS_SCSI) != 0) {
1003 irq_phase = nsp_index_read(base, IRQPHASESENCE);
1008 //nsp_dbg(NSP_DEBUG_INTR, "irq_phase=0x%x", irq_phase);
1011 * timer interrupt handler (scsi vs timer interrupts)
1013 //nsp_dbg(NSP_DEBUG_INTR, "timercount=%d", data->TimerCount);
1014 if (data->TimerCount != 0) {
1015 //nsp_dbg(NSP_DEBUG_INTR, "stop timer");
1016 nsp_index_write(base, TIMERCOUNT, 0);
1017 nsp_index_write(base, TIMERCOUNT, 0);
1018 data->TimerCount = 0;
1021 if ((irq_status & IRQSTATUS_MASK) == IRQSTATUS_TIMER &&
1022 data->SelectionTimeOut == 0) {
1023 //nsp_dbg(NSP_DEBUG_INTR, "timer start");
1024 nsp_write(base, IRQCONTROL, IRQCONTROL_TIMER_CLEAR);
1028 nsp_write(base, IRQCONTROL, IRQCONTROL_TIMER_CLEAR | IRQCONTROL_FIFO_CLEAR);
1030 if ((irq_status & IRQSTATUS_SCSI) &&
1031 (irq_phase & SCSI_RESET_IRQ)) {
1032 nsp_msg(KERN_ERR, "bus reset (power off?)");
1035 nsp_bus_reset(data);
1037 if(data->CurrentSC != NULL) {
1038 tmpSC = data->CurrentSC;
1039 tmpSC->result = (DID_RESET << 16) |
1040 ((tmpSC->SCp.Message & 0xff) << 8) |
1041 ((tmpSC->SCp.Status & 0xff) << 0);
1042 nsp_scsi_done(tmpSC);
1047 if (data->CurrentSC == NULL) {
1048 nsp_msg(KERN_ERR, "CurrentSC==NULL irq_status=0x%x phase=0x%x irq_phase=0x%x this can't be happen. reset everything", irq_status, phase, irq_phase);
1050 nsp_bus_reset(data);
1054 tmpSC = data->CurrentSC;
1055 target = tmpSC->device->id;
1056 lun = tmpSC->device->lun;
1057 sync_neg = &(data->Sync[target].SyncNegotiation);
1060 * parse hardware SCSI irq reasons register
1062 if (irq_status & IRQSTATUS_SCSI) {
1063 if (irq_phase & RESELECT_IRQ) {
1064 nsp_dbg(NSP_DEBUG_INTR, "reselect");
1065 nsp_write(base, IRQCONTROL, IRQCONTROL_RESELECT_CLEAR);
1066 if (nsp_reselected(tmpSC) != FALSE) {
1071 if ((irq_phase & (PHASE_CHANGE_IRQ | LATCHED_BUS_FREE)) == 0) {
1076 //show_phase(tmpSC);
1078 switch(tmpSC->SCp.phase) {
1080 // *sync_neg = SYNC_NOT_YET;
1081 if ((phase & BUSMON_BSY) == 0) {
1082 //nsp_dbg(NSP_DEBUG_INTR, "selection count=%d", data->SelectionTimeOut);
1083 if (data->SelectionTimeOut >= NSP_SELTIMEOUT) {
1084 nsp_dbg(NSP_DEBUG_INTR, "selection time out");
1085 data->SelectionTimeOut = 0;
1086 nsp_index_write(base, SCSIBUSCTRL, 0);
1088 tmpSC->result = DID_TIME_OUT << 16;
1089 nsp_scsi_done(tmpSC);
1093 data->SelectionTimeOut += 1;
1094 nsp_start_timer(tmpSC, 1000/51);
1098 /* attention assert */
1099 //nsp_dbg(NSP_DEBUG_INTR, "attention assert");
1100 data->SelectionTimeOut = 0;
1101 tmpSC->SCp.phase = PH_SELECTED;
1102 nsp_index_write(base, SCSIBUSCTRL, SCSI_ATN);
1104 nsp_index_write(base, SCSIBUSCTRL, SCSI_ATN | AUTODIRECTION | ACKENB);
1110 //nsp_dbg(NSP_DEBUG_INTR, "phase reselect");
1111 // *sync_neg = SYNC_NOT_YET;
1112 if ((phase & BUSMON_PHASE_MASK) != BUSPHASE_MESSAGE_IN) {
1114 tmpSC->result = DID_ABORT << 16;
1115 nsp_scsi_done(tmpSC);
1120 if ((irq_status & (IRQSTATUS_SCSI | IRQSTATUS_FIFO)) == 0) {
1129 //nsp_dbg(NSP_DEBUG_INTR, "start scsi seq");
1131 /* normal disconnect */
1132 if (((tmpSC->SCp.phase == PH_MSG_IN) || (tmpSC->SCp.phase == PH_MSG_OUT)) &&
1133 (irq_phase & LATCHED_BUS_FREE) != 0 ) {
1134 nsp_dbg(NSP_DEBUG_INTR, "normal disconnect irq_status=0x%x, phase=0x%x, irq_phase=0x%x", irq_status, phase, irq_phase);
1136 //*sync_neg = SYNC_NOT_YET;
1138 if ((tmpSC->SCp.Message == MSG_COMMAND_COMPLETE)) { /* all command complete and return status */
1139 tmpSC->result = (DID_OK << 16) |
1140 ((tmpSC->SCp.Message & 0xff) << 8) |
1141 ((tmpSC->SCp.Status & 0xff) << 0);
1142 nsp_dbg(NSP_DEBUG_INTR, "command complete result=0x%x", tmpSC->result);
1143 nsp_scsi_done(tmpSC);
1152 /* check unexpected bus free state */
1154 nsp_msg(KERN_DEBUG, "unexpected bus free. irq_status=0x%x, phase=0x%x, irq_phase=0x%x", irq_status, phase, irq_phase);
1156 *sync_neg = SYNC_NG;
1157 tmpSC->result = DID_ERROR << 16;
1158 nsp_scsi_done(tmpSC);
1162 switch (phase & BUSMON_PHASE_MASK) {
1163 case BUSPHASE_COMMAND:
1164 nsp_dbg(NSP_DEBUG_INTR, "BUSPHASE_COMMAND");
1165 if ((phase & BUSMON_REQ) == 0) {
1166 nsp_dbg(NSP_DEBUG_INTR, "REQ == 0");
1170 tmpSC->SCp.phase = PH_COMMAND;
1174 /* write scsi command */
1175 nsp_dbg(NSP_DEBUG_INTR, "cmd_len=%d", tmpSC->cmd_len);
1176 nsp_index_write(base, COMMANDCTRL, CLEAR_COMMAND_POINTER);
1177 for (i = 0; i < tmpSC->cmd_len; i++) {
1178 nsp_index_write(base, COMMANDDATA, tmpSC->cmnd[i]);
1180 nsp_index_write(base, COMMANDCTRL, CLEAR_COMMAND_POINTER | AUTO_COMMAND_GO);
1183 case BUSPHASE_DATA_OUT:
1184 nsp_dbg(NSP_DEBUG_INTR, "BUSPHASE_DATA_OUT");
1186 tmpSC->SCp.phase = PH_DATA;
1187 tmpSC->SCp.have_data_in = IO_OUT;
1189 nsp_pio_write(tmpSC);
1193 case BUSPHASE_DATA_IN:
1194 nsp_dbg(NSP_DEBUG_INTR, "BUSPHASE_DATA_IN");
1196 tmpSC->SCp.phase = PH_DATA;
1197 tmpSC->SCp.have_data_in = IO_IN;
1199 nsp_pio_read(tmpSC);
1203 case BUSPHASE_STATUS:
1204 nsp_dataphase_bypass(tmpSC);
1205 nsp_dbg(NSP_DEBUG_INTR, "BUSPHASE_STATUS");
1207 tmpSC->SCp.phase = PH_STATUS;
1209 tmpSC->SCp.Status = nsp_index_read(base, SCSIDATAWITHACK);
1210 nsp_dbg(NSP_DEBUG_INTR, "message=0x%x status=0x%x", tmpSC->SCp.Message, tmpSC->SCp.Status);
1214 case BUSPHASE_MESSAGE_OUT:
1215 nsp_dbg(NSP_DEBUG_INTR, "BUSPHASE_MESSAGE_OUT");
1216 if ((phase & BUSMON_REQ) == 0) {
1220 tmpSC->SCp.phase = PH_MSG_OUT;
1222 //*sync_neg = SYNC_NOT_YET;
1224 data->MsgLen = i = 0;
1225 data->MsgBuffer[i] = IDENTIFY(TRUE, lun); i++;
1227 if (*sync_neg == SYNC_NOT_YET) {
1228 data->Sync[target].SyncPeriod = 0;
1229 data->Sync[target].SyncOffset = 0;
1232 data->MsgBuffer[i] = MSG_EXTENDED; i++;
1233 data->MsgBuffer[i] = 3; i++;
1234 data->MsgBuffer[i] = MSG_EXT_SDTR; i++;
1235 data->MsgBuffer[i] = 0x0c; i++;
1236 data->MsgBuffer[i] = 15; i++;
1241 nsp_analyze_sdtr(tmpSC);
1243 nsp_message_out(tmpSC);
1246 case BUSPHASE_MESSAGE_IN:
1247 nsp_dataphase_bypass(tmpSC);
1248 nsp_dbg(NSP_DEBUG_INTR, "BUSPHASE_MESSAGE_IN");
1249 if ((phase & BUSMON_REQ) == 0) {
1253 tmpSC->SCp.phase = PH_MSG_IN;
1254 nsp_message_in(tmpSC);
1257 if (*sync_neg == SYNC_NOT_YET) {
1258 //nsp_dbg(NSP_DEBUG_INTR, "sync target=%d,lun=%d",target,lun);
1260 if (data->MsgLen >= 5 &&
1261 data->MsgBuffer[0] == MSG_EXTENDED &&
1262 data->MsgBuffer[1] == 3 &&
1263 data->MsgBuffer[2] == MSG_EXT_SDTR ) {
1264 data->Sync[target].SyncPeriod = data->MsgBuffer[3];
1265 data->Sync[target].SyncOffset = data->MsgBuffer[4];
1266 //nsp_dbg(NSP_DEBUG_INTR, "sync ok, %d %d", data->MsgBuffer[3], data->MsgBuffer[4]);
1267 *sync_neg = SYNC_OK;
1269 data->Sync[target].SyncPeriod = 0;
1270 data->Sync[target].SyncOffset = 0;
1271 *sync_neg = SYNC_NG;
1273 nsp_analyze_sdtr(tmpSC);
1277 /* search last messeage byte */
1279 for (i = 0; i < data->MsgLen; i++) {
1280 tmp = data->MsgBuffer[i];
1281 if (data->MsgBuffer[i] == MSG_EXTENDED) {
1282 i += (1 + data->MsgBuffer[i+1]);
1285 tmpSC->SCp.Message = tmp;
1287 nsp_dbg(NSP_DEBUG_INTR, "message=0x%x len=%d", tmpSC->SCp.Message, data->MsgLen);
1292 case BUSPHASE_SELECT:
1294 nsp_dbg(NSP_DEBUG_INTR, "BUSPHASE other");
1299 //nsp_dbg(NSP_DEBUG_INTR, "out");
1303 nsp_start_timer(tmpSC, 1000/102);
1308 #include "nsp_debug.c"
1309 #endif /* NSP_DEBUG */
1311 /*----------------------------------------------------------------*/
1312 /* look for ninja3 card and init if found */
1313 /*----------------------------------------------------------------*/
1314 static struct Scsi_Host *nsp_detect(Scsi_Host_Template *sht)
1316 struct Scsi_Host *host; /* registered host structure */
1317 nsp_hw_data *data_b = &nsp_data_base, *data;
1319 nsp_dbg(NSP_DEBUG_INIT, "this_id=%d", sht->this_id);
1320 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,73))
1321 host = scsi_host_alloc(&nsp_driver_template, sizeof(nsp_hw_data));
1323 host = scsi_register(sht, sizeof(nsp_hw_data));
1326 nsp_dbg(NSP_DEBUG_INIT, "host failed");
1330 memcpy(host->hostdata, data_b, sizeof(nsp_hw_data));
1331 data = (nsp_hw_data *)host->hostdata;
1332 data->ScsiInfo->host = host;
1337 nsp_dbg(NSP_DEBUG_INIT, "irq=%d,%d", data_b->IrqNumber, ((nsp_hw_data *)host->hostdata)->IrqNumber);
1339 host->unique_id = data->BaseAddress;
1340 host->io_port = data->BaseAddress;
1341 host->n_io_port = data->NumAddress;
1342 host->irq = data->IrqNumber;
1343 host->base = data->MmioAddress;
1345 spin_lock_init(&(data->Lock));
1347 snprintf(data->nspinfo,
1348 sizeof(data->nspinfo),
1349 "NinjaSCSI-3/32Bi Driver $Revision: 1.23 $ IO:0x%04lx-0x%04lx MMIO(virt addr):0x%04lx IRQ:%02d",
1350 host->io_port, host->io_port + host->n_io_port - 1,
1353 sht->name = data->nspinfo;
1355 nsp_dbg(NSP_DEBUG_INIT, "end");
1358 return host; /* detect done. */
1361 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
1362 static int nsp_detect_old(Scsi_Host_Template *sht)
1364 if (nsp_detect(sht) == NULL) {
1367 //MOD_INC_USE_COUNT;
1373 static int nsp_release_old(struct Scsi_Host *shpnt)
1375 //nsp_hw_data *data = (nsp_hw_data *)shpnt->hostdata;
1377 /* PCMCIA Card Service dose same things below. */
1378 /* So we do nothing. */
1380 // free_irq(shpnt->irq, data->ScsiInfo);
1382 //if (shpnt->io_port) {
1383 // release_region(shpnt->io_port, shpnt->n_io_port);
1386 //MOD_DEC_USE_COUNT;
1392 /*----------------------------------------------------------------*/
1393 /* return info string */
1394 /*----------------------------------------------------------------*/
1395 static const char *nsp_info(struct Scsi_Host *shpnt)
1397 nsp_hw_data *data = (nsp_hw_data *)shpnt->hostdata;
1399 return data->nspinfo;
1403 #define SPRINTF(args...) \
1405 if(length > (pos - buffer)) { \
1406 pos += snprintf(pos, length - (pos - buffer) + 1, ## args); \
1407 nsp_dbg(NSP_DEBUG_PROC, "buffer=0x%p pos=0x%p length=%d %d\n", buffer, pos, length, length - (pos - buffer));\
1412 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,73))
1413 struct Scsi_Host *host,
1419 #if !(LINUX_VERSION_CODE > KERNEL_VERSION(2,5,73))
1428 unsigned long flags;
1430 #if !(LINUX_VERSION_CODE > KERNEL_VERSION(2,5,73))
1431 struct Scsi_Host *host;
1439 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,73))
1440 hostno = host->host_no;
1442 /* search this HBA host */
1443 host = scsi_host_hn_get(hostno);
1448 data = (nsp_hw_data *)host->hostdata;
1451 SPRINTF("NinjaSCSI status\n\n");
1452 SPRINTF("Driver version: $Revision: 1.23 $\n");
1453 SPRINTF("SCSI host No.: %d\n", hostno);
1454 SPRINTF("IRQ: %d\n", host->irq);
1455 SPRINTF("IO: 0x%lx-0x%lx\n", host->io_port, host->io_port + host->n_io_port - 1);
1456 SPRINTF("MMIO(virtual address): 0x%lx-0x%lx\n", host->base, host->base + data->MmioLength - 1);
1457 SPRINTF("sg_tablesize: %d\n", host->sg_tablesize);
1459 SPRINTF("burst transfer mode: ");
1460 switch (nsp_burst_mode) {
1477 spin_lock_irqsave(&(data->Lock), flags);
1478 SPRINTF("CurrentSC: 0x%p\n\n", data->CurrentSC);
1479 spin_unlock_irqrestore(&(data->Lock), flags);
1481 SPRINTF("SDTR status\n");
1482 for(id = 0; id < ARRAY_SIZE(data->Sync); id++) {
1484 SPRINTF("id %d: ", id);
1486 if (id == host->this_id) {
1487 SPRINTF("----- NinjaSCSI-3 host adapter\n");
1491 switch(data->Sync[id].SyncNegotiation) {
1506 if (data->Sync[id].SyncPeriod != 0) {
1507 speed = 1000000 / (data->Sync[id].SyncPeriod * 4);
1509 SPRINTF(" transfer %d.%dMB/s, offset %d",
1512 data->Sync[id].SyncOffset
1518 thislength = pos - (buffer + offset);
1520 if(thislength < 0) {
1526 thislength = min(thislength, length);
1527 *start = buffer + offset;
1533 /*---------------------------------------------------------------*/
1535 /*---------------------------------------------------------------*/
1538 static int nsp_eh_abort(Scsi_Cmnd *SCpnt)
1540 nsp_dbg(NSP_DEBUG_BUSRESET, "SCpnt=0x%p", SCpnt);
1542 return nsp_eh_bus_reset(SCpnt);
1545 static int nsp_bus_reset(nsp_hw_data *data)
1547 unsigned int base = data->BaseAddress;
1550 nsp_write(base, IRQCONTROL, IRQCONTROL_ALLMASK);
1552 nsp_index_write(base, SCSIBUSCTRL, SCSI_RST);
1553 mdelay(100); /* 100ms */
1554 nsp_index_write(base, SCSIBUSCTRL, 0);
1555 for(i = 0; i < 5; i++) {
1556 nsp_index_read(base, IRQPHASESENCE); /* dummy read */
1559 nsphw_init_sync(data);
1561 nsp_write(base, IRQCONTROL, IRQCONTROL_ALLCLEAR);
1566 static int nsp_eh_bus_reset(Scsi_Cmnd *SCpnt)
1568 nsp_hw_data *data = (nsp_hw_data *)SCpnt->device->host->hostdata;
1570 nsp_dbg(NSP_DEBUG_BUSRESET, "SCpnt=0x%p", SCpnt);
1572 return nsp_bus_reset(data);
1575 static int nsp_eh_host_reset(Scsi_Cmnd *SCpnt)
1577 nsp_hw_data *data = (nsp_hw_data *)SCpnt->device->host->hostdata;
1579 nsp_dbg(NSP_DEBUG_BUSRESET, "in");
1587 /**********************************************************************
1589 **********************************************************************/
1591 /*======================================================================
1592 nsp_cs_attach() creates an "instance" of the driver, allocating
1593 local data structures for one device. The device is registered
1596 The dev_link structure is initialized, but we don't actually
1597 configure the card at this point -- we wait until we receive a
1598 card insertion event.
1599 ======================================================================*/
1600 static dev_link_t *nsp_cs_attach(void)
1603 client_reg_t client_reg;
1606 nsp_hw_data *data = &nsp_data_base;
1608 nsp_dbg(NSP_DEBUG_INIT, "in");
1610 /* Create new SCSI device */
1611 info = kmalloc(sizeof(*info), GFP_KERNEL);
1612 if (info == NULL) { return NULL; }
1613 memset(info, 0, sizeof(*info));
1616 data->ScsiInfo = info;
1618 nsp_dbg(NSP_DEBUG_INIT, "info=0x%p", info);
1620 /* The io structure describes IO port mapping */
1621 link->io.NumPorts1 = 0x10;
1622 link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
1623 link->io.IOAddrLines = 10; /* not used */
1625 /* Interrupt setup */
1626 link->irq.Attributes = IRQ_TYPE_EXCLUSIVE | IRQ_HANDLE_PRESENT;
1627 link->irq.IRQInfo1 = IRQ_LEVEL_ID;
1629 /* Interrupt handler */
1630 link->irq.Handler = &nspintr;
1631 link->irq.Instance = info;
1632 link->irq.Attributes |= (SA_SHIRQ | SA_SAMPLE_RANDOM);
1634 /* General socket configuration */
1635 link->conf.Attributes = CONF_ENABLE_IRQ;
1636 link->conf.Vcc = 50;
1637 link->conf.IntType = INT_MEMORY_AND_IO;
1638 link->conf.Present = PRESENT_OPTION;
1641 /* Register with Card Services */
1642 link->next = dev_list;
1644 client_reg.dev_info = &dev_info;
1645 client_reg.EventMask =
1646 CS_EVENT_CARD_INSERTION | CS_EVENT_CARD_REMOVAL |
1647 CS_EVENT_RESET_PHYSICAL | CS_EVENT_CARD_RESET |
1648 CS_EVENT_PM_SUSPEND | CS_EVENT_PM_RESUME ;
1649 client_reg.event_handler = &nsp_cs_event;
1650 client_reg.Version = 0x0210;
1651 client_reg.event_callback_args.client_data = link;
1652 ret = pcmcia_register_client(&link->handle, &client_reg);
1653 if (ret != CS_SUCCESS) {
1654 cs_error(link->handle, RegisterClient, ret);
1655 nsp_cs_detach(link);
1660 nsp_dbg(NSP_DEBUG_INIT, "link=0x%p", link);
1662 } /* nsp_cs_attach */
1665 /*======================================================================
1666 This deletes a driver "instance". The device is de-registered
1667 with Card Services. If it has been released, all local data
1668 structures are freed. Otherwise, the structures will be freed
1669 when the device is released.
1670 ======================================================================*/
1671 static void nsp_cs_detach(dev_link_t *link)
1675 nsp_dbg(NSP_DEBUG_INIT, "in, link=0x%p", link);
1677 /* Locate device structure */
1678 for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next) {
1679 if (*linkp == link) {
1683 if (*linkp == NULL) {
1687 if (link->state & DEV_CONFIG)
1688 nsp_cs_release(link);
1690 /* Break the link with Card Services */
1692 pcmcia_deregister_client(link->handle);
1695 /* Unlink device structure, free bits */
1696 *linkp = link->next;
1700 } /* nsp_cs_detach */
1703 /*======================================================================
1704 nsp_cs_config() is scheduled to run after a CARD_INSERTION event
1705 is received, to configure the PCMCIA socket, and to make the
1706 ethernet device available to the system.
1707 ======================================================================*/
1708 #define CS_CHECK(fn, ret) \
1709 do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
1710 /*====================================================================*/
1711 static void nsp_cs_config(dev_link_t *link)
1713 client_handle_t handle = link->handle;
1714 scsi_info_t *info = link->priv;
1717 int last_ret, last_fn;
1718 unsigned char tuple_data[64];
1722 cistpl_cftable_entry_t dflt = { 0 };
1723 struct Scsi_Host *host;
1724 nsp_hw_data *data = &nsp_data_base;
1725 #if !(LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,74))
1727 dev_node_t **tail, *node;
1730 nsp_dbg(NSP_DEBUG_INIT, "in");
1732 tuple.DesiredTuple = CISTPL_CONFIG;
1733 tuple.Attributes = 0;
1734 tuple.TupleData = tuple_data;
1735 tuple.TupleDataMax = sizeof(tuple_data);
1736 tuple.TupleOffset = 0;
1737 CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(handle, &tuple));
1738 CS_CHECK(GetTupleData, pcmcia_get_tuple_data(handle, &tuple));
1739 CS_CHECK(ParseTuple, pcmcia_parse_tuple(handle, &tuple, &parse));
1740 link->conf.ConfigBase = parse.config.base;
1741 link->conf.Present = parse.config.rmask[0];
1743 /* Configure card */
1744 link->state |= DEV_CONFIG;
1746 /* Look up the current Vcc */
1747 CS_CHECK(GetConfigurationInfo, pcmcia_get_configuration_info(handle, &conf));
1748 link->conf.Vcc = conf.Vcc;
1750 tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
1751 CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(handle, &tuple));
1753 cistpl_cftable_entry_t *cfg = &(parse.cftable_entry);
1755 if (pcmcia_get_tuple_data(handle, &tuple) != 0 ||
1756 pcmcia_parse_tuple(handle, &tuple, &parse) != 0)
1759 if (cfg->flags & CISTPL_CFTABLE_DEFAULT) { dflt = *cfg; }
1760 if (cfg->index == 0) { goto next_entry; }
1761 link->conf.ConfigIndex = cfg->index;
1763 /* Does this card need audio output? */
1764 if (cfg->flags & CISTPL_CFTABLE_AUDIO) {
1765 link->conf.Attributes |= CONF_ENABLE_SPKR;
1766 link->conf.Status = CCSR_AUDIO_ENA;
1769 /* Use power settings for Vcc and Vpp if present */
1770 /* Note that the CIS values need to be rescaled */
1771 if (cfg->vcc.present & (1<<CISTPL_POWER_VNOM)) {
1772 if (conf.Vcc != cfg->vcc.param[CISTPL_POWER_VNOM]/10000) {
1775 } else if (dflt.vcc.present & (1<<CISTPL_POWER_VNOM)) {
1776 if (conf.Vcc != dflt.vcc.param[CISTPL_POWER_VNOM]/10000) {
1781 if (cfg->vpp1.present & (1 << CISTPL_POWER_VNOM)) {
1782 link->conf.Vpp1 = link->conf.Vpp2 =
1783 cfg->vpp1.param[CISTPL_POWER_VNOM] / 10000;
1784 } else if (dflt.vpp1.present & (1 << CISTPL_POWER_VNOM)) {
1785 link->conf.Vpp1 = link->conf.Vpp2 =
1786 dflt.vpp1.param[CISTPL_POWER_VNOM] / 10000;
1789 /* Do we need to allocate an interrupt? */
1790 if (cfg->irq.IRQInfo1 || dflt.irq.IRQInfo1) {
1791 link->conf.Attributes |= CONF_ENABLE_IRQ;
1794 /* IO window settings */
1795 link->io.NumPorts1 = link->io.NumPorts2 = 0;
1796 if ((cfg->io.nwin > 0) || (dflt.io.nwin > 0)) {
1797 cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt.io;
1798 link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
1799 if (!(io->flags & CISTPL_IO_8BIT))
1800 link->io.Attributes1 = IO_DATA_PATH_WIDTH_16;
1801 if (!(io->flags & CISTPL_IO_16BIT))
1802 link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
1803 link->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK;
1804 link->io.BasePort1 = io->win[0].base;
1805 link->io.NumPorts1 = io->win[0].len;
1807 link->io.Attributes2 = link->io.Attributes1;
1808 link->io.BasePort2 = io->win[1].base;
1809 link->io.NumPorts2 = io->win[1].len;
1811 /* This reserves IO space but doesn't actually enable it */
1812 if (pcmcia_request_io(link->handle, &link->io) != 0)
1816 if ((cfg->mem.nwin > 0) || (dflt.mem.nwin > 0)) {
1818 (cfg->mem.nwin) ? &cfg->mem : &dflt.mem;
1819 req.Attributes = WIN_DATA_WIDTH_16|WIN_MEMORY_TYPE_CM;
1820 req.Attributes |= WIN_ENABLE;
1821 req.Base = mem->win[0].host_addr;
1822 req.Size = mem->win[0].len;
1823 if (req.Size < 0x1000) {
1826 req.AccessSpeed = 0;
1827 if (pcmcia_request_window(&link->handle, &req, &link->win) != 0)
1829 map.Page = 0; map.CardOffset = mem->win[0].card_addr;
1830 if (pcmcia_map_mem_page(link->win, &map) != 0)
1833 data->MmioAddress = (unsigned long)ioremap_nocache(req.Base, req.Size);
1834 data->MmioLength = req.Size;
1836 /* If we got this far, we're cool! */
1840 nsp_dbg(NSP_DEBUG_INIT, "next");
1842 if (link->io.NumPorts1) {
1843 pcmcia_release_io(link->handle, &link->io);
1845 CS_CHECK(GetNextTuple, pcmcia_get_next_tuple(handle, &tuple));
1848 if (link->conf.Attributes & CONF_ENABLE_IRQ) {
1849 CS_CHECK(RequestIRQ, pcmcia_request_irq(link->handle, &link->irq));
1851 CS_CHECK(RequestConfiguration, pcmcia_request_configuration(handle, &link->conf));
1854 if (link->io.BasePort1) {
1855 release_region(link->io.BasePort1, link->io.NumPorts1);
1857 if (link->io.BasePort2) {
1858 release_region(link->io.BasePort2, link->io.NumPorts2);
1862 /* Set port and IRQ */
1863 data->BaseAddress = link->io.BasePort1;
1864 data->NumAddress = link->io.NumPorts1;
1865 data->IrqNumber = link->irq.AssignedIRQ;
1867 nsp_dbg(NSP_DEBUG_INIT, "I/O[0x%x+0x%x] IRQ %d",
1868 data->BaseAddress, data->NumAddress, data->IrqNumber);
1870 if(nsphw_init(data) == FALSE) {
1874 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,2))
1875 host = nsp_detect(&nsp_driver_template);
1877 scsi_register_host(&nsp_driver_template);
1878 for (host = scsi_host_get_next(NULL); host != NULL;
1879 host = scsi_host_get_next(host)) {
1880 if (host->hostt == &nsp_driver_template) {
1887 nsp_dbg(NSP_DEBUG_INIT, "detect failed");
1892 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,74))
1893 scsi_add_host (host, NULL);
1894 scsi_scan_host(host);
1896 snprintf(info->node.dev_name, sizeof(info->node.dev_name), "scsi%d", host->host_no);
1897 link->dev = &info->node;
1901 nsp_dbg(NSP_DEBUG_INIT, "GET_SCSI_INFO");
1905 nsp_dbg(NSP_DEBUG_INIT, "host=0x%p", host);
1907 for (dev = host->host_queue; dev != NULL; dev = dev->next) {
1909 id = (dev->id & 0x0f) + ((dev->lun & 0x0f) << 4) +
1910 ((dev->channel & 0x0f) << 8) +
1911 ((dev->host->host_no & 0x0f) << 12);
1912 node = &info->node[info->ndev];
1914 switch (dev->type) {
1916 node->major = SCSI_TAPE_MAJOR;
1917 snprintf(node->dev_name, sizeof(node->dev_name), "st#%04lx", id);
1921 node->major = SCSI_DISK0_MAJOR;
1922 snprintf(node->dev_name, sizeof(node->dev_name), "sd#%04lx", id);
1926 node->major = SCSI_CDROM_MAJOR;
1927 snprintf(node->dev_name, sizeof(node->dev_name), "sr#%04lx", id);
1930 node->major = SCSI_GENERIC_MAJOR;
1931 snprintf(node->dev_name, sizeof(node->dev_name), "sg#%04lx", id);
1934 *tail = node; tail = &node->next;
1936 info->host = dev->host;
1940 if (info->ndev == 0) {
1941 nsp_msg(KERN_INFO, "no SCSI devices found");
1943 nsp_dbg(NSP_DEBUG_INIT, "host=0x%p", host);
1946 /* Finally, report what we've done */
1947 printk(KERN_INFO "nsp_cs: index 0x%02x: Vcc %d.%d",
1948 link->conf.ConfigIndex,
1949 link->conf.Vcc/10, link->conf.Vcc%10);
1950 if (link->conf.Vpp1) {
1951 printk(", Vpp %d.%d", link->conf.Vpp1/10, link->conf.Vpp1%10);
1953 if (link->conf.Attributes & CONF_ENABLE_IRQ) {
1954 printk(", irq %d", link->irq.AssignedIRQ);
1956 if (link->io.NumPorts1) {
1957 printk(", io 0x%04x-0x%04x", link->io.BasePort1,
1958 link->io.BasePort1+link->io.NumPorts1-1);
1960 if (link->io.NumPorts2)
1961 printk(" & 0x%04x-0x%04x", link->io.BasePort2,
1962 link->io.BasePort2+link->io.NumPorts2-1);
1964 printk(", mem 0x%06lx-0x%06lx", req.Base,
1965 req.Base+req.Size-1);
1968 link->state &= ~DEV_CONFIG_PENDING;
1972 nsp_dbg(NSP_DEBUG_INIT, "config fail");
1973 cs_error(link->handle, last_fn, last_ret);
1974 nsp_cs_release(link);
1977 } /* nsp_cs_config */
1981 /*======================================================================
1982 After a card is removed, nsp_cs_release() will unregister the net
1983 device, and release the PCMCIA configuration. If the device is
1984 still open, this will be postponed until it is closed.
1985 ======================================================================*/
1986 static void nsp_cs_release(dev_link_t *link)
1988 scsi_info_t *info = link->priv;
1989 nsp_hw_data *data = NULL;
1991 if (info->host == NULL) {
1992 nsp_msg(KERN_DEBUG, "unexpected card release call.");
1994 data = (nsp_hw_data *)info->host->hostdata;
1997 nsp_dbg(NSP_DEBUG_INIT, "link=0x%p", link);
1999 /* Unlink the device chain */
2000 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,2))
2001 if (info->host != NULL) {
2002 scsi_remove_host(info->host);
2005 scsi_unregister_host(&nsp_driver_template);
2011 iounmap((void *)(data->MmioAddress));
2013 pcmcia_release_window(link->win);
2015 pcmcia_release_configuration(link->handle);
2016 if (link->io.NumPorts1) {
2017 pcmcia_release_io(link->handle, &link->io);
2019 if (link->irq.AssignedIRQ) {
2020 pcmcia_release_irq(link->handle, &link->irq);
2022 link->state &= ~DEV_CONFIG;
2023 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,2))
2024 if (info->host != NULL) {
2025 scsi_host_put(info->host);
2028 } /* nsp_cs_release */
2030 /*======================================================================
2032 The card status event handler. Mostly, this schedules other
2033 stuff to run after an event is received. A CARD_REMOVAL event
2034 also sets some flags to discourage the net drivers from trying
2035 to talk to the card any more.
2037 When a CARD_REMOVAL event is received, we immediately set a flag
2038 to block future accesses to this device. All the functions that
2039 actually access the device should check this flag to make sure
2040 the card is still present.
2042 ======================================================================*/
2043 static int nsp_cs_event(event_t event,
2045 event_callback_args_t *args)
2047 dev_link_t *link = args->client_data;
2048 scsi_info_t *info = link->priv;
2051 nsp_dbg(NSP_DEBUG_INIT, "in, event=0x%08x", event);
2054 case CS_EVENT_CARD_REMOVAL:
2055 nsp_dbg(NSP_DEBUG_INIT, "event: remove");
2056 link->state &= ~DEV_PRESENT;
2057 if (link->state & DEV_CONFIG) {
2058 ((scsi_info_t *)link->priv)->stop = 1;
2059 nsp_cs_release(link);
2063 case CS_EVENT_CARD_INSERTION:
2064 nsp_dbg(NSP_DEBUG_INIT, "event: insert");
2065 link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
2066 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,68))
2067 info->bus = args->bus;
2069 nsp_cs_config(link);
2072 case CS_EVENT_PM_SUSPEND:
2073 nsp_dbg(NSP_DEBUG_INIT, "event: suspend");
2074 link->state |= DEV_SUSPEND;
2075 /* Fall through... */
2076 case CS_EVENT_RESET_PHYSICAL:
2077 /* Mark the device as stopped, to block IO until later */
2078 nsp_dbg(NSP_DEBUG_INIT, "event: reset physical");
2080 if (info->host != NULL) {
2081 nsp_msg(KERN_INFO, "clear SDTR status");
2083 data = (nsp_hw_data *)info->host->hostdata;
2085 nsphw_init_sync(data);
2089 if (link->state & DEV_CONFIG) {
2090 pcmcia_release_configuration(link->handle);
2094 case CS_EVENT_PM_RESUME:
2095 nsp_dbg(NSP_DEBUG_INIT, "event: resume");
2096 link->state &= ~DEV_SUSPEND;
2097 /* Fall through... */
2098 case CS_EVENT_CARD_RESET:
2099 nsp_dbg(NSP_DEBUG_INIT, "event: reset");
2100 if (link->state & DEV_CONFIG) {
2101 pcmcia_request_configuration(link->handle, &link->conf);
2105 if (info->host != NULL) {
2106 nsp_msg(KERN_INFO, "reset host and bus");
2108 data = (nsp_hw_data *)info->host->hostdata;
2111 nsp_bus_reset(data);
2117 nsp_dbg(NSP_DEBUG_INIT, "event: unknown");
2120 nsp_dbg(NSP_DEBUG_INIT, "end");
2122 } /* nsp_cs_event */
2124 /*======================================================================*
2125 * module entry point
2126 *====================================================================*/
2127 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,68))
2128 static struct pcmcia_device_id nsp_cs_ids[] = {
2129 PCMCIA_DEVICE_PROD_ID123("IO DATA", "CBSC16 ", "1", 0x547e66dc, 0x0d63a3fd, 0x51de003a),
2130 PCMCIA_DEVICE_PROD_ID123("KME ", "SCSI-CARD-001", "1", 0x534c02bc, 0x52008408, 0x51de003a),
2131 PCMCIA_DEVICE_PROD_ID123("KME ", "SCSI-CARD-002", "1", 0x534c02bc, 0xcb09d5b2, 0x51de003a),
2132 PCMCIA_DEVICE_PROD_ID123("KME ", "SCSI-CARD-003", "1", 0x534c02bc, 0xbc0ee524, 0x51de003a),
2133 PCMCIA_DEVICE_PROD_ID123("KME ", "SCSI-CARD-004", "1", 0x534c02bc, 0x226a7087, 0x51de003a),
2134 PCMCIA_DEVICE_PROD_ID123("WBT", "NinjaSCSI-3", "R1.0", 0xc7ba805f, 0xfdc7c97d, 0x6973710e),
2135 PCMCIA_DEVICE_PROD_ID123("WORKBIT", "UltraNinja-16", "1", 0x28191418, 0xb70f4b09, 0x51de003a),
2138 MODULE_DEVICE_TABLE(pcmcia, nsp_cs_ids);
2140 static struct pcmcia_driver nsp_driver = {
2141 .owner = THIS_MODULE,
2145 .attach = nsp_cs_attach,
2146 .detach = nsp_cs_detach,
2147 .id_table = nsp_cs_ids,
2151 static int __init nsp_cs_init(void)
2153 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,68))
2154 nsp_msg(KERN_INFO, "loading...");
2156 return pcmcia_register_driver(&nsp_driver);
2160 nsp_msg(KERN_INFO, "loading...");
2161 pcmcia_get_card_services_info(&serv);
2162 if (serv.Revision != CS_RELEASE_CODE) {
2163 nsp_msg(KERN_DEBUG, "Card Services release does not match!");
2166 register_pcmcia_driver(&dev_info, &nsp_cs_attach, &nsp_cs_detach);
2168 nsp_dbg(NSP_DEBUG_INIT, "out");
2173 static void __exit nsp_cs_exit(void)
2175 nsp_msg(KERN_INFO, "unloading...");
2177 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,68))
2178 pcmcia_unregister_driver(&nsp_driver);
2179 BUG_ON(dev_list != NULL);
2181 unregister_pcmcia_driver(&dev_info);
2182 /* XXX: this really needs to move into generic code.. */
2183 while (dev_list != NULL) {
2184 if (dev_list->state & DEV_CONFIG) {
2185 nsp_cs_release(dev_list);
2187 nsp_cs_detach(dev_list);
2193 module_init(nsp_cs_init)
2194 module_exit(nsp_cs_exit)