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