mic: vop: Fix use-after-free on remove
[linux/fpc-iii.git] / drivers / scsi / pcmcia / nsp_cs.c
blob1bd6825a4f142680feb0f2d6e2dbeb84fc85feb5
1 /*======================================================================
3 NinjaSCSI-3 / NinjaSCSI-32Bi PCMCIA SCSI host adapter card driver
4 By: YOKOTA Hiroshi <yokota@netlab.is.tsukuba.ac.jp>
6 Ver.2.8 Support 32bit MMIO mode
7 Support Synchronous Data Transfer Request (SDTR) mode
8 Ver.2.0 Support 32bit PIO mode
9 Ver.1.1.2 Fix for scatter list buffer exceeds
10 Ver.1.1 Support scatter list
11 Ver.0.1 Initial version
13 This software may be used and distributed according to the terms of
14 the GNU General Public License.
16 ======================================================================*/
18 /***********************************************************************
19 This driver is for these PCcards.
21 I-O DATA PCSC-F (Workbit NinjaSCSI-3)
22 "WBT", "NinjaSCSI-3", "R1.0"
23 I-O DATA CBSC-II (Workbit NinjaSCSI-32Bi in 16bit mode)
24 "IO DATA", "CBSC16 ", "1"
26 ***********************************************************************/
28 #include <linux/module.h>
29 #include <linux/kernel.h>
30 #include <linux/init.h>
31 #include <linux/slab.h>
32 #include <linux/string.h>
33 #include <linux/timer.h>
34 #include <linux/ioport.h>
35 #include <linux/delay.h>
36 #include <linux/interrupt.h>
37 #include <linux/major.h>
38 #include <linux/blkdev.h>
39 #include <linux/stat.h>
41 #include <asm/io.h>
42 #include <asm/irq.h>
44 #include <../drivers/scsi/scsi.h>
45 #include <scsi/scsi_host.h>
47 #include <scsi/scsi.h>
48 #include <scsi/scsi_ioctl.h>
50 #include <pcmcia/cistpl.h>
51 #include <pcmcia/cisreg.h>
52 #include <pcmcia/ds.h>
54 #include "nsp_cs.h"
56 MODULE_AUTHOR("YOKOTA Hiroshi <yokota@netlab.is.tsukuba.ac.jp>");
57 MODULE_DESCRIPTION("WorkBit NinjaSCSI-3 / NinjaSCSI-32Bi(16bit) PCMCIA SCSI host adapter module");
58 MODULE_SUPPORTED_DEVICE("sd,sr,sg,st");
59 #ifdef MODULE_LICENSE
60 MODULE_LICENSE("GPL");
61 #endif
63 #include "nsp_io.h"
65 /*====================================================================*/
66 /* Parameters that can be set with 'insmod' */
68 static int nsp_burst_mode = BURST_MEM32;
69 module_param(nsp_burst_mode, int, 0);
70 MODULE_PARM_DESC(nsp_burst_mode, "Burst transfer mode (0=io8, 1=io32, 2=mem32(default))");
72 /* Release IO ports after configuration? */
73 static bool free_ports = 0;
74 module_param(free_ports, bool, 0);
75 MODULE_PARM_DESC(free_ports, "Release IO ports after configuration? (default: 0 (=no))");
77 static struct scsi_host_template nsp_driver_template = {
78 .proc_name = "nsp_cs",
79 .show_info = nsp_show_info,
80 .name = "WorkBit NinjaSCSI-3/32Bi(16bit)",
81 .info = nsp_info,
82 .queuecommand = nsp_queuecommand,
83 /* .eh_abort_handler = nsp_eh_abort,*/
84 .eh_bus_reset_handler = nsp_eh_bus_reset,
85 .eh_host_reset_handler = nsp_eh_host_reset,
86 .can_queue = 1,
87 .this_id = NSP_INITIATOR_ID,
88 .sg_tablesize = SG_ALL,
89 .dma_boundary = PAGE_SIZE - 1,
92 static nsp_hw_data nsp_data_base; /* attach <-> detect glue */
97 * debug, error print
99 #ifndef NSP_DEBUG
100 # define NSP_DEBUG_MASK 0x000000
101 # define nsp_msg(type, args...) nsp_cs_message("", 0, (type), args)
102 # define nsp_dbg(mask, args...) /* */
103 #else
104 # define NSP_DEBUG_MASK 0xffffff
105 # define nsp_msg(type, args...) \
106 nsp_cs_message (__func__, __LINE__, (type), args)
107 # define nsp_dbg(mask, args...) \
108 nsp_cs_dmessage(__func__, __LINE__, (mask), args)
109 #endif
111 #define NSP_DEBUG_QUEUECOMMAND BIT(0)
112 #define NSP_DEBUG_REGISTER BIT(1)
113 #define NSP_DEBUG_AUTOSCSI BIT(2)
114 #define NSP_DEBUG_INTR BIT(3)
115 #define NSP_DEBUG_SGLIST BIT(4)
116 #define NSP_DEBUG_BUSFREE BIT(5)
117 #define NSP_DEBUG_CDB_CONTENTS BIT(6)
118 #define NSP_DEBUG_RESELECTION BIT(7)
119 #define NSP_DEBUG_MSGINOCCUR BIT(8)
120 #define NSP_DEBUG_EEPROM BIT(9)
121 #define NSP_DEBUG_MSGOUTOCCUR BIT(10)
122 #define NSP_DEBUG_BUSRESET BIT(11)
123 #define NSP_DEBUG_RESTART BIT(12)
124 #define NSP_DEBUG_SYNC BIT(13)
125 #define NSP_DEBUG_WAIT BIT(14)
126 #define NSP_DEBUG_TARGETFLAG BIT(15)
127 #define NSP_DEBUG_PROC BIT(16)
128 #define NSP_DEBUG_INIT BIT(17)
129 #define NSP_DEBUG_DATA_IO BIT(18)
130 #define NSP_SPECIAL_PRINT_REGISTER BIT(20)
132 #define NSP_DEBUG_BUF_LEN 150
134 static inline void nsp_inc_resid(struct scsi_cmnd *SCpnt, int residInc)
136 scsi_set_resid(SCpnt, scsi_get_resid(SCpnt) + residInc);
139 static void nsp_cs_message(const char *func, int line, char *type, char *fmt, ...)
141 va_list args;
142 char buf[NSP_DEBUG_BUF_LEN];
144 va_start(args, fmt);
145 vsnprintf(buf, sizeof(buf), fmt, args);
146 va_end(args);
148 #ifndef NSP_DEBUG
149 printk("%snsp_cs: %s\n", type, buf);
150 #else
151 printk("%snsp_cs: %s (%d): %s\n", type, func, line, buf);
152 #endif
155 #ifdef NSP_DEBUG
156 static void nsp_cs_dmessage(const char *func, int line, int mask, char *fmt, ...)
158 va_list args;
159 char buf[NSP_DEBUG_BUF_LEN];
161 va_start(args, fmt);
162 vsnprintf(buf, sizeof(buf), fmt, args);
163 va_end(args);
165 if (mask & NSP_DEBUG_MASK) {
166 printk("nsp_cs-debug: 0x%x %s (%d): %s\n", mask, func, line, buf);
169 #endif
171 /***********************************************************/
173 /*====================================================
174 * Clenaup parameters and call done() functions.
175 * You must be set SCpnt->result before call this function.
177 static void nsp_scsi_done(struct scsi_cmnd *SCpnt)
179 nsp_hw_data *data = (nsp_hw_data *)SCpnt->device->host->hostdata;
181 data->CurrentSC = NULL;
183 SCpnt->scsi_done(SCpnt);
186 static int nsp_queuecommand_lck(struct scsi_cmnd *SCpnt,
187 void (*done)(struct scsi_cmnd *))
189 #ifdef NSP_DEBUG
190 /*unsigned int host_id = SCpnt->device->host->this_id;*/
191 /*unsigned int base = SCpnt->device->host->io_port;*/
192 unsigned char target = scmd_id(SCpnt);
193 #endif
194 nsp_hw_data *data = (nsp_hw_data *)SCpnt->device->host->hostdata;
196 nsp_dbg(NSP_DEBUG_QUEUECOMMAND,
197 "SCpnt=0x%p target=%d lun=%llu sglist=0x%p bufflen=%d sg_count=%d",
198 SCpnt, target, SCpnt->device->lun, scsi_sglist(SCpnt),
199 scsi_bufflen(SCpnt), scsi_sg_count(SCpnt));
200 //nsp_dbg(NSP_DEBUG_QUEUECOMMAND, "before CurrentSC=0x%p", data->CurrentSC);
202 SCpnt->scsi_done = done;
204 if (data->CurrentSC != NULL) {
205 nsp_msg(KERN_DEBUG, "CurrentSC!=NULL this can't be happen");
206 SCpnt->result = DID_BAD_TARGET << 16;
207 nsp_scsi_done(SCpnt);
208 return 0;
211 #if 0
212 /* XXX: pcmcia-cs generates SCSI command with "scsi_info" utility.
213 This makes kernel crash when suspending... */
214 if (data->ScsiInfo->stop != 0) {
215 nsp_msg(KERN_INFO, "suspending device. reject command.");
216 SCpnt->result = DID_BAD_TARGET << 16;
217 nsp_scsi_done(SCpnt);
218 return SCSI_MLQUEUE_HOST_BUSY;
220 #endif
222 show_command(SCpnt);
224 data->CurrentSC = SCpnt;
226 SCpnt->SCp.Status = CHECK_CONDITION;
227 SCpnt->SCp.Message = 0;
228 SCpnt->SCp.have_data_in = IO_UNKNOWN;
229 SCpnt->SCp.sent_command = 0;
230 SCpnt->SCp.phase = PH_UNDETERMINED;
231 scsi_set_resid(SCpnt, scsi_bufflen(SCpnt));
233 /* setup scratch area
234 SCp.ptr : buffer pointer
235 SCp.this_residual : buffer length
236 SCp.buffer : next buffer
237 SCp.buffers_residual : left buffers in list
238 SCp.phase : current state of the command */
239 if (scsi_bufflen(SCpnt)) {
240 SCpnt->SCp.buffer = scsi_sglist(SCpnt);
241 SCpnt->SCp.ptr = BUFFER_ADDR;
242 SCpnt->SCp.this_residual = SCpnt->SCp.buffer->length;
243 SCpnt->SCp.buffers_residual = scsi_sg_count(SCpnt) - 1;
244 } else {
245 SCpnt->SCp.ptr = NULL;
246 SCpnt->SCp.this_residual = 0;
247 SCpnt->SCp.buffer = NULL;
248 SCpnt->SCp.buffers_residual = 0;
251 if (nsphw_start_selection(SCpnt) == FALSE) {
252 nsp_dbg(NSP_DEBUG_QUEUECOMMAND, "selection fail");
253 SCpnt->result = DID_BUS_BUSY << 16;
254 nsp_scsi_done(SCpnt);
255 return 0;
259 //nsp_dbg(NSP_DEBUG_QUEUECOMMAND, "out");
260 #ifdef NSP_DEBUG
261 data->CmdId++;
262 #endif
263 return 0;
266 static DEF_SCSI_QCMD(nsp_queuecommand)
269 * setup PIO FIFO transfer mode and enable/disable to data out
271 static void nsp_setup_fifo(nsp_hw_data *data, int enabled)
273 unsigned int base = data->BaseAddress;
274 unsigned char transfer_mode_reg;
276 //nsp_dbg(NSP_DEBUG_DATA_IO, "enabled=%d", enabled);
278 if (enabled != FALSE) {
279 transfer_mode_reg = TRANSFER_GO | BRAIND;
280 } else {
281 transfer_mode_reg = 0;
284 transfer_mode_reg |= data->TransferMode;
286 nsp_index_write(base, TRANSFERMODE, transfer_mode_reg);
289 static void nsphw_init_sync(nsp_hw_data *data)
291 sync_data tmp_sync = { .SyncNegotiation = SYNC_NOT_YET,
292 .SyncPeriod = 0,
293 .SyncOffset = 0
295 int i;
297 /* setup sync data */
298 for ( i = 0; i < ARRAY_SIZE(data->Sync); i++ ) {
299 data->Sync[i] = tmp_sync;
304 * Initialize Ninja hardware
306 static int nsphw_init(nsp_hw_data *data)
308 unsigned int base = data->BaseAddress;
310 nsp_dbg(NSP_DEBUG_INIT, "in base=0x%x", base);
312 data->ScsiClockDiv = CLOCK_40M | FAST_20;
313 data->CurrentSC = NULL;
314 data->FifoCount = 0;
315 data->TransferMode = MODE_IO8;
317 nsphw_init_sync(data);
319 /* block all interrupts */
320 nsp_write(base, IRQCONTROL, IRQCONTROL_ALLMASK);
322 /* setup SCSI interface */
323 nsp_write(base, IFSELECT, IF_IFSEL);
325 nsp_index_write(base, SCSIIRQMODE, 0);
327 nsp_index_write(base, TRANSFERMODE, MODE_IO8);
328 nsp_index_write(base, CLOCKDIV, data->ScsiClockDiv);
330 nsp_index_write(base, PARITYCTRL, 0);
331 nsp_index_write(base, POINTERCLR, POINTER_CLEAR |
332 ACK_COUNTER_CLEAR |
333 REQ_COUNTER_CLEAR |
334 HOST_COUNTER_CLEAR);
336 /* setup fifo asic */
337 nsp_write(base, IFSELECT, IF_REGSEL);
338 nsp_index_write(base, TERMPWRCTRL, 0);
339 if ((nsp_index_read(base, OTHERCONTROL) & TPWR_SENSE) == 0) {
340 nsp_msg(KERN_INFO, "terminator power on");
341 nsp_index_write(base, TERMPWRCTRL, POWER_ON);
344 nsp_index_write(base, TIMERCOUNT, 0);
345 nsp_index_write(base, TIMERCOUNT, 0); /* requires 2 times!! */
347 nsp_index_write(base, SYNCREG, 0);
348 nsp_index_write(base, ACKWIDTH, 0);
350 /* enable interrupts and ack them */
351 nsp_index_write(base, SCSIIRQMODE, SCSI_PHASE_CHANGE_EI |
352 RESELECT_EI |
353 SCSI_RESET_IRQ_EI );
354 nsp_write(base, IRQCONTROL, IRQCONTROL_ALLCLEAR);
356 nsp_setup_fifo(data, FALSE);
358 return TRUE;
362 * Start selection phase
364 static int nsphw_start_selection(struct scsi_cmnd *SCpnt)
366 unsigned int host_id = SCpnt->device->host->this_id;
367 unsigned int base = SCpnt->device->host->io_port;
368 unsigned char target = scmd_id(SCpnt);
369 nsp_hw_data *data = (nsp_hw_data *)SCpnt->device->host->hostdata;
370 int time_out;
371 unsigned char phase, arbit;
373 //nsp_dbg(NSP_DEBUG_RESELECTION, "in");
375 phase = nsp_index_read(base, SCSIBUSMON);
376 if(phase != BUSMON_BUS_FREE) {
377 //nsp_dbg(NSP_DEBUG_RESELECTION, "bus busy");
378 return FALSE;
381 /* start arbitration */
382 //nsp_dbg(NSP_DEBUG_RESELECTION, "start arbit");
383 SCpnt->SCp.phase = PH_ARBSTART;
384 nsp_index_write(base, SETARBIT, ARBIT_GO);
386 time_out = 1000;
387 do {
388 /* XXX: what a stupid chip! */
389 arbit = nsp_index_read(base, ARBITSTATUS);
390 //nsp_dbg(NSP_DEBUG_RESELECTION, "arbit=%d, wait_count=%d", arbit, wait_count);
391 udelay(1); /* hold 1.2us */
392 } while((arbit & (ARBIT_WIN | ARBIT_FAIL)) == 0 &&
393 (time_out-- != 0));
395 if (!(arbit & ARBIT_WIN)) {
396 //nsp_dbg(NSP_DEBUG_RESELECTION, "arbit fail");
397 nsp_index_write(base, SETARBIT, ARBIT_FLAG_CLEAR);
398 return FALSE;
401 /* assert select line */
402 //nsp_dbg(NSP_DEBUG_RESELECTION, "assert SEL line");
403 SCpnt->SCp.phase = PH_SELSTART;
404 udelay(3); /* wait 2.4us */
405 nsp_index_write(base, SCSIDATALATCH, BIT(host_id) | BIT(target));
406 nsp_index_write(base, SCSIBUSCTRL, SCSI_SEL | SCSI_BSY | SCSI_ATN);
407 udelay(2); /* wait >1.2us */
408 nsp_index_write(base, SCSIBUSCTRL, SCSI_SEL | SCSI_BSY | SCSI_DATAOUT_ENB | SCSI_ATN);
409 nsp_index_write(base, SETARBIT, ARBIT_FLAG_CLEAR);
410 /*udelay(1);*/ /* wait >90ns */
411 nsp_index_write(base, SCSIBUSCTRL, SCSI_SEL | SCSI_DATAOUT_ENB | SCSI_ATN);
413 /* check selection timeout */
414 nsp_start_timer(SCpnt, 1000/51);
415 data->SelectionTimeOut = 1;
417 return TRUE;
420 struct nsp_sync_table {
421 unsigned int min_period;
422 unsigned int max_period;
423 unsigned int chip_period;
424 unsigned int ack_width;
427 static struct nsp_sync_table nsp_sync_table_40M[] = {
428 {0x0c, 0x0c, 0x1, 0}, /* 20MB 50ns*/
429 {0x19, 0x19, 0x3, 1}, /* 10MB 100ns*/
430 {0x1a, 0x25, 0x5, 2}, /* 7.5MB 150ns*/
431 {0x26, 0x32, 0x7, 3}, /* 5MB 200ns*/
432 { 0, 0, 0, 0},
435 static struct nsp_sync_table nsp_sync_table_20M[] = {
436 {0x19, 0x19, 0x1, 0}, /* 10MB 100ns*/
437 {0x1a, 0x25, 0x2, 0}, /* 7.5MB 150ns*/
438 {0x26, 0x32, 0x3, 1}, /* 5MB 200ns*/
439 { 0, 0, 0, 0},
443 * setup synchronous data transfer mode
445 static int nsp_analyze_sdtr(struct scsi_cmnd *SCpnt)
447 unsigned char target = scmd_id(SCpnt);
448 // unsigned char lun = SCpnt->device->lun;
449 nsp_hw_data *data = (nsp_hw_data *)SCpnt->device->host->hostdata;
450 sync_data *sync = &(data->Sync[target]);
451 struct nsp_sync_table *sync_table;
452 unsigned int period, offset;
453 int i;
456 nsp_dbg(NSP_DEBUG_SYNC, "in");
458 period = sync->SyncPeriod;
459 offset = sync->SyncOffset;
461 nsp_dbg(NSP_DEBUG_SYNC, "period=0x%x, offset=0x%x", period, offset);
463 if ((data->ScsiClockDiv & (BIT(0)|BIT(1))) == CLOCK_20M) {
464 sync_table = nsp_sync_table_20M;
465 } else {
466 sync_table = nsp_sync_table_40M;
469 for ( i = 0; sync_table->max_period != 0; i++, sync_table++) {
470 if ( period >= sync_table->min_period &&
471 period <= sync_table->max_period ) {
472 break;
476 if (period != 0 && sync_table->max_period == 0) {
478 * No proper period/offset found
480 nsp_dbg(NSP_DEBUG_SYNC, "no proper period/offset");
482 sync->SyncPeriod = 0;
483 sync->SyncOffset = 0;
484 sync->SyncRegister = 0;
485 sync->AckWidth = 0;
487 return FALSE;
490 sync->SyncRegister = (sync_table->chip_period << SYNCREG_PERIOD_SHIFT) |
491 (offset & SYNCREG_OFFSET_MASK);
492 sync->AckWidth = sync_table->ack_width;
494 nsp_dbg(NSP_DEBUG_SYNC, "sync_reg=0x%x, ack_width=0x%x", sync->SyncRegister, sync->AckWidth);
496 return TRUE;
501 * start ninja hardware timer
503 static void nsp_start_timer(struct scsi_cmnd *SCpnt, int time)
505 unsigned int base = SCpnt->device->host->io_port;
506 nsp_hw_data *data = (nsp_hw_data *)SCpnt->device->host->hostdata;
508 //nsp_dbg(NSP_DEBUG_INTR, "in SCpnt=0x%p, time=%d", SCpnt, time);
509 data->TimerCount = time;
510 nsp_index_write(base, TIMERCOUNT, time);
514 * wait for bus phase change
516 static int nsp_negate_signal(struct scsi_cmnd *SCpnt, unsigned char mask,
517 char *str)
519 unsigned int base = SCpnt->device->host->io_port;
520 unsigned char reg;
521 int time_out;
523 //nsp_dbg(NSP_DEBUG_INTR, "in");
525 time_out = 100;
527 do {
528 reg = nsp_index_read(base, SCSIBUSMON);
529 if (reg == 0xff) {
530 break;
532 } while ((--time_out != 0) && (reg & mask) != 0);
534 if (time_out == 0) {
535 nsp_msg(KERN_DEBUG, " %s signal off timeout", str);
538 return 0;
542 * expect Ninja Irq
544 static int nsp_expect_signal(struct scsi_cmnd *SCpnt,
545 unsigned char current_phase,
546 unsigned char mask)
548 unsigned int base = SCpnt->device->host->io_port;
549 int time_out;
550 unsigned char phase, i_src;
552 //nsp_dbg(NSP_DEBUG_INTR, "current_phase=0x%x, mask=0x%x", current_phase, mask);
554 time_out = 100;
555 do {
556 phase = nsp_index_read(base, SCSIBUSMON);
557 if (phase == 0xff) {
558 //nsp_dbg(NSP_DEBUG_INTR, "ret -1");
559 return -1;
561 i_src = nsp_read(base, IRQSTATUS);
562 if (i_src & IRQSTATUS_SCSI) {
563 //nsp_dbg(NSP_DEBUG_INTR, "ret 0 found scsi signal");
564 return 0;
566 if ((phase & mask) != 0 && (phase & BUSMON_PHASE_MASK) == current_phase) {
567 //nsp_dbg(NSP_DEBUG_INTR, "ret 1 phase=0x%x", phase);
568 return 1;
570 } while(time_out-- != 0);
572 //nsp_dbg(NSP_DEBUG_INTR, "timeout");
573 return -1;
577 * transfer SCSI message
579 static int nsp_xfer(struct scsi_cmnd *SCpnt, int phase)
581 unsigned int base = SCpnt->device->host->io_port;
582 nsp_hw_data *data = (nsp_hw_data *)SCpnt->device->host->hostdata;
583 char *buf = data->MsgBuffer;
584 int len = min(MSGBUF_SIZE, data->MsgLen);
585 int ptr;
586 int ret;
588 //nsp_dbg(NSP_DEBUG_DATA_IO, "in");
589 for (ptr = 0; len > 0; len--, ptr++) {
591 ret = nsp_expect_signal(SCpnt, phase, BUSMON_REQ);
592 if (ret <= 0) {
593 nsp_dbg(NSP_DEBUG_DATA_IO, "xfer quit");
594 return 0;
597 /* if last byte, negate ATN */
598 if (len == 1 && SCpnt->SCp.phase == PH_MSG_OUT) {
599 nsp_index_write(base, SCSIBUSCTRL, AUTODIRECTION | ACKENB);
602 /* read & write message */
603 if (phase & BUSMON_IO) {
604 nsp_dbg(NSP_DEBUG_DATA_IO, "read msg");
605 buf[ptr] = nsp_index_read(base, SCSIDATAWITHACK);
606 } else {
607 nsp_dbg(NSP_DEBUG_DATA_IO, "write msg");
608 nsp_index_write(base, SCSIDATAWITHACK, buf[ptr]);
610 nsp_negate_signal(SCpnt, BUSMON_ACK, "xfer<ack>");
613 return len;
617 * get extra SCSI data from fifo
619 static int nsp_dataphase_bypass(struct scsi_cmnd *SCpnt)
621 nsp_hw_data *data = (nsp_hw_data *)SCpnt->device->host->hostdata;
622 unsigned int count;
624 //nsp_dbg(NSP_DEBUG_DATA_IO, "in");
626 if (SCpnt->SCp.have_data_in != IO_IN) {
627 return 0;
630 count = nsp_fifo_count(SCpnt);
631 if (data->FifoCount == count) {
632 //nsp_dbg(NSP_DEBUG_DATA_IO, "not use bypass quirk");
633 return 0;
637 * XXX: NSP_QUIRK
638 * data phase skip only occures in case of SCSI_LOW_READ
640 nsp_dbg(NSP_DEBUG_DATA_IO, "use bypass quirk");
641 SCpnt->SCp.phase = PH_DATA;
642 nsp_pio_read(SCpnt);
643 nsp_setup_fifo(data, FALSE);
645 return 0;
649 * accept reselection
651 static int nsp_reselected(struct scsi_cmnd *SCpnt)
653 unsigned int base = SCpnt->device->host->io_port;
654 unsigned int host_id = SCpnt->device->host->this_id;
655 //nsp_hw_data *data = (nsp_hw_data *)SCpnt->device->host->hostdata;
656 unsigned char bus_reg;
657 unsigned char id_reg, tmp;
658 int target;
660 nsp_dbg(NSP_DEBUG_RESELECTION, "in");
662 id_reg = nsp_index_read(base, RESELECTID);
663 tmp = id_reg & (~BIT(host_id));
664 target = 0;
665 while(tmp != 0) {
666 if (tmp & BIT(0)) {
667 break;
669 tmp >>= 1;
670 target++;
673 if (scmd_id(SCpnt) != target) {
674 nsp_msg(KERN_ERR, "XXX: reselect ID must be %d in this implementation.", target);
677 nsp_negate_signal(SCpnt, BUSMON_SEL, "reselect<SEL>");
679 nsp_nexus(SCpnt);
680 bus_reg = nsp_index_read(base, SCSIBUSCTRL) & ~(SCSI_BSY | SCSI_ATN);
681 nsp_index_write(base, SCSIBUSCTRL, bus_reg);
682 nsp_index_write(base, SCSIBUSCTRL, bus_reg | AUTODIRECTION | ACKENB);
684 return TRUE;
688 * count how many data transferd
690 static int nsp_fifo_count(struct scsi_cmnd *SCpnt)
692 unsigned int base = SCpnt->device->host->io_port;
693 unsigned int count;
694 unsigned int l, m, h, dummy;
696 nsp_index_write(base, POINTERCLR, POINTER_CLEAR | ACK_COUNTER);
698 l = nsp_index_read(base, TRANSFERCOUNT);
699 m = nsp_index_read(base, TRANSFERCOUNT);
700 h = nsp_index_read(base, TRANSFERCOUNT);
701 dummy = nsp_index_read(base, TRANSFERCOUNT); /* required this! */
703 count = (h << 16) | (m << 8) | (l << 0);
705 //nsp_dbg(NSP_DEBUG_DATA_IO, "count=0x%x", count);
707 return count;
710 /* fifo size */
711 #define RFIFO_CRIT 64
712 #define WFIFO_CRIT 64
715 * read data in DATA IN phase
717 static void nsp_pio_read(struct scsi_cmnd *SCpnt)
719 unsigned int base = SCpnt->device->host->io_port;
720 unsigned long mmio_base = SCpnt->device->host->base;
721 nsp_hw_data *data = (nsp_hw_data *)SCpnt->device->host->hostdata;
722 long time_out;
723 int ocount, res;
724 unsigned char stat, fifo_stat;
726 ocount = data->FifoCount;
728 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",
729 SCpnt, scsi_get_resid(SCpnt), ocount, SCpnt->SCp.ptr,
730 SCpnt->SCp.this_residual, SCpnt->SCp.buffer,
731 SCpnt->SCp.buffers_residual);
733 time_out = 1000;
735 while ((time_out-- != 0) &&
736 (SCpnt->SCp.this_residual > 0 || SCpnt->SCp.buffers_residual > 0 ) ) {
738 stat = nsp_index_read(base, SCSIBUSMON);
739 stat &= BUSMON_PHASE_MASK;
742 res = nsp_fifo_count(SCpnt) - ocount;
743 //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);
744 if (res == 0) { /* if some data available ? */
745 if (stat == BUSPHASE_DATA_IN) { /* phase changed? */
746 //nsp_dbg(NSP_DEBUG_DATA_IO, " wait for data this=%d", SCpnt->SCp.this_residual);
747 continue;
748 } else {
749 nsp_dbg(NSP_DEBUG_DATA_IO, "phase changed stat=0x%x", stat);
750 break;
754 fifo_stat = nsp_read(base, FIFOSTATUS);
755 if ((fifo_stat & FIFOSTATUS_FULL_EMPTY) == 0 &&
756 stat == BUSPHASE_DATA_IN) {
757 continue;
760 res = min(res, SCpnt->SCp.this_residual);
762 switch (data->TransferMode) {
763 case MODE_IO32:
764 res &= ~(BIT(1)|BIT(0)); /* align 4 */
765 nsp_fifo32_read(base, SCpnt->SCp.ptr, res >> 2);
766 break;
767 case MODE_IO8:
768 nsp_fifo8_read (base, SCpnt->SCp.ptr, res );
769 break;
771 case MODE_MEM32:
772 res &= ~(BIT(1)|BIT(0)); /* align 4 */
773 nsp_mmio_fifo32_read(mmio_base, SCpnt->SCp.ptr, res >> 2);
774 break;
776 default:
777 nsp_dbg(NSP_DEBUG_DATA_IO, "unknown read mode");
778 return;
781 nsp_inc_resid(SCpnt, -res);
782 SCpnt->SCp.ptr += res;
783 SCpnt->SCp.this_residual -= res;
784 ocount += res;
785 //nsp_dbg(NSP_DEBUG_DATA_IO, "ptr=0x%p this_residual=0x%x ocount=0x%x", SCpnt->SCp.ptr, SCpnt->SCp.this_residual, ocount);
787 /* go to next scatter list if available */
788 if (SCpnt->SCp.this_residual == 0 &&
789 SCpnt->SCp.buffers_residual != 0 ) {
790 //nsp_dbg(NSP_DEBUG_DATA_IO, "scatterlist next timeout=%d", time_out);
791 SCpnt->SCp.buffers_residual--;
792 SCpnt->SCp.buffer++;
793 SCpnt->SCp.ptr = BUFFER_ADDR;
794 SCpnt->SCp.this_residual = SCpnt->SCp.buffer->length;
795 time_out = 1000;
797 //nsp_dbg(NSP_DEBUG_DATA_IO, "page: 0x%p, off: 0x%x", SCpnt->SCp.buffer->page, SCpnt->SCp.buffer->offset);
801 data->FifoCount = ocount;
803 if (time_out < 0) {
804 nsp_msg(KERN_DEBUG, "pio read timeout resid=%d this_residual=%d buffers_residual=%d",
805 scsi_get_resid(SCpnt), SCpnt->SCp.this_residual,
806 SCpnt->SCp.buffers_residual);
808 nsp_dbg(NSP_DEBUG_DATA_IO, "read ocount=0x%x", ocount);
809 nsp_dbg(NSP_DEBUG_DATA_IO, "r cmd=%d resid=0x%x\n", data->CmdId,
810 scsi_get_resid(SCpnt));
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,
829 SCpnt->SCp.buffer, SCpnt->SCp.buffers_residual,
830 scsi_get_resid(SCpnt));
832 time_out = 1000;
834 while ((time_out-- != 0) &&
835 (SCpnt->SCp.this_residual > 0 || SCpnt->SCp.buffers_residual > 0)) {
836 stat = nsp_index_read(base, SCSIBUSMON);
837 stat &= BUSMON_PHASE_MASK;
839 if (stat != BUSPHASE_DATA_OUT) {
840 res = ocount - nsp_fifo_count(SCpnt);
842 nsp_dbg(NSP_DEBUG_DATA_IO, "phase changed stat=0x%x, res=%d\n", stat, res);
843 /* Put back pointer */
844 nsp_inc_resid(SCpnt, res);
845 SCpnt->SCp.ptr -= res;
846 SCpnt->SCp.this_residual += res;
847 ocount -= res;
849 break;
852 res = ocount - nsp_fifo_count(SCpnt);
853 if (res > 0) { /* write all data? */
854 nsp_dbg(NSP_DEBUG_DATA_IO, "wait for all data out. ocount=0x%x res=%d", ocount, res);
855 continue;
858 res = min(SCpnt->SCp.this_residual, WFIFO_CRIT);
860 //nsp_dbg(NSP_DEBUG_DATA_IO, "ptr=0x%p this=0x%x res=0x%x", SCpnt->SCp.ptr, SCpnt->SCp.this_residual, res);
861 switch (data->TransferMode) {
862 case MODE_IO32:
863 res &= ~(BIT(1)|BIT(0)); /* align 4 */
864 nsp_fifo32_write(base, SCpnt->SCp.ptr, res >> 2);
865 break;
866 case MODE_IO8:
867 nsp_fifo8_write (base, SCpnt->SCp.ptr, res );
868 break;
870 case MODE_MEM32:
871 res &= ~(BIT(1)|BIT(0)); /* align 4 */
872 nsp_mmio_fifo32_write(mmio_base, SCpnt->SCp.ptr, res >> 2);
873 break;
875 default:
876 nsp_dbg(NSP_DEBUG_DATA_IO, "unknown write mode");
877 break;
880 nsp_inc_resid(SCpnt, -res);
881 SCpnt->SCp.ptr += res;
882 SCpnt->SCp.this_residual -= res;
883 ocount += res;
885 /* go to next scatter list if available */
886 if (SCpnt->SCp.this_residual == 0 &&
887 SCpnt->SCp.buffers_residual != 0 ) {
888 //nsp_dbg(NSP_DEBUG_DATA_IO, "scatterlist next");
889 SCpnt->SCp.buffers_residual--;
890 SCpnt->SCp.buffer++;
891 SCpnt->SCp.ptr = BUFFER_ADDR;
892 SCpnt->SCp.this_residual = SCpnt->SCp.buffer->length;
893 time_out = 1000;
897 data->FifoCount = ocount;
899 if (time_out < 0) {
900 nsp_msg(KERN_DEBUG, "pio write timeout resid=0x%x",
901 scsi_get_resid(SCpnt));
903 nsp_dbg(NSP_DEBUG_DATA_IO, "write ocount=0x%x", ocount);
904 nsp_dbg(NSP_DEBUG_DATA_IO, "w cmd=%d resid=0x%x\n", data->CmdId,
905 scsi_get_resid(SCpnt));
907 #undef RFIFO_CRIT
908 #undef WFIFO_CRIT
911 * setup synchronous/asynchronous data transfer mode
913 static int nsp_nexus(struct scsi_cmnd *SCpnt)
915 unsigned int base = SCpnt->device->host->io_port;
916 unsigned char target = scmd_id(SCpnt);
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 (scsi_get_resid(SCpnt) % 4 != 0 ||
928 scsi_get_resid(SCpnt) <= PAGE_SIZE ) {
929 data->TransferMode = MODE_IO8;
930 } else if (nsp_burst_mode == BURST_MEM32) {
931 data->TransferMode = MODE_MEM32;
932 } else if (nsp_burst_mode == BURST_IO32) {
933 data->TransferMode = MODE_IO32;
934 } else {
935 data->TransferMode = MODE_IO8;
938 /* setup pdma fifo */
939 nsp_setup_fifo(data, TRUE);
941 /* clear ack counter */
942 data->FifoCount = 0;
943 nsp_index_write(base, POINTERCLR, POINTER_CLEAR |
944 ACK_COUNTER_CLEAR |
945 REQ_COUNTER_CLEAR |
946 HOST_COUNTER_CLEAR);
948 return 0;
951 #include "nsp_message.c"
953 * interrupt handler
955 static irqreturn_t nspintr(int irq, void *dev_id)
957 unsigned int base;
958 unsigned char irq_status, irq_phase, phase;
959 struct scsi_cmnd *tmpSC;
960 unsigned char target, lun;
961 unsigned int *sync_neg;
962 int i, tmp;
963 nsp_hw_data *data;
966 //nsp_dbg(NSP_DEBUG_INTR, "dev_id=0x%p", dev_id);
967 //nsp_dbg(NSP_DEBUG_INTR, "host=0x%p", ((scsi_info_t *)dev_id)->host);
969 if ( dev_id != NULL &&
970 ((scsi_info_t *)dev_id)->host != NULL ) {
971 scsi_info_t *info = (scsi_info_t *)dev_id;
973 data = (nsp_hw_data *)info->host->hostdata;
974 } else {
975 nsp_dbg(NSP_DEBUG_INTR, "host data wrong");
976 return IRQ_NONE;
979 //nsp_dbg(NSP_DEBUG_INTR, "&nsp_data_base=0x%p, dev_id=0x%p", &nsp_data_base, dev_id);
981 base = data->BaseAddress;
982 //nsp_dbg(NSP_DEBUG_INTR, "base=0x%x", base);
985 * interrupt check
987 nsp_write(base, IRQCONTROL, IRQCONTROL_IRQDISABLE);
988 irq_status = nsp_read(base, IRQSTATUS);
989 //nsp_dbg(NSP_DEBUG_INTR, "irq_status=0x%x", irq_status);
990 if ((irq_status == 0xff) || ((irq_status & IRQSTATUS_MASK) == 0)) {
991 nsp_write(base, IRQCONTROL, 0);
992 //nsp_dbg(NSP_DEBUG_INTR, "no irq/shared irq");
993 return IRQ_NONE;
996 /* XXX: IMPORTANT
997 * Do not read an irq_phase register if no scsi phase interrupt.
998 * Unless, you should lose a scsi phase interrupt.
1000 phase = nsp_index_read(base, SCSIBUSMON);
1001 if((irq_status & IRQSTATUS_SCSI) != 0) {
1002 irq_phase = nsp_index_read(base, IRQPHASESENCE);
1003 } else {
1004 irq_phase = 0;
1007 //nsp_dbg(NSP_DEBUG_INTR, "irq_phase=0x%x", irq_phase);
1010 * timer interrupt handler (scsi vs timer interrupts)
1012 //nsp_dbg(NSP_DEBUG_INTR, "timercount=%d", data->TimerCount);
1013 if (data->TimerCount != 0) {
1014 //nsp_dbg(NSP_DEBUG_INTR, "stop timer");
1015 nsp_index_write(base, TIMERCOUNT, 0);
1016 nsp_index_write(base, TIMERCOUNT, 0);
1017 data->TimerCount = 0;
1020 if ((irq_status & IRQSTATUS_MASK) == IRQSTATUS_TIMER &&
1021 data->SelectionTimeOut == 0) {
1022 //nsp_dbg(NSP_DEBUG_INTR, "timer start");
1023 nsp_write(base, IRQCONTROL, IRQCONTROL_TIMER_CLEAR);
1024 return IRQ_HANDLED;
1027 nsp_write(base, IRQCONTROL, IRQCONTROL_TIMER_CLEAR | IRQCONTROL_FIFO_CLEAR);
1029 if ((irq_status & IRQSTATUS_SCSI) &&
1030 (irq_phase & SCSI_RESET_IRQ)) {
1031 nsp_msg(KERN_ERR, "bus reset (power off?)");
1033 nsphw_init(data);
1034 nsp_bus_reset(data);
1036 if(data->CurrentSC != NULL) {
1037 tmpSC = data->CurrentSC;
1038 tmpSC->result = (DID_RESET << 16) |
1039 ((tmpSC->SCp.Message & 0xff) << 8) |
1040 ((tmpSC->SCp.Status & 0xff) << 0);
1041 nsp_scsi_done(tmpSC);
1043 return IRQ_HANDLED;
1046 if (data->CurrentSC == NULL) {
1047 nsp_msg(KERN_ERR, "CurrentSC==NULL irq_status=0x%x phase=0x%x irq_phase=0x%x this can't be happen. reset everything", irq_status, phase, irq_phase);
1048 nsphw_init(data);
1049 nsp_bus_reset(data);
1050 return IRQ_HANDLED;
1053 tmpSC = data->CurrentSC;
1054 target = tmpSC->device->id;
1055 lun = tmpSC->device->lun;
1056 sync_neg = &(data->Sync[target].SyncNegotiation);
1059 * parse hardware SCSI irq reasons register
1061 if (irq_status & IRQSTATUS_SCSI) {
1062 if (irq_phase & RESELECT_IRQ) {
1063 nsp_dbg(NSP_DEBUG_INTR, "reselect");
1064 nsp_write(base, IRQCONTROL, IRQCONTROL_RESELECT_CLEAR);
1065 if (nsp_reselected(tmpSC) != FALSE) {
1066 return IRQ_HANDLED;
1070 if ((irq_phase & (PHASE_CHANGE_IRQ | LATCHED_BUS_FREE)) == 0) {
1071 return IRQ_HANDLED;
1075 //show_phase(tmpSC);
1077 switch(tmpSC->SCp.phase) {
1078 case PH_SELSTART:
1079 // *sync_neg = SYNC_NOT_YET;
1080 if ((phase & BUSMON_BSY) == 0) {
1081 //nsp_dbg(NSP_DEBUG_INTR, "selection count=%d", data->SelectionTimeOut);
1082 if (data->SelectionTimeOut >= NSP_SELTIMEOUT) {
1083 nsp_dbg(NSP_DEBUG_INTR, "selection time out");
1084 data->SelectionTimeOut = 0;
1085 nsp_index_write(base, SCSIBUSCTRL, 0);
1087 tmpSC->result = DID_TIME_OUT << 16;
1088 nsp_scsi_done(tmpSC);
1090 return IRQ_HANDLED;
1092 data->SelectionTimeOut += 1;
1093 nsp_start_timer(tmpSC, 1000/51);
1094 return IRQ_HANDLED;
1097 /* attention assert */
1098 //nsp_dbg(NSP_DEBUG_INTR, "attention assert");
1099 data->SelectionTimeOut = 0;
1100 tmpSC->SCp.phase = PH_SELECTED;
1101 nsp_index_write(base, SCSIBUSCTRL, SCSI_ATN);
1102 udelay(1);
1103 nsp_index_write(base, SCSIBUSCTRL, SCSI_ATN | AUTODIRECTION | ACKENB);
1104 return IRQ_HANDLED;
1106 break;
1108 case PH_RESELECT:
1109 //nsp_dbg(NSP_DEBUG_INTR, "phase reselect");
1110 // *sync_neg = SYNC_NOT_YET;
1111 if ((phase & BUSMON_PHASE_MASK) != BUSPHASE_MESSAGE_IN) {
1113 tmpSC->result = DID_ABORT << 16;
1114 nsp_scsi_done(tmpSC);
1115 return IRQ_HANDLED;
1117 /* fall thru */
1118 default:
1119 if ((irq_status & (IRQSTATUS_SCSI | IRQSTATUS_FIFO)) == 0) {
1120 return IRQ_HANDLED;
1122 break;
1126 * SCSI sequencer
1128 //nsp_dbg(NSP_DEBUG_INTR, "start scsi seq");
1130 /* normal disconnect */
1131 if (((tmpSC->SCp.phase == PH_MSG_IN) || (tmpSC->SCp.phase == PH_MSG_OUT)) &&
1132 (irq_phase & LATCHED_BUS_FREE) != 0 ) {
1133 nsp_dbg(NSP_DEBUG_INTR, "normal disconnect irq_status=0x%x, phase=0x%x, irq_phase=0x%x", irq_status, phase, irq_phase);
1135 //*sync_neg = SYNC_NOT_YET;
1137 if ((tmpSC->SCp.Message == MSG_COMMAND_COMPLETE)) { /* all command complete and return status */
1138 tmpSC->result = (DID_OK << 16) |
1139 ((tmpSC->SCp.Message & 0xff) << 8) |
1140 ((tmpSC->SCp.Status & 0xff) << 0);
1141 nsp_dbg(NSP_DEBUG_INTR, "command complete result=0x%x", tmpSC->result);
1142 nsp_scsi_done(tmpSC);
1144 return IRQ_HANDLED;
1147 return IRQ_HANDLED;
1151 /* check unexpected bus free state */
1152 if (phase == 0) {
1153 nsp_msg(KERN_DEBUG, "unexpected bus free. irq_status=0x%x, phase=0x%x, irq_phase=0x%x", irq_status, phase, irq_phase);
1155 *sync_neg = SYNC_NG;
1156 tmpSC->result = DID_ERROR << 16;
1157 nsp_scsi_done(tmpSC);
1158 return IRQ_HANDLED;
1161 switch (phase & BUSMON_PHASE_MASK) {
1162 case BUSPHASE_COMMAND:
1163 nsp_dbg(NSP_DEBUG_INTR, "BUSPHASE_COMMAND");
1164 if ((phase & BUSMON_REQ) == 0) {
1165 nsp_dbg(NSP_DEBUG_INTR, "REQ == 0");
1166 return IRQ_HANDLED;
1169 tmpSC->SCp.phase = PH_COMMAND;
1171 nsp_nexus(tmpSC);
1173 /* write scsi command */
1174 nsp_dbg(NSP_DEBUG_INTR, "cmd_len=%d", tmpSC->cmd_len);
1175 nsp_index_write(base, COMMANDCTRL, CLEAR_COMMAND_POINTER);
1176 for (i = 0; i < tmpSC->cmd_len; i++) {
1177 nsp_index_write(base, COMMANDDATA, tmpSC->cmnd[i]);
1179 nsp_index_write(base, COMMANDCTRL, CLEAR_COMMAND_POINTER | AUTO_COMMAND_GO);
1180 break;
1182 case BUSPHASE_DATA_OUT:
1183 nsp_dbg(NSP_DEBUG_INTR, "BUSPHASE_DATA_OUT");
1185 tmpSC->SCp.phase = PH_DATA;
1186 tmpSC->SCp.have_data_in = IO_OUT;
1188 nsp_pio_write(tmpSC);
1190 break;
1192 case BUSPHASE_DATA_IN:
1193 nsp_dbg(NSP_DEBUG_INTR, "BUSPHASE_DATA_IN");
1195 tmpSC->SCp.phase = PH_DATA;
1196 tmpSC->SCp.have_data_in = IO_IN;
1198 nsp_pio_read(tmpSC);
1200 break;
1202 case BUSPHASE_STATUS:
1203 nsp_dataphase_bypass(tmpSC);
1204 nsp_dbg(NSP_DEBUG_INTR, "BUSPHASE_STATUS");
1206 tmpSC->SCp.phase = PH_STATUS;
1208 tmpSC->SCp.Status = nsp_index_read(base, SCSIDATAWITHACK);
1209 nsp_dbg(NSP_DEBUG_INTR, "message=0x%x status=0x%x", tmpSC->SCp.Message, tmpSC->SCp.Status);
1211 break;
1213 case BUSPHASE_MESSAGE_OUT:
1214 nsp_dbg(NSP_DEBUG_INTR, "BUSPHASE_MESSAGE_OUT");
1215 if ((phase & BUSMON_REQ) == 0) {
1216 goto timer_out;
1219 tmpSC->SCp.phase = PH_MSG_OUT;
1221 //*sync_neg = SYNC_NOT_YET;
1223 data->MsgLen = i = 0;
1224 data->MsgBuffer[i] = IDENTIFY(TRUE, lun); i++;
1226 if (*sync_neg == SYNC_NOT_YET) {
1227 data->Sync[target].SyncPeriod = 0;
1228 data->Sync[target].SyncOffset = 0;
1230 /**/
1231 data->MsgBuffer[i] = MSG_EXTENDED; i++;
1232 data->MsgBuffer[i] = 3; i++;
1233 data->MsgBuffer[i] = MSG_EXT_SDTR; i++;
1234 data->MsgBuffer[i] = 0x0c; i++;
1235 data->MsgBuffer[i] = 15; i++;
1236 /**/
1238 data->MsgLen = i;
1240 nsp_analyze_sdtr(tmpSC);
1241 show_message(data);
1242 nsp_message_out(tmpSC);
1243 break;
1245 case BUSPHASE_MESSAGE_IN:
1246 nsp_dataphase_bypass(tmpSC);
1247 nsp_dbg(NSP_DEBUG_INTR, "BUSPHASE_MESSAGE_IN");
1248 if ((phase & BUSMON_REQ) == 0) {
1249 goto timer_out;
1252 tmpSC->SCp.phase = PH_MSG_IN;
1253 nsp_message_in(tmpSC);
1255 /**/
1256 if (*sync_neg == SYNC_NOT_YET) {
1257 //nsp_dbg(NSP_DEBUG_INTR, "sync target=%d,lun=%d",target,lun);
1259 if (data->MsgLen >= 5 &&
1260 data->MsgBuffer[0] == MSG_EXTENDED &&
1261 data->MsgBuffer[1] == 3 &&
1262 data->MsgBuffer[2] == MSG_EXT_SDTR ) {
1263 data->Sync[target].SyncPeriod = data->MsgBuffer[3];
1264 data->Sync[target].SyncOffset = data->MsgBuffer[4];
1265 //nsp_dbg(NSP_DEBUG_INTR, "sync ok, %d %d", data->MsgBuffer[3], data->MsgBuffer[4]);
1266 *sync_neg = SYNC_OK;
1267 } else {
1268 data->Sync[target].SyncPeriod = 0;
1269 data->Sync[target].SyncOffset = 0;
1270 *sync_neg = SYNC_NG;
1272 nsp_analyze_sdtr(tmpSC);
1274 /**/
1276 /* search last messeage byte */
1277 tmp = -1;
1278 for (i = 0; i < data->MsgLen; i++) {
1279 tmp = data->MsgBuffer[i];
1280 if (data->MsgBuffer[i] == MSG_EXTENDED) {
1281 i += (1 + data->MsgBuffer[i+1]);
1284 tmpSC->SCp.Message = tmp;
1286 nsp_dbg(NSP_DEBUG_INTR, "message=0x%x len=%d", tmpSC->SCp.Message, data->MsgLen);
1287 show_message(data);
1289 break;
1291 case BUSPHASE_SELECT:
1292 default:
1293 nsp_dbg(NSP_DEBUG_INTR, "BUSPHASE other");
1295 break;
1298 //nsp_dbg(NSP_DEBUG_INTR, "out");
1299 return IRQ_HANDLED;
1301 timer_out:
1302 nsp_start_timer(tmpSC, 1000/102);
1303 return IRQ_HANDLED;
1306 #ifdef NSP_DEBUG
1307 #include "nsp_debug.c"
1308 #endif /* NSP_DEBUG */
1310 /*----------------------------------------------------------------*/
1311 /* look for ninja3 card and init if found */
1312 /*----------------------------------------------------------------*/
1313 static struct Scsi_Host *nsp_detect(struct scsi_host_template *sht)
1315 struct Scsi_Host *host; /* registered host structure */
1316 nsp_hw_data *data_b = &nsp_data_base, *data;
1318 nsp_dbg(NSP_DEBUG_INIT, "this_id=%d", sht->this_id);
1319 host = scsi_host_alloc(&nsp_driver_template, sizeof(nsp_hw_data));
1320 if (host == NULL) {
1321 nsp_dbg(NSP_DEBUG_INIT, "host failed");
1322 return NULL;
1325 memcpy(host->hostdata, data_b, sizeof(nsp_hw_data));
1326 data = (nsp_hw_data *)host->hostdata;
1327 data->ScsiInfo->host = host;
1328 #ifdef NSP_DEBUG
1329 data->CmdId = 0;
1330 #endif
1332 nsp_dbg(NSP_DEBUG_INIT, "irq=%d,%d", data_b->IrqNumber, ((nsp_hw_data *)host->hostdata)->IrqNumber);
1334 host->unique_id = data->BaseAddress;
1335 host->io_port = data->BaseAddress;
1336 host->n_io_port = data->NumAddress;
1337 host->irq = data->IrqNumber;
1338 host->base = data->MmioAddress;
1340 spin_lock_init(&(data->Lock));
1342 snprintf(data->nspinfo,
1343 sizeof(data->nspinfo),
1344 "NinjaSCSI-3/32Bi Driver $Revision: 1.23 $ IO:0x%04lx-0x%04lx MMIO(virt addr):0x%04lx IRQ:%02d",
1345 host->io_port, host->io_port + host->n_io_port - 1,
1346 host->base,
1347 host->irq);
1348 sht->name = data->nspinfo;
1350 nsp_dbg(NSP_DEBUG_INIT, "end");
1353 return host; /* detect done. */
1356 /*----------------------------------------------------------------*/
1357 /* return info string */
1358 /*----------------------------------------------------------------*/
1359 static const char *nsp_info(struct Scsi_Host *shpnt)
1361 nsp_hw_data *data = (nsp_hw_data *)shpnt->hostdata;
1363 return data->nspinfo;
1366 static int nsp_show_info(struct seq_file *m, struct Scsi_Host *host)
1368 int id;
1369 int speed;
1370 unsigned long flags;
1371 nsp_hw_data *data;
1372 int hostno;
1374 hostno = host->host_no;
1375 data = (nsp_hw_data *)host->hostdata;
1377 seq_puts(m, "NinjaSCSI status\n\n"
1378 "Driver version: $Revision: 1.23 $\n");
1379 seq_printf(m, "SCSI host No.: %d\n", hostno);
1380 seq_printf(m, "IRQ: %d\n", host->irq);
1381 seq_printf(m, "IO: 0x%lx-0x%lx\n", host->io_port, host->io_port + host->n_io_port - 1);
1382 seq_printf(m, "MMIO(virtual address): 0x%lx-0x%lx\n", host->base, host->base + data->MmioLength - 1);
1383 seq_printf(m, "sg_tablesize: %d\n", host->sg_tablesize);
1385 seq_puts(m, "burst transfer mode: ");
1386 switch (nsp_burst_mode) {
1387 case BURST_IO8:
1388 seq_puts(m, "io8");
1389 break;
1390 case BURST_IO32:
1391 seq_puts(m, "io32");
1392 break;
1393 case BURST_MEM32:
1394 seq_puts(m, "mem32");
1395 break;
1396 default:
1397 seq_puts(m, "???");
1398 break;
1400 seq_putc(m, '\n');
1403 spin_lock_irqsave(&(data->Lock), flags);
1404 seq_printf(m, "CurrentSC: 0x%p\n\n", data->CurrentSC);
1405 spin_unlock_irqrestore(&(data->Lock), flags);
1407 seq_puts(m, "SDTR status\n");
1408 for(id = 0; id < ARRAY_SIZE(data->Sync); id++) {
1410 seq_printf(m, "id %d: ", id);
1412 if (id == host->this_id) {
1413 seq_puts(m, "----- NinjaSCSI-3 host adapter\n");
1414 continue;
1417 switch(data->Sync[id].SyncNegotiation) {
1418 case SYNC_OK:
1419 seq_puts(m, " sync");
1420 break;
1421 case SYNC_NG:
1422 seq_puts(m, "async");
1423 break;
1424 case SYNC_NOT_YET:
1425 seq_puts(m, " none");
1426 break;
1427 default:
1428 seq_puts(m, "?????");
1429 break;
1432 if (data->Sync[id].SyncPeriod != 0) {
1433 speed = 1000000 / (data->Sync[id].SyncPeriod * 4);
1435 seq_printf(m, " transfer %d.%dMB/s, offset %d",
1436 speed / 1000,
1437 speed % 1000,
1438 data->Sync[id].SyncOffset
1441 seq_putc(m, '\n');
1443 return 0;
1446 /*---------------------------------------------------------------*/
1447 /* error handler */
1448 /*---------------------------------------------------------------*/
1451 static int nsp_eh_abort(struct scsi_cmnd *SCpnt)
1453 nsp_dbg(NSP_DEBUG_BUSRESET, "SCpnt=0x%p", SCpnt);
1455 return nsp_eh_bus_reset(SCpnt);
1458 static int nsp_bus_reset(nsp_hw_data *data)
1460 unsigned int base = data->BaseAddress;
1461 int i;
1463 nsp_write(base, IRQCONTROL, IRQCONTROL_ALLMASK);
1465 nsp_index_write(base, SCSIBUSCTRL, SCSI_RST);
1466 mdelay(100); /* 100ms */
1467 nsp_index_write(base, SCSIBUSCTRL, 0);
1468 for(i = 0; i < 5; i++) {
1469 nsp_index_read(base, IRQPHASESENCE); /* dummy read */
1472 nsphw_init_sync(data);
1474 nsp_write(base, IRQCONTROL, IRQCONTROL_ALLCLEAR);
1476 return SUCCESS;
1479 static int nsp_eh_bus_reset(struct scsi_cmnd *SCpnt)
1481 nsp_hw_data *data = (nsp_hw_data *)SCpnt->device->host->hostdata;
1483 nsp_dbg(NSP_DEBUG_BUSRESET, "SCpnt=0x%p", SCpnt);
1485 return nsp_bus_reset(data);
1488 static int nsp_eh_host_reset(struct scsi_cmnd *SCpnt)
1490 nsp_hw_data *data = (nsp_hw_data *)SCpnt->device->host->hostdata;
1492 nsp_dbg(NSP_DEBUG_BUSRESET, "in");
1494 nsphw_init(data);
1496 return SUCCESS;
1500 /**********************************************************************
1501 PCMCIA functions
1502 **********************************************************************/
1504 static int nsp_cs_probe(struct pcmcia_device *link)
1506 scsi_info_t *info;
1507 nsp_hw_data *data = &nsp_data_base;
1508 int ret;
1510 nsp_dbg(NSP_DEBUG_INIT, "in");
1512 /* Create new SCSI device */
1513 info = kzalloc(sizeof(*info), GFP_KERNEL);
1514 if (info == NULL) { return -ENOMEM; }
1515 info->p_dev = link;
1516 link->priv = info;
1517 data->ScsiInfo = info;
1519 nsp_dbg(NSP_DEBUG_INIT, "info=0x%p", info);
1521 ret = nsp_cs_config(link);
1523 nsp_dbg(NSP_DEBUG_INIT, "link=0x%p", link);
1524 return ret;
1525 } /* nsp_cs_attach */
1528 static void nsp_cs_detach(struct pcmcia_device *link)
1530 nsp_dbg(NSP_DEBUG_INIT, "in, link=0x%p", link);
1532 ((scsi_info_t *)link->priv)->stop = 1;
1533 nsp_cs_release(link);
1535 kfree(link->priv);
1536 link->priv = NULL;
1537 } /* nsp_cs_detach */
1540 static int nsp_cs_config_check(struct pcmcia_device *p_dev, void *priv_data)
1542 nsp_hw_data *data = priv_data;
1544 if (p_dev->config_index == 0)
1545 return -ENODEV;
1547 /* This reserves IO space but doesn't actually enable it */
1548 if (pcmcia_request_io(p_dev) != 0)
1549 goto next_entry;
1551 if (resource_size(p_dev->resource[2])) {
1552 p_dev->resource[2]->flags |= (WIN_DATA_WIDTH_16 |
1553 WIN_MEMORY_TYPE_CM |
1554 WIN_ENABLE);
1555 if (p_dev->resource[2]->end < 0x1000)
1556 p_dev->resource[2]->end = 0x1000;
1557 if (pcmcia_request_window(p_dev, p_dev->resource[2], 0) != 0)
1558 goto next_entry;
1559 if (pcmcia_map_mem_page(p_dev, p_dev->resource[2],
1560 p_dev->card_addr) != 0)
1561 goto next_entry;
1563 data->MmioAddress = (unsigned long)
1564 ioremap_nocache(p_dev->resource[2]->start,
1565 resource_size(p_dev->resource[2]));
1566 data->MmioLength = resource_size(p_dev->resource[2]);
1568 /* If we got this far, we're cool! */
1569 return 0;
1571 next_entry:
1572 nsp_dbg(NSP_DEBUG_INIT, "next");
1573 pcmcia_disable_device(p_dev);
1574 return -ENODEV;
1577 static int nsp_cs_config(struct pcmcia_device *link)
1579 int ret;
1580 scsi_info_t *info = link->priv;
1581 struct Scsi_Host *host;
1582 nsp_hw_data *data = &nsp_data_base;
1584 nsp_dbg(NSP_DEBUG_INIT, "in");
1586 link->config_flags |= CONF_ENABLE_IRQ | CONF_AUTO_CHECK_VCC |
1587 CONF_AUTO_SET_VPP | CONF_AUTO_AUDIO | CONF_AUTO_SET_IOMEM |
1588 CONF_AUTO_SET_IO;
1590 ret = pcmcia_loop_config(link, nsp_cs_config_check, data);
1591 if (ret)
1592 goto cs_failed;
1594 if (pcmcia_request_irq(link, nspintr))
1595 goto cs_failed;
1597 ret = pcmcia_enable_device(link);
1598 if (ret)
1599 goto cs_failed;
1601 if (free_ports) {
1602 if (link->resource[0]) {
1603 release_region(link->resource[0]->start,
1604 resource_size(link->resource[0]));
1606 if (link->resource[1]) {
1607 release_region(link->resource[1]->start,
1608 resource_size(link->resource[1]));
1612 /* Set port and IRQ */
1613 data->BaseAddress = link->resource[0]->start;
1614 data->NumAddress = resource_size(link->resource[0]);
1615 data->IrqNumber = link->irq;
1617 nsp_dbg(NSP_DEBUG_INIT, "I/O[0x%x+0x%x] IRQ %d",
1618 data->BaseAddress, data->NumAddress, data->IrqNumber);
1620 if(nsphw_init(data) == FALSE) {
1621 goto cs_failed;
1624 host = nsp_detect(&nsp_driver_template);
1626 if (host == NULL) {
1627 nsp_dbg(NSP_DEBUG_INIT, "detect failed");
1628 goto cs_failed;
1632 ret = scsi_add_host (host, NULL);
1633 if (ret)
1634 goto cs_failed;
1636 scsi_scan_host(host);
1638 info->host = host;
1640 return 0;
1642 cs_failed:
1643 nsp_dbg(NSP_DEBUG_INIT, "config fail");
1644 nsp_cs_release(link);
1646 return -ENODEV;
1647 } /* nsp_cs_config */
1650 static void nsp_cs_release(struct pcmcia_device *link)
1652 scsi_info_t *info = link->priv;
1653 nsp_hw_data *data = NULL;
1655 if (info->host == NULL) {
1656 nsp_msg(KERN_DEBUG, "unexpected card release call.");
1657 } else {
1658 data = (nsp_hw_data *)info->host->hostdata;
1661 nsp_dbg(NSP_DEBUG_INIT, "link=0x%p", link);
1663 /* Unlink the device chain */
1664 if (info->host != NULL) {
1665 scsi_remove_host(info->host);
1668 if (resource_size(link->resource[2])) {
1669 if (data != NULL) {
1670 iounmap((void *)(data->MmioAddress));
1673 pcmcia_disable_device(link);
1675 if (info->host != NULL) {
1676 scsi_host_put(info->host);
1678 } /* nsp_cs_release */
1680 static int nsp_cs_suspend(struct pcmcia_device *link)
1682 scsi_info_t *info = link->priv;
1683 nsp_hw_data *data;
1685 nsp_dbg(NSP_DEBUG_INIT, "event: suspend");
1687 if (info->host != NULL) {
1688 nsp_msg(KERN_INFO, "clear SDTR status");
1690 data = (nsp_hw_data *)info->host->hostdata;
1692 nsphw_init_sync(data);
1695 info->stop = 1;
1697 return 0;
1700 static int nsp_cs_resume(struct pcmcia_device *link)
1702 scsi_info_t *info = link->priv;
1703 nsp_hw_data *data;
1705 nsp_dbg(NSP_DEBUG_INIT, "event: resume");
1707 info->stop = 0;
1709 if (info->host != NULL) {
1710 nsp_msg(KERN_INFO, "reset host and bus");
1712 data = (nsp_hw_data *)info->host->hostdata;
1714 nsphw_init (data);
1715 nsp_bus_reset(data);
1718 return 0;
1721 /*======================================================================*
1722 * module entry point
1723 *====================================================================*/
1724 static const struct pcmcia_device_id nsp_cs_ids[] = {
1725 PCMCIA_DEVICE_PROD_ID123("IO DATA", "CBSC16 ", "1", 0x547e66dc, 0x0d63a3fd, 0x51de003a),
1726 PCMCIA_DEVICE_PROD_ID123("KME ", "SCSI-CARD-001", "1", 0x534c02bc, 0x52008408, 0x51de003a),
1727 PCMCIA_DEVICE_PROD_ID123("KME ", "SCSI-CARD-002", "1", 0x534c02bc, 0xcb09d5b2, 0x51de003a),
1728 PCMCIA_DEVICE_PROD_ID123("KME ", "SCSI-CARD-003", "1", 0x534c02bc, 0xbc0ee524, 0x51de003a),
1729 PCMCIA_DEVICE_PROD_ID123("KME ", "SCSI-CARD-004", "1", 0x534c02bc, 0x226a7087, 0x51de003a),
1730 PCMCIA_DEVICE_PROD_ID123("WBT", "NinjaSCSI-3", "R1.0", 0xc7ba805f, 0xfdc7c97d, 0x6973710e),
1731 PCMCIA_DEVICE_PROD_ID123("WORKBIT", "UltraNinja-16", "1", 0x28191418, 0xb70f4b09, 0x51de003a),
1732 PCMCIA_DEVICE_NULL
1734 MODULE_DEVICE_TABLE(pcmcia, nsp_cs_ids);
1736 static struct pcmcia_driver nsp_driver = {
1737 .owner = THIS_MODULE,
1738 .name = "nsp_cs",
1739 .probe = nsp_cs_probe,
1740 .remove = nsp_cs_detach,
1741 .id_table = nsp_cs_ids,
1742 .suspend = nsp_cs_suspend,
1743 .resume = nsp_cs_resume,
1745 module_pcmcia_driver(nsp_driver);
1747 /* end */