scsi: core: Remove the 'done' argument from SCSI queuecommand_lck functions
[linux-2.6-block.git] / drivers / scsi / pcmcia / nsp_cs.c
CommitLineData
1da177e4
LT
1/*======================================================================
2
3 NinjaSCSI-3 / NinjaSCSI-32Bi PCMCIA SCSI host adapter card driver
4 By: YOKOTA Hiroshi <yokota@netlab.is.tsukuba.ac.jp>
5
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
12
13 This software may be used and distributed according to the terms of
14 the GNU General Public License.
15
16======================================================================*/
17
18/***********************************************************************
19 This driver is for these PCcards.
20
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"
25
26***********************************************************************/
27
1da177e4
LT
28#include <linux/module.h>
29#include <linux/kernel.h>
30#include <linux/init.h>
1da177e4
LT
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>
40
41#include <asm/io.h>
42#include <asm/irq.h>
43
44#include <../drivers/scsi/scsi.h>
45#include <scsi/scsi_host.h>
46
47#include <scsi/scsi.h>
48#include <scsi/scsi_ioctl.h>
49
1da177e4
LT
50#include <pcmcia/cistpl.h>
51#include <pcmcia/cisreg.h>
52#include <pcmcia/ds.h>
53
54#include "nsp_cs.h"
55
56MODULE_AUTHOR("YOKOTA Hiroshi <yokota@netlab.is.tsukuba.ac.jp>");
774251ef 57MODULE_DESCRIPTION("WorkBit NinjaSCSI-3 / NinjaSCSI-32Bi(16bit) PCMCIA SCSI host adapter module");
1da177e4 58MODULE_LICENSE("GPL");
1da177e4
LT
59
60#include "nsp_io.h"
61
62/*====================================================================*/
63/* Parameters that can be set with 'insmod' */
64
65static int nsp_burst_mode = BURST_MEM32;
66module_param(nsp_burst_mode, int, 0);
67MODULE_PARM_DESC(nsp_burst_mode, "Burst transfer mode (0=io8, 1=io32, 2=mem32(default))");
68
69/* Release IO ports after configuration? */
90ab5ee9 70static bool free_ports = 0;
1da177e4
LT
71module_param(free_ports, bool, 0);
72MODULE_PARM_DESC(free_ports, "Release IO ports after configuration? (default: 0 (=no))");
73
d0be4a7d 74static struct scsi_host_template nsp_driver_template = {
1da177e4 75 .proc_name = "nsp_cs",
63fd57cb 76 .show_info = nsp_show_info,
1da177e4 77 .name = "WorkBit NinjaSCSI-3/32Bi(16bit)",
1da177e4
LT
78 .info = nsp_info,
79 .queuecommand = nsp_queuecommand,
1da177e4 80/* .eh_abort_handler = nsp_eh_abort,*/
1da177e4
LT
81 .eh_bus_reset_handler = nsp_eh_bus_reset,
82 .eh_host_reset_handler = nsp_eh_host_reset,
83 .can_queue = 1,
84 .this_id = NSP_INITIATOR_ID,
85 .sg_tablesize = SG_ALL,
4af14d11 86 .dma_boundary = PAGE_SIZE - 1,
1da177e4
LT
87};
88
1da177e4
LT
89static nsp_hw_data nsp_data_base; /* attach <-> detect glue */
90
91
92
93/*
94 * debug, error print
95 */
96#ifndef NSP_DEBUG
97# define NSP_DEBUG_MASK 0x000000
98# define nsp_msg(type, args...) nsp_cs_message("", 0, (type), args)
99# define nsp_dbg(mask, args...) /* */
100#else
101# define NSP_DEBUG_MASK 0xffffff
102# define nsp_msg(type, args...) \
cadbd4a5 103 nsp_cs_message (__func__, __LINE__, (type), args)
1da177e4 104# define nsp_dbg(mask, args...) \
cadbd4a5 105 nsp_cs_dmessage(__func__, __LINE__, (mask), args)
1da177e4
LT
106#endif
107
108#define NSP_DEBUG_QUEUECOMMAND BIT(0)
109#define NSP_DEBUG_REGISTER BIT(1)
110#define NSP_DEBUG_AUTOSCSI BIT(2)
111#define NSP_DEBUG_INTR BIT(3)
112#define NSP_DEBUG_SGLIST BIT(4)
113#define NSP_DEBUG_BUSFREE BIT(5)
114#define NSP_DEBUG_CDB_CONTENTS BIT(6)
115#define NSP_DEBUG_RESELECTION BIT(7)
116#define NSP_DEBUG_MSGINOCCUR BIT(8)
117#define NSP_DEBUG_EEPROM BIT(9)
118#define NSP_DEBUG_MSGOUTOCCUR BIT(10)
119#define NSP_DEBUG_BUSRESET BIT(11)
120#define NSP_DEBUG_RESTART BIT(12)
121#define NSP_DEBUG_SYNC BIT(13)
122#define NSP_DEBUG_WAIT BIT(14)
123#define NSP_DEBUG_TARGETFLAG BIT(15)
124#define NSP_DEBUG_PROC BIT(16)
125#define NSP_DEBUG_INIT BIT(17)
126#define NSP_DEBUG_DATA_IO BIT(18)
127#define NSP_SPECIAL_PRINT_REGISTER BIT(20)
128
129#define NSP_DEBUG_BUF_LEN 150
130
040cd232
BH
131static inline void nsp_inc_resid(struct scsi_cmnd *SCpnt, int residInc)
132{
133 scsi_set_resid(SCpnt, scsi_get_resid(SCpnt) + residInc);
134}
135
af0b55d0 136__printf(4, 5)
1da177e4
LT
137static void nsp_cs_message(const char *func, int line, char *type, char *fmt, ...)
138{
139 va_list args;
140 char buf[NSP_DEBUG_BUF_LEN];
141
142 va_start(args, fmt);
143 vsnprintf(buf, sizeof(buf), fmt, args);
144 va_end(args);
145
146#ifndef NSP_DEBUG
147 printk("%snsp_cs: %s\n", type, buf);
148#else
149 printk("%snsp_cs: %s (%d): %s\n", type, func, line, buf);
150#endif
151}
152
153#ifdef NSP_DEBUG
154static void nsp_cs_dmessage(const char *func, int line, int mask, char *fmt, ...)
155{
156 va_list args;
157 char buf[NSP_DEBUG_BUF_LEN];
158
159 va_start(args, fmt);
160 vsnprintf(buf, sizeof(buf), fmt, args);
161 va_end(args);
162
163 if (mask & NSP_DEBUG_MASK) {
164 printk("nsp_cs-debug: 0x%x %s (%d): %s\n", mask, func, line, buf);
165 }
166}
167#endif
168
169/***********************************************************/
170
171/*====================================================
172 * Clenaup parameters and call done() functions.
173 * You must be set SCpnt->result before call this function.
174 */
0fc82d5e 175static void nsp_scsi_done(struct scsi_cmnd *SCpnt)
1da177e4
LT
176{
177 nsp_hw_data *data = (nsp_hw_data *)SCpnt->device->host->hostdata;
178
179 data->CurrentSC = NULL;
180
ca0d62d2 181 scsi_done(SCpnt);
1da177e4
LT
182}
183
af049dfd 184static int nsp_queuecommand_lck(struct scsi_cmnd *SCpnt)
1da177e4
LT
185{
186#ifdef NSP_DEBUG
187 /*unsigned int host_id = SCpnt->device->host->this_id;*/
188 /*unsigned int base = SCpnt->device->host->io_port;*/
422c0d61 189 unsigned char target = scmd_id(SCpnt);
1da177e4
LT
190#endif
191 nsp_hw_data *data = (nsp_hw_data *)SCpnt->device->host->hostdata;
192
040cd232 193 nsp_dbg(NSP_DEBUG_QUEUECOMMAND,
9cb78c16 194 "SCpnt=0x%p target=%d lun=%llu sglist=0x%p bufflen=%d sg_count=%d",
040cd232
BH
195 SCpnt, target, SCpnt->device->lun, scsi_sglist(SCpnt),
196 scsi_bufflen(SCpnt), scsi_sg_count(SCpnt));
1da177e4
LT
197 //nsp_dbg(NSP_DEBUG_QUEUECOMMAND, "before CurrentSC=0x%p", data->CurrentSC);
198
1da177e4
LT
199 if (data->CurrentSC != NULL) {
200 nsp_msg(KERN_DEBUG, "CurrentSC!=NULL this can't be happen");
201 SCpnt->result = DID_BAD_TARGET << 16;
202 nsp_scsi_done(SCpnt);
203 return 0;
204 }
205
206#if 0
207 /* XXX: pcmcia-cs generates SCSI command with "scsi_info" utility.
208 This makes kernel crash when suspending... */
209 if (data->ScsiInfo->stop != 0) {
210 nsp_msg(KERN_INFO, "suspending device. reject command.");
211 SCpnt->result = DID_BAD_TARGET << 16;
212 nsp_scsi_done(SCpnt);
213 return SCSI_MLQUEUE_HOST_BUSY;
214 }
215#endif
216
217 show_command(SCpnt);
218
219 data->CurrentSC = SCpnt;
220
50207148 221 SCpnt->SCp.Status = SAM_STAT_CHECK_CONDITION;
1da177e4
LT
222 SCpnt->SCp.Message = 0;
223 SCpnt->SCp.have_data_in = IO_UNKNOWN;
224 SCpnt->SCp.sent_command = 0;
225 SCpnt->SCp.phase = PH_UNDETERMINED;
040cd232 226 scsi_set_resid(SCpnt, scsi_bufflen(SCpnt));
1da177e4
LT
227
228 /* setup scratch area
229 SCp.ptr : buffer pointer
230 SCp.this_residual : buffer length
231 SCp.buffer : next buffer
232 SCp.buffers_residual : left buffers in list
233 SCp.phase : current state of the command */
040cd232
BH
234 if (scsi_bufflen(SCpnt)) {
235 SCpnt->SCp.buffer = scsi_sglist(SCpnt);
1da177e4
LT
236 SCpnt->SCp.ptr = BUFFER_ADDR;
237 SCpnt->SCp.this_residual = SCpnt->SCp.buffer->length;
040cd232 238 SCpnt->SCp.buffers_residual = scsi_sg_count(SCpnt) - 1;
1da177e4 239 } else {
040cd232
BH
240 SCpnt->SCp.ptr = NULL;
241 SCpnt->SCp.this_residual = 0;
1da177e4
LT
242 SCpnt->SCp.buffer = NULL;
243 SCpnt->SCp.buffers_residual = 0;
244 }
245
246 if (nsphw_start_selection(SCpnt) == FALSE) {
247 nsp_dbg(NSP_DEBUG_QUEUECOMMAND, "selection fail");
248 SCpnt->result = DID_BUS_BUSY << 16;
249 nsp_scsi_done(SCpnt);
250 return 0;
251 }
252
253
254 //nsp_dbg(NSP_DEBUG_QUEUECOMMAND, "out");
255#ifdef NSP_DEBUG
256 data->CmdId++;
257#endif
258 return 0;
259}
260
f281233d
JG
261static DEF_SCSI_QCMD(nsp_queuecommand)
262
1da177e4
LT
263/*
264 * setup PIO FIFO transfer mode and enable/disable to data out
265 */
266static void nsp_setup_fifo(nsp_hw_data *data, int enabled)
267{
268 unsigned int base = data->BaseAddress;
269 unsigned char transfer_mode_reg;
270
271 //nsp_dbg(NSP_DEBUG_DATA_IO, "enabled=%d", enabled);
272
273 if (enabled != FALSE) {
274 transfer_mode_reg = TRANSFER_GO | BRAIND;
275 } else {
276 transfer_mode_reg = 0;
277 }
278
279 transfer_mode_reg |= data->TransferMode;
280
281 nsp_index_write(base, TRANSFERMODE, transfer_mode_reg);
282}
283
284static void nsphw_init_sync(nsp_hw_data *data)
285{
286 sync_data tmp_sync = { .SyncNegotiation = SYNC_NOT_YET,
287 .SyncPeriod = 0,
288 .SyncOffset = 0
289 };
290 int i;
291
292 /* setup sync data */
293 for ( i = 0; i < ARRAY_SIZE(data->Sync); i++ ) {
294 data->Sync[i] = tmp_sync;
295 }
296}
297
298/*
299 * Initialize Ninja hardware
300 */
301static int nsphw_init(nsp_hw_data *data)
302{
303 unsigned int base = data->BaseAddress;
304
305 nsp_dbg(NSP_DEBUG_INIT, "in base=0x%x", base);
306
307 data->ScsiClockDiv = CLOCK_40M | FAST_20;
308 data->CurrentSC = NULL;
309 data->FifoCount = 0;
310 data->TransferMode = MODE_IO8;
311
312 nsphw_init_sync(data);
313
314 /* block all interrupts */
315 nsp_write(base, IRQCONTROL, IRQCONTROL_ALLMASK);
316
317 /* setup SCSI interface */
318 nsp_write(base, IFSELECT, IF_IFSEL);
319
320 nsp_index_write(base, SCSIIRQMODE, 0);
321
322 nsp_index_write(base, TRANSFERMODE, MODE_IO8);
323 nsp_index_write(base, CLOCKDIV, data->ScsiClockDiv);
324
325 nsp_index_write(base, PARITYCTRL, 0);
326 nsp_index_write(base, POINTERCLR, POINTER_CLEAR |
327 ACK_COUNTER_CLEAR |
328 REQ_COUNTER_CLEAR |
329 HOST_COUNTER_CLEAR);
330
331 /* setup fifo asic */
332 nsp_write(base, IFSELECT, IF_REGSEL);
333 nsp_index_write(base, TERMPWRCTRL, 0);
334 if ((nsp_index_read(base, OTHERCONTROL) & TPWR_SENSE) == 0) {
335 nsp_msg(KERN_INFO, "terminator power on");
336 nsp_index_write(base, TERMPWRCTRL, POWER_ON);
337 }
338
339 nsp_index_write(base, TIMERCOUNT, 0);
340 nsp_index_write(base, TIMERCOUNT, 0); /* requires 2 times!! */
341
342 nsp_index_write(base, SYNCREG, 0);
343 nsp_index_write(base, ACKWIDTH, 0);
344
345 /* enable interrupts and ack them */
346 nsp_index_write(base, SCSIIRQMODE, SCSI_PHASE_CHANGE_EI |
347 RESELECT_EI |
348 SCSI_RESET_IRQ_EI );
349 nsp_write(base, IRQCONTROL, IRQCONTROL_ALLCLEAR);
350
351 nsp_setup_fifo(data, FALSE);
352
353 return TRUE;
354}
355
356/*
357 * Start selection phase
358 */
0fc82d5e 359static int nsphw_start_selection(struct scsi_cmnd *SCpnt)
1da177e4
LT
360{
361 unsigned int host_id = SCpnt->device->host->this_id;
362 unsigned int base = SCpnt->device->host->io_port;
422c0d61 363 unsigned char target = scmd_id(SCpnt);
1da177e4
LT
364 nsp_hw_data *data = (nsp_hw_data *)SCpnt->device->host->hostdata;
365 int time_out;
366 unsigned char phase, arbit;
367
368 //nsp_dbg(NSP_DEBUG_RESELECTION, "in");
369
370 phase = nsp_index_read(base, SCSIBUSMON);
371 if(phase != BUSMON_BUS_FREE) {
372 //nsp_dbg(NSP_DEBUG_RESELECTION, "bus busy");
373 return FALSE;
374 }
375
376 /* start arbitration */
377 //nsp_dbg(NSP_DEBUG_RESELECTION, "start arbit");
378 SCpnt->SCp.phase = PH_ARBSTART;
379 nsp_index_write(base, SETARBIT, ARBIT_GO);
380
381 time_out = 1000;
382 do {
383 /* XXX: what a stupid chip! */
384 arbit = nsp_index_read(base, ARBITSTATUS);
385 //nsp_dbg(NSP_DEBUG_RESELECTION, "arbit=%d, wait_count=%d", arbit, wait_count);
386 udelay(1); /* hold 1.2us */
387 } while((arbit & (ARBIT_WIN | ARBIT_FAIL)) == 0 &&
388 (time_out-- != 0));
389
390 if (!(arbit & ARBIT_WIN)) {
391 //nsp_dbg(NSP_DEBUG_RESELECTION, "arbit fail");
392 nsp_index_write(base, SETARBIT, ARBIT_FLAG_CLEAR);
393 return FALSE;
394 }
395
396 /* assert select line */
397 //nsp_dbg(NSP_DEBUG_RESELECTION, "assert SEL line");
398 SCpnt->SCp.phase = PH_SELSTART;
399 udelay(3); /* wait 2.4us */
400 nsp_index_write(base, SCSIDATALATCH, BIT(host_id) | BIT(target));
401 nsp_index_write(base, SCSIBUSCTRL, SCSI_SEL | SCSI_BSY | SCSI_ATN);
402 udelay(2); /* wait >1.2us */
403 nsp_index_write(base, SCSIBUSCTRL, SCSI_SEL | SCSI_BSY | SCSI_DATAOUT_ENB | SCSI_ATN);
404 nsp_index_write(base, SETARBIT, ARBIT_FLAG_CLEAR);
405 /*udelay(1);*/ /* wait >90ns */
406 nsp_index_write(base, SCSIBUSCTRL, SCSI_SEL | SCSI_DATAOUT_ENB | SCSI_ATN);
407
408 /* check selection timeout */
409 nsp_start_timer(SCpnt, 1000/51);
410 data->SelectionTimeOut = 1;
411
412 return TRUE;
413}
414
415struct nsp_sync_table {
416 unsigned int min_period;
417 unsigned int max_period;
418 unsigned int chip_period;
419 unsigned int ack_width;
420};
421
422static struct nsp_sync_table nsp_sync_table_40M[] = {
423 {0x0c, 0x0c, 0x1, 0}, /* 20MB 50ns*/
424 {0x19, 0x19, 0x3, 1}, /* 10MB 100ns*/
425 {0x1a, 0x25, 0x5, 2}, /* 7.5MB 150ns*/
426 {0x26, 0x32, 0x7, 3}, /* 5MB 200ns*/
427 { 0, 0, 0, 0},
428};
429
430static struct nsp_sync_table nsp_sync_table_20M[] = {
431 {0x19, 0x19, 0x1, 0}, /* 10MB 100ns*/
432 {0x1a, 0x25, 0x2, 0}, /* 7.5MB 150ns*/
433 {0x26, 0x32, 0x3, 1}, /* 5MB 200ns*/
434 { 0, 0, 0, 0},
435};
436
437/*
438 * setup synchronous data transfer mode
439 */
0fc82d5e 440static int nsp_analyze_sdtr(struct scsi_cmnd *SCpnt)
1da177e4 441{
422c0d61 442 unsigned char target = scmd_id(SCpnt);
1da177e4
LT
443// unsigned char lun = SCpnt->device->lun;
444 nsp_hw_data *data = (nsp_hw_data *)SCpnt->device->host->hostdata;
445 sync_data *sync = &(data->Sync[target]);
446 struct nsp_sync_table *sync_table;
447 unsigned int period, offset;
448 int i;
449
450
451 nsp_dbg(NSP_DEBUG_SYNC, "in");
452
453 period = sync->SyncPeriod;
454 offset = sync->SyncOffset;
455
456 nsp_dbg(NSP_DEBUG_SYNC, "period=0x%x, offset=0x%x", period, offset);
457
458 if ((data->ScsiClockDiv & (BIT(0)|BIT(1))) == CLOCK_20M) {
459 sync_table = nsp_sync_table_20M;
460 } else {
461 sync_table = nsp_sync_table_40M;
462 }
463
464 for ( i = 0; sync_table->max_period != 0; i++, sync_table++) {
465 if ( period >= sync_table->min_period &&
466 period <= sync_table->max_period ) {
467 break;
468 }
469 }
470
471 if (period != 0 && sync_table->max_period == 0) {
472 /*
473 * No proper period/offset found
474 */
475 nsp_dbg(NSP_DEBUG_SYNC, "no proper period/offset");
476
477 sync->SyncPeriod = 0;
478 sync->SyncOffset = 0;
479 sync->SyncRegister = 0;
480 sync->AckWidth = 0;
481
482 return FALSE;
483 }
484
485 sync->SyncRegister = (sync_table->chip_period << SYNCREG_PERIOD_SHIFT) |
486 (offset & SYNCREG_OFFSET_MASK);
487 sync->AckWidth = sync_table->ack_width;
488
489 nsp_dbg(NSP_DEBUG_SYNC, "sync_reg=0x%x, ack_width=0x%x", sync->SyncRegister, sync->AckWidth);
490
491 return TRUE;
492}
493
494
495/*
496 * start ninja hardware timer
497 */
0fc82d5e 498static void nsp_start_timer(struct scsi_cmnd *SCpnt, int time)
1da177e4
LT
499{
500 unsigned int base = SCpnt->device->host->io_port;
501 nsp_hw_data *data = (nsp_hw_data *)SCpnt->device->host->hostdata;
502
503 //nsp_dbg(NSP_DEBUG_INTR, "in SCpnt=0x%p, time=%d", SCpnt, time);
504 data->TimerCount = time;
505 nsp_index_write(base, TIMERCOUNT, time);
506}
507
508/*
509 * wait for bus phase change
510 */
0fc82d5e
HK
511static int nsp_negate_signal(struct scsi_cmnd *SCpnt, unsigned char mask,
512 char *str)
1da177e4
LT
513{
514 unsigned int base = SCpnt->device->host->io_port;
515 unsigned char reg;
516 int time_out;
517
518 //nsp_dbg(NSP_DEBUG_INTR, "in");
519
520 time_out = 100;
521
522 do {
523 reg = nsp_index_read(base, SCSIBUSMON);
524 if (reg == 0xff) {
525 break;
526 }
0454c740 527 } while ((--time_out != 0) && (reg & mask) != 0);
1da177e4
LT
528
529 if (time_out == 0) {
9b13494c 530 nsp_msg(KERN_DEBUG, " %s signal off timeout", str);
1da177e4
LT
531 }
532
533 return 0;
534}
535
536/*
537 * expect Ninja Irq
538 */
0fc82d5e
HK
539static int nsp_expect_signal(struct scsi_cmnd *SCpnt,
540 unsigned char current_phase,
541 unsigned char mask)
1da177e4
LT
542{
543 unsigned int base = SCpnt->device->host->io_port;
544 int time_out;
545 unsigned char phase, i_src;
546
547 //nsp_dbg(NSP_DEBUG_INTR, "current_phase=0x%x, mask=0x%x", current_phase, mask);
548
549 time_out = 100;
550 do {
551 phase = nsp_index_read(base, SCSIBUSMON);
552 if (phase == 0xff) {
553 //nsp_dbg(NSP_DEBUG_INTR, "ret -1");
554 return -1;
555 }
556 i_src = nsp_read(base, IRQSTATUS);
557 if (i_src & IRQSTATUS_SCSI) {
558 //nsp_dbg(NSP_DEBUG_INTR, "ret 0 found scsi signal");
559 return 0;
560 }
561 if ((phase & mask) != 0 && (phase & BUSMON_PHASE_MASK) == current_phase) {
562 //nsp_dbg(NSP_DEBUG_INTR, "ret 1 phase=0x%x", phase);
563 return 1;
564 }
565 } while(time_out-- != 0);
566
567 //nsp_dbg(NSP_DEBUG_INTR, "timeout");
568 return -1;
569}
570
571/*
572 * transfer SCSI message
573 */
0fc82d5e 574static int nsp_xfer(struct scsi_cmnd *SCpnt, int phase)
1da177e4
LT
575{
576 unsigned int base = SCpnt->device->host->io_port;
577 nsp_hw_data *data = (nsp_hw_data *)SCpnt->device->host->hostdata;
578 char *buf = data->MsgBuffer;
579 int len = min(MSGBUF_SIZE, data->MsgLen);
580 int ptr;
581 int ret;
582
583 //nsp_dbg(NSP_DEBUG_DATA_IO, "in");
584 for (ptr = 0; len > 0; len--, ptr++) {
585
586 ret = nsp_expect_signal(SCpnt, phase, BUSMON_REQ);
587 if (ret <= 0) {
588 nsp_dbg(NSP_DEBUG_DATA_IO, "xfer quit");
589 return 0;
590 }
591
592 /* if last byte, negate ATN */
593 if (len == 1 && SCpnt->SCp.phase == PH_MSG_OUT) {
594 nsp_index_write(base, SCSIBUSCTRL, AUTODIRECTION | ACKENB);
595 }
596
597 /* read & write message */
598 if (phase & BUSMON_IO) {
599 nsp_dbg(NSP_DEBUG_DATA_IO, "read msg");
600 buf[ptr] = nsp_index_read(base, SCSIDATAWITHACK);
601 } else {
602 nsp_dbg(NSP_DEBUG_DATA_IO, "write msg");
603 nsp_index_write(base, SCSIDATAWITHACK, buf[ptr]);
604 }
605 nsp_negate_signal(SCpnt, BUSMON_ACK, "xfer<ack>");
606
607 }
608 return len;
609}
610
611/*
612 * get extra SCSI data from fifo
613 */
0fc82d5e 614static int nsp_dataphase_bypass(struct scsi_cmnd *SCpnt)
1da177e4
LT
615{
616 nsp_hw_data *data = (nsp_hw_data *)SCpnt->device->host->hostdata;
617 unsigned int count;
618
619 //nsp_dbg(NSP_DEBUG_DATA_IO, "in");
620
621 if (SCpnt->SCp.have_data_in != IO_IN) {
622 return 0;
623 }
624
625 count = nsp_fifo_count(SCpnt);
626 if (data->FifoCount == count) {
627 //nsp_dbg(NSP_DEBUG_DATA_IO, "not use bypass quirk");
628 return 0;
629 }
630
631 /*
632 * XXX: NSP_QUIRK
633 * data phase skip only occures in case of SCSI_LOW_READ
634 */
635 nsp_dbg(NSP_DEBUG_DATA_IO, "use bypass quirk");
636 SCpnt->SCp.phase = PH_DATA;
637 nsp_pio_read(SCpnt);
638 nsp_setup_fifo(data, FALSE);
639
640 return 0;
641}
642
643/*
644 * accept reselection
645 */
0fc82d5e 646static int nsp_reselected(struct scsi_cmnd *SCpnt)
1da177e4
LT
647{
648 unsigned int base = SCpnt->device->host->io_port;
649 unsigned int host_id = SCpnt->device->host->this_id;
650 //nsp_hw_data *data = (nsp_hw_data *)SCpnt->device->host->hostdata;
651 unsigned char bus_reg;
652 unsigned char id_reg, tmp;
653 int target;
654
655 nsp_dbg(NSP_DEBUG_RESELECTION, "in");
656
657 id_reg = nsp_index_read(base, RESELECTID);
658 tmp = id_reg & (~BIT(host_id));
659 target = 0;
660 while(tmp != 0) {
661 if (tmp & BIT(0)) {
662 break;
663 }
664 tmp >>= 1;
665 target++;
666 }
667
422c0d61 668 if (scmd_id(SCpnt) != target) {
1da177e4
LT
669 nsp_msg(KERN_ERR, "XXX: reselect ID must be %d in this implementation.", target);
670 }
671
672 nsp_negate_signal(SCpnt, BUSMON_SEL, "reselect<SEL>");
673
674 nsp_nexus(SCpnt);
675 bus_reg = nsp_index_read(base, SCSIBUSCTRL) & ~(SCSI_BSY | SCSI_ATN);
676 nsp_index_write(base, SCSIBUSCTRL, bus_reg);
677 nsp_index_write(base, SCSIBUSCTRL, bus_reg | AUTODIRECTION | ACKENB);
678
679 return TRUE;
680}
681
682/*
683 * count how many data transferd
684 */
0fc82d5e 685static int nsp_fifo_count(struct scsi_cmnd *SCpnt)
1da177e4
LT
686{
687 unsigned int base = SCpnt->device->host->io_port;
688 unsigned int count;
97a33483 689 unsigned int l, m, h;
1da177e4
LT
690
691 nsp_index_write(base, POINTERCLR, POINTER_CLEAR | ACK_COUNTER);
692
693 l = nsp_index_read(base, TRANSFERCOUNT);
694 m = nsp_index_read(base, TRANSFERCOUNT);
695 h = nsp_index_read(base, TRANSFERCOUNT);
97a33483 696 nsp_index_read(base, TRANSFERCOUNT); /* required this! */
1da177e4
LT
697
698 count = (h << 16) | (m << 8) | (l << 0);
699
700 //nsp_dbg(NSP_DEBUG_DATA_IO, "count=0x%x", count);
701
702 return count;
703}
704
705/* fifo size */
706#define RFIFO_CRIT 64
707#define WFIFO_CRIT 64
708
709/*
710 * read data in DATA IN phase
711 */
0fc82d5e 712static void nsp_pio_read(struct scsi_cmnd *SCpnt)
1da177e4
LT
713{
714 unsigned int base = SCpnt->device->host->io_port;
715 unsigned long mmio_base = SCpnt->device->host->base;
716 nsp_hw_data *data = (nsp_hw_data *)SCpnt->device->host->hostdata;
717 long time_out;
718 int ocount, res;
719 unsigned char stat, fifo_stat;
720
721 ocount = data->FifoCount;
722
723 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",
040cd232
BH
724 SCpnt, scsi_get_resid(SCpnt), ocount, SCpnt->SCp.ptr,
725 SCpnt->SCp.this_residual, SCpnt->SCp.buffer,
726 SCpnt->SCp.buffers_residual);
1da177e4
LT
727
728 time_out = 1000;
729
730 while ((time_out-- != 0) &&
731 (SCpnt->SCp.this_residual > 0 || SCpnt->SCp.buffers_residual > 0 ) ) {
732
733 stat = nsp_index_read(base, SCSIBUSMON);
734 stat &= BUSMON_PHASE_MASK;
735
736
737 res = nsp_fifo_count(SCpnt) - ocount;
738 //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);
25985edc 739 if (res == 0) { /* if some data available ? */
1da177e4
LT
740 if (stat == BUSPHASE_DATA_IN) { /* phase changed? */
741 //nsp_dbg(NSP_DEBUG_DATA_IO, " wait for data this=%d", SCpnt->SCp.this_residual);
742 continue;
743 } else {
744 nsp_dbg(NSP_DEBUG_DATA_IO, "phase changed stat=0x%x", stat);
745 break;
746 }
747 }
748
749 fifo_stat = nsp_read(base, FIFOSTATUS);
750 if ((fifo_stat & FIFOSTATUS_FULL_EMPTY) == 0 &&
751 stat == BUSPHASE_DATA_IN) {
752 continue;
753 }
754
755 res = min(res, SCpnt->SCp.this_residual);
756
757 switch (data->TransferMode) {
758 case MODE_IO32:
759 res &= ~(BIT(1)|BIT(0)); /* align 4 */
760 nsp_fifo32_read(base, SCpnt->SCp.ptr, res >> 2);
761 break;
762 case MODE_IO8:
763 nsp_fifo8_read (base, SCpnt->SCp.ptr, res );
764 break;
765
766 case MODE_MEM32:
767 res &= ~(BIT(1)|BIT(0)); /* align 4 */
768 nsp_mmio_fifo32_read(mmio_base, SCpnt->SCp.ptr, res >> 2);
769 break;
770
771 default:
772 nsp_dbg(NSP_DEBUG_DATA_IO, "unknown read mode");
773 return;
774 }
775
040cd232 776 nsp_inc_resid(SCpnt, -res);
1da177e4
LT
777 SCpnt->SCp.ptr += res;
778 SCpnt->SCp.this_residual -= res;
779 ocount += res;
780 //nsp_dbg(NSP_DEBUG_DATA_IO, "ptr=0x%p this_residual=0x%x ocount=0x%x", SCpnt->SCp.ptr, SCpnt->SCp.this_residual, ocount);
781
782 /* go to next scatter list if available */
783 if (SCpnt->SCp.this_residual == 0 &&
784 SCpnt->SCp.buffers_residual != 0 ) {
785 //nsp_dbg(NSP_DEBUG_DATA_IO, "scatterlist next timeout=%d", time_out);
786 SCpnt->SCp.buffers_residual--;
1b3a4640 787 SCpnt->SCp.buffer = sg_next(SCpnt->SCp.buffer);
1da177e4
LT
788 SCpnt->SCp.ptr = BUFFER_ADDR;
789 SCpnt->SCp.this_residual = SCpnt->SCp.buffer->length;
790 time_out = 1000;
791
792 //nsp_dbg(NSP_DEBUG_DATA_IO, "page: 0x%p, off: 0x%x", SCpnt->SCp.buffer->page, SCpnt->SCp.buffer->offset);
793 }
794 }
795
796 data->FifoCount = ocount;
797
0454c740 798 if (time_out < 0) {
1da177e4 799 nsp_msg(KERN_DEBUG, "pio read timeout resid=%d this_residual=%d buffers_residual=%d",
040cd232
BH
800 scsi_get_resid(SCpnt), SCpnt->SCp.this_residual,
801 SCpnt->SCp.buffers_residual);
1da177e4
LT
802 }
803 nsp_dbg(NSP_DEBUG_DATA_IO, "read ocount=0x%x", ocount);
040cd232
BH
804 nsp_dbg(NSP_DEBUG_DATA_IO, "r cmd=%d resid=0x%x\n", data->CmdId,
805 scsi_get_resid(SCpnt));
1da177e4
LT
806}
807
808/*
809 * write data in DATA OUT phase
810 */
0fc82d5e 811static void nsp_pio_write(struct scsi_cmnd *SCpnt)
1da177e4
LT
812{
813 unsigned int base = SCpnt->device->host->io_port;
814 unsigned long mmio_base = SCpnt->device->host->base;
815 nsp_hw_data *data = (nsp_hw_data *)SCpnt->device->host->hostdata;
816 int time_out;
817 int ocount, res;
818 unsigned char stat;
819
820 ocount = data->FifoCount;
821
822 nsp_dbg(NSP_DEBUG_DATA_IO, "in fifocount=%d ptr=0x%p this_residual=%d buffers=0x%p nbuf=%d resid=0x%x",
040cd232
BH
823 data->FifoCount, SCpnt->SCp.ptr, SCpnt->SCp.this_residual,
824 SCpnt->SCp.buffer, SCpnt->SCp.buffers_residual,
825 scsi_get_resid(SCpnt));
1da177e4
LT
826
827 time_out = 1000;
828
829 while ((time_out-- != 0) &&
830 (SCpnt->SCp.this_residual > 0 || SCpnt->SCp.buffers_residual > 0)) {
831 stat = nsp_index_read(base, SCSIBUSMON);
832 stat &= BUSMON_PHASE_MASK;
833
834 if (stat != BUSPHASE_DATA_OUT) {
835 res = ocount - nsp_fifo_count(SCpnt);
836
837 nsp_dbg(NSP_DEBUG_DATA_IO, "phase changed stat=0x%x, res=%d\n", stat, res);
838 /* Put back pointer */
040cd232 839 nsp_inc_resid(SCpnt, res);
1da177e4
LT
840 SCpnt->SCp.ptr -= res;
841 SCpnt->SCp.this_residual += res;
842 ocount -= res;
843
844 break;
845 }
846
847 res = ocount - nsp_fifo_count(SCpnt);
848 if (res > 0) { /* write all data? */
849 nsp_dbg(NSP_DEBUG_DATA_IO, "wait for all data out. ocount=0x%x res=%d", ocount, res);
850 continue;
851 }
852
853 res = min(SCpnt->SCp.this_residual, WFIFO_CRIT);
854
855 //nsp_dbg(NSP_DEBUG_DATA_IO, "ptr=0x%p this=0x%x res=0x%x", SCpnt->SCp.ptr, SCpnt->SCp.this_residual, res);
856 switch (data->TransferMode) {
857 case MODE_IO32:
858 res &= ~(BIT(1)|BIT(0)); /* align 4 */
859 nsp_fifo32_write(base, SCpnt->SCp.ptr, res >> 2);
860 break;
861 case MODE_IO8:
862 nsp_fifo8_write (base, SCpnt->SCp.ptr, res );
863 break;
864
865 case MODE_MEM32:
866 res &= ~(BIT(1)|BIT(0)); /* align 4 */
867 nsp_mmio_fifo32_write(mmio_base, SCpnt->SCp.ptr, res >> 2);
868 break;
869
870 default:
871 nsp_dbg(NSP_DEBUG_DATA_IO, "unknown write mode");
872 break;
873 }
874
040cd232 875 nsp_inc_resid(SCpnt, -res);
1da177e4
LT
876 SCpnt->SCp.ptr += res;
877 SCpnt->SCp.this_residual -= res;
878 ocount += res;
879
880 /* go to next scatter list if available */
881 if (SCpnt->SCp.this_residual == 0 &&
882 SCpnt->SCp.buffers_residual != 0 ) {
883 //nsp_dbg(NSP_DEBUG_DATA_IO, "scatterlist next");
884 SCpnt->SCp.buffers_residual--;
1b3a4640 885 SCpnt->SCp.buffer = sg_next(SCpnt->SCp.buffer);
1da177e4
LT
886 SCpnt->SCp.ptr = BUFFER_ADDR;
887 SCpnt->SCp.this_residual = SCpnt->SCp.buffer->length;
888 time_out = 1000;
889 }
890 }
891
892 data->FifoCount = ocount;
893
0454c740 894 if (time_out < 0) {
040cd232
BH
895 nsp_msg(KERN_DEBUG, "pio write timeout resid=0x%x",
896 scsi_get_resid(SCpnt));
1da177e4
LT
897 }
898 nsp_dbg(NSP_DEBUG_DATA_IO, "write ocount=0x%x", ocount);
040cd232
BH
899 nsp_dbg(NSP_DEBUG_DATA_IO, "w cmd=%d resid=0x%x\n", data->CmdId,
900 scsi_get_resid(SCpnt));
1da177e4
LT
901}
902#undef RFIFO_CRIT
903#undef WFIFO_CRIT
904
905/*
906 * setup synchronous/asynchronous data transfer mode
907 */
0fc82d5e 908static int nsp_nexus(struct scsi_cmnd *SCpnt)
1da177e4
LT
909{
910 unsigned int base = SCpnt->device->host->io_port;
422c0d61 911 unsigned char target = scmd_id(SCpnt);
1da177e4
LT
912// unsigned char lun = SCpnt->device->lun;
913 nsp_hw_data *data = (nsp_hw_data *)SCpnt->device->host->hostdata;
914 sync_data *sync = &(data->Sync[target]);
915
916 //nsp_dbg(NSP_DEBUG_DATA_IO, "in SCpnt=0x%p", SCpnt);
917
918 /* setup synch transfer registers */
919 nsp_index_write(base, SYNCREG, sync->SyncRegister);
920 nsp_index_write(base, ACKWIDTH, sync->AckWidth);
921
040cd232
BH
922 if (scsi_get_resid(SCpnt) % 4 != 0 ||
923 scsi_get_resid(SCpnt) <= PAGE_SIZE ) {
1da177e4
LT
924 data->TransferMode = MODE_IO8;
925 } else if (nsp_burst_mode == BURST_MEM32) {
926 data->TransferMode = MODE_MEM32;
927 } else if (nsp_burst_mode == BURST_IO32) {
928 data->TransferMode = MODE_IO32;
929 } else {
930 data->TransferMode = MODE_IO8;
931 }
932
933 /* setup pdma fifo */
934 nsp_setup_fifo(data, TRUE);
935
936 /* clear ack counter */
937 data->FifoCount = 0;
938 nsp_index_write(base, POINTERCLR, POINTER_CLEAR |
939 ACK_COUNTER_CLEAR |
940 REQ_COUNTER_CLEAR |
941 HOST_COUNTER_CLEAR);
942
943 return 0;
944}
945
946#include "nsp_message.c"
947/*
948 * interrupt handler
949 */
7d12e780 950static irqreturn_t nspintr(int irq, void *dev_id)
1da177e4
LT
951{
952 unsigned int base;
953 unsigned char irq_status, irq_phase, phase;
0fc82d5e 954 struct scsi_cmnd *tmpSC;
1da177e4
LT
955 unsigned char target, lun;
956 unsigned int *sync_neg;
957 int i, tmp;
958 nsp_hw_data *data;
959
960
961 //nsp_dbg(NSP_DEBUG_INTR, "dev_id=0x%p", dev_id);
962 //nsp_dbg(NSP_DEBUG_INTR, "host=0x%p", ((scsi_info_t *)dev_id)->host);
963
964 if ( dev_id != NULL &&
965 ((scsi_info_t *)dev_id)->host != NULL ) {
966 scsi_info_t *info = (scsi_info_t *)dev_id;
967
968 data = (nsp_hw_data *)info->host->hostdata;
969 } else {
970 nsp_dbg(NSP_DEBUG_INTR, "host data wrong");
971 return IRQ_NONE;
972 }
973
974 //nsp_dbg(NSP_DEBUG_INTR, "&nsp_data_base=0x%p, dev_id=0x%p", &nsp_data_base, dev_id);
975
976 base = data->BaseAddress;
977 //nsp_dbg(NSP_DEBUG_INTR, "base=0x%x", base);
978
979 /*
980 * interrupt check
981 */
982 nsp_write(base, IRQCONTROL, IRQCONTROL_IRQDISABLE);
983 irq_status = nsp_read(base, IRQSTATUS);
984 //nsp_dbg(NSP_DEBUG_INTR, "irq_status=0x%x", irq_status);
985 if ((irq_status == 0xff) || ((irq_status & IRQSTATUS_MASK) == 0)) {
986 nsp_write(base, IRQCONTROL, 0);
987 //nsp_dbg(NSP_DEBUG_INTR, "no irq/shared irq");
988 return IRQ_NONE;
989 }
990
991 /* XXX: IMPORTANT
992 * Do not read an irq_phase register if no scsi phase interrupt.
993 * Unless, you should lose a scsi phase interrupt.
994 */
995 phase = nsp_index_read(base, SCSIBUSMON);
996 if((irq_status & IRQSTATUS_SCSI) != 0) {
997 irq_phase = nsp_index_read(base, IRQPHASESENCE);
998 } else {
999 irq_phase = 0;
1000 }
1001
1002 //nsp_dbg(NSP_DEBUG_INTR, "irq_phase=0x%x", irq_phase);
1003
1004 /*
1005 * timer interrupt handler (scsi vs timer interrupts)
1006 */
1007 //nsp_dbg(NSP_DEBUG_INTR, "timercount=%d", data->TimerCount);
1008 if (data->TimerCount != 0) {
1009 //nsp_dbg(NSP_DEBUG_INTR, "stop timer");
1010 nsp_index_write(base, TIMERCOUNT, 0);
1011 nsp_index_write(base, TIMERCOUNT, 0);
1012 data->TimerCount = 0;
1013 }
1014
1015 if ((irq_status & IRQSTATUS_MASK) == IRQSTATUS_TIMER &&
1016 data->SelectionTimeOut == 0) {
1017 //nsp_dbg(NSP_DEBUG_INTR, "timer start");
1018 nsp_write(base, IRQCONTROL, IRQCONTROL_TIMER_CLEAR);
1019 return IRQ_HANDLED;
1020 }
1021
1022 nsp_write(base, IRQCONTROL, IRQCONTROL_TIMER_CLEAR | IRQCONTROL_FIFO_CLEAR);
1023
1024 if ((irq_status & IRQSTATUS_SCSI) &&
1025 (irq_phase & SCSI_RESET_IRQ)) {
1026 nsp_msg(KERN_ERR, "bus reset (power off?)");
1027
1028 nsphw_init(data);
1029 nsp_bus_reset(data);
1030
1031 if(data->CurrentSC != NULL) {
1032 tmpSC = data->CurrentSC;
1033 tmpSC->result = (DID_RESET << 16) |
1034 ((tmpSC->SCp.Message & 0xff) << 8) |
1035 ((tmpSC->SCp.Status & 0xff) << 0);
1036 nsp_scsi_done(tmpSC);
1037 }
1038 return IRQ_HANDLED;
1039 }
1040
1041 if (data->CurrentSC == NULL) {
1042 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);
1043 nsphw_init(data);
1044 nsp_bus_reset(data);
1045 return IRQ_HANDLED;
1046 }
1047
1048 tmpSC = data->CurrentSC;
1049 target = tmpSC->device->id;
1050 lun = tmpSC->device->lun;
1051 sync_neg = &(data->Sync[target].SyncNegotiation);
1052
1053 /*
1054 * parse hardware SCSI irq reasons register
1055 */
1056 if (irq_status & IRQSTATUS_SCSI) {
1057 if (irq_phase & RESELECT_IRQ) {
1058 nsp_dbg(NSP_DEBUG_INTR, "reselect");
1059 nsp_write(base, IRQCONTROL, IRQCONTROL_RESELECT_CLEAR);
1060 if (nsp_reselected(tmpSC) != FALSE) {
1061 return IRQ_HANDLED;
1062 }
1063 }
1064
1065 if ((irq_phase & (PHASE_CHANGE_IRQ | LATCHED_BUS_FREE)) == 0) {
1066 return IRQ_HANDLED;
1067 }
1068 }
1069
1070 //show_phase(tmpSC);
1071
1072 switch(tmpSC->SCp.phase) {
1073 case PH_SELSTART:
1074 // *sync_neg = SYNC_NOT_YET;
1075 if ((phase & BUSMON_BSY) == 0) {
1076 //nsp_dbg(NSP_DEBUG_INTR, "selection count=%d", data->SelectionTimeOut);
1077 if (data->SelectionTimeOut >= NSP_SELTIMEOUT) {
1078 nsp_dbg(NSP_DEBUG_INTR, "selection time out");
1079 data->SelectionTimeOut = 0;
1080 nsp_index_write(base, SCSIBUSCTRL, 0);
1081
1082 tmpSC->result = DID_TIME_OUT << 16;
1083 nsp_scsi_done(tmpSC);
1084
1085 return IRQ_HANDLED;
1086 }
1087 data->SelectionTimeOut += 1;
1088 nsp_start_timer(tmpSC, 1000/51);
1089 return IRQ_HANDLED;
1090 }
1091
1092 /* attention assert */
1093 //nsp_dbg(NSP_DEBUG_INTR, "attention assert");
1094 data->SelectionTimeOut = 0;
1095 tmpSC->SCp.phase = PH_SELECTED;
1096 nsp_index_write(base, SCSIBUSCTRL, SCSI_ATN);
1097 udelay(1);
1098 nsp_index_write(base, SCSIBUSCTRL, SCSI_ATN | AUTODIRECTION | ACKENB);
1099 return IRQ_HANDLED;
1100
1da177e4
LT
1101 case PH_RESELECT:
1102 //nsp_dbg(NSP_DEBUG_INTR, "phase reselect");
1103 // *sync_neg = SYNC_NOT_YET;
1104 if ((phase & BUSMON_PHASE_MASK) != BUSPHASE_MESSAGE_IN) {
1105
1106 tmpSC->result = DID_ABORT << 16;
1107 nsp_scsi_done(tmpSC);
1108 return IRQ_HANDLED;
1109 }
df561f66 1110 fallthrough;
1da177e4
LT
1111 default:
1112 if ((irq_status & (IRQSTATUS_SCSI | IRQSTATUS_FIFO)) == 0) {
1113 return IRQ_HANDLED;
1114 }
1115 break;
1116 }
1117
1118 /*
1119 * SCSI sequencer
1120 */
1121 //nsp_dbg(NSP_DEBUG_INTR, "start scsi seq");
1122
1123 /* normal disconnect */
1124 if (((tmpSC->SCp.phase == PH_MSG_IN) || (tmpSC->SCp.phase == PH_MSG_OUT)) &&
1125 (irq_phase & LATCHED_BUS_FREE) != 0 ) {
1126 nsp_dbg(NSP_DEBUG_INTR, "normal disconnect irq_status=0x%x, phase=0x%x, irq_phase=0x%x", irq_status, phase, irq_phase);
1127
1128 //*sync_neg = SYNC_NOT_YET;
1129
7e1c99e5 1130 /* all command complete and return status */
1c9eb798 1131 if (tmpSC->SCp.Message == COMMAND_COMPLETE) {
1da177e4
LT
1132 tmpSC->result = (DID_OK << 16) |
1133 ((tmpSC->SCp.Message & 0xff) << 8) |
1134 ((tmpSC->SCp.Status & 0xff) << 0);
1135 nsp_dbg(NSP_DEBUG_INTR, "command complete result=0x%x", tmpSC->result);
1136 nsp_scsi_done(tmpSC);
1137
1138 return IRQ_HANDLED;
1139 }
1140
1141 return IRQ_HANDLED;
1142 }
1143
1144
1145 /* check unexpected bus free state */
1146 if (phase == 0) {
1147 nsp_msg(KERN_DEBUG, "unexpected bus free. irq_status=0x%x, phase=0x%x, irq_phase=0x%x", irq_status, phase, irq_phase);
1148
1149 *sync_neg = SYNC_NG;
1150 tmpSC->result = DID_ERROR << 16;
1151 nsp_scsi_done(tmpSC);
1152 return IRQ_HANDLED;
1153 }
1154
1155 switch (phase & BUSMON_PHASE_MASK) {
1156 case BUSPHASE_COMMAND:
1157 nsp_dbg(NSP_DEBUG_INTR, "BUSPHASE_COMMAND");
1158 if ((phase & BUSMON_REQ) == 0) {
1159 nsp_dbg(NSP_DEBUG_INTR, "REQ == 0");
1160 return IRQ_HANDLED;
1161 }
1162
1163 tmpSC->SCp.phase = PH_COMMAND;
1164
1165 nsp_nexus(tmpSC);
1166
1167 /* write scsi command */
1168 nsp_dbg(NSP_DEBUG_INTR, "cmd_len=%d", tmpSC->cmd_len);
1169 nsp_index_write(base, COMMANDCTRL, CLEAR_COMMAND_POINTER);
1170 for (i = 0; i < tmpSC->cmd_len; i++) {
1171 nsp_index_write(base, COMMANDDATA, tmpSC->cmnd[i]);
1172 }
1173 nsp_index_write(base, COMMANDCTRL, CLEAR_COMMAND_POINTER | AUTO_COMMAND_GO);
1174 break;
1175
1176 case BUSPHASE_DATA_OUT:
1177 nsp_dbg(NSP_DEBUG_INTR, "BUSPHASE_DATA_OUT");
1178
1179 tmpSC->SCp.phase = PH_DATA;
1180 tmpSC->SCp.have_data_in = IO_OUT;
1181
1182 nsp_pio_write(tmpSC);
1183
1184 break;
1185
1186 case BUSPHASE_DATA_IN:
1187 nsp_dbg(NSP_DEBUG_INTR, "BUSPHASE_DATA_IN");
1188
1189 tmpSC->SCp.phase = PH_DATA;
1190 tmpSC->SCp.have_data_in = IO_IN;
1191
1192 nsp_pio_read(tmpSC);
1193
1194 break;
1195
1196 case BUSPHASE_STATUS:
1197 nsp_dataphase_bypass(tmpSC);
1198 nsp_dbg(NSP_DEBUG_INTR, "BUSPHASE_STATUS");
1199
1200 tmpSC->SCp.phase = PH_STATUS;
1201
1202 tmpSC->SCp.Status = nsp_index_read(base, SCSIDATAWITHACK);
1203 nsp_dbg(NSP_DEBUG_INTR, "message=0x%x status=0x%x", tmpSC->SCp.Message, tmpSC->SCp.Status);
1204
1205 break;
1206
1207 case BUSPHASE_MESSAGE_OUT:
1208 nsp_dbg(NSP_DEBUG_INTR, "BUSPHASE_MESSAGE_OUT");
1209 if ((phase & BUSMON_REQ) == 0) {
1210 goto timer_out;
1211 }
1212
1213 tmpSC->SCp.phase = PH_MSG_OUT;
1214
1215 //*sync_neg = SYNC_NOT_YET;
1216
1217 data->MsgLen = i = 0;
1218 data->MsgBuffer[i] = IDENTIFY(TRUE, lun); i++;
1219
1220 if (*sync_neg == SYNC_NOT_YET) {
1221 data->Sync[target].SyncPeriod = 0;
1222 data->Sync[target].SyncOffset = 0;
1223
1224 /**/
1c9eb798 1225 data->MsgBuffer[i] = EXTENDED_MESSAGE; i++;
1da177e4 1226 data->MsgBuffer[i] = 3; i++;
1c9eb798 1227 data->MsgBuffer[i] = EXTENDED_SDTR; i++;
1da177e4
LT
1228 data->MsgBuffer[i] = 0x0c; i++;
1229 data->MsgBuffer[i] = 15; i++;
1230 /**/
1231 }
1232 data->MsgLen = i;
1233
1234 nsp_analyze_sdtr(tmpSC);
1235 show_message(data);
1236 nsp_message_out(tmpSC);
1237 break;
1238
1239 case BUSPHASE_MESSAGE_IN:
1240 nsp_dataphase_bypass(tmpSC);
1241 nsp_dbg(NSP_DEBUG_INTR, "BUSPHASE_MESSAGE_IN");
1242 if ((phase & BUSMON_REQ) == 0) {
1243 goto timer_out;
1244 }
1245
1246 tmpSC->SCp.phase = PH_MSG_IN;
1247 nsp_message_in(tmpSC);
1248
1249 /**/
1250 if (*sync_neg == SYNC_NOT_YET) {
1251 //nsp_dbg(NSP_DEBUG_INTR, "sync target=%d,lun=%d",target,lun);
1252
1253 if (data->MsgLen >= 5 &&
1c9eb798 1254 data->MsgBuffer[0] == EXTENDED_MESSAGE &&
1da177e4 1255 data->MsgBuffer[1] == 3 &&
1c9eb798 1256 data->MsgBuffer[2] == EXTENDED_SDTR ) {
1da177e4
LT
1257 data->Sync[target].SyncPeriod = data->MsgBuffer[3];
1258 data->Sync[target].SyncOffset = data->MsgBuffer[4];
1259 //nsp_dbg(NSP_DEBUG_INTR, "sync ok, %d %d", data->MsgBuffer[3], data->MsgBuffer[4]);
1260 *sync_neg = SYNC_OK;
1261 } else {
1262 data->Sync[target].SyncPeriod = 0;
1263 data->Sync[target].SyncOffset = 0;
1264 *sync_neg = SYNC_NG;
1265 }
1266 nsp_analyze_sdtr(tmpSC);
1267 }
1268 /**/
1269
1270 /* search last messeage byte */
1271 tmp = -1;
1272 for (i = 0; i < data->MsgLen; i++) {
1273 tmp = data->MsgBuffer[i];
1c9eb798 1274 if (data->MsgBuffer[i] == EXTENDED_MESSAGE) {
1da177e4
LT
1275 i += (1 + data->MsgBuffer[i+1]);
1276 }
1277 }
1278 tmpSC->SCp.Message = tmp;
1279
1280 nsp_dbg(NSP_DEBUG_INTR, "message=0x%x len=%d", tmpSC->SCp.Message, data->MsgLen);
1281 show_message(data);
1282
1283 break;
1284
1285 case BUSPHASE_SELECT:
1286 default:
1287 nsp_dbg(NSP_DEBUG_INTR, "BUSPHASE other");
1288
1289 break;
1290 }
1291
1292 //nsp_dbg(NSP_DEBUG_INTR, "out");
1293 return IRQ_HANDLED;
1294
1295timer_out:
1296 nsp_start_timer(tmpSC, 1000/102);
1297 return IRQ_HANDLED;
1298}
1299
1300#ifdef NSP_DEBUG
1301#include "nsp_debug.c"
1302#endif /* NSP_DEBUG */
1303
1304/*----------------------------------------------------------------*/
1305/* look for ninja3 card and init if found */
1306/*----------------------------------------------------------------*/
d0be4a7d 1307static struct Scsi_Host *nsp_detect(struct scsi_host_template *sht)
1da177e4
LT
1308{
1309 struct Scsi_Host *host; /* registered host structure */
1310 nsp_hw_data *data_b = &nsp_data_base, *data;
1311
1312 nsp_dbg(NSP_DEBUG_INIT, "this_id=%d", sht->this_id);
1da177e4 1313 host = scsi_host_alloc(&nsp_driver_template, sizeof(nsp_hw_data));
1da177e4
LT
1314 if (host == NULL) {
1315 nsp_dbg(NSP_DEBUG_INIT, "host failed");
1316 return NULL;
1317 }
1318
1319 memcpy(host->hostdata, data_b, sizeof(nsp_hw_data));
1320 data = (nsp_hw_data *)host->hostdata;
1321 data->ScsiInfo->host = host;
1322#ifdef NSP_DEBUG
1323 data->CmdId = 0;
1324#endif
1325
1326 nsp_dbg(NSP_DEBUG_INIT, "irq=%d,%d", data_b->IrqNumber, ((nsp_hw_data *)host->hostdata)->IrqNumber);
1327
1328 host->unique_id = data->BaseAddress;
1329 host->io_port = data->BaseAddress;
1330 host->n_io_port = data->NumAddress;
1331 host->irq = data->IrqNumber;
1332 host->base = data->MmioAddress;
1333
1334 spin_lock_init(&(data->Lock));
1335
1336 snprintf(data->nspinfo,
1337 sizeof(data->nspinfo),
1338 "NinjaSCSI-3/32Bi Driver $Revision: 1.23 $ IO:0x%04lx-0x%04lx MMIO(virt addr):0x%04lx IRQ:%02d",
1339 host->io_port, host->io_port + host->n_io_port - 1,
1340 host->base,
1341 host->irq);
1342 sht->name = data->nspinfo;
1343
1344 nsp_dbg(NSP_DEBUG_INIT, "end");
1345
1346
1347 return host; /* detect done. */
1348}
1349
1da177e4
LT
1350/*----------------------------------------------------------------*/
1351/* return info string */
1352/*----------------------------------------------------------------*/
1353static const char *nsp_info(struct Scsi_Host *shpnt)
1354{
1355 nsp_hw_data *data = (nsp_hw_data *)shpnt->hostdata;
1356
1357 return data->nspinfo;
1358}
1359
63fd57cb 1360static int nsp_show_info(struct seq_file *m, struct Scsi_Host *host)
1da177e4
LT
1361{
1362 int id;
1da177e4
LT
1363 int speed;
1364 unsigned long flags;
1365 nsp_hw_data *data;
1da177e4 1366 int hostno;
774251ef 1367
1da177e4 1368 hostno = host->host_no;
1da177e4
LT
1369 data = (nsp_hw_data *)host->hostdata;
1370
3d30079c
RV
1371 seq_puts(m, "NinjaSCSI status\n\n"
1372 "Driver version: $Revision: 1.23 $\n");
0c3de38f
RV
1373 seq_printf(m, "SCSI host No.: %d\n", hostno);
1374 seq_printf(m, "IRQ: %d\n", host->irq);
1375 seq_printf(m, "IO: 0x%lx-0x%lx\n", host->io_port, host->io_port + host->n_io_port - 1);
1376 seq_printf(m, "MMIO(virtual address): 0x%lx-0x%lx\n", host->base, host->base + data->MmioLength - 1);
1377 seq_printf(m, "sg_tablesize: %d\n", host->sg_tablesize);
1da177e4 1378
91c40f24 1379 seq_puts(m, "burst transfer mode: ");
1da177e4
LT
1380 switch (nsp_burst_mode) {
1381 case BURST_IO8:
91c40f24 1382 seq_puts(m, "io8");
1da177e4
LT
1383 break;
1384 case BURST_IO32:
91c40f24 1385 seq_puts(m, "io32");
1da177e4
LT
1386 break;
1387 case BURST_MEM32:
91c40f24 1388 seq_puts(m, "mem32");
1da177e4
LT
1389 break;
1390 default:
91c40f24 1391 seq_puts(m, "???");
1da177e4
LT
1392 break;
1393 }
f50332ff 1394 seq_putc(m, '\n');
1da177e4
LT
1395
1396
1397 spin_lock_irqsave(&(data->Lock), flags);
0c3de38f 1398 seq_printf(m, "CurrentSC: 0x%p\n\n", data->CurrentSC);
1da177e4
LT
1399 spin_unlock_irqrestore(&(data->Lock), flags);
1400
91c40f24 1401 seq_puts(m, "SDTR status\n");
1da177e4
LT
1402 for(id = 0; id < ARRAY_SIZE(data->Sync); id++) {
1403
0c3de38f 1404 seq_printf(m, "id %d: ", id);
1da177e4
LT
1405
1406 if (id == host->this_id) {
91c40f24 1407 seq_puts(m, "----- NinjaSCSI-3 host adapter\n");
1da177e4
LT
1408 continue;
1409 }
1410
1411 switch(data->Sync[id].SyncNegotiation) {
1412 case SYNC_OK:
91c40f24 1413 seq_puts(m, " sync");
1da177e4
LT
1414 break;
1415 case SYNC_NG:
91c40f24 1416 seq_puts(m, "async");
1da177e4
LT
1417 break;
1418 case SYNC_NOT_YET:
91c40f24 1419 seq_puts(m, " none");
1da177e4
LT
1420 break;
1421 default:
91c40f24 1422 seq_puts(m, "?????");
1da177e4
LT
1423 break;
1424 }
1425
1426 if (data->Sync[id].SyncPeriod != 0) {
1427 speed = 1000000 / (data->Sync[id].SyncPeriod * 4);
1428
0c3de38f 1429 seq_printf(m, " transfer %d.%dMB/s, offset %d",
1da177e4
LT
1430 speed / 1000,
1431 speed % 1000,
1432 data->Sync[id].SyncOffset
1433 );
1434 }
f50332ff 1435 seq_putc(m, '\n');
1da177e4 1436 }
63fd57cb 1437 return 0;
1da177e4 1438}
1da177e4
LT
1439
1440/*---------------------------------------------------------------*/
1441/* error handler */
1442/*---------------------------------------------------------------*/
1443
1da177e4 1444/*
0fc82d5e 1445static int nsp_eh_abort(struct scsi_cmnd *SCpnt)
1da177e4
LT
1446{
1447 nsp_dbg(NSP_DEBUG_BUSRESET, "SCpnt=0x%p", SCpnt);
1448
1449 return nsp_eh_bus_reset(SCpnt);
1450}*/
1451
1da177e4
LT
1452static int nsp_bus_reset(nsp_hw_data *data)
1453{
1454 unsigned int base = data->BaseAddress;
1455 int i;
1456
1457 nsp_write(base, IRQCONTROL, IRQCONTROL_ALLMASK);
1458
1459 nsp_index_write(base, SCSIBUSCTRL, SCSI_RST);
1460 mdelay(100); /* 100ms */
1461 nsp_index_write(base, SCSIBUSCTRL, 0);
1462 for(i = 0; i < 5; i++) {
1463 nsp_index_read(base, IRQPHASESENCE); /* dummy read */
1464 }
1465
1466 nsphw_init_sync(data);
1467
1468 nsp_write(base, IRQCONTROL, IRQCONTROL_ALLCLEAR);
1469
1470 return SUCCESS;
1471}
1472
0fc82d5e 1473static int nsp_eh_bus_reset(struct scsi_cmnd *SCpnt)
1da177e4
LT
1474{
1475 nsp_hw_data *data = (nsp_hw_data *)SCpnt->device->host->hostdata;
1476
1477 nsp_dbg(NSP_DEBUG_BUSRESET, "SCpnt=0x%p", SCpnt);
1478
1479 return nsp_bus_reset(data);
1480}
1481
0fc82d5e 1482static int nsp_eh_host_reset(struct scsi_cmnd *SCpnt)
1da177e4
LT
1483{
1484 nsp_hw_data *data = (nsp_hw_data *)SCpnt->device->host->hostdata;
1485
1486 nsp_dbg(NSP_DEBUG_BUSRESET, "in");
1487
1488 nsphw_init(data);
1489
1490 return SUCCESS;
1491}
1492
1493
1494/**********************************************************************
1495 PCMCIA functions
1496**********************************************************************/
1497
15b99ac1 1498static int nsp_cs_probe(struct pcmcia_device *link)
1da177e4
LT
1499{
1500 scsi_info_t *info;
1da177e4 1501 nsp_hw_data *data = &nsp_data_base;
15b99ac1 1502 int ret;
1da177e4
LT
1503
1504 nsp_dbg(NSP_DEBUG_INIT, "in");
1505
1506 /* Create new SCSI device */
dd00cc48 1507 info = kzalloc(sizeof(*info), GFP_KERNEL);
f8cfa618 1508 if (info == NULL) { return -ENOMEM; }
fba395ee 1509 info->p_dev = link;
1da177e4
LT
1510 link->priv = info;
1511 data->ScsiInfo = info;
1512
1513 nsp_dbg(NSP_DEBUG_INIT, "info=0x%p", info);
1514
15b99ac1 1515 ret = nsp_cs_config(link);
1da177e4
LT
1516
1517 nsp_dbg(NSP_DEBUG_INIT, "link=0x%p", link);
15b99ac1 1518 return ret;
1da177e4
LT
1519} /* nsp_cs_attach */
1520
1521
fba395ee 1522static void nsp_cs_detach(struct pcmcia_device *link)
1da177e4 1523{
1da177e4
LT
1524 nsp_dbg(NSP_DEBUG_INIT, "in, link=0x%p", link);
1525
e2d40963
DB
1526 ((scsi_info_t *)link->priv)->stop = 1;
1527 nsp_cs_release(link);
1da177e4 1528
1da177e4
LT
1529 kfree(link->priv);
1530 link->priv = NULL;
1da177e4
LT
1531} /* nsp_cs_detach */
1532
1533
00990e7c 1534static int nsp_cs_config_check(struct pcmcia_device *p_dev, void *priv_data)
0e6f9d27 1535{
cdb13808 1536 nsp_hw_data *data = priv_data;
1da177e4 1537
00990e7c 1538 if (p_dev->config_index == 0)
0e6f9d27 1539 return -ENODEV;
1da177e4 1540
00990e7c
DB
1541 /* This reserves IO space but doesn't actually enable it */
1542 if (pcmcia_request_io(p_dev) != 0)
1543 goto next_entry;
1da177e4 1544
00990e7c 1545 if (resource_size(p_dev->resource[2])) {
440eed43
DB
1546 p_dev->resource[2]->flags |= (WIN_DATA_WIDTH_16 |
1547 WIN_MEMORY_TYPE_CM |
1548 WIN_ENABLE);
440eed43
DB
1549 if (p_dev->resource[2]->end < 0x1000)
1550 p_dev->resource[2]->end = 0x1000;
1551 if (pcmcia_request_window(p_dev, p_dev->resource[2], 0) != 0)
1552 goto next_entry;
1553 if (pcmcia_map_mem_page(p_dev, p_dev->resource[2],
00990e7c 1554 p_dev->card_addr) != 0)
440eed43
DB
1555 goto next_entry;
1556
1557 data->MmioAddress = (unsigned long)
4bdc0d67 1558 ioremap(p_dev->resource[2]->start,
cdb13808 1559 resource_size(p_dev->resource[2]));
440eed43 1560 data->MmioLength = resource_size(p_dev->resource[2]);
1da177e4 1561 }
440eed43
DB
1562 /* If we got this far, we're cool! */
1563 return 0;
1da177e4 1564
0e6f9d27
DB
1565next_entry:
1566 nsp_dbg(NSP_DEBUG_INIT, "next");
1567 pcmcia_disable_device(p_dev);
1568 return -ENODEV;
1569}
1570
1571static int nsp_cs_config(struct pcmcia_device *link)
1572{
1573 int ret;
1574 scsi_info_t *info = link->priv;
0e6f9d27
DB
1575 struct Scsi_Host *host;
1576 nsp_hw_data *data = &nsp_data_base;
1577
1578 nsp_dbg(NSP_DEBUG_INIT, "in");
1579
440eed43 1580 link->config_flags |= CONF_ENABLE_IRQ | CONF_AUTO_CHECK_VCC |
00990e7c
DB
1581 CONF_AUTO_SET_VPP | CONF_AUTO_AUDIO | CONF_AUTO_SET_IOMEM |
1582 CONF_AUTO_SET_IO;
440eed43 1583
cdb13808 1584 ret = pcmcia_loop_config(link, nsp_cs_config_check, data);
e794c01b 1585 if (ret)
0e6f9d27
DB
1586 goto cs_failed;
1587
eb14120f
DB
1588 if (pcmcia_request_irq(link, nspintr))
1589 goto cs_failed;
0e6f9d27 1590
1ac71e5a 1591 ret = pcmcia_enable_device(link);
0e6f9d27
DB
1592 if (ret)
1593 goto cs_failed;
1da177e4
LT
1594
1595 if (free_ports) {
9a017a91
DB
1596 if (link->resource[0]) {
1597 release_region(link->resource[0]->start,
1598 resource_size(link->resource[0]));
1da177e4 1599 }
9a017a91
DB
1600 if (link->resource[1]) {
1601 release_region(link->resource[1]->start,
1602 resource_size(link->resource[1]));
1da177e4
LT
1603 }
1604 }
1605
1606 /* Set port and IRQ */
9a017a91
DB
1607 data->BaseAddress = link->resource[0]->start;
1608 data->NumAddress = resource_size(link->resource[0]);
eb14120f 1609 data->IrqNumber = link->irq;
1da177e4
LT
1610
1611 nsp_dbg(NSP_DEBUG_INIT, "I/O[0x%x+0x%x] IRQ %d",
1612 data->BaseAddress, data->NumAddress, data->IrqNumber);
1613
1614 if(nsphw_init(data) == FALSE) {
1615 goto cs_failed;
1616 }
1617
1da177e4 1618 host = nsp_detect(&nsp_driver_template);
1da177e4
LT
1619
1620 if (host == NULL) {
1621 nsp_dbg(NSP_DEBUG_INIT, "detect failed");
1622 goto cs_failed;
1623 }
1624
1625
15b99ac1
DB
1626 ret = scsi_add_host (host, NULL);
1627 if (ret)
1628 goto cs_failed;
1629
1da177e4
LT
1630 scsi_scan_host(host);
1631
1da177e4
LT
1632 info->host = host;
1633
15b99ac1 1634 return 0;
1da177e4
LT
1635
1636 cs_failed:
1637 nsp_dbg(NSP_DEBUG_INIT, "config fail");
1da177e4
LT
1638 nsp_cs_release(link);
1639
15b99ac1 1640 return -ENODEV;
1da177e4 1641} /* nsp_cs_config */
1da177e4
LT
1642
1643
fba395ee 1644static void nsp_cs_release(struct pcmcia_device *link)
1da177e4
LT
1645{
1646 scsi_info_t *info = link->priv;
1647 nsp_hw_data *data = NULL;
1648
1649 if (info->host == NULL) {
1650 nsp_msg(KERN_DEBUG, "unexpected card release call.");
1651 } else {
1652 data = (nsp_hw_data *)info->host->hostdata;
1653 }
1654
1655 nsp_dbg(NSP_DEBUG_INIT, "link=0x%p", link);
1656
1657 /* Unlink the device chain */
1da177e4
LT
1658 if (info->host != NULL) {
1659 scsi_remove_host(info->host);
1660 }
1da177e4 1661
cdb13808 1662 if (resource_size(link->resource[2])) {
1da177e4
LT
1663 if (data != NULL) {
1664 iounmap((void *)(data->MmioAddress));
1665 }
1da177e4 1666 }
fba395ee 1667 pcmcia_disable_device(link);
5f2a71fc 1668
1da177e4
LT
1669 if (info->host != NULL) {
1670 scsi_host_put(info->host);
1671 }
1da177e4
LT
1672} /* nsp_cs_release */
1673
fba395ee 1674static int nsp_cs_suspend(struct pcmcia_device *link)
98e4c28b 1675{
98e4c28b
DB
1676 scsi_info_t *info = link->priv;
1677 nsp_hw_data *data;
1678
98e4c28b
DB
1679 nsp_dbg(NSP_DEBUG_INIT, "event: suspend");
1680
1681 if (info->host != NULL) {
1682 nsp_msg(KERN_INFO, "clear SDTR status");
1683
1684 data = (nsp_hw_data *)info->host->hostdata;
1685
1686 nsphw_init_sync(data);
1687 }
1688
1689 info->stop = 1;
1690
98e4c28b
DB
1691 return 0;
1692}
1693
fba395ee 1694static int nsp_cs_resume(struct pcmcia_device *link)
98e4c28b 1695{
98e4c28b
DB
1696 scsi_info_t *info = link->priv;
1697 nsp_hw_data *data;
1698
1699 nsp_dbg(NSP_DEBUG_INIT, "event: resume");
1700
98e4c28b
DB
1701 info->stop = 0;
1702
1703 if (info->host != NULL) {
1704 nsp_msg(KERN_INFO, "reset host and bus");
1705
1706 data = (nsp_hw_data *)info->host->hostdata;
1707
1708 nsphw_init (data);
1709 nsp_bus_reset(data);
1710 }
1711
1712 return 0;
1713}
1714
1da177e4
LT
1715/*======================================================================*
1716 * module entry point
1717 *====================================================================*/
25f8f54f 1718static const struct pcmcia_device_id nsp_cs_ids[] = {
aba14100
DB
1719 PCMCIA_DEVICE_PROD_ID123("IO DATA", "CBSC16 ", "1", 0x547e66dc, 0x0d63a3fd, 0x51de003a),
1720 PCMCIA_DEVICE_PROD_ID123("KME ", "SCSI-CARD-001", "1", 0x534c02bc, 0x52008408, 0x51de003a),
1721 PCMCIA_DEVICE_PROD_ID123("KME ", "SCSI-CARD-002", "1", 0x534c02bc, 0xcb09d5b2, 0x51de003a),
1722 PCMCIA_DEVICE_PROD_ID123("KME ", "SCSI-CARD-003", "1", 0x534c02bc, 0xbc0ee524, 0x51de003a),
1723 PCMCIA_DEVICE_PROD_ID123("KME ", "SCSI-CARD-004", "1", 0x534c02bc, 0x226a7087, 0x51de003a),
1724 PCMCIA_DEVICE_PROD_ID123("WBT", "NinjaSCSI-3", "R1.0", 0xc7ba805f, 0xfdc7c97d, 0x6973710e),
1725 PCMCIA_DEVICE_PROD_ID123("WORKBIT", "UltraNinja-16", "1", 0x28191418, 0xb70f4b09, 0x51de003a),
1726 PCMCIA_DEVICE_NULL
1727};
1728MODULE_DEVICE_TABLE(pcmcia, nsp_cs_ids);
1729
1da177e4 1730static struct pcmcia_driver nsp_driver = {
1e212f36 1731 .owner = THIS_MODULE,
2e9b981a 1732 .name = "nsp_cs",
15b99ac1 1733 .probe = nsp_cs_probe,
cc3b4866 1734 .remove = nsp_cs_detach,
aba14100 1735 .id_table = nsp_cs_ids,
98e4c28b
DB
1736 .suspend = nsp_cs_suspend,
1737 .resume = nsp_cs_resume,
1da177e4 1738};
dc245cfa 1739module_pcmcia_driver(nsp_driver);
1da177e4
LT
1740
1741/* end */