[MIPS] RTLX: Protect rtlx_{read,write} with mutex.
[linux-2.6/linux-mips/linux-dm7025.git] / drivers / scsi / pcmcia / nsp_cs.c
blobc6f8c6e65e057105a9d240cf7db8dbfa21313682
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/slab.h>
35 #include <linux/string.h>
36 #include <linux/timer.h>
37 #include <linux/ioport.h>
38 #include <linux/delay.h>
39 #include <linux/interrupt.h>
40 #include <linux/major.h>
41 #include <linux/blkdev.h>
42 #include <linux/stat.h>
44 #include <asm/io.h>
45 #include <asm/irq.h>
47 #include <../drivers/scsi/scsi.h>
48 #include <scsi/scsi_host.h>
50 #include <scsi/scsi.h>
51 #include <scsi/scsi_ioctl.h>
53 #include <pcmcia/cs_types.h>
54 #include <pcmcia/cs.h>
55 #include <pcmcia/cistpl.h>
56 #include <pcmcia/cisreg.h>
57 #include <pcmcia/ds.h>
59 #include "nsp_cs.h"
61 MODULE_AUTHOR("YOKOTA Hiroshi <yokota@netlab.is.tsukuba.ac.jp>");
62 MODULE_DESCRIPTION("WorkBit NinjaSCSI-3 / NinjaSCSI-32Bi(16bit) PCMCIA SCSI host adapter module $Revision: 1.23 $");
63 MODULE_SUPPORTED_DEVICE("sd,sr,sg,st");
64 #ifdef MODULE_LICENSE
65 MODULE_LICENSE("GPL");
66 #endif
68 #include "nsp_io.h"
70 /*====================================================================*/
71 /* Parameters that can be set with 'insmod' */
73 static int nsp_burst_mode = BURST_MEM32;
74 module_param(nsp_burst_mode, int, 0);
75 MODULE_PARM_DESC(nsp_burst_mode, "Burst transfer mode (0=io8, 1=io32, 2=mem32(default))");
77 /* Release IO ports after configuration? */
78 static int free_ports = 0;
79 module_param(free_ports, bool, 0);
80 MODULE_PARM_DESC(free_ports, "Release IO ports after configuration? (default: 0 (=no))");
82 static struct scsi_host_template nsp_driver_template = {
83 .proc_name = "nsp_cs",
84 .proc_info = nsp_proc_info,
85 .name = "WorkBit NinjaSCSI-3/32Bi(16bit)",
86 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
87 .detect = nsp_detect_old,
88 .release = nsp_release_old,
89 #endif
90 .info = nsp_info,
91 .queuecommand = nsp_queuecommand,
92 /* .eh_abort_handler = nsp_eh_abort,*/
93 .eh_bus_reset_handler = nsp_eh_bus_reset,
94 .eh_host_reset_handler = nsp_eh_host_reset,
95 .can_queue = 1,
96 .this_id = NSP_INITIATOR_ID,
97 .sg_tablesize = SG_ALL,
98 .cmd_per_lun = 1,
99 .use_clustering = DISABLE_CLUSTERING,
100 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,2))
101 .use_new_eh_code = 1,
102 #endif
105 static nsp_hw_data nsp_data_base; /* attach <-> detect glue */
110 * debug, error print
112 #ifndef NSP_DEBUG
113 # define NSP_DEBUG_MASK 0x000000
114 # define nsp_msg(type, args...) nsp_cs_message("", 0, (type), args)
115 # define nsp_dbg(mask, args...) /* */
116 #else
117 # define NSP_DEBUG_MASK 0xffffff
118 # define nsp_msg(type, args...) \
119 nsp_cs_message (__FUNCTION__, __LINE__, (type), args)
120 # define nsp_dbg(mask, args...) \
121 nsp_cs_dmessage(__FUNCTION__, __LINE__, (mask), args)
122 #endif
124 #define NSP_DEBUG_QUEUECOMMAND BIT(0)
125 #define NSP_DEBUG_REGISTER BIT(1)
126 #define NSP_DEBUG_AUTOSCSI BIT(2)
127 #define NSP_DEBUG_INTR BIT(3)
128 #define NSP_DEBUG_SGLIST BIT(4)
129 #define NSP_DEBUG_BUSFREE BIT(5)
130 #define NSP_DEBUG_CDB_CONTENTS BIT(6)
131 #define NSP_DEBUG_RESELECTION BIT(7)
132 #define NSP_DEBUG_MSGINOCCUR BIT(8)
133 #define NSP_DEBUG_EEPROM BIT(9)
134 #define NSP_DEBUG_MSGOUTOCCUR BIT(10)
135 #define NSP_DEBUG_BUSRESET BIT(11)
136 #define NSP_DEBUG_RESTART BIT(12)
137 #define NSP_DEBUG_SYNC BIT(13)
138 #define NSP_DEBUG_WAIT BIT(14)
139 #define NSP_DEBUG_TARGETFLAG BIT(15)
140 #define NSP_DEBUG_PROC BIT(16)
141 #define NSP_DEBUG_INIT BIT(17)
142 #define NSP_DEBUG_DATA_IO BIT(18)
143 #define NSP_SPECIAL_PRINT_REGISTER BIT(20)
145 #define NSP_DEBUG_BUF_LEN 150
147 static void nsp_cs_message(const char *func, int line, char *type, char *fmt, ...)
149 va_list args;
150 char buf[NSP_DEBUG_BUF_LEN];
152 va_start(args, fmt);
153 vsnprintf(buf, sizeof(buf), fmt, args);
154 va_end(args);
156 #ifndef NSP_DEBUG
157 printk("%snsp_cs: %s\n", type, buf);
158 #else
159 printk("%snsp_cs: %s (%d): %s\n", type, func, line, buf);
160 #endif
163 #ifdef NSP_DEBUG
164 static void nsp_cs_dmessage(const char *func, int line, int mask, char *fmt, ...)
166 va_list args;
167 char buf[NSP_DEBUG_BUF_LEN];
169 va_start(args, fmt);
170 vsnprintf(buf, sizeof(buf), fmt, args);
171 va_end(args);
173 if (mask & NSP_DEBUG_MASK) {
174 printk("nsp_cs-debug: 0x%x %s (%d): %s\n", mask, func, line, buf);
177 #endif
179 /***********************************************************/
181 /*====================================================
182 * Clenaup parameters and call done() functions.
183 * You must be set SCpnt->result before call this function.
185 static void nsp_scsi_done(struct scsi_cmnd *SCpnt)
187 nsp_hw_data *data = (nsp_hw_data *)SCpnt->device->host->hostdata;
189 data->CurrentSC = NULL;
191 SCpnt->scsi_done(SCpnt);
194 static int nsp_queuecommand(struct scsi_cmnd *SCpnt,
195 void (*done)(struct scsi_cmnd *))
197 #ifdef NSP_DEBUG
198 /*unsigned int host_id = SCpnt->device->host->this_id;*/
199 /*unsigned int base = SCpnt->device->host->io_port;*/
200 unsigned char target = scmd_id(SCpnt);
201 #endif
202 nsp_hw_data *data = (nsp_hw_data *)SCpnt->device->host->hostdata;
204 nsp_dbg(NSP_DEBUG_QUEUECOMMAND, "SCpnt=0x%p target=%d lun=%d buff=0x%p bufflen=%d use_sg=%d",
205 SCpnt, target, SCpnt->device->lun, SCpnt->request_buffer, SCpnt->request_bufflen, SCpnt->use_sg);
206 //nsp_dbg(NSP_DEBUG_QUEUECOMMAND, "before CurrentSC=0x%p", data->CurrentSC);
208 SCpnt->scsi_done = done;
210 if (data->CurrentSC != NULL) {
211 nsp_msg(KERN_DEBUG, "CurrentSC!=NULL this can't be happen");
212 SCpnt->result = DID_BAD_TARGET << 16;
213 nsp_scsi_done(SCpnt);
214 return 0;
217 #if 0
218 /* XXX: pcmcia-cs generates SCSI command with "scsi_info" utility.
219 This makes kernel crash when suspending... */
220 if (data->ScsiInfo->stop != 0) {
221 nsp_msg(KERN_INFO, "suspending device. reject command.");
222 SCpnt->result = DID_BAD_TARGET << 16;
223 nsp_scsi_done(SCpnt);
224 return SCSI_MLQUEUE_HOST_BUSY;
226 #endif
228 show_command(SCpnt);
230 data->CurrentSC = SCpnt;
232 SCpnt->SCp.Status = CHECK_CONDITION;
233 SCpnt->SCp.Message = 0;
234 SCpnt->SCp.have_data_in = IO_UNKNOWN;
235 SCpnt->SCp.sent_command = 0;
236 SCpnt->SCp.phase = PH_UNDETERMINED;
237 SCpnt->resid = SCpnt->request_bufflen;
239 /* setup scratch area
240 SCp.ptr : buffer pointer
241 SCp.this_residual : buffer length
242 SCp.buffer : next buffer
243 SCp.buffers_residual : left buffers in list
244 SCp.phase : current state of the command */
245 if (SCpnt->use_sg) {
246 SCpnt->SCp.buffer = (struct scatterlist *) SCpnt->request_buffer;
247 SCpnt->SCp.ptr = BUFFER_ADDR;
248 SCpnt->SCp.this_residual = SCpnt->SCp.buffer->length;
249 SCpnt->SCp.buffers_residual = SCpnt->use_sg - 1;
250 } else {
251 SCpnt->SCp.ptr = (char *) SCpnt->request_buffer;
252 SCpnt->SCp.this_residual = SCpnt->request_bufflen;
253 SCpnt->SCp.buffer = NULL;
254 SCpnt->SCp.buffers_residual = 0;
257 if (nsphw_start_selection(SCpnt) == FALSE) {
258 nsp_dbg(NSP_DEBUG_QUEUECOMMAND, "selection fail");
259 SCpnt->result = DID_BUS_BUSY << 16;
260 nsp_scsi_done(SCpnt);
261 return 0;
265 //nsp_dbg(NSP_DEBUG_QUEUECOMMAND, "out");
266 #ifdef NSP_DEBUG
267 data->CmdId++;
268 #endif
269 return 0;
273 * setup PIO FIFO transfer mode and enable/disable to data out
275 static void nsp_setup_fifo(nsp_hw_data *data, int enabled)
277 unsigned int base = data->BaseAddress;
278 unsigned char transfer_mode_reg;
280 //nsp_dbg(NSP_DEBUG_DATA_IO, "enabled=%d", enabled);
282 if (enabled != FALSE) {
283 transfer_mode_reg = TRANSFER_GO | BRAIND;
284 } else {
285 transfer_mode_reg = 0;
288 transfer_mode_reg |= data->TransferMode;
290 nsp_index_write(base, TRANSFERMODE, transfer_mode_reg);
293 static void nsphw_init_sync(nsp_hw_data *data)
295 sync_data tmp_sync = { .SyncNegotiation = SYNC_NOT_YET,
296 .SyncPeriod = 0,
297 .SyncOffset = 0
299 int i;
301 /* setup sync data */
302 for ( i = 0; i < ARRAY_SIZE(data->Sync); i++ ) {
303 data->Sync[i] = tmp_sync;
308 * Initialize Ninja hardware
310 static int nsphw_init(nsp_hw_data *data)
312 unsigned int base = data->BaseAddress;
314 nsp_dbg(NSP_DEBUG_INIT, "in base=0x%x", base);
316 data->ScsiClockDiv = CLOCK_40M | FAST_20;
317 data->CurrentSC = NULL;
318 data->FifoCount = 0;
319 data->TransferMode = MODE_IO8;
321 nsphw_init_sync(data);
323 /* block all interrupts */
324 nsp_write(base, IRQCONTROL, IRQCONTROL_ALLMASK);
326 /* setup SCSI interface */
327 nsp_write(base, IFSELECT, IF_IFSEL);
329 nsp_index_write(base, SCSIIRQMODE, 0);
331 nsp_index_write(base, TRANSFERMODE, MODE_IO8);
332 nsp_index_write(base, CLOCKDIV, data->ScsiClockDiv);
334 nsp_index_write(base, PARITYCTRL, 0);
335 nsp_index_write(base, POINTERCLR, POINTER_CLEAR |
336 ACK_COUNTER_CLEAR |
337 REQ_COUNTER_CLEAR |
338 HOST_COUNTER_CLEAR);
340 /* setup fifo asic */
341 nsp_write(base, IFSELECT, IF_REGSEL);
342 nsp_index_write(base, TERMPWRCTRL, 0);
343 if ((nsp_index_read(base, OTHERCONTROL) & TPWR_SENSE) == 0) {
344 nsp_msg(KERN_INFO, "terminator power on");
345 nsp_index_write(base, TERMPWRCTRL, POWER_ON);
348 nsp_index_write(base, TIMERCOUNT, 0);
349 nsp_index_write(base, TIMERCOUNT, 0); /* requires 2 times!! */
351 nsp_index_write(base, SYNCREG, 0);
352 nsp_index_write(base, ACKWIDTH, 0);
354 /* enable interrupts and ack them */
355 nsp_index_write(base, SCSIIRQMODE, SCSI_PHASE_CHANGE_EI |
356 RESELECT_EI |
357 SCSI_RESET_IRQ_EI );
358 nsp_write(base, IRQCONTROL, IRQCONTROL_ALLCLEAR);
360 nsp_setup_fifo(data, FALSE);
362 return TRUE;
366 * Start selection phase
368 static int nsphw_start_selection(struct scsi_cmnd *SCpnt)
370 unsigned int host_id = SCpnt->device->host->this_id;
371 unsigned int base = SCpnt->device->host->io_port;
372 unsigned char target = scmd_id(SCpnt);
373 nsp_hw_data *data = (nsp_hw_data *)SCpnt->device->host->hostdata;
374 int time_out;
375 unsigned char phase, arbit;
377 //nsp_dbg(NSP_DEBUG_RESELECTION, "in");
379 phase = nsp_index_read(base, SCSIBUSMON);
380 if(phase != BUSMON_BUS_FREE) {
381 //nsp_dbg(NSP_DEBUG_RESELECTION, "bus busy");
382 return FALSE;
385 /* start arbitration */
386 //nsp_dbg(NSP_DEBUG_RESELECTION, "start arbit");
387 SCpnt->SCp.phase = PH_ARBSTART;
388 nsp_index_write(base, SETARBIT, ARBIT_GO);
390 time_out = 1000;
391 do {
392 /* XXX: what a stupid chip! */
393 arbit = nsp_index_read(base, ARBITSTATUS);
394 //nsp_dbg(NSP_DEBUG_RESELECTION, "arbit=%d, wait_count=%d", arbit, wait_count);
395 udelay(1); /* hold 1.2us */
396 } while((arbit & (ARBIT_WIN | ARBIT_FAIL)) == 0 &&
397 (time_out-- != 0));
399 if (!(arbit & ARBIT_WIN)) {
400 //nsp_dbg(NSP_DEBUG_RESELECTION, "arbit fail");
401 nsp_index_write(base, SETARBIT, ARBIT_FLAG_CLEAR);
402 return FALSE;
405 /* assert select line */
406 //nsp_dbg(NSP_DEBUG_RESELECTION, "assert SEL line");
407 SCpnt->SCp.phase = PH_SELSTART;
408 udelay(3); /* wait 2.4us */
409 nsp_index_write(base, SCSIDATALATCH, BIT(host_id) | BIT(target));
410 nsp_index_write(base, SCSIBUSCTRL, SCSI_SEL | SCSI_BSY | SCSI_ATN);
411 udelay(2); /* wait >1.2us */
412 nsp_index_write(base, SCSIBUSCTRL, SCSI_SEL | SCSI_BSY | SCSI_DATAOUT_ENB | SCSI_ATN);
413 nsp_index_write(base, SETARBIT, ARBIT_FLAG_CLEAR);
414 /*udelay(1);*/ /* wait >90ns */
415 nsp_index_write(base, SCSIBUSCTRL, SCSI_SEL | SCSI_DATAOUT_ENB | SCSI_ATN);
417 /* check selection timeout */
418 nsp_start_timer(SCpnt, 1000/51);
419 data->SelectionTimeOut = 1;
421 return TRUE;
424 struct nsp_sync_table {
425 unsigned int min_period;
426 unsigned int max_period;
427 unsigned int chip_period;
428 unsigned int ack_width;
431 static struct nsp_sync_table nsp_sync_table_40M[] = {
432 {0x0c, 0x0c, 0x1, 0}, /* 20MB 50ns*/
433 {0x19, 0x19, 0x3, 1}, /* 10MB 100ns*/
434 {0x1a, 0x25, 0x5, 2}, /* 7.5MB 150ns*/
435 {0x26, 0x32, 0x7, 3}, /* 5MB 200ns*/
436 { 0, 0, 0, 0},
439 static struct nsp_sync_table nsp_sync_table_20M[] = {
440 {0x19, 0x19, 0x1, 0}, /* 10MB 100ns*/
441 {0x1a, 0x25, 0x2, 0}, /* 7.5MB 150ns*/
442 {0x26, 0x32, 0x3, 1}, /* 5MB 200ns*/
443 { 0, 0, 0, 0},
447 * setup synchronous data transfer mode
449 static int nsp_analyze_sdtr(struct scsi_cmnd *SCpnt)
451 unsigned char target = scmd_id(SCpnt);
452 // unsigned char lun = SCpnt->device->lun;
453 nsp_hw_data *data = (nsp_hw_data *)SCpnt->device->host->hostdata;
454 sync_data *sync = &(data->Sync[target]);
455 struct nsp_sync_table *sync_table;
456 unsigned int period, offset;
457 int i;
460 nsp_dbg(NSP_DEBUG_SYNC, "in");
462 period = sync->SyncPeriod;
463 offset = sync->SyncOffset;
465 nsp_dbg(NSP_DEBUG_SYNC, "period=0x%x, offset=0x%x", period, offset);
467 if ((data->ScsiClockDiv & (BIT(0)|BIT(1))) == CLOCK_20M) {
468 sync_table = nsp_sync_table_20M;
469 } else {
470 sync_table = nsp_sync_table_40M;
473 for ( i = 0; sync_table->max_period != 0; i++, sync_table++) {
474 if ( period >= sync_table->min_period &&
475 period <= sync_table->max_period ) {
476 break;
480 if (period != 0 && sync_table->max_period == 0) {
482 * No proper period/offset found
484 nsp_dbg(NSP_DEBUG_SYNC, "no proper period/offset");
486 sync->SyncPeriod = 0;
487 sync->SyncOffset = 0;
488 sync->SyncRegister = 0;
489 sync->AckWidth = 0;
491 return FALSE;
494 sync->SyncRegister = (sync_table->chip_period << SYNCREG_PERIOD_SHIFT) |
495 (offset & SYNCREG_OFFSET_MASK);
496 sync->AckWidth = sync_table->ack_width;
498 nsp_dbg(NSP_DEBUG_SYNC, "sync_reg=0x%x, ack_width=0x%x", sync->SyncRegister, sync->AckWidth);
500 return TRUE;
505 * start ninja hardware timer
507 static void nsp_start_timer(struct scsi_cmnd *SCpnt, int time)
509 unsigned int base = SCpnt->device->host->io_port;
510 nsp_hw_data *data = (nsp_hw_data *)SCpnt->device->host->hostdata;
512 //nsp_dbg(NSP_DEBUG_INTR, "in SCpnt=0x%p, time=%d", SCpnt, time);
513 data->TimerCount = time;
514 nsp_index_write(base, TIMERCOUNT, time);
518 * wait for bus phase change
520 static int nsp_negate_signal(struct scsi_cmnd *SCpnt, unsigned char mask,
521 char *str)
523 unsigned int base = SCpnt->device->host->io_port;
524 unsigned char reg;
525 int time_out;
527 //nsp_dbg(NSP_DEBUG_INTR, "in");
529 time_out = 100;
531 do {
532 reg = nsp_index_read(base, SCSIBUSMON);
533 if (reg == 0xff) {
534 break;
536 } while ((time_out-- != 0) && (reg & mask) != 0);
538 if (time_out == 0) {
539 nsp_msg(KERN_DEBUG, " %s signal off timeut", str);
542 return 0;
546 * expect Ninja Irq
548 static int nsp_expect_signal(struct scsi_cmnd *SCpnt,
549 unsigned char current_phase,
550 unsigned char mask)
552 unsigned int base = SCpnt->device->host->io_port;
553 int time_out;
554 unsigned char phase, i_src;
556 //nsp_dbg(NSP_DEBUG_INTR, "current_phase=0x%x, mask=0x%x", current_phase, mask);
558 time_out = 100;
559 do {
560 phase = nsp_index_read(base, SCSIBUSMON);
561 if (phase == 0xff) {
562 //nsp_dbg(NSP_DEBUG_INTR, "ret -1");
563 return -1;
565 i_src = nsp_read(base, IRQSTATUS);
566 if (i_src & IRQSTATUS_SCSI) {
567 //nsp_dbg(NSP_DEBUG_INTR, "ret 0 found scsi signal");
568 return 0;
570 if ((phase & mask) != 0 && (phase & BUSMON_PHASE_MASK) == current_phase) {
571 //nsp_dbg(NSP_DEBUG_INTR, "ret 1 phase=0x%x", phase);
572 return 1;
574 } while(time_out-- != 0);
576 //nsp_dbg(NSP_DEBUG_INTR, "timeout");
577 return -1;
581 * transfer SCSI message
583 static int nsp_xfer(struct scsi_cmnd *SCpnt, int phase)
585 unsigned int base = SCpnt->device->host->io_port;
586 nsp_hw_data *data = (nsp_hw_data *)SCpnt->device->host->hostdata;
587 char *buf = data->MsgBuffer;
588 int len = min(MSGBUF_SIZE, data->MsgLen);
589 int ptr;
590 int ret;
592 //nsp_dbg(NSP_DEBUG_DATA_IO, "in");
593 for (ptr = 0; len > 0; len--, ptr++) {
595 ret = nsp_expect_signal(SCpnt, phase, BUSMON_REQ);
596 if (ret <= 0) {
597 nsp_dbg(NSP_DEBUG_DATA_IO, "xfer quit");
598 return 0;
601 /* if last byte, negate ATN */
602 if (len == 1 && SCpnt->SCp.phase == PH_MSG_OUT) {
603 nsp_index_write(base, SCSIBUSCTRL, AUTODIRECTION | ACKENB);
606 /* read & write message */
607 if (phase & BUSMON_IO) {
608 nsp_dbg(NSP_DEBUG_DATA_IO, "read msg");
609 buf[ptr] = nsp_index_read(base, SCSIDATAWITHACK);
610 } else {
611 nsp_dbg(NSP_DEBUG_DATA_IO, "write msg");
612 nsp_index_write(base, SCSIDATAWITHACK, buf[ptr]);
614 nsp_negate_signal(SCpnt, BUSMON_ACK, "xfer<ack>");
617 return len;
621 * get extra SCSI data from fifo
623 static int nsp_dataphase_bypass(struct scsi_cmnd *SCpnt)
625 nsp_hw_data *data = (nsp_hw_data *)SCpnt->device->host->hostdata;
626 unsigned int count;
628 //nsp_dbg(NSP_DEBUG_DATA_IO, "in");
630 if (SCpnt->SCp.have_data_in != IO_IN) {
631 return 0;
634 count = nsp_fifo_count(SCpnt);
635 if (data->FifoCount == count) {
636 //nsp_dbg(NSP_DEBUG_DATA_IO, "not use bypass quirk");
637 return 0;
641 * XXX: NSP_QUIRK
642 * data phase skip only occures in case of SCSI_LOW_READ
644 nsp_dbg(NSP_DEBUG_DATA_IO, "use bypass quirk");
645 SCpnt->SCp.phase = PH_DATA;
646 nsp_pio_read(SCpnt);
647 nsp_setup_fifo(data, FALSE);
649 return 0;
653 * accept reselection
655 static int nsp_reselected(struct scsi_cmnd *SCpnt)
657 unsigned int base = SCpnt->device->host->io_port;
658 unsigned int host_id = SCpnt->device->host->this_id;
659 //nsp_hw_data *data = (nsp_hw_data *)SCpnt->device->host->hostdata;
660 unsigned char bus_reg;
661 unsigned char id_reg, tmp;
662 int target;
664 nsp_dbg(NSP_DEBUG_RESELECTION, "in");
666 id_reg = nsp_index_read(base, RESELECTID);
667 tmp = id_reg & (~BIT(host_id));
668 target = 0;
669 while(tmp != 0) {
670 if (tmp & BIT(0)) {
671 break;
673 tmp >>= 1;
674 target++;
677 if (scmd_id(SCpnt) != target) {
678 nsp_msg(KERN_ERR, "XXX: reselect ID must be %d in this implementation.", target);
681 nsp_negate_signal(SCpnt, BUSMON_SEL, "reselect<SEL>");
683 nsp_nexus(SCpnt);
684 bus_reg = nsp_index_read(base, SCSIBUSCTRL) & ~(SCSI_BSY | SCSI_ATN);
685 nsp_index_write(base, SCSIBUSCTRL, bus_reg);
686 nsp_index_write(base, SCSIBUSCTRL, bus_reg | AUTODIRECTION | ACKENB);
688 return TRUE;
692 * count how many data transferd
694 static int nsp_fifo_count(struct scsi_cmnd *SCpnt)
696 unsigned int base = SCpnt->device->host->io_port;
697 unsigned int count;
698 unsigned int l, m, h, dummy;
700 nsp_index_write(base, POINTERCLR, POINTER_CLEAR | ACK_COUNTER);
702 l = nsp_index_read(base, TRANSFERCOUNT);
703 m = nsp_index_read(base, TRANSFERCOUNT);
704 h = nsp_index_read(base, TRANSFERCOUNT);
705 dummy = nsp_index_read(base, TRANSFERCOUNT); /* required this! */
707 count = (h << 16) | (m << 8) | (l << 0);
709 //nsp_dbg(NSP_DEBUG_DATA_IO, "count=0x%x", count);
711 return count;
714 /* fifo size */
715 #define RFIFO_CRIT 64
716 #define WFIFO_CRIT 64
719 * read data in DATA IN phase
721 static void nsp_pio_read(struct scsi_cmnd *SCpnt)
723 unsigned int base = SCpnt->device->host->io_port;
724 unsigned long mmio_base = SCpnt->device->host->base;
725 nsp_hw_data *data = (nsp_hw_data *)SCpnt->device->host->hostdata;
726 long time_out;
727 int ocount, res;
728 unsigned char stat, fifo_stat;
730 ocount = data->FifoCount;
732 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",
733 SCpnt, SCpnt->resid, ocount, SCpnt->SCp.ptr, SCpnt->SCp.this_residual, SCpnt->SCp.buffer, SCpnt->SCp.buffers_residual);
735 time_out = 1000;
737 while ((time_out-- != 0) &&
738 (SCpnt->SCp.this_residual > 0 || SCpnt->SCp.buffers_residual > 0 ) ) {
740 stat = nsp_index_read(base, SCSIBUSMON);
741 stat &= BUSMON_PHASE_MASK;
744 res = nsp_fifo_count(SCpnt) - ocount;
745 //nsp_dbg(NSP_DEBUG_DATA_IO, "ptr=0x%p this=0x%x ocount=0x%x res=0x%x", SCpnt->SCp.ptr, SCpnt->SCp.this_residual, ocount, res);
746 if (res == 0) { /* if some data avilable ? */
747 if (stat == BUSPHASE_DATA_IN) { /* phase changed? */
748 //nsp_dbg(NSP_DEBUG_DATA_IO, " wait for data this=%d", SCpnt->SCp.this_residual);
749 continue;
750 } else {
751 nsp_dbg(NSP_DEBUG_DATA_IO, "phase changed stat=0x%x", stat);
752 break;
756 fifo_stat = nsp_read(base, FIFOSTATUS);
757 if ((fifo_stat & FIFOSTATUS_FULL_EMPTY) == 0 &&
758 stat == BUSPHASE_DATA_IN) {
759 continue;
762 res = min(res, SCpnt->SCp.this_residual);
764 switch (data->TransferMode) {
765 case MODE_IO32:
766 res &= ~(BIT(1)|BIT(0)); /* align 4 */
767 nsp_fifo32_read(base, SCpnt->SCp.ptr, res >> 2);
768 break;
769 case MODE_IO8:
770 nsp_fifo8_read (base, SCpnt->SCp.ptr, res );
771 break;
773 case MODE_MEM32:
774 res &= ~(BIT(1)|BIT(0)); /* align 4 */
775 nsp_mmio_fifo32_read(mmio_base, SCpnt->SCp.ptr, res >> 2);
776 break;
778 default:
779 nsp_dbg(NSP_DEBUG_DATA_IO, "unknown read mode");
780 return;
783 SCpnt->resid -= res;
784 SCpnt->SCp.ptr += res;
785 SCpnt->SCp.this_residual -= res;
786 ocount += res;
787 //nsp_dbg(NSP_DEBUG_DATA_IO, "ptr=0x%p this_residual=0x%x ocount=0x%x", SCpnt->SCp.ptr, SCpnt->SCp.this_residual, ocount);
789 /* go to next scatter list if available */
790 if (SCpnt->SCp.this_residual == 0 &&
791 SCpnt->SCp.buffers_residual != 0 ) {
792 //nsp_dbg(NSP_DEBUG_DATA_IO, "scatterlist next timeout=%d", time_out);
793 SCpnt->SCp.buffers_residual--;
794 SCpnt->SCp.buffer++;
795 SCpnt->SCp.ptr = BUFFER_ADDR;
796 SCpnt->SCp.this_residual = SCpnt->SCp.buffer->length;
797 time_out = 1000;
799 //nsp_dbg(NSP_DEBUG_DATA_IO, "page: 0x%p, off: 0x%x", SCpnt->SCp.buffer->page, SCpnt->SCp.buffer->offset);
803 data->FifoCount = ocount;
805 if (time_out == 0) {
806 nsp_msg(KERN_DEBUG, "pio read timeout resid=%d this_residual=%d buffers_residual=%d",
807 SCpnt->resid, SCpnt->SCp.this_residual, SCpnt->SCp.buffers_residual);
809 nsp_dbg(NSP_DEBUG_DATA_IO, "read ocount=0x%x", ocount);
810 nsp_dbg(NSP_DEBUG_DATA_IO, "r cmd=%d resid=0x%x\n", data->CmdId, SCpnt->resid);
814 * write data in DATA OUT phase
816 static void nsp_pio_write(struct scsi_cmnd *SCpnt)
818 unsigned int base = SCpnt->device->host->io_port;
819 unsigned long mmio_base = SCpnt->device->host->base;
820 nsp_hw_data *data = (nsp_hw_data *)SCpnt->device->host->hostdata;
821 int time_out;
822 int ocount, res;
823 unsigned char stat;
825 ocount = data->FifoCount;
827 nsp_dbg(NSP_DEBUG_DATA_IO, "in fifocount=%d ptr=0x%p this_residual=%d buffers=0x%p nbuf=%d resid=0x%x",
828 data->FifoCount, SCpnt->SCp.ptr, SCpnt->SCp.this_residual, SCpnt->SCp.buffer, SCpnt->SCp.buffers_residual, SCpnt->resid);
830 time_out = 1000;
832 while ((time_out-- != 0) &&
833 (SCpnt->SCp.this_residual > 0 || SCpnt->SCp.buffers_residual > 0)) {
834 stat = nsp_index_read(base, SCSIBUSMON);
835 stat &= BUSMON_PHASE_MASK;
837 if (stat != BUSPHASE_DATA_OUT) {
838 res = ocount - nsp_fifo_count(SCpnt);
840 nsp_dbg(NSP_DEBUG_DATA_IO, "phase changed stat=0x%x, res=%d\n", stat, res);
841 /* Put back pointer */
842 SCpnt->resid += res;
843 SCpnt->SCp.ptr -= res;
844 SCpnt->SCp.this_residual += res;
845 ocount -= res;
847 break;
850 res = ocount - nsp_fifo_count(SCpnt);
851 if (res > 0) { /* write all data? */
852 nsp_dbg(NSP_DEBUG_DATA_IO, "wait for all data out. ocount=0x%x res=%d", ocount, res);
853 continue;
856 res = min(SCpnt->SCp.this_residual, WFIFO_CRIT);
858 //nsp_dbg(NSP_DEBUG_DATA_IO, "ptr=0x%p this=0x%x res=0x%x", SCpnt->SCp.ptr, SCpnt->SCp.this_residual, res);
859 switch (data->TransferMode) {
860 case MODE_IO32:
861 res &= ~(BIT(1)|BIT(0)); /* align 4 */
862 nsp_fifo32_write(base, SCpnt->SCp.ptr, res >> 2);
863 break;
864 case MODE_IO8:
865 nsp_fifo8_write (base, SCpnt->SCp.ptr, res );
866 break;
868 case MODE_MEM32:
869 res &= ~(BIT(1)|BIT(0)); /* align 4 */
870 nsp_mmio_fifo32_write(mmio_base, SCpnt->SCp.ptr, res >> 2);
871 break;
873 default:
874 nsp_dbg(NSP_DEBUG_DATA_IO, "unknown write mode");
875 break;
878 SCpnt->resid -= res;
879 SCpnt->SCp.ptr += res;
880 SCpnt->SCp.this_residual -= res;
881 ocount += res;
883 /* go to next scatter list if available */
884 if (SCpnt->SCp.this_residual == 0 &&
885 SCpnt->SCp.buffers_residual != 0 ) {
886 //nsp_dbg(NSP_DEBUG_DATA_IO, "scatterlist next");
887 SCpnt->SCp.buffers_residual--;
888 SCpnt->SCp.buffer++;
889 SCpnt->SCp.ptr = BUFFER_ADDR;
890 SCpnt->SCp.this_residual = SCpnt->SCp.buffer->length;
891 time_out = 1000;
895 data->FifoCount = ocount;
897 if (time_out == 0) {
898 nsp_msg(KERN_DEBUG, "pio write timeout resid=0x%x", SCpnt->resid);
900 nsp_dbg(NSP_DEBUG_DATA_IO, "write ocount=0x%x", ocount);
901 nsp_dbg(NSP_DEBUG_DATA_IO, "w cmd=%d resid=0x%x\n", data->CmdId, SCpnt->resid);
903 #undef RFIFO_CRIT
904 #undef WFIFO_CRIT
907 * setup synchronous/asynchronous data transfer mode
909 static int nsp_nexus(struct scsi_cmnd *SCpnt)
911 unsigned int base = SCpnt->device->host->io_port;
912 unsigned char target = scmd_id(SCpnt);
913 // unsigned char lun = SCpnt->device->lun;
914 nsp_hw_data *data = (nsp_hw_data *)SCpnt->device->host->hostdata;
915 sync_data *sync = &(data->Sync[target]);
917 //nsp_dbg(NSP_DEBUG_DATA_IO, "in SCpnt=0x%p", SCpnt);
919 /* setup synch transfer registers */
920 nsp_index_write(base, SYNCREG, sync->SyncRegister);
921 nsp_index_write(base, ACKWIDTH, sync->AckWidth);
923 if (SCpnt->use_sg == 0 ||
924 SCpnt->resid % 4 != 0 ||
925 SCpnt->resid <= PAGE_SIZE ) {
926 data->TransferMode = MODE_IO8;
927 } else if (nsp_burst_mode == BURST_MEM32) {
928 data->TransferMode = MODE_MEM32;
929 } else if (nsp_burst_mode == BURST_IO32) {
930 data->TransferMode = MODE_IO32;
931 } else {
932 data->TransferMode = MODE_IO8;
935 /* setup pdma fifo */
936 nsp_setup_fifo(data, TRUE);
938 /* clear ack counter */
939 data->FifoCount = 0;
940 nsp_index_write(base, POINTERCLR, POINTER_CLEAR |
941 ACK_COUNTER_CLEAR |
942 REQ_COUNTER_CLEAR |
943 HOST_COUNTER_CLEAR);
945 return 0;
948 #include "nsp_message.c"
950 * interrupt handler
952 static irqreturn_t nspintr(int irq, void *dev_id)
954 unsigned int base;
955 unsigned char irq_status, irq_phase, phase;
956 struct scsi_cmnd *tmpSC;
957 unsigned char target, lun;
958 unsigned int *sync_neg;
959 int i, tmp;
960 nsp_hw_data *data;
963 //nsp_dbg(NSP_DEBUG_INTR, "dev_id=0x%p", dev_id);
964 //nsp_dbg(NSP_DEBUG_INTR, "host=0x%p", ((scsi_info_t *)dev_id)->host);
966 if ( dev_id != NULL &&
967 ((scsi_info_t *)dev_id)->host != NULL ) {
968 scsi_info_t *info = (scsi_info_t *)dev_id;
970 data = (nsp_hw_data *)info->host->hostdata;
971 } else {
972 nsp_dbg(NSP_DEBUG_INTR, "host data wrong");
973 return IRQ_NONE;
976 //nsp_dbg(NSP_DEBUG_INTR, "&nsp_data_base=0x%p, dev_id=0x%p", &nsp_data_base, dev_id);
978 base = data->BaseAddress;
979 //nsp_dbg(NSP_DEBUG_INTR, "base=0x%x", base);
982 * interrupt check
984 nsp_write(base, IRQCONTROL, IRQCONTROL_IRQDISABLE);
985 irq_status = nsp_read(base, IRQSTATUS);
986 //nsp_dbg(NSP_DEBUG_INTR, "irq_status=0x%x", irq_status);
987 if ((irq_status == 0xff) || ((irq_status & IRQSTATUS_MASK) == 0)) {
988 nsp_write(base, IRQCONTROL, 0);
989 //nsp_dbg(NSP_DEBUG_INTR, "no irq/shared irq");
990 return IRQ_NONE;
993 /* XXX: IMPORTANT
994 * Do not read an irq_phase register if no scsi phase interrupt.
995 * Unless, you should lose a scsi phase interrupt.
997 phase = nsp_index_read(base, SCSIBUSMON);
998 if((irq_status & IRQSTATUS_SCSI) != 0) {
999 irq_phase = nsp_index_read(base, IRQPHASESENCE);
1000 } else {
1001 irq_phase = 0;
1004 //nsp_dbg(NSP_DEBUG_INTR, "irq_phase=0x%x", irq_phase);
1007 * timer interrupt handler (scsi vs timer interrupts)
1009 //nsp_dbg(NSP_DEBUG_INTR, "timercount=%d", data->TimerCount);
1010 if (data->TimerCount != 0) {
1011 //nsp_dbg(NSP_DEBUG_INTR, "stop timer");
1012 nsp_index_write(base, TIMERCOUNT, 0);
1013 nsp_index_write(base, TIMERCOUNT, 0);
1014 data->TimerCount = 0;
1017 if ((irq_status & IRQSTATUS_MASK) == IRQSTATUS_TIMER &&
1018 data->SelectionTimeOut == 0) {
1019 //nsp_dbg(NSP_DEBUG_INTR, "timer start");
1020 nsp_write(base, IRQCONTROL, IRQCONTROL_TIMER_CLEAR);
1021 return IRQ_HANDLED;
1024 nsp_write(base, IRQCONTROL, IRQCONTROL_TIMER_CLEAR | IRQCONTROL_FIFO_CLEAR);
1026 if ((irq_status & IRQSTATUS_SCSI) &&
1027 (irq_phase & SCSI_RESET_IRQ)) {
1028 nsp_msg(KERN_ERR, "bus reset (power off?)");
1030 nsphw_init(data);
1031 nsp_bus_reset(data);
1033 if(data->CurrentSC != NULL) {
1034 tmpSC = data->CurrentSC;
1035 tmpSC->result = (DID_RESET << 16) |
1036 ((tmpSC->SCp.Message & 0xff) << 8) |
1037 ((tmpSC->SCp.Status & 0xff) << 0);
1038 nsp_scsi_done(tmpSC);
1040 return IRQ_HANDLED;
1043 if (data->CurrentSC == NULL) {
1044 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);
1045 nsphw_init(data);
1046 nsp_bus_reset(data);
1047 return IRQ_HANDLED;
1050 tmpSC = data->CurrentSC;
1051 target = tmpSC->device->id;
1052 lun = tmpSC->device->lun;
1053 sync_neg = &(data->Sync[target].SyncNegotiation);
1056 * parse hardware SCSI irq reasons register
1058 if (irq_status & IRQSTATUS_SCSI) {
1059 if (irq_phase & RESELECT_IRQ) {
1060 nsp_dbg(NSP_DEBUG_INTR, "reselect");
1061 nsp_write(base, IRQCONTROL, IRQCONTROL_RESELECT_CLEAR);
1062 if (nsp_reselected(tmpSC) != FALSE) {
1063 return IRQ_HANDLED;
1067 if ((irq_phase & (PHASE_CHANGE_IRQ | LATCHED_BUS_FREE)) == 0) {
1068 return IRQ_HANDLED;
1072 //show_phase(tmpSC);
1074 switch(tmpSC->SCp.phase) {
1075 case PH_SELSTART:
1076 // *sync_neg = SYNC_NOT_YET;
1077 if ((phase & BUSMON_BSY) == 0) {
1078 //nsp_dbg(NSP_DEBUG_INTR, "selection count=%d", data->SelectionTimeOut);
1079 if (data->SelectionTimeOut >= NSP_SELTIMEOUT) {
1080 nsp_dbg(NSP_DEBUG_INTR, "selection time out");
1081 data->SelectionTimeOut = 0;
1082 nsp_index_write(base, SCSIBUSCTRL, 0);
1084 tmpSC->result = DID_TIME_OUT << 16;
1085 nsp_scsi_done(tmpSC);
1087 return IRQ_HANDLED;
1089 data->SelectionTimeOut += 1;
1090 nsp_start_timer(tmpSC, 1000/51);
1091 return IRQ_HANDLED;
1094 /* attention assert */
1095 //nsp_dbg(NSP_DEBUG_INTR, "attention assert");
1096 data->SelectionTimeOut = 0;
1097 tmpSC->SCp.phase = PH_SELECTED;
1098 nsp_index_write(base, SCSIBUSCTRL, SCSI_ATN);
1099 udelay(1);
1100 nsp_index_write(base, SCSIBUSCTRL, SCSI_ATN | AUTODIRECTION | ACKENB);
1101 return IRQ_HANDLED;
1103 break;
1105 case PH_RESELECT:
1106 //nsp_dbg(NSP_DEBUG_INTR, "phase reselect");
1107 // *sync_neg = SYNC_NOT_YET;
1108 if ((phase & BUSMON_PHASE_MASK) != BUSPHASE_MESSAGE_IN) {
1110 tmpSC->result = DID_ABORT << 16;
1111 nsp_scsi_done(tmpSC);
1112 return IRQ_HANDLED;
1114 /* fall thru */
1115 default:
1116 if ((irq_status & (IRQSTATUS_SCSI | IRQSTATUS_FIFO)) == 0) {
1117 return IRQ_HANDLED;
1119 break;
1123 * SCSI sequencer
1125 //nsp_dbg(NSP_DEBUG_INTR, "start scsi seq");
1127 /* normal disconnect */
1128 if (((tmpSC->SCp.phase == PH_MSG_IN) || (tmpSC->SCp.phase == PH_MSG_OUT)) &&
1129 (irq_phase & LATCHED_BUS_FREE) != 0 ) {
1130 nsp_dbg(NSP_DEBUG_INTR, "normal disconnect irq_status=0x%x, phase=0x%x, irq_phase=0x%x", irq_status, phase, irq_phase);
1132 //*sync_neg = SYNC_NOT_YET;
1134 if ((tmpSC->SCp.Message == MSG_COMMAND_COMPLETE)) { /* all command complete and return status */
1135 tmpSC->result = (DID_OK << 16) |
1136 ((tmpSC->SCp.Message & 0xff) << 8) |
1137 ((tmpSC->SCp.Status & 0xff) << 0);
1138 nsp_dbg(NSP_DEBUG_INTR, "command complete result=0x%x", tmpSC->result);
1139 nsp_scsi_done(tmpSC);
1141 return IRQ_HANDLED;
1144 return IRQ_HANDLED;
1148 /* check unexpected bus free state */
1149 if (phase == 0) {
1150 nsp_msg(KERN_DEBUG, "unexpected bus free. irq_status=0x%x, phase=0x%x, irq_phase=0x%x", irq_status, phase, irq_phase);
1152 *sync_neg = SYNC_NG;
1153 tmpSC->result = DID_ERROR << 16;
1154 nsp_scsi_done(tmpSC);
1155 return IRQ_HANDLED;
1158 switch (phase & BUSMON_PHASE_MASK) {
1159 case BUSPHASE_COMMAND:
1160 nsp_dbg(NSP_DEBUG_INTR, "BUSPHASE_COMMAND");
1161 if ((phase & BUSMON_REQ) == 0) {
1162 nsp_dbg(NSP_DEBUG_INTR, "REQ == 0");
1163 return IRQ_HANDLED;
1166 tmpSC->SCp.phase = PH_COMMAND;
1168 nsp_nexus(tmpSC);
1170 /* write scsi command */
1171 nsp_dbg(NSP_DEBUG_INTR, "cmd_len=%d", tmpSC->cmd_len);
1172 nsp_index_write(base, COMMANDCTRL, CLEAR_COMMAND_POINTER);
1173 for (i = 0; i < tmpSC->cmd_len; i++) {
1174 nsp_index_write(base, COMMANDDATA, tmpSC->cmnd[i]);
1176 nsp_index_write(base, COMMANDCTRL, CLEAR_COMMAND_POINTER | AUTO_COMMAND_GO);
1177 break;
1179 case BUSPHASE_DATA_OUT:
1180 nsp_dbg(NSP_DEBUG_INTR, "BUSPHASE_DATA_OUT");
1182 tmpSC->SCp.phase = PH_DATA;
1183 tmpSC->SCp.have_data_in = IO_OUT;
1185 nsp_pio_write(tmpSC);
1187 break;
1189 case BUSPHASE_DATA_IN:
1190 nsp_dbg(NSP_DEBUG_INTR, "BUSPHASE_DATA_IN");
1192 tmpSC->SCp.phase = PH_DATA;
1193 tmpSC->SCp.have_data_in = IO_IN;
1195 nsp_pio_read(tmpSC);
1197 break;
1199 case BUSPHASE_STATUS:
1200 nsp_dataphase_bypass(tmpSC);
1201 nsp_dbg(NSP_DEBUG_INTR, "BUSPHASE_STATUS");
1203 tmpSC->SCp.phase = PH_STATUS;
1205 tmpSC->SCp.Status = nsp_index_read(base, SCSIDATAWITHACK);
1206 nsp_dbg(NSP_DEBUG_INTR, "message=0x%x status=0x%x", tmpSC->SCp.Message, tmpSC->SCp.Status);
1208 break;
1210 case BUSPHASE_MESSAGE_OUT:
1211 nsp_dbg(NSP_DEBUG_INTR, "BUSPHASE_MESSAGE_OUT");
1212 if ((phase & BUSMON_REQ) == 0) {
1213 goto timer_out;
1216 tmpSC->SCp.phase = PH_MSG_OUT;
1218 //*sync_neg = SYNC_NOT_YET;
1220 data->MsgLen = i = 0;
1221 data->MsgBuffer[i] = IDENTIFY(TRUE, lun); i++;
1223 if (*sync_neg == SYNC_NOT_YET) {
1224 data->Sync[target].SyncPeriod = 0;
1225 data->Sync[target].SyncOffset = 0;
1227 /**/
1228 data->MsgBuffer[i] = MSG_EXTENDED; i++;
1229 data->MsgBuffer[i] = 3; i++;
1230 data->MsgBuffer[i] = MSG_EXT_SDTR; i++;
1231 data->MsgBuffer[i] = 0x0c; i++;
1232 data->MsgBuffer[i] = 15; i++;
1233 /**/
1235 data->MsgLen = i;
1237 nsp_analyze_sdtr(tmpSC);
1238 show_message(data);
1239 nsp_message_out(tmpSC);
1240 break;
1242 case BUSPHASE_MESSAGE_IN:
1243 nsp_dataphase_bypass(tmpSC);
1244 nsp_dbg(NSP_DEBUG_INTR, "BUSPHASE_MESSAGE_IN");
1245 if ((phase & BUSMON_REQ) == 0) {
1246 goto timer_out;
1249 tmpSC->SCp.phase = PH_MSG_IN;
1250 nsp_message_in(tmpSC);
1252 /**/
1253 if (*sync_neg == SYNC_NOT_YET) {
1254 //nsp_dbg(NSP_DEBUG_INTR, "sync target=%d,lun=%d",target,lun);
1256 if (data->MsgLen >= 5 &&
1257 data->MsgBuffer[0] == MSG_EXTENDED &&
1258 data->MsgBuffer[1] == 3 &&
1259 data->MsgBuffer[2] == MSG_EXT_SDTR ) {
1260 data->Sync[target].SyncPeriod = data->MsgBuffer[3];
1261 data->Sync[target].SyncOffset = data->MsgBuffer[4];
1262 //nsp_dbg(NSP_DEBUG_INTR, "sync ok, %d %d", data->MsgBuffer[3], data->MsgBuffer[4]);
1263 *sync_neg = SYNC_OK;
1264 } else {
1265 data->Sync[target].SyncPeriod = 0;
1266 data->Sync[target].SyncOffset = 0;
1267 *sync_neg = SYNC_NG;
1269 nsp_analyze_sdtr(tmpSC);
1271 /**/
1273 /* search last messeage byte */
1274 tmp = -1;
1275 for (i = 0; i < data->MsgLen; i++) {
1276 tmp = data->MsgBuffer[i];
1277 if (data->MsgBuffer[i] == MSG_EXTENDED) {
1278 i += (1 + data->MsgBuffer[i+1]);
1281 tmpSC->SCp.Message = tmp;
1283 nsp_dbg(NSP_DEBUG_INTR, "message=0x%x len=%d", tmpSC->SCp.Message, data->MsgLen);
1284 show_message(data);
1286 break;
1288 case BUSPHASE_SELECT:
1289 default:
1290 nsp_dbg(NSP_DEBUG_INTR, "BUSPHASE other");
1292 break;
1295 //nsp_dbg(NSP_DEBUG_INTR, "out");
1296 return IRQ_HANDLED;
1298 timer_out:
1299 nsp_start_timer(tmpSC, 1000/102);
1300 return IRQ_HANDLED;
1303 #ifdef NSP_DEBUG
1304 #include "nsp_debug.c"
1305 #endif /* NSP_DEBUG */
1307 /*----------------------------------------------------------------*/
1308 /* look for ninja3 card and init if found */
1309 /*----------------------------------------------------------------*/
1310 static struct Scsi_Host *nsp_detect(struct scsi_host_template *sht)
1312 struct Scsi_Host *host; /* registered host structure */
1313 nsp_hw_data *data_b = &nsp_data_base, *data;
1315 nsp_dbg(NSP_DEBUG_INIT, "this_id=%d", sht->this_id);
1316 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,73))
1317 host = scsi_host_alloc(&nsp_driver_template, sizeof(nsp_hw_data));
1318 #else
1319 host = scsi_register(sht, sizeof(nsp_hw_data));
1320 #endif
1321 if (host == NULL) {
1322 nsp_dbg(NSP_DEBUG_INIT, "host failed");
1323 return NULL;
1326 memcpy(host->hostdata, data_b, sizeof(nsp_hw_data));
1327 data = (nsp_hw_data *)host->hostdata;
1328 data->ScsiInfo->host = host;
1329 #ifdef NSP_DEBUG
1330 data->CmdId = 0;
1331 #endif
1333 nsp_dbg(NSP_DEBUG_INIT, "irq=%d,%d", data_b->IrqNumber, ((nsp_hw_data *)host->hostdata)->IrqNumber);
1335 host->unique_id = data->BaseAddress;
1336 host->io_port = data->BaseAddress;
1337 host->n_io_port = data->NumAddress;
1338 host->irq = data->IrqNumber;
1339 host->base = data->MmioAddress;
1341 spin_lock_init(&(data->Lock));
1343 snprintf(data->nspinfo,
1344 sizeof(data->nspinfo),
1345 "NinjaSCSI-3/32Bi Driver $Revision: 1.23 $ IO:0x%04lx-0x%04lx MMIO(virt addr):0x%04lx IRQ:%02d",
1346 host->io_port, host->io_port + host->n_io_port - 1,
1347 host->base,
1348 host->irq);
1349 sht->name = data->nspinfo;
1351 nsp_dbg(NSP_DEBUG_INIT, "end");
1354 return host; /* detect done. */
1357 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
1358 static int nsp_detect_old(struct scsi_host_template *sht)
1360 if (nsp_detect(sht) == NULL) {
1361 return 0;
1362 } else {
1363 //MOD_INC_USE_COUNT;
1364 return 1;
1369 static int nsp_release_old(struct Scsi_Host *shpnt)
1371 //nsp_hw_data *data = (nsp_hw_data *)shpnt->hostdata;
1373 /* PCMCIA Card Service dose same things below. */
1374 /* So we do nothing. */
1375 //if (shpnt->irq) {
1376 // free_irq(shpnt->irq, data->ScsiInfo);
1378 //if (shpnt->io_port) {
1379 // release_region(shpnt->io_port, shpnt->n_io_port);
1382 //MOD_DEC_USE_COUNT;
1384 return 0;
1386 #endif
1388 /*----------------------------------------------------------------*/
1389 /* return info string */
1390 /*----------------------------------------------------------------*/
1391 static const char *nsp_info(struct Scsi_Host *shpnt)
1393 nsp_hw_data *data = (nsp_hw_data *)shpnt->hostdata;
1395 return data->nspinfo;
1398 #undef SPRINTF
1399 #define SPRINTF(args...) \
1400 do { \
1401 if(length > (pos - buffer)) { \
1402 pos += snprintf(pos, length - (pos - buffer) + 1, ## args); \
1403 nsp_dbg(NSP_DEBUG_PROC, "buffer=0x%p pos=0x%p length=%d %d\n", buffer, pos, length, length - (pos - buffer));\
1405 } while(0)
1406 static int
1407 nsp_proc_info(
1408 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,73))
1409 struct Scsi_Host *host,
1410 #endif
1411 char *buffer,
1412 char **start,
1413 off_t offset,
1414 int length,
1415 #if !(LINUX_VERSION_CODE > KERNEL_VERSION(2,5,73))
1416 int hostno,
1417 #endif
1418 int inout)
1420 int id;
1421 char *pos = buffer;
1422 int thislength;
1423 int speed;
1424 unsigned long flags;
1425 nsp_hw_data *data;
1426 #if !(LINUX_VERSION_CODE > KERNEL_VERSION(2,5,73))
1427 struct Scsi_Host *host;
1428 #else
1429 int hostno;
1430 #endif
1431 if (inout) {
1432 return -EINVAL;
1435 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,73))
1436 hostno = host->host_no;
1437 #else
1438 /* search this HBA host */
1439 host = scsi_host_hn_get(hostno);
1440 if (host == NULL) {
1441 return -ESRCH;
1443 #endif
1444 data = (nsp_hw_data *)host->hostdata;
1447 SPRINTF("NinjaSCSI status\n\n");
1448 SPRINTF("Driver version: $Revision: 1.23 $\n");
1449 SPRINTF("SCSI host No.: %d\n", hostno);
1450 SPRINTF("IRQ: %d\n", host->irq);
1451 SPRINTF("IO: 0x%lx-0x%lx\n", host->io_port, host->io_port + host->n_io_port - 1);
1452 SPRINTF("MMIO(virtual address): 0x%lx-0x%lx\n", host->base, host->base + data->MmioLength - 1);
1453 SPRINTF("sg_tablesize: %d\n", host->sg_tablesize);
1455 SPRINTF("burst transfer mode: ");
1456 switch (nsp_burst_mode) {
1457 case BURST_IO8:
1458 SPRINTF("io8");
1459 break;
1460 case BURST_IO32:
1461 SPRINTF("io32");
1462 break;
1463 case BURST_MEM32:
1464 SPRINTF("mem32");
1465 break;
1466 default:
1467 SPRINTF("???");
1468 break;
1470 SPRINTF("\n");
1473 spin_lock_irqsave(&(data->Lock), flags);
1474 SPRINTF("CurrentSC: 0x%p\n\n", data->CurrentSC);
1475 spin_unlock_irqrestore(&(data->Lock), flags);
1477 SPRINTF("SDTR status\n");
1478 for(id = 0; id < ARRAY_SIZE(data->Sync); id++) {
1480 SPRINTF("id %d: ", id);
1482 if (id == host->this_id) {
1483 SPRINTF("----- NinjaSCSI-3 host adapter\n");
1484 continue;
1487 switch(data->Sync[id].SyncNegotiation) {
1488 case SYNC_OK:
1489 SPRINTF(" sync");
1490 break;
1491 case SYNC_NG:
1492 SPRINTF("async");
1493 break;
1494 case SYNC_NOT_YET:
1495 SPRINTF(" none");
1496 break;
1497 default:
1498 SPRINTF("?????");
1499 break;
1502 if (data->Sync[id].SyncPeriod != 0) {
1503 speed = 1000000 / (data->Sync[id].SyncPeriod * 4);
1505 SPRINTF(" transfer %d.%dMB/s, offset %d",
1506 speed / 1000,
1507 speed % 1000,
1508 data->Sync[id].SyncOffset
1511 SPRINTF("\n");
1514 thislength = pos - (buffer + offset);
1516 if(thislength < 0) {
1517 *start = NULL;
1518 return 0;
1522 thislength = min(thislength, length);
1523 *start = buffer + offset;
1525 return thislength;
1527 #undef SPRINTF
1529 /*---------------------------------------------------------------*/
1530 /* error handler */
1531 /*---------------------------------------------------------------*/
1534 static int nsp_eh_abort(struct scsi_cmnd *SCpnt)
1536 nsp_dbg(NSP_DEBUG_BUSRESET, "SCpnt=0x%p", SCpnt);
1538 return nsp_eh_bus_reset(SCpnt);
1541 static int nsp_bus_reset(nsp_hw_data *data)
1543 unsigned int base = data->BaseAddress;
1544 int i;
1546 nsp_write(base, IRQCONTROL, IRQCONTROL_ALLMASK);
1548 nsp_index_write(base, SCSIBUSCTRL, SCSI_RST);
1549 mdelay(100); /* 100ms */
1550 nsp_index_write(base, SCSIBUSCTRL, 0);
1551 for(i = 0; i < 5; i++) {
1552 nsp_index_read(base, IRQPHASESENCE); /* dummy read */
1555 nsphw_init_sync(data);
1557 nsp_write(base, IRQCONTROL, IRQCONTROL_ALLCLEAR);
1559 return SUCCESS;
1562 static int nsp_eh_bus_reset(struct scsi_cmnd *SCpnt)
1564 nsp_hw_data *data = (nsp_hw_data *)SCpnt->device->host->hostdata;
1566 nsp_dbg(NSP_DEBUG_BUSRESET, "SCpnt=0x%p", SCpnt);
1568 return nsp_bus_reset(data);
1571 static int nsp_eh_host_reset(struct scsi_cmnd *SCpnt)
1573 nsp_hw_data *data = (nsp_hw_data *)SCpnt->device->host->hostdata;
1575 nsp_dbg(NSP_DEBUG_BUSRESET, "in");
1577 nsphw_init(data);
1579 return SUCCESS;
1583 /**********************************************************************
1584 PCMCIA functions
1585 **********************************************************************/
1587 /*======================================================================
1588 nsp_cs_attach() creates an "instance" of the driver, allocating
1589 local data structures for one device. The device is registered
1590 with Card Services.
1592 The dev_link structure is initialized, but we don't actually
1593 configure the card at this point -- we wait until we receive a
1594 card insertion event.
1595 ======================================================================*/
1596 static int nsp_cs_probe(struct pcmcia_device *link)
1598 scsi_info_t *info;
1599 nsp_hw_data *data = &nsp_data_base;
1600 int ret;
1602 nsp_dbg(NSP_DEBUG_INIT, "in");
1604 /* Create new SCSI device */
1605 info = kmalloc(sizeof(*info), GFP_KERNEL);
1606 if (info == NULL) { return -ENOMEM; }
1607 memset(info, 0, sizeof(*info));
1608 info->p_dev = link;
1609 link->priv = info;
1610 data->ScsiInfo = info;
1612 nsp_dbg(NSP_DEBUG_INIT, "info=0x%p", info);
1614 /* The io structure describes IO port mapping */
1615 link->io.NumPorts1 = 0x10;
1616 link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
1617 link->io.IOAddrLines = 10; /* not used */
1619 /* Interrupt setup */
1620 link->irq.Attributes = IRQ_TYPE_EXCLUSIVE | IRQ_HANDLE_PRESENT;
1621 link->irq.IRQInfo1 = IRQ_LEVEL_ID;
1623 /* Interrupt handler */
1624 link->irq.Handler = &nspintr;
1625 link->irq.Instance = info;
1626 link->irq.Attributes |= IRQF_SHARED;
1628 /* General socket configuration */
1629 link->conf.Attributes = CONF_ENABLE_IRQ;
1630 link->conf.IntType = INT_MEMORY_AND_IO;
1632 ret = nsp_cs_config(link);
1634 nsp_dbg(NSP_DEBUG_INIT, "link=0x%p", link);
1635 return ret;
1636 } /* nsp_cs_attach */
1639 /*======================================================================
1640 This deletes a driver "instance". The device is de-registered
1641 with Card Services. If it has been released, all local data
1642 structures are freed. Otherwise, the structures will be freed
1643 when the device is released.
1644 ======================================================================*/
1645 static void nsp_cs_detach(struct pcmcia_device *link)
1647 nsp_dbg(NSP_DEBUG_INIT, "in, link=0x%p", link);
1649 ((scsi_info_t *)link->priv)->stop = 1;
1650 nsp_cs_release(link);
1652 kfree(link->priv);
1653 link->priv = NULL;
1654 } /* nsp_cs_detach */
1657 /*======================================================================
1658 nsp_cs_config() is scheduled to run after a CARD_INSERTION event
1659 is received, to configure the PCMCIA socket, and to make the
1660 ethernet device available to the system.
1661 ======================================================================*/
1662 #define CS_CHECK(fn, ret) \
1663 do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
1664 /*====================================================================*/
1665 static int nsp_cs_config(struct pcmcia_device *link)
1667 int ret;
1668 scsi_info_t *info = link->priv;
1669 tuple_t tuple;
1670 cisparse_t parse;
1671 int last_ret, last_fn;
1672 unsigned char tuple_data[64];
1673 config_info_t conf;
1674 win_req_t req;
1675 memreq_t map;
1676 cistpl_cftable_entry_t dflt = { 0 };
1677 struct Scsi_Host *host;
1678 nsp_hw_data *data = &nsp_data_base;
1679 #if !(LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,74))
1680 struct scsi_device *dev;
1681 dev_node_t **tail, *node;
1682 #endif
1684 nsp_dbg(NSP_DEBUG_INIT, "in");
1686 tuple.Attributes = 0;
1687 tuple.TupleData = tuple_data;
1688 tuple.TupleDataMax = sizeof(tuple_data);
1689 tuple.TupleOffset = 0;
1691 /* Look up the current Vcc */
1692 CS_CHECK(GetConfigurationInfo, pcmcia_get_configuration_info(link, &conf));
1694 tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
1695 CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple));
1696 while (1) {
1697 cistpl_cftable_entry_t *cfg = &(parse.cftable_entry);
1699 if (pcmcia_get_tuple_data(link, &tuple) != 0 ||
1700 pcmcia_parse_tuple(link, &tuple, &parse) != 0)
1701 goto next_entry;
1703 if (cfg->flags & CISTPL_CFTABLE_DEFAULT) { dflt = *cfg; }
1704 if (cfg->index == 0) { goto next_entry; }
1705 link->conf.ConfigIndex = cfg->index;
1707 /* Does this card need audio output? */
1708 if (cfg->flags & CISTPL_CFTABLE_AUDIO) {
1709 link->conf.Attributes |= CONF_ENABLE_SPKR;
1710 link->conf.Status = CCSR_AUDIO_ENA;
1713 /* Use power settings for Vcc and Vpp if present */
1714 /* Note that the CIS values need to be rescaled */
1715 if (cfg->vcc.present & (1<<CISTPL_POWER_VNOM)) {
1716 if (conf.Vcc != cfg->vcc.param[CISTPL_POWER_VNOM]/10000) {
1717 goto next_entry;
1719 } else if (dflt.vcc.present & (1<<CISTPL_POWER_VNOM)) {
1720 if (conf.Vcc != dflt.vcc.param[CISTPL_POWER_VNOM]/10000) {
1721 goto next_entry;
1725 if (cfg->vpp1.present & (1 << CISTPL_POWER_VNOM)) {
1726 link->conf.Vpp =
1727 cfg->vpp1.param[CISTPL_POWER_VNOM] / 10000;
1728 } else if (dflt.vpp1.present & (1 << CISTPL_POWER_VNOM)) {
1729 link->conf.Vpp =
1730 dflt.vpp1.param[CISTPL_POWER_VNOM] / 10000;
1733 /* Do we need to allocate an interrupt? */
1734 if (cfg->irq.IRQInfo1 || dflt.irq.IRQInfo1) {
1735 link->conf.Attributes |= CONF_ENABLE_IRQ;
1738 /* IO window settings */
1739 link->io.NumPorts1 = link->io.NumPorts2 = 0;
1740 if ((cfg->io.nwin > 0) || (dflt.io.nwin > 0)) {
1741 cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt.io;
1742 link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
1743 if (!(io->flags & CISTPL_IO_8BIT))
1744 link->io.Attributes1 = IO_DATA_PATH_WIDTH_16;
1745 if (!(io->flags & CISTPL_IO_16BIT))
1746 link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
1747 link->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK;
1748 link->io.BasePort1 = io->win[0].base;
1749 link->io.NumPorts1 = io->win[0].len;
1750 if (io->nwin > 1) {
1751 link->io.Attributes2 = link->io.Attributes1;
1752 link->io.BasePort2 = io->win[1].base;
1753 link->io.NumPorts2 = io->win[1].len;
1755 /* This reserves IO space but doesn't actually enable it */
1756 if (pcmcia_request_io(link, &link->io) != 0)
1757 goto next_entry;
1760 if ((cfg->mem.nwin > 0) || (dflt.mem.nwin > 0)) {
1761 cistpl_mem_t *mem =
1762 (cfg->mem.nwin) ? &cfg->mem : &dflt.mem;
1763 req.Attributes = WIN_DATA_WIDTH_16|WIN_MEMORY_TYPE_CM;
1764 req.Attributes |= WIN_ENABLE;
1765 req.Base = mem->win[0].host_addr;
1766 req.Size = mem->win[0].len;
1767 if (req.Size < 0x1000) {
1768 req.Size = 0x1000;
1770 req.AccessSpeed = 0;
1771 if (pcmcia_request_window(&link, &req, &link->win) != 0)
1772 goto next_entry;
1773 map.Page = 0; map.CardOffset = mem->win[0].card_addr;
1774 if (pcmcia_map_mem_page(link->win, &map) != 0)
1775 goto next_entry;
1777 data->MmioAddress = (unsigned long)ioremap_nocache(req.Base, req.Size);
1778 data->MmioLength = req.Size;
1780 /* If we got this far, we're cool! */
1781 break;
1783 next_entry:
1784 nsp_dbg(NSP_DEBUG_INIT, "next");
1785 pcmcia_disable_device(link);
1786 CS_CHECK(GetNextTuple, pcmcia_get_next_tuple(link, &tuple));
1789 if (link->conf.Attributes & CONF_ENABLE_IRQ) {
1790 CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq));
1792 CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link, &link->conf));
1794 if (free_ports) {
1795 if (link->io.BasePort1) {
1796 release_region(link->io.BasePort1, link->io.NumPorts1);
1798 if (link->io.BasePort2) {
1799 release_region(link->io.BasePort2, link->io.NumPorts2);
1803 /* Set port and IRQ */
1804 data->BaseAddress = link->io.BasePort1;
1805 data->NumAddress = link->io.NumPorts1;
1806 data->IrqNumber = link->irq.AssignedIRQ;
1808 nsp_dbg(NSP_DEBUG_INIT, "I/O[0x%x+0x%x] IRQ %d",
1809 data->BaseAddress, data->NumAddress, data->IrqNumber);
1811 if(nsphw_init(data) == FALSE) {
1812 goto cs_failed;
1815 #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,2))
1816 host = nsp_detect(&nsp_driver_template);
1817 #else
1818 scsi_register_host(&nsp_driver_template);
1819 for (host = scsi_host_get_next(NULL); host != NULL;
1820 host = scsi_host_get_next(host)) {
1821 if (host->hostt == &nsp_driver_template) {
1822 break;
1825 #endif
1827 if (host == NULL) {
1828 nsp_dbg(NSP_DEBUG_INIT, "detect failed");
1829 goto cs_failed;
1833 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,74))
1834 ret = scsi_add_host (host, NULL);
1835 if (ret)
1836 goto cs_failed;
1838 scsi_scan_host(host);
1840 snprintf(info->node.dev_name, sizeof(info->node.dev_name), "scsi%d", host->host_no);
1841 link->dev_node = &info->node;
1842 info->host = host;
1844 #else
1845 nsp_dbg(NSP_DEBUG_INIT, "GET_SCSI_INFO");
1846 tail = &link->dev_node;
1847 info->ndev = 0;
1849 nsp_dbg(NSP_DEBUG_INIT, "host=0x%p", host);
1851 for (dev = host->host_queue; dev != NULL; dev = dev->next) {
1852 unsigned long id;
1853 id = (dev->id & 0x0f) + ((dev->lun & 0x0f) << 4) +
1854 ((dev->channel & 0x0f) << 8) +
1855 ((dev->host->host_no & 0x0f) << 12);
1856 node = &info->node[info->ndev];
1857 node->minor = 0;
1858 switch (dev->type) {
1859 case TYPE_TAPE:
1860 node->major = SCSI_TAPE_MAJOR;
1861 snprintf(node->dev_name, sizeof(node->dev_name), "st#%04lx", id);
1862 break;
1863 case TYPE_DISK:
1864 case TYPE_MOD:
1865 node->major = SCSI_DISK0_MAJOR;
1866 snprintf(node->dev_name, sizeof(node->dev_name), "sd#%04lx", id);
1867 break;
1868 case TYPE_ROM:
1869 case TYPE_WORM:
1870 node->major = SCSI_CDROM_MAJOR;
1871 snprintf(node->dev_name, sizeof(node->dev_name), "sr#%04lx", id);
1872 break;
1873 default:
1874 node->major = SCSI_GENERIC_MAJOR;
1875 snprintf(node->dev_name, sizeof(node->dev_name), "sg#%04lx", id);
1876 break;
1878 *tail = node; tail = &node->next;
1879 info->ndev++;
1880 info->host = dev->host;
1883 *tail = NULL;
1884 if (info->ndev == 0) {
1885 nsp_msg(KERN_INFO, "no SCSI devices found");
1887 nsp_dbg(NSP_DEBUG_INIT, "host=0x%p", host);
1888 #endif
1890 /* Finally, report what we've done */
1891 printk(KERN_INFO "nsp_cs: index 0x%02x: ",
1892 link->conf.ConfigIndex);
1893 if (link->conf.Vpp) {
1894 printk(", Vpp %d.%d", link->conf.Vpp/10, link->conf.Vpp%10);
1896 if (link->conf.Attributes & CONF_ENABLE_IRQ) {
1897 printk(", irq %d", link->irq.AssignedIRQ);
1899 if (link->io.NumPorts1) {
1900 printk(", io 0x%04x-0x%04x", link->io.BasePort1,
1901 link->io.BasePort1+link->io.NumPorts1-1);
1903 if (link->io.NumPorts2)
1904 printk(" & 0x%04x-0x%04x", link->io.BasePort2,
1905 link->io.BasePort2+link->io.NumPorts2-1);
1906 if (link->win)
1907 printk(", mem 0x%06lx-0x%06lx", req.Base,
1908 req.Base+req.Size-1);
1909 printk("\n");
1911 return 0;
1913 cs_failed:
1914 nsp_dbg(NSP_DEBUG_INIT, "config fail");
1915 cs_error(link, last_fn, last_ret);
1916 nsp_cs_release(link);
1918 return -ENODEV;
1919 } /* nsp_cs_config */
1920 #undef CS_CHECK
1923 /*======================================================================
1924 After a card is removed, nsp_cs_release() will unregister the net
1925 device, and release the PCMCIA configuration. If the device is
1926 still open, this will be postponed until it is closed.
1927 ======================================================================*/
1928 static void nsp_cs_release(struct pcmcia_device *link)
1930 scsi_info_t *info = link->priv;
1931 nsp_hw_data *data = NULL;
1933 if (info->host == NULL) {
1934 nsp_msg(KERN_DEBUG, "unexpected card release call.");
1935 } else {
1936 data = (nsp_hw_data *)info->host->hostdata;
1939 nsp_dbg(NSP_DEBUG_INIT, "link=0x%p", link);
1941 /* Unlink the device chain */
1942 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,2))
1943 if (info->host != NULL) {
1944 scsi_remove_host(info->host);
1946 #else
1947 scsi_unregister_host(&nsp_driver_template);
1948 #endif
1949 link->dev_node = NULL;
1951 if (link->win) {
1952 if (data != NULL) {
1953 iounmap((void *)(data->MmioAddress));
1956 pcmcia_disable_device(link);
1958 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,2))
1959 if (info->host != NULL) {
1960 scsi_host_put(info->host);
1962 #endif
1963 } /* nsp_cs_release */
1965 static int nsp_cs_suspend(struct pcmcia_device *link)
1967 scsi_info_t *info = link->priv;
1968 nsp_hw_data *data;
1970 nsp_dbg(NSP_DEBUG_INIT, "event: suspend");
1972 if (info->host != NULL) {
1973 nsp_msg(KERN_INFO, "clear SDTR status");
1975 data = (nsp_hw_data *)info->host->hostdata;
1977 nsphw_init_sync(data);
1980 info->stop = 1;
1982 return 0;
1985 static int nsp_cs_resume(struct pcmcia_device *link)
1987 scsi_info_t *info = link->priv;
1988 nsp_hw_data *data;
1990 nsp_dbg(NSP_DEBUG_INIT, "event: resume");
1992 info->stop = 0;
1994 if (info->host != NULL) {
1995 nsp_msg(KERN_INFO, "reset host and bus");
1997 data = (nsp_hw_data *)info->host->hostdata;
1999 nsphw_init (data);
2000 nsp_bus_reset(data);
2003 return 0;
2006 /*======================================================================*
2007 * module entry point
2008 *====================================================================*/
2009 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,68))
2010 static struct pcmcia_device_id nsp_cs_ids[] = {
2011 PCMCIA_DEVICE_PROD_ID123("IO DATA", "CBSC16 ", "1", 0x547e66dc, 0x0d63a3fd, 0x51de003a),
2012 PCMCIA_DEVICE_PROD_ID123("KME ", "SCSI-CARD-001", "1", 0x534c02bc, 0x52008408, 0x51de003a),
2013 PCMCIA_DEVICE_PROD_ID123("KME ", "SCSI-CARD-002", "1", 0x534c02bc, 0xcb09d5b2, 0x51de003a),
2014 PCMCIA_DEVICE_PROD_ID123("KME ", "SCSI-CARD-003", "1", 0x534c02bc, 0xbc0ee524, 0x51de003a),
2015 PCMCIA_DEVICE_PROD_ID123("KME ", "SCSI-CARD-004", "1", 0x534c02bc, 0x226a7087, 0x51de003a),
2016 PCMCIA_DEVICE_PROD_ID123("WBT", "NinjaSCSI-3", "R1.0", 0xc7ba805f, 0xfdc7c97d, 0x6973710e),
2017 PCMCIA_DEVICE_PROD_ID123("WORKBIT", "UltraNinja-16", "1", 0x28191418, 0xb70f4b09, 0x51de003a),
2018 PCMCIA_DEVICE_NULL
2020 MODULE_DEVICE_TABLE(pcmcia, nsp_cs_ids);
2022 static struct pcmcia_driver nsp_driver = {
2023 .owner = THIS_MODULE,
2024 .drv = {
2025 .name = "nsp_cs",
2027 .probe = nsp_cs_probe,
2028 .remove = nsp_cs_detach,
2029 .id_table = nsp_cs_ids,
2030 .suspend = nsp_cs_suspend,
2031 .resume = nsp_cs_resume,
2033 #endif
2035 static int __init nsp_cs_init(void)
2037 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,68))
2038 nsp_msg(KERN_INFO, "loading...");
2040 return pcmcia_register_driver(&nsp_driver);
2041 #else
2042 servinfo_t serv;
2044 nsp_msg(KERN_INFO, "loading...");
2045 pcmcia_get_card_services_info(&serv);
2046 if (serv.Revision != CS_RELEASE_CODE) {
2047 nsp_msg(KERN_DEBUG, "Card Services release does not match!");
2048 return -EINVAL;
2050 register_pcmcia_driver(&dev_info, &nsp_cs_attach, &nsp_cs_detach);
2052 nsp_dbg(NSP_DEBUG_INIT, "out");
2053 return 0;
2054 #endif
2057 static void __exit nsp_cs_exit(void)
2059 nsp_msg(KERN_INFO, "unloading...");
2060 pcmcia_unregister_driver(&nsp_driver);
2064 module_init(nsp_cs_init)
2065 module_exit(nsp_cs_exit)
2067 /* end */