blob: c8755adfd917e616942c2ed1486cb6dd7b697425 [file] [log] [blame]
Linus Torvalds1da177e2005-04-16 15:20:36 -07001/*======================================================================
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
28/* $Id: nsp_cs.c,v 1.23 2003/08/18 11:09:19 elca Exp $ */
29
30#include <linux/version.h>
31#include <linux/module.h>
32#include <linux/kernel.h>
33#include <linux/init.h>
34#include <linux/sched.h>
35#include <linux/slab.h>
36#include <linux/string.h>
37#include <linux/timer.h>
38#include <linux/ioport.h>
39#include <linux/delay.h>
40#include <linux/interrupt.h>
41#include <linux/major.h>
42#include <linux/blkdev.h>
43#include <linux/stat.h>
44
45#include <asm/io.h>
46#include <asm/irq.h>
47
48#include <../drivers/scsi/scsi.h>
49#include <scsi/scsi_host.h>
50
51#include <scsi/scsi.h>
52#include <scsi/scsi_ioctl.h>
53
54#include <pcmcia/version.h>
55#include <pcmcia/cs_types.h>
56#include <pcmcia/cs.h>
57#include <pcmcia/cistpl.h>
58#include <pcmcia/cisreg.h>
59#include <pcmcia/ds.h>
60
61#include "nsp_cs.h"
62
63MODULE_AUTHOR("YOKOTA Hiroshi <yokota@netlab.is.tsukuba.ac.jp>");
64MODULE_DESCRIPTION("WorkBit NinjaSCSI-3 / NinjaSCSI-32Bi(16bit) PCMCIA SCSI host adapter module $Revision: 1.23 $");
65MODULE_SUPPORTED_DEVICE("sd,sr,sg,st");
66#ifdef MODULE_LICENSE
67MODULE_LICENSE("GPL");
68#endif
69
70#include "nsp_io.h"
71
72/*====================================================================*/
73/* Parameters that can be set with 'insmod' */
74
75static int nsp_burst_mode = BURST_MEM32;
76module_param(nsp_burst_mode, int, 0);
77MODULE_PARM_DESC(nsp_burst_mode, "Burst transfer mode (0=io8, 1=io32, 2=mem32(default))");
78
79/* Release IO ports after configuration? */
80static int free_ports = 0;
81module_param(free_ports, bool, 0);
82MODULE_PARM_DESC(free_ports, "Release IO ports after configuration? (default: 0 (=no))");
83
84/* /usr/src/linux/drivers/scsi/hosts.h */
85static Scsi_Host_Template nsp_driver_template = {
86 .proc_name = "nsp_cs",
87 .proc_info = nsp_proc_info,
88 .name = "WorkBit NinjaSCSI-3/32Bi(16bit)",
89#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
90 .detect = nsp_detect_old,
91 .release = nsp_release_old,
92#endif
93 .info = nsp_info,
94 .queuecommand = nsp_queuecommand,
Linus Torvalds1da177e2005-04-16 15:20:36 -070095/* .eh_abort_handler = nsp_eh_abort,*/
Linus Torvalds1da177e2005-04-16 15:20:36 -070096 .eh_bus_reset_handler = nsp_eh_bus_reset,
97 .eh_host_reset_handler = nsp_eh_host_reset,
98 .can_queue = 1,
99 .this_id = NSP_INITIATOR_ID,
100 .sg_tablesize = SG_ALL,
101 .cmd_per_lun = 1,
102 .use_clustering = DISABLE_CLUSTERING,
103#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,2))
104 .use_new_eh_code = 1,
105#endif
106};
107
108static dev_link_t *dev_list = NULL;
109static dev_info_t dev_info = {"nsp_cs"};
110
111static nsp_hw_data nsp_data_base; /* attach <-> detect glue */
112
113
114
115/*
116 * debug, error print
117 */
118#ifndef NSP_DEBUG
119# define NSP_DEBUG_MASK 0x000000
120# define nsp_msg(type, args...) nsp_cs_message("", 0, (type), args)
121# define nsp_dbg(mask, args...) /* */
122#else
123# define NSP_DEBUG_MASK 0xffffff
124# define nsp_msg(type, args...) \
125 nsp_cs_message (__FUNCTION__, __LINE__, (type), args)
126# define nsp_dbg(mask, args...) \
127 nsp_cs_dmessage(__FUNCTION__, __LINE__, (mask), args)
128#endif
129
130#define NSP_DEBUG_QUEUECOMMAND BIT(0)
131#define NSP_DEBUG_REGISTER BIT(1)
132#define NSP_DEBUG_AUTOSCSI BIT(2)
133#define NSP_DEBUG_INTR BIT(3)
134#define NSP_DEBUG_SGLIST BIT(4)
135#define NSP_DEBUG_BUSFREE BIT(5)
136#define NSP_DEBUG_CDB_CONTENTS BIT(6)
137#define NSP_DEBUG_RESELECTION BIT(7)
138#define NSP_DEBUG_MSGINOCCUR BIT(8)
139#define NSP_DEBUG_EEPROM BIT(9)
140#define NSP_DEBUG_MSGOUTOCCUR BIT(10)
141#define NSP_DEBUG_BUSRESET BIT(11)
142#define NSP_DEBUG_RESTART BIT(12)
143#define NSP_DEBUG_SYNC BIT(13)
144#define NSP_DEBUG_WAIT BIT(14)
145#define NSP_DEBUG_TARGETFLAG BIT(15)
146#define NSP_DEBUG_PROC BIT(16)
147#define NSP_DEBUG_INIT BIT(17)
148#define NSP_DEBUG_DATA_IO BIT(18)
149#define NSP_SPECIAL_PRINT_REGISTER BIT(20)
150
151#define NSP_DEBUG_BUF_LEN 150
152
153static void nsp_cs_message(const char *func, int line, char *type, char *fmt, ...)
154{
155 va_list args;
156 char buf[NSP_DEBUG_BUF_LEN];
157
158 va_start(args, fmt);
159 vsnprintf(buf, sizeof(buf), fmt, args);
160 va_end(args);
161
162#ifndef NSP_DEBUG
163 printk("%snsp_cs: %s\n", type, buf);
164#else
165 printk("%snsp_cs: %s (%d): %s\n", type, func, line, buf);
166#endif
167}
168
169#ifdef NSP_DEBUG
170static void nsp_cs_dmessage(const char *func, int line, int mask, char *fmt, ...)
171{
172 va_list args;
173 char buf[NSP_DEBUG_BUF_LEN];
174
175 va_start(args, fmt);
176 vsnprintf(buf, sizeof(buf), fmt, args);
177 va_end(args);
178
179 if (mask & NSP_DEBUG_MASK) {
180 printk("nsp_cs-debug: 0x%x %s (%d): %s\n", mask, func, line, buf);
181 }
182}
183#endif
184
185/***********************************************************/
186
187/*====================================================
188 * Clenaup parameters and call done() functions.
189 * You must be set SCpnt->result before call this function.
190 */
191static void nsp_scsi_done(Scsi_Cmnd *SCpnt)
192{
193 nsp_hw_data *data = (nsp_hw_data *)SCpnt->device->host->hostdata;
194
195 data->CurrentSC = NULL;
196
197 SCpnt->scsi_done(SCpnt);
198}
199
200static int nsp_queuecommand(Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *))
201{
202#ifdef NSP_DEBUG
203 /*unsigned int host_id = SCpnt->device->host->this_id;*/
204 /*unsigned int base = SCpnt->device->host->io_port;*/
205 unsigned char target = SCpnt->device->id;
206#endif
207 nsp_hw_data *data = (nsp_hw_data *)SCpnt->device->host->hostdata;
208
209 nsp_dbg(NSP_DEBUG_QUEUECOMMAND, "SCpnt=0x%p target=%d lun=%d buff=0x%p bufflen=%d use_sg=%d",
210 SCpnt, target, SCpnt->device->lun, SCpnt->request_buffer, SCpnt->request_bufflen, SCpnt->use_sg);
211 //nsp_dbg(NSP_DEBUG_QUEUECOMMAND, "before CurrentSC=0x%p", data->CurrentSC);
212
213 SCpnt->scsi_done = done;
214
215 if (data->CurrentSC != NULL) {
216 nsp_msg(KERN_DEBUG, "CurrentSC!=NULL this can't be happen");
217 SCpnt->result = DID_BAD_TARGET << 16;
218 nsp_scsi_done(SCpnt);
219 return 0;
220 }
221
222#if 0
223 /* XXX: pcmcia-cs generates SCSI command with "scsi_info" utility.
224 This makes kernel crash when suspending... */
225 if (data->ScsiInfo->stop != 0) {
226 nsp_msg(KERN_INFO, "suspending device. reject command.");
227 SCpnt->result = DID_BAD_TARGET << 16;
228 nsp_scsi_done(SCpnt);
229 return SCSI_MLQUEUE_HOST_BUSY;
230 }
231#endif
232
233 show_command(SCpnt);
234
235 data->CurrentSC = SCpnt;
236
237 SCpnt->SCp.Status = CHECK_CONDITION;
238 SCpnt->SCp.Message = 0;
239 SCpnt->SCp.have_data_in = IO_UNKNOWN;
240 SCpnt->SCp.sent_command = 0;
241 SCpnt->SCp.phase = PH_UNDETERMINED;
242 SCpnt->resid = SCpnt->request_bufflen;
243
244 /* setup scratch area
245 SCp.ptr : buffer pointer
246 SCp.this_residual : buffer length
247 SCp.buffer : next buffer
248 SCp.buffers_residual : left buffers in list
249 SCp.phase : current state of the command */
250 if (SCpnt->use_sg) {
251 SCpnt->SCp.buffer = (struct scatterlist *) SCpnt->request_buffer;
252 SCpnt->SCp.ptr = BUFFER_ADDR;
253 SCpnt->SCp.this_residual = SCpnt->SCp.buffer->length;
254 SCpnt->SCp.buffers_residual = SCpnt->use_sg - 1;
255 } else {
256 SCpnt->SCp.ptr = (char *) SCpnt->request_buffer;
257 SCpnt->SCp.this_residual = SCpnt->request_bufflen;
258 SCpnt->SCp.buffer = NULL;
259 SCpnt->SCp.buffers_residual = 0;
260 }
261
262 if (nsphw_start_selection(SCpnt) == FALSE) {
263 nsp_dbg(NSP_DEBUG_QUEUECOMMAND, "selection fail");
264 SCpnt->result = DID_BUS_BUSY << 16;
265 nsp_scsi_done(SCpnt);
266 return 0;
267 }
268
269
270 //nsp_dbg(NSP_DEBUG_QUEUECOMMAND, "out");
271#ifdef NSP_DEBUG
272 data->CmdId++;
273#endif
274 return 0;
275}
276
277/*
278 * setup PIO FIFO transfer mode and enable/disable to data out
279 */
280static void nsp_setup_fifo(nsp_hw_data *data, int enabled)
281{
282 unsigned int base = data->BaseAddress;
283 unsigned char transfer_mode_reg;
284
285 //nsp_dbg(NSP_DEBUG_DATA_IO, "enabled=%d", enabled);
286
287 if (enabled != FALSE) {
288 transfer_mode_reg = TRANSFER_GO | BRAIND;
289 } else {
290 transfer_mode_reg = 0;
291 }
292
293 transfer_mode_reg |= data->TransferMode;
294
295 nsp_index_write(base, TRANSFERMODE, transfer_mode_reg);
296}
297
298static void nsphw_init_sync(nsp_hw_data *data)
299{
300 sync_data tmp_sync = { .SyncNegotiation = SYNC_NOT_YET,
301 .SyncPeriod = 0,
302 .SyncOffset = 0
303 };
304 int i;
305
306 /* setup sync data */
307 for ( i = 0; i < ARRAY_SIZE(data->Sync); i++ ) {
308 data->Sync[i] = tmp_sync;
309 }
310}
311
312/*
313 * Initialize Ninja hardware
314 */
315static int nsphw_init(nsp_hw_data *data)
316{
317 unsigned int base = data->BaseAddress;
318
319 nsp_dbg(NSP_DEBUG_INIT, "in base=0x%x", base);
320
321 data->ScsiClockDiv = CLOCK_40M | FAST_20;
322 data->CurrentSC = NULL;
323 data->FifoCount = 0;
324 data->TransferMode = MODE_IO8;
325
326 nsphw_init_sync(data);
327
328 /* block all interrupts */
329 nsp_write(base, IRQCONTROL, IRQCONTROL_ALLMASK);
330
331 /* setup SCSI interface */
332 nsp_write(base, IFSELECT, IF_IFSEL);
333
334 nsp_index_write(base, SCSIIRQMODE, 0);
335
336 nsp_index_write(base, TRANSFERMODE, MODE_IO8);
337 nsp_index_write(base, CLOCKDIV, data->ScsiClockDiv);
338
339 nsp_index_write(base, PARITYCTRL, 0);
340 nsp_index_write(base, POINTERCLR, POINTER_CLEAR |
341 ACK_COUNTER_CLEAR |
342 REQ_COUNTER_CLEAR |
343 HOST_COUNTER_CLEAR);
344
345 /* setup fifo asic */
346 nsp_write(base, IFSELECT, IF_REGSEL);
347 nsp_index_write(base, TERMPWRCTRL, 0);
348 if ((nsp_index_read(base, OTHERCONTROL) & TPWR_SENSE) == 0) {
349 nsp_msg(KERN_INFO, "terminator power on");
350 nsp_index_write(base, TERMPWRCTRL, POWER_ON);
351 }
352
353 nsp_index_write(base, TIMERCOUNT, 0);
354 nsp_index_write(base, TIMERCOUNT, 0); /* requires 2 times!! */
355
356 nsp_index_write(base, SYNCREG, 0);
357 nsp_index_write(base, ACKWIDTH, 0);
358
359 /* enable interrupts and ack them */
360 nsp_index_write(base, SCSIIRQMODE, SCSI_PHASE_CHANGE_EI |
361 RESELECT_EI |
362 SCSI_RESET_IRQ_EI );
363 nsp_write(base, IRQCONTROL, IRQCONTROL_ALLCLEAR);
364
365 nsp_setup_fifo(data, FALSE);
366
367 return TRUE;
368}
369
370/*
371 * Start selection phase
372 */
373static int nsphw_start_selection(Scsi_Cmnd *SCpnt)
374{
375 unsigned int host_id = SCpnt->device->host->this_id;
376 unsigned int base = SCpnt->device->host->io_port;
377 unsigned char target = SCpnt->device->id;
378 nsp_hw_data *data = (nsp_hw_data *)SCpnt->device->host->hostdata;
379 int time_out;
380 unsigned char phase, arbit;
381
382 //nsp_dbg(NSP_DEBUG_RESELECTION, "in");
383
384 phase = nsp_index_read(base, SCSIBUSMON);
385 if(phase != BUSMON_BUS_FREE) {
386 //nsp_dbg(NSP_DEBUG_RESELECTION, "bus busy");
387 return FALSE;
388 }
389
390 /* start arbitration */
391 //nsp_dbg(NSP_DEBUG_RESELECTION, "start arbit");
392 SCpnt->SCp.phase = PH_ARBSTART;
393 nsp_index_write(base, SETARBIT, ARBIT_GO);
394
395 time_out = 1000;
396 do {
397 /* XXX: what a stupid chip! */
398 arbit = nsp_index_read(base, ARBITSTATUS);
399 //nsp_dbg(NSP_DEBUG_RESELECTION, "arbit=%d, wait_count=%d", arbit, wait_count);
400 udelay(1); /* hold 1.2us */
401 } while((arbit & (ARBIT_WIN | ARBIT_FAIL)) == 0 &&
402 (time_out-- != 0));
403
404 if (!(arbit & ARBIT_WIN)) {
405 //nsp_dbg(NSP_DEBUG_RESELECTION, "arbit fail");
406 nsp_index_write(base, SETARBIT, ARBIT_FLAG_CLEAR);
407 return FALSE;
408 }
409
410 /* assert select line */
411 //nsp_dbg(NSP_DEBUG_RESELECTION, "assert SEL line");
412 SCpnt->SCp.phase = PH_SELSTART;
413 udelay(3); /* wait 2.4us */
414 nsp_index_write(base, SCSIDATALATCH, BIT(host_id) | BIT(target));
415 nsp_index_write(base, SCSIBUSCTRL, SCSI_SEL | SCSI_BSY | SCSI_ATN);
416 udelay(2); /* wait >1.2us */
417 nsp_index_write(base, SCSIBUSCTRL, SCSI_SEL | SCSI_BSY | SCSI_DATAOUT_ENB | SCSI_ATN);
418 nsp_index_write(base, SETARBIT, ARBIT_FLAG_CLEAR);
419 /*udelay(1);*/ /* wait >90ns */
420 nsp_index_write(base, SCSIBUSCTRL, SCSI_SEL | SCSI_DATAOUT_ENB | SCSI_ATN);
421
422 /* check selection timeout */
423 nsp_start_timer(SCpnt, 1000/51);
424 data->SelectionTimeOut = 1;
425
426 return TRUE;
427}
428
429struct nsp_sync_table {
430 unsigned int min_period;
431 unsigned int max_period;
432 unsigned int chip_period;
433 unsigned int ack_width;
434};
435
436static struct nsp_sync_table nsp_sync_table_40M[] = {
437 {0x0c, 0x0c, 0x1, 0}, /* 20MB 50ns*/
438 {0x19, 0x19, 0x3, 1}, /* 10MB 100ns*/
439 {0x1a, 0x25, 0x5, 2}, /* 7.5MB 150ns*/
440 {0x26, 0x32, 0x7, 3}, /* 5MB 200ns*/
441 { 0, 0, 0, 0},
442};
443
444static struct nsp_sync_table nsp_sync_table_20M[] = {
445 {0x19, 0x19, 0x1, 0}, /* 10MB 100ns*/
446 {0x1a, 0x25, 0x2, 0}, /* 7.5MB 150ns*/
447 {0x26, 0x32, 0x3, 1}, /* 5MB 200ns*/
448 { 0, 0, 0, 0},
449};
450
451/*
452 * setup synchronous data transfer mode
453 */
454static int nsp_analyze_sdtr(Scsi_Cmnd *SCpnt)
455{
456 unsigned char target = SCpnt->device->id;
457// unsigned char lun = SCpnt->device->lun;
458 nsp_hw_data *data = (nsp_hw_data *)SCpnt->device->host->hostdata;
459 sync_data *sync = &(data->Sync[target]);
460 struct nsp_sync_table *sync_table;
461 unsigned int period, offset;
462 int i;
463
464
465 nsp_dbg(NSP_DEBUG_SYNC, "in");
466
467 period = sync->SyncPeriod;
468 offset = sync->SyncOffset;
469
470 nsp_dbg(NSP_DEBUG_SYNC, "period=0x%x, offset=0x%x", period, offset);
471
472 if ((data->ScsiClockDiv & (BIT(0)|BIT(1))) == CLOCK_20M) {
473 sync_table = nsp_sync_table_20M;
474 } else {
475 sync_table = nsp_sync_table_40M;
476 }
477
478 for ( i = 0; sync_table->max_period != 0; i++, sync_table++) {
479 if ( period >= sync_table->min_period &&
480 period <= sync_table->max_period ) {
481 break;
482 }
483 }
484
485 if (period != 0 && sync_table->max_period == 0) {
486 /*
487 * No proper period/offset found
488 */
489 nsp_dbg(NSP_DEBUG_SYNC, "no proper period/offset");
490
491 sync->SyncPeriod = 0;
492 sync->SyncOffset = 0;
493 sync->SyncRegister = 0;
494 sync->AckWidth = 0;
495
496 return FALSE;
497 }
498
499 sync->SyncRegister = (sync_table->chip_period << SYNCREG_PERIOD_SHIFT) |
500 (offset & SYNCREG_OFFSET_MASK);
501 sync->AckWidth = sync_table->ack_width;
502
503 nsp_dbg(NSP_DEBUG_SYNC, "sync_reg=0x%x, ack_width=0x%x", sync->SyncRegister, sync->AckWidth);
504
505 return TRUE;
506}
507
508
509/*
510 * start ninja hardware timer
511 */
512static void nsp_start_timer(Scsi_Cmnd *SCpnt, int time)
513{
514 unsigned int base = SCpnt->device->host->io_port;
515 nsp_hw_data *data = (nsp_hw_data *)SCpnt->device->host->hostdata;
516
517 //nsp_dbg(NSP_DEBUG_INTR, "in SCpnt=0x%p, time=%d", SCpnt, time);
518 data->TimerCount = time;
519 nsp_index_write(base, TIMERCOUNT, time);
520}
521
522/*
523 * wait for bus phase change
524 */
525static int nsp_negate_signal(Scsi_Cmnd *SCpnt, unsigned char mask, char *str)
526{
527 unsigned int base = SCpnt->device->host->io_port;
528 unsigned char reg;
529 int time_out;
530
531 //nsp_dbg(NSP_DEBUG_INTR, "in");
532
533 time_out = 100;
534
535 do {
536 reg = nsp_index_read(base, SCSIBUSMON);
537 if (reg == 0xff) {
538 break;
539 }
540 } while ((time_out-- != 0) && (reg & mask) != 0);
541
542 if (time_out == 0) {
543 nsp_msg(KERN_DEBUG, " %s signal off timeut", str);
544 }
545
546 return 0;
547}
548
549/*
550 * expect Ninja Irq
551 */
552static int nsp_expect_signal(Scsi_Cmnd *SCpnt,
553 unsigned char current_phase,
554 unsigned char mask)
555{
556 unsigned int base = SCpnt->device->host->io_port;
557 int time_out;
558 unsigned char phase, i_src;
559
560 //nsp_dbg(NSP_DEBUG_INTR, "current_phase=0x%x, mask=0x%x", current_phase, mask);
561
562 time_out = 100;
563 do {
564 phase = nsp_index_read(base, SCSIBUSMON);
565 if (phase == 0xff) {
566 //nsp_dbg(NSP_DEBUG_INTR, "ret -1");
567 return -1;
568 }
569 i_src = nsp_read(base, IRQSTATUS);
570 if (i_src & IRQSTATUS_SCSI) {
571 //nsp_dbg(NSP_DEBUG_INTR, "ret 0 found scsi signal");
572 return 0;
573 }
574 if ((phase & mask) != 0 && (phase & BUSMON_PHASE_MASK) == current_phase) {
575 //nsp_dbg(NSP_DEBUG_INTR, "ret 1 phase=0x%x", phase);
576 return 1;
577 }
578 } while(time_out-- != 0);
579
580 //nsp_dbg(NSP_DEBUG_INTR, "timeout");
581 return -1;
582}
583
584/*
585 * transfer SCSI message
586 */
587static int nsp_xfer(Scsi_Cmnd *SCpnt, int phase)
588{
589 unsigned int base = SCpnt->device->host->io_port;
590 nsp_hw_data *data = (nsp_hw_data *)SCpnt->device->host->hostdata;
591 char *buf = data->MsgBuffer;
592 int len = min(MSGBUF_SIZE, data->MsgLen);
593 int ptr;
594 int ret;
595
596 //nsp_dbg(NSP_DEBUG_DATA_IO, "in");
597 for (ptr = 0; len > 0; len--, ptr++) {
598
599 ret = nsp_expect_signal(SCpnt, phase, BUSMON_REQ);
600 if (ret <= 0) {
601 nsp_dbg(NSP_DEBUG_DATA_IO, "xfer quit");
602 return 0;
603 }
604
605 /* if last byte, negate ATN */
606 if (len == 1 && SCpnt->SCp.phase == PH_MSG_OUT) {
607 nsp_index_write(base, SCSIBUSCTRL, AUTODIRECTION | ACKENB);
608 }
609
610 /* read & write message */
611 if (phase & BUSMON_IO) {
612 nsp_dbg(NSP_DEBUG_DATA_IO, "read msg");
613 buf[ptr] = nsp_index_read(base, SCSIDATAWITHACK);
614 } else {
615 nsp_dbg(NSP_DEBUG_DATA_IO, "write msg");
616 nsp_index_write(base, SCSIDATAWITHACK, buf[ptr]);
617 }
618 nsp_negate_signal(SCpnt, BUSMON_ACK, "xfer<ack>");
619
620 }
621 return len;
622}
623
624/*
625 * get extra SCSI data from fifo
626 */
627static int nsp_dataphase_bypass(Scsi_Cmnd *SCpnt)
628{
629 nsp_hw_data *data = (nsp_hw_data *)SCpnt->device->host->hostdata;
630 unsigned int count;
631
632 //nsp_dbg(NSP_DEBUG_DATA_IO, "in");
633
634 if (SCpnt->SCp.have_data_in != IO_IN) {
635 return 0;
636 }
637
638 count = nsp_fifo_count(SCpnt);
639 if (data->FifoCount == count) {
640 //nsp_dbg(NSP_DEBUG_DATA_IO, "not use bypass quirk");
641 return 0;
642 }
643
644 /*
645 * XXX: NSP_QUIRK
646 * data phase skip only occures in case of SCSI_LOW_READ
647 */
648 nsp_dbg(NSP_DEBUG_DATA_IO, "use bypass quirk");
649 SCpnt->SCp.phase = PH_DATA;
650 nsp_pio_read(SCpnt);
651 nsp_setup_fifo(data, FALSE);
652
653 return 0;
654}
655
656/*
657 * accept reselection
658 */
659static int nsp_reselected(Scsi_Cmnd *SCpnt)
660{
661 unsigned int base = SCpnt->device->host->io_port;
662 unsigned int host_id = SCpnt->device->host->this_id;
663 //nsp_hw_data *data = (nsp_hw_data *)SCpnt->device->host->hostdata;
664 unsigned char bus_reg;
665 unsigned char id_reg, tmp;
666 int target;
667
668 nsp_dbg(NSP_DEBUG_RESELECTION, "in");
669
670 id_reg = nsp_index_read(base, RESELECTID);
671 tmp = id_reg & (~BIT(host_id));
672 target = 0;
673 while(tmp != 0) {
674 if (tmp & BIT(0)) {
675 break;
676 }
677 tmp >>= 1;
678 target++;
679 }
680
681 if (SCpnt->device->id != target) {
682 nsp_msg(KERN_ERR, "XXX: reselect ID must be %d in this implementation.", target);
683 }
684
685 nsp_negate_signal(SCpnt, BUSMON_SEL, "reselect<SEL>");
686
687 nsp_nexus(SCpnt);
688 bus_reg = nsp_index_read(base, SCSIBUSCTRL) & ~(SCSI_BSY | SCSI_ATN);
689 nsp_index_write(base, SCSIBUSCTRL, bus_reg);
690 nsp_index_write(base, SCSIBUSCTRL, bus_reg | AUTODIRECTION | ACKENB);
691
692 return TRUE;
693}
694
695/*
696 * count how many data transferd
697 */
698static int nsp_fifo_count(Scsi_Cmnd *SCpnt)
699{
700 unsigned int base = SCpnt->device->host->io_port;
701 unsigned int count;
702 unsigned int l, m, h, dummy;
703
704 nsp_index_write(base, POINTERCLR, POINTER_CLEAR | ACK_COUNTER);
705
706 l = nsp_index_read(base, TRANSFERCOUNT);
707 m = nsp_index_read(base, TRANSFERCOUNT);
708 h = nsp_index_read(base, TRANSFERCOUNT);
709 dummy = nsp_index_read(base, TRANSFERCOUNT); /* required this! */
710
711 count = (h << 16) | (m << 8) | (l << 0);
712
713 //nsp_dbg(NSP_DEBUG_DATA_IO, "count=0x%x", count);
714
715 return count;
716}
717
718/* fifo size */
719#define RFIFO_CRIT 64
720#define WFIFO_CRIT 64
721
722/*
723 * read data in DATA IN phase
724 */
725static void nsp_pio_read(Scsi_Cmnd *SCpnt)
726{
727 unsigned int base = SCpnt->device->host->io_port;
728 unsigned long mmio_base = SCpnt->device->host->base;
729 nsp_hw_data *data = (nsp_hw_data *)SCpnt->device->host->hostdata;
730 long time_out;
731 int ocount, res;
732 unsigned char stat, fifo_stat;
733
734 ocount = data->FifoCount;
735
736 nsp_dbg(NSP_DEBUG_DATA_IO, "in SCpnt=0x%p resid=%d ocount=%d ptr=0x%p this_residual=%d buffers=0x%p nbuf=%d",
737 SCpnt, SCpnt->resid, ocount, SCpnt->SCp.ptr, SCpnt->SCp.this_residual, SCpnt->SCp.buffer, SCpnt->SCp.buffers_residual);
738
739 time_out = 1000;
740
741 while ((time_out-- != 0) &&
742 (SCpnt->SCp.this_residual > 0 || SCpnt->SCp.buffers_residual > 0 ) ) {
743
744 stat = nsp_index_read(base, SCSIBUSMON);
745 stat &= BUSMON_PHASE_MASK;
746
747
748 res = nsp_fifo_count(SCpnt) - ocount;
749 //nsp_dbg(NSP_DEBUG_DATA_IO, "ptr=0x%p this=0x%x ocount=0x%x res=0x%x", SCpnt->SCp.ptr, SCpnt->SCp.this_residual, ocount, res);
750 if (res == 0) { /* if some data avilable ? */
751 if (stat == BUSPHASE_DATA_IN) { /* phase changed? */
752 //nsp_dbg(NSP_DEBUG_DATA_IO, " wait for data this=%d", SCpnt->SCp.this_residual);
753 continue;
754 } else {
755 nsp_dbg(NSP_DEBUG_DATA_IO, "phase changed stat=0x%x", stat);
756 break;
757 }
758 }
759
760 fifo_stat = nsp_read(base, FIFOSTATUS);
761 if ((fifo_stat & FIFOSTATUS_FULL_EMPTY) == 0 &&
762 stat == BUSPHASE_DATA_IN) {
763 continue;
764 }
765
766 res = min(res, SCpnt->SCp.this_residual);
767
768 switch (data->TransferMode) {
769 case MODE_IO32:
770 res &= ~(BIT(1)|BIT(0)); /* align 4 */
771 nsp_fifo32_read(base, SCpnt->SCp.ptr, res >> 2);
772 break;
773 case MODE_IO8:
774 nsp_fifo8_read (base, SCpnt->SCp.ptr, res );
775 break;
776
777 case MODE_MEM32:
778 res &= ~(BIT(1)|BIT(0)); /* align 4 */
779 nsp_mmio_fifo32_read(mmio_base, SCpnt->SCp.ptr, res >> 2);
780 break;
781
782 default:
783 nsp_dbg(NSP_DEBUG_DATA_IO, "unknown read mode");
784 return;
785 }
786
787 SCpnt->resid -= res;
788 SCpnt->SCp.ptr += res;
789 SCpnt->SCp.this_residual -= res;
790 ocount += res;
791 //nsp_dbg(NSP_DEBUG_DATA_IO, "ptr=0x%p this_residual=0x%x ocount=0x%x", SCpnt->SCp.ptr, SCpnt->SCp.this_residual, ocount);
792
793 /* go to next scatter list if available */
794 if (SCpnt->SCp.this_residual == 0 &&
795 SCpnt->SCp.buffers_residual != 0 ) {
796 //nsp_dbg(NSP_DEBUG_DATA_IO, "scatterlist next timeout=%d", time_out);
797 SCpnt->SCp.buffers_residual--;
798 SCpnt->SCp.buffer++;
799 SCpnt->SCp.ptr = BUFFER_ADDR;
800 SCpnt->SCp.this_residual = SCpnt->SCp.buffer->length;
801 time_out = 1000;
802
803 //nsp_dbg(NSP_DEBUG_DATA_IO, "page: 0x%p, off: 0x%x", SCpnt->SCp.buffer->page, SCpnt->SCp.buffer->offset);
804 }
805 }
806
807 data->FifoCount = ocount;
808
809 if (time_out == 0) {
810 nsp_msg(KERN_DEBUG, "pio read timeout resid=%d this_residual=%d buffers_residual=%d",
811 SCpnt->resid, SCpnt->SCp.this_residual, SCpnt->SCp.buffers_residual);
812 }
813 nsp_dbg(NSP_DEBUG_DATA_IO, "read ocount=0x%x", ocount);
814 nsp_dbg(NSP_DEBUG_DATA_IO, "r cmd=%d resid=0x%x\n", data->CmdId, SCpnt->resid);
815}
816
817/*
818 * write data in DATA OUT phase
819 */
820static void nsp_pio_write(Scsi_Cmnd *SCpnt)
821{
822 unsigned int base = SCpnt->device->host->io_port;
823 unsigned long mmio_base = SCpnt->device->host->base;
824 nsp_hw_data *data = (nsp_hw_data *)SCpnt->device->host->hostdata;
825 int time_out;
826 int ocount, res;
827 unsigned char stat;
828
829 ocount = data->FifoCount;
830
831 nsp_dbg(NSP_DEBUG_DATA_IO, "in fifocount=%d ptr=0x%p this_residual=%d buffers=0x%p nbuf=%d resid=0x%x",
832 data->FifoCount, SCpnt->SCp.ptr, SCpnt->SCp.this_residual, SCpnt->SCp.buffer, SCpnt->SCp.buffers_residual, SCpnt->resid);
833
834 time_out = 1000;
835
836 while ((time_out-- != 0) &&
837 (SCpnt->SCp.this_residual > 0 || SCpnt->SCp.buffers_residual > 0)) {
838 stat = nsp_index_read(base, SCSIBUSMON);
839 stat &= BUSMON_PHASE_MASK;
840
841 if (stat != BUSPHASE_DATA_OUT) {
842 res = ocount - nsp_fifo_count(SCpnt);
843
844 nsp_dbg(NSP_DEBUG_DATA_IO, "phase changed stat=0x%x, res=%d\n", stat, res);
845 /* Put back pointer */
846 SCpnt->resid += res;
847 SCpnt->SCp.ptr -= res;
848 SCpnt->SCp.this_residual += res;
849 ocount -= res;
850
851 break;
852 }
853
854 res = ocount - nsp_fifo_count(SCpnt);
855 if (res > 0) { /* write all data? */
856 nsp_dbg(NSP_DEBUG_DATA_IO, "wait for all data out. ocount=0x%x res=%d", ocount, res);
857 continue;
858 }
859
860 res = min(SCpnt->SCp.this_residual, WFIFO_CRIT);
861
862 //nsp_dbg(NSP_DEBUG_DATA_IO, "ptr=0x%p this=0x%x res=0x%x", SCpnt->SCp.ptr, SCpnt->SCp.this_residual, res);
863 switch (data->TransferMode) {
864 case MODE_IO32:
865 res &= ~(BIT(1)|BIT(0)); /* align 4 */
866 nsp_fifo32_write(base, SCpnt->SCp.ptr, res >> 2);
867 break;
868 case MODE_IO8:
869 nsp_fifo8_write (base, SCpnt->SCp.ptr, res );
870 break;
871
872 case MODE_MEM32:
873 res &= ~(BIT(1)|BIT(0)); /* align 4 */
874 nsp_mmio_fifo32_write(mmio_base, SCpnt->SCp.ptr, res >> 2);
875 break;
876
877 default:
878 nsp_dbg(NSP_DEBUG_DATA_IO, "unknown write mode");
879 break;
880 }
881
882 SCpnt->resid -= res;
883 SCpnt->SCp.ptr += res;
884 SCpnt->SCp.this_residual -= res;
885 ocount += res;
886
887 /* go to next scatter list if available */
888 if (SCpnt->SCp.this_residual == 0 &&
889 SCpnt->SCp.buffers_residual != 0 ) {
890 //nsp_dbg(NSP_DEBUG_DATA_IO, "scatterlist next");
891 SCpnt->SCp.buffers_residual--;
892 SCpnt->SCp.buffer++;
893 SCpnt->SCp.ptr = BUFFER_ADDR;
894 SCpnt->SCp.this_residual = SCpnt->SCp.buffer->length;
895 time_out = 1000;
896 }
897 }
898
899 data->FifoCount = ocount;
900
901 if (time_out == 0) {
902 nsp_msg(KERN_DEBUG, "pio write timeout resid=0x%x", SCpnt->resid);
903 }
904 nsp_dbg(NSP_DEBUG_DATA_IO, "write ocount=0x%x", ocount);
905 nsp_dbg(NSP_DEBUG_DATA_IO, "w cmd=%d resid=0x%x\n", data->CmdId, SCpnt->resid);
906}
907#undef RFIFO_CRIT
908#undef WFIFO_CRIT
909
910/*
911 * setup synchronous/asynchronous data transfer mode
912 */
913static int nsp_nexus(Scsi_Cmnd *SCpnt)
914{
915 unsigned int base = SCpnt->device->host->io_port;
916 unsigned char target = SCpnt->device->id;
917// unsigned char lun = SCpnt->device->lun;
918 nsp_hw_data *data = (nsp_hw_data *)SCpnt->device->host->hostdata;
919 sync_data *sync = &(data->Sync[target]);
920
921 //nsp_dbg(NSP_DEBUG_DATA_IO, "in SCpnt=0x%p", SCpnt);
922
923 /* setup synch transfer registers */
924 nsp_index_write(base, SYNCREG, sync->SyncRegister);
925 nsp_index_write(base, ACKWIDTH, sync->AckWidth);
926
927 if (SCpnt->use_sg == 0 ||
928 SCpnt->resid % 4 != 0 ||
929 SCpnt->resid <= PAGE_SIZE ) {
930 data->TransferMode = MODE_IO8;
931 } else if (nsp_burst_mode == BURST_MEM32) {
932 data->TransferMode = MODE_MEM32;
933 } else if (nsp_burst_mode == BURST_IO32) {
934 data->TransferMode = MODE_IO32;
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 */
956static irqreturn_t nspintr(int irq, void *dev_id, struct pt_regs *regs)
957{
958 unsigned int base;
959 unsigned char irq_status, irq_phase, phase;
960 Scsi_Cmnd *tmpSC;
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/*----------------------------------------------------------------*/
1314static struct Scsi_Host *nsp_detect(Scsi_Host_Template *sht)
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);
1320#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,73))
1321 host = scsi_host_alloc(&nsp_driver_template, sizeof(nsp_hw_data));
1322#else
1323 host = scsi_register(sht, sizeof(nsp_hw_data));
1324#endif
1325 if (host == NULL) {
1326 nsp_dbg(NSP_DEBUG_INIT, "host failed");
1327 return NULL;
1328 }
1329
1330 memcpy(host->hostdata, data_b, sizeof(nsp_hw_data));
1331 data = (nsp_hw_data *)host->hostdata;
1332 data->ScsiInfo->host = host;
1333#ifdef NSP_DEBUG
1334 data->CmdId = 0;
1335#endif
1336
1337 nsp_dbg(NSP_DEBUG_INIT, "irq=%d,%d", data_b->IrqNumber, ((nsp_hw_data *)host->hostdata)->IrqNumber);
1338
1339 host->unique_id = data->BaseAddress;
1340 host->io_port = data->BaseAddress;
1341 host->n_io_port = data->NumAddress;
1342 host->irq = data->IrqNumber;
1343 host->base = data->MmioAddress;
1344
1345 spin_lock_init(&(data->Lock));
1346
1347 snprintf(data->nspinfo,
1348 sizeof(data->nspinfo),
1349 "NinjaSCSI-3/32Bi Driver $Revision: 1.23 $ IO:0x%04lx-0x%04lx MMIO(virt addr):0x%04lx IRQ:%02d",
1350 host->io_port, host->io_port + host->n_io_port - 1,
1351 host->base,
1352 host->irq);
1353 sht->name = data->nspinfo;
1354
1355 nsp_dbg(NSP_DEBUG_INIT, "end");
1356
1357
1358 return host; /* detect done. */
1359}
1360
1361#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
1362static int nsp_detect_old(Scsi_Host_Template *sht)
1363{
1364 if (nsp_detect(sht) == NULL) {
1365 return 0;
1366 } else {
1367 //MOD_INC_USE_COUNT;
1368 return 1;
1369 }
1370}
1371
1372
1373static int nsp_release_old(struct Scsi_Host *shpnt)
1374{
1375 //nsp_hw_data *data = (nsp_hw_data *)shpnt->hostdata;
1376
1377 /* PCMCIA Card Service dose same things below. */
1378 /* So we do nothing. */
1379 //if (shpnt->irq) {
1380 // free_irq(shpnt->irq, data->ScsiInfo);
1381 //}
1382 //if (shpnt->io_port) {
1383 // release_region(shpnt->io_port, shpnt->n_io_port);
1384 //}
1385
1386 //MOD_DEC_USE_COUNT;
1387
1388 return 0;
1389}
1390#endif
1391
1392/*----------------------------------------------------------------*/
1393/* return info string */
1394/*----------------------------------------------------------------*/
1395static const char *nsp_info(struct Scsi_Host *shpnt)
1396{
1397 nsp_hw_data *data = (nsp_hw_data *)shpnt->hostdata;
1398
1399 return data->nspinfo;
1400}
1401
1402#undef SPRINTF
1403#define SPRINTF(args...) \
1404 do { \
1405 if(length > (pos - buffer)) { \
1406 pos += snprintf(pos, length - (pos - buffer) + 1, ## args); \
1407 nsp_dbg(NSP_DEBUG_PROC, "buffer=0x%p pos=0x%p length=%d %d\n", buffer, pos, length, length - (pos - buffer));\
1408 } \
1409 } while(0)
1410static int
1411nsp_proc_info(
1412#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,73))
1413 struct Scsi_Host *host,
1414#endif
1415 char *buffer,
1416 char **start,
1417 off_t offset,
1418 int length,
1419#if !(LINUX_VERSION_CODE > KERNEL_VERSION(2,5,73))
1420 int hostno,
1421#endif
1422 int inout)
1423{
1424 int id;
1425 char *pos = buffer;
1426 int thislength;
1427 int speed;
1428 unsigned long flags;
1429 nsp_hw_data *data;
1430#if !(LINUX_VERSION_CODE > KERNEL_VERSION(2,5,73))
1431 struct Scsi_Host *host;
1432#else
1433 int hostno;
1434#endif
1435 if (inout) {
1436 return -EINVAL;
1437 }
1438
1439#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,73))
1440 hostno = host->host_no;
1441#else
1442 /* search this HBA host */
1443 host = scsi_host_hn_get(hostno);
1444 if (host == NULL) {
1445 return -ESRCH;
1446 }
1447#endif
1448 data = (nsp_hw_data *)host->hostdata;
1449
1450
1451 SPRINTF("NinjaSCSI status\n\n");
1452 SPRINTF("Driver version: $Revision: 1.23 $\n");
1453 SPRINTF("SCSI host No.: %d\n", hostno);
1454 SPRINTF("IRQ: %d\n", host->irq);
1455 SPRINTF("IO: 0x%lx-0x%lx\n", host->io_port, host->io_port + host->n_io_port - 1);
1456 SPRINTF("MMIO(virtual address): 0x%lx-0x%lx\n", host->base, host->base + data->MmioLength - 1);
1457 SPRINTF("sg_tablesize: %d\n", host->sg_tablesize);
1458
1459 SPRINTF("burst transfer mode: ");
1460 switch (nsp_burst_mode) {
1461 case BURST_IO8:
1462 SPRINTF("io8");
1463 break;
1464 case BURST_IO32:
1465 SPRINTF("io32");
1466 break;
1467 case BURST_MEM32:
1468 SPRINTF("mem32");
1469 break;
1470 default:
1471 SPRINTF("???");
1472 break;
1473 }
1474 SPRINTF("\n");
1475
1476
1477 spin_lock_irqsave(&(data->Lock), flags);
1478 SPRINTF("CurrentSC: 0x%p\n\n", data->CurrentSC);
1479 spin_unlock_irqrestore(&(data->Lock), flags);
1480
1481 SPRINTF("SDTR status\n");
1482 for(id = 0; id < ARRAY_SIZE(data->Sync); id++) {
1483
1484 SPRINTF("id %d: ", id);
1485
1486 if (id == host->this_id) {
1487 SPRINTF("----- NinjaSCSI-3 host adapter\n");
1488 continue;
1489 }
1490
1491 switch(data->Sync[id].SyncNegotiation) {
1492 case SYNC_OK:
1493 SPRINTF(" sync");
1494 break;
1495 case SYNC_NG:
1496 SPRINTF("async");
1497 break;
1498 case SYNC_NOT_YET:
1499 SPRINTF(" none");
1500 break;
1501 default:
1502 SPRINTF("?????");
1503 break;
1504 }
1505
1506 if (data->Sync[id].SyncPeriod != 0) {
1507 speed = 1000000 / (data->Sync[id].SyncPeriod * 4);
1508
1509 SPRINTF(" transfer %d.%dMB/s, offset %d",
1510 speed / 1000,
1511 speed % 1000,
1512 data->Sync[id].SyncOffset
1513 );
1514 }
1515 SPRINTF("\n");
1516 }
1517
1518 thislength = pos - (buffer + offset);
1519
1520 if(thislength < 0) {
1521 *start = NULL;
1522 return 0;
1523 }
1524
1525
1526 thislength = min(thislength, length);
1527 *start = buffer + offset;
1528
1529 return thislength;
1530}
1531#undef SPRINTF
1532
1533/*---------------------------------------------------------------*/
1534/* error handler */
1535/*---------------------------------------------------------------*/
1536
Linus Torvalds1da177e2005-04-16 15:20:36 -07001537/*
1538static int nsp_eh_abort(Scsi_Cmnd *SCpnt)
1539{
1540 nsp_dbg(NSP_DEBUG_BUSRESET, "SCpnt=0x%p", SCpnt);
1541
1542 return nsp_eh_bus_reset(SCpnt);
1543}*/
1544
Linus Torvalds1da177e2005-04-16 15:20:36 -07001545static int nsp_bus_reset(nsp_hw_data *data)
1546{
1547 unsigned int base = data->BaseAddress;
1548 int i;
1549
1550 nsp_write(base, IRQCONTROL, IRQCONTROL_ALLMASK);
1551
1552 nsp_index_write(base, SCSIBUSCTRL, SCSI_RST);
1553 mdelay(100); /* 100ms */
1554 nsp_index_write(base, SCSIBUSCTRL, 0);
1555 for(i = 0; i < 5; i++) {
1556 nsp_index_read(base, IRQPHASESENCE); /* dummy read */
1557 }
1558
1559 nsphw_init_sync(data);
1560
1561 nsp_write(base, IRQCONTROL, IRQCONTROL_ALLCLEAR);
1562
1563 return SUCCESS;
1564}
1565
1566static int nsp_eh_bus_reset(Scsi_Cmnd *SCpnt)
1567{
1568 nsp_hw_data *data = (nsp_hw_data *)SCpnt->device->host->hostdata;
1569
1570 nsp_dbg(NSP_DEBUG_BUSRESET, "SCpnt=0x%p", SCpnt);
1571
1572 return nsp_bus_reset(data);
1573}
1574
1575static int nsp_eh_host_reset(Scsi_Cmnd *SCpnt)
1576{
1577 nsp_hw_data *data = (nsp_hw_data *)SCpnt->device->host->hostdata;
1578
1579 nsp_dbg(NSP_DEBUG_BUSRESET, "in");
1580
1581 nsphw_init(data);
1582
1583 return SUCCESS;
1584}
1585
1586
1587/**********************************************************************
1588 PCMCIA functions
1589**********************************************************************/
1590
1591/*======================================================================
1592 nsp_cs_attach() creates an "instance" of the driver, allocating
1593 local data structures for one device. The device is registered
1594 with Card Services.
1595
1596 The dev_link structure is initialized, but we don't actually
1597 configure the card at this point -- we wait until we receive a
1598 card insertion event.
1599======================================================================*/
1600static dev_link_t *nsp_cs_attach(void)
1601{
1602 scsi_info_t *info;
1603 client_reg_t client_reg;
1604 dev_link_t *link;
1605 int ret;
1606 nsp_hw_data *data = &nsp_data_base;
1607
1608 nsp_dbg(NSP_DEBUG_INIT, "in");
1609
1610 /* Create new SCSI device */
1611 info = kmalloc(sizeof(*info), GFP_KERNEL);
1612 if (info == NULL) { return NULL; }
1613 memset(info, 0, sizeof(*info));
1614 link = &info->link;
1615 link->priv = info;
1616 data->ScsiInfo = info;
1617
1618 nsp_dbg(NSP_DEBUG_INIT, "info=0x%p", info);
1619
1620 /* The io structure describes IO port mapping */
1621 link->io.NumPorts1 = 0x10;
1622 link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
1623 link->io.IOAddrLines = 10; /* not used */
1624
1625 /* Interrupt setup */
1626 link->irq.Attributes = IRQ_TYPE_EXCLUSIVE | IRQ_HANDLE_PRESENT;
1627 link->irq.IRQInfo1 = IRQ_LEVEL_ID;
1628
1629 /* Interrupt handler */
1630 link->irq.Handler = &nspintr;
1631 link->irq.Instance = info;
1632 link->irq.Attributes |= (SA_SHIRQ | SA_SAMPLE_RANDOM);
1633
1634 /* General socket configuration */
1635 link->conf.Attributes = CONF_ENABLE_IRQ;
1636 link->conf.Vcc = 50;
1637 link->conf.IntType = INT_MEMORY_AND_IO;
1638 link->conf.Present = PRESENT_OPTION;
1639
1640
1641 /* Register with Card Services */
1642 link->next = dev_list;
1643 dev_list = link;
1644 client_reg.dev_info = &dev_info;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001645 client_reg.Version = 0x0210;
1646 client_reg.event_callback_args.client_data = link;
1647 ret = pcmcia_register_client(&link->handle, &client_reg);
1648 if (ret != CS_SUCCESS) {
1649 cs_error(link->handle, RegisterClient, ret);
1650 nsp_cs_detach(link);
1651 return NULL;
1652 }
1653
1654
1655 nsp_dbg(NSP_DEBUG_INIT, "link=0x%p", link);
1656 return link;
1657} /* nsp_cs_attach */
1658
1659
1660/*======================================================================
1661 This deletes a driver "instance". The device is de-registered
1662 with Card Services. If it has been released, all local data
1663 structures are freed. Otherwise, the structures will be freed
1664 when the device is released.
1665======================================================================*/
1666static void nsp_cs_detach(dev_link_t *link)
1667{
1668 dev_link_t **linkp;
1669
1670 nsp_dbg(NSP_DEBUG_INIT, "in, link=0x%p", link);
1671
1672 /* Locate device structure */
1673 for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next) {
1674 if (*linkp == link) {
1675 break;
1676 }
1677 }
1678 if (*linkp == NULL) {
1679 return;
1680 }
1681
1682 if (link->state & DEV_CONFIG)
1683 nsp_cs_release(link);
1684
1685 /* Break the link with Card Services */
1686 if (link->handle) {
1687 pcmcia_deregister_client(link->handle);
1688 }
1689
1690 /* Unlink device structure, free bits */
1691 *linkp = link->next;
1692 kfree(link->priv);
1693 link->priv = NULL;
1694
1695} /* nsp_cs_detach */
1696
1697
1698/*======================================================================
1699 nsp_cs_config() is scheduled to run after a CARD_INSERTION event
1700 is received, to configure the PCMCIA socket, and to make the
1701 ethernet device available to the system.
1702======================================================================*/
1703#define CS_CHECK(fn, ret) \
1704do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
1705/*====================================================================*/
1706static void nsp_cs_config(dev_link_t *link)
1707{
1708 client_handle_t handle = link->handle;
1709 scsi_info_t *info = link->priv;
1710 tuple_t tuple;
1711 cisparse_t parse;
1712 int last_ret, last_fn;
1713 unsigned char tuple_data[64];
1714 config_info_t conf;
1715 win_req_t req;
1716 memreq_t map;
1717 cistpl_cftable_entry_t dflt = { 0 };
1718 struct Scsi_Host *host;
1719 nsp_hw_data *data = &nsp_data_base;
1720#if !(LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,74))
1721 Scsi_Device *dev;
1722 dev_node_t **tail, *node;
1723#endif
1724
1725 nsp_dbg(NSP_DEBUG_INIT, "in");
1726
1727 tuple.DesiredTuple = CISTPL_CONFIG;
1728 tuple.Attributes = 0;
1729 tuple.TupleData = tuple_data;
1730 tuple.TupleDataMax = sizeof(tuple_data);
1731 tuple.TupleOffset = 0;
1732 CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(handle, &tuple));
1733 CS_CHECK(GetTupleData, pcmcia_get_tuple_data(handle, &tuple));
1734 CS_CHECK(ParseTuple, pcmcia_parse_tuple(handle, &tuple, &parse));
1735 link->conf.ConfigBase = parse.config.base;
1736 link->conf.Present = parse.config.rmask[0];
1737
1738 /* Configure card */
1739 link->state |= DEV_CONFIG;
1740
1741 /* Look up the current Vcc */
1742 CS_CHECK(GetConfigurationInfo, pcmcia_get_configuration_info(handle, &conf));
1743 link->conf.Vcc = conf.Vcc;
1744
1745 tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
1746 CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(handle, &tuple));
1747 while (1) {
1748 cistpl_cftable_entry_t *cfg = &(parse.cftable_entry);
1749
1750 if (pcmcia_get_tuple_data(handle, &tuple) != 0 ||
1751 pcmcia_parse_tuple(handle, &tuple, &parse) != 0)
1752 goto next_entry;
1753
1754 if (cfg->flags & CISTPL_CFTABLE_DEFAULT) { dflt = *cfg; }
1755 if (cfg->index == 0) { goto next_entry; }
1756 link->conf.ConfigIndex = cfg->index;
1757
1758 /* Does this card need audio output? */
1759 if (cfg->flags & CISTPL_CFTABLE_AUDIO) {
1760 link->conf.Attributes |= CONF_ENABLE_SPKR;
1761 link->conf.Status = CCSR_AUDIO_ENA;
1762 }
1763
1764 /* Use power settings for Vcc and Vpp if present */
1765 /* Note that the CIS values need to be rescaled */
1766 if (cfg->vcc.present & (1<<CISTPL_POWER_VNOM)) {
1767 if (conf.Vcc != cfg->vcc.param[CISTPL_POWER_VNOM]/10000) {
1768 goto next_entry;
1769 }
1770 } else if (dflt.vcc.present & (1<<CISTPL_POWER_VNOM)) {
1771 if (conf.Vcc != dflt.vcc.param[CISTPL_POWER_VNOM]/10000) {
1772 goto next_entry;
1773 }
1774 }
1775
1776 if (cfg->vpp1.present & (1 << CISTPL_POWER_VNOM)) {
1777 link->conf.Vpp1 = link->conf.Vpp2 =
1778 cfg->vpp1.param[CISTPL_POWER_VNOM] / 10000;
1779 } else if (dflt.vpp1.present & (1 << CISTPL_POWER_VNOM)) {
1780 link->conf.Vpp1 = link->conf.Vpp2 =
1781 dflt.vpp1.param[CISTPL_POWER_VNOM] / 10000;
1782 }
1783
1784 /* Do we need to allocate an interrupt? */
1785 if (cfg->irq.IRQInfo1 || dflt.irq.IRQInfo1) {
1786 link->conf.Attributes |= CONF_ENABLE_IRQ;
1787 }
1788
1789 /* IO window settings */
1790 link->io.NumPorts1 = link->io.NumPorts2 = 0;
1791 if ((cfg->io.nwin > 0) || (dflt.io.nwin > 0)) {
1792 cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt.io;
1793 link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
1794 if (!(io->flags & CISTPL_IO_8BIT))
1795 link->io.Attributes1 = IO_DATA_PATH_WIDTH_16;
1796 if (!(io->flags & CISTPL_IO_16BIT))
1797 link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
1798 link->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK;
1799 link->io.BasePort1 = io->win[0].base;
1800 link->io.NumPorts1 = io->win[0].len;
1801 if (io->nwin > 1) {
1802 link->io.Attributes2 = link->io.Attributes1;
1803 link->io.BasePort2 = io->win[1].base;
1804 link->io.NumPorts2 = io->win[1].len;
1805 }
1806 /* This reserves IO space but doesn't actually enable it */
1807 if (pcmcia_request_io(link->handle, &link->io) != 0)
1808 goto next_entry;
1809 }
1810
1811 if ((cfg->mem.nwin > 0) || (dflt.mem.nwin > 0)) {
1812 cistpl_mem_t *mem =
1813 (cfg->mem.nwin) ? &cfg->mem : &dflt.mem;
1814 req.Attributes = WIN_DATA_WIDTH_16|WIN_MEMORY_TYPE_CM;
1815 req.Attributes |= WIN_ENABLE;
1816 req.Base = mem->win[0].host_addr;
1817 req.Size = mem->win[0].len;
1818 if (req.Size < 0x1000) {
1819 req.Size = 0x1000;
1820 }
1821 req.AccessSpeed = 0;
1822 if (pcmcia_request_window(&link->handle, &req, &link->win) != 0)
1823 goto next_entry;
1824 map.Page = 0; map.CardOffset = mem->win[0].card_addr;
1825 if (pcmcia_map_mem_page(link->win, &map) != 0)
1826 goto next_entry;
1827
1828 data->MmioAddress = (unsigned long)ioremap_nocache(req.Base, req.Size);
1829 data->MmioLength = req.Size;
1830 }
1831 /* If we got this far, we're cool! */
1832 break;
1833
1834 next_entry:
1835 nsp_dbg(NSP_DEBUG_INIT, "next");
1836
1837 if (link->io.NumPorts1) {
1838 pcmcia_release_io(link->handle, &link->io);
1839 }
1840 CS_CHECK(GetNextTuple, pcmcia_get_next_tuple(handle, &tuple));
1841 }
1842
1843 if (link->conf.Attributes & CONF_ENABLE_IRQ) {
1844 CS_CHECK(RequestIRQ, pcmcia_request_irq(link->handle, &link->irq));
1845 }
1846 CS_CHECK(RequestConfiguration, pcmcia_request_configuration(handle, &link->conf));
1847
1848 if (free_ports) {
1849 if (link->io.BasePort1) {
1850 release_region(link->io.BasePort1, link->io.NumPorts1);
1851 }
1852 if (link->io.BasePort2) {
1853 release_region(link->io.BasePort2, link->io.NumPorts2);
1854 }
1855 }
1856
1857 /* Set port and IRQ */
1858 data->BaseAddress = link->io.BasePort1;
1859 data->NumAddress = link->io.NumPorts1;
1860 data->IrqNumber = link->irq.AssignedIRQ;
1861
1862 nsp_dbg(NSP_DEBUG_INIT, "I/O[0x%x+0x%x] IRQ %d",
1863 data->BaseAddress, data->NumAddress, data->IrqNumber);
1864
1865 if(nsphw_init(data) == FALSE) {
1866 goto cs_failed;
1867 }
1868
1869#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,2))
1870 host = nsp_detect(&nsp_driver_template);
1871#else
1872 scsi_register_host(&nsp_driver_template);
1873 for (host = scsi_host_get_next(NULL); host != NULL;
1874 host = scsi_host_get_next(host)) {
1875 if (host->hostt == &nsp_driver_template) {
1876 break;
1877 }
1878 }
1879#endif
1880
1881 if (host == NULL) {
1882 nsp_dbg(NSP_DEBUG_INIT, "detect failed");
1883 goto cs_failed;
1884 }
1885
1886
1887#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,74))
1888 scsi_add_host (host, NULL);
1889 scsi_scan_host(host);
1890
1891 snprintf(info->node.dev_name, sizeof(info->node.dev_name), "scsi%d", host->host_no);
1892 link->dev = &info->node;
1893 info->host = host;
1894
1895#else
1896 nsp_dbg(NSP_DEBUG_INIT, "GET_SCSI_INFO");
1897 tail = &link->dev;
1898 info->ndev = 0;
1899
1900 nsp_dbg(NSP_DEBUG_INIT, "host=0x%p", host);
1901
1902 for (dev = host->host_queue; dev != NULL; dev = dev->next) {
1903 unsigned long id;
1904 id = (dev->id & 0x0f) + ((dev->lun & 0x0f) << 4) +
1905 ((dev->channel & 0x0f) << 8) +
1906 ((dev->host->host_no & 0x0f) << 12);
1907 node = &info->node[info->ndev];
1908 node->minor = 0;
1909 switch (dev->type) {
1910 case TYPE_TAPE:
1911 node->major = SCSI_TAPE_MAJOR;
1912 snprintf(node->dev_name, sizeof(node->dev_name), "st#%04lx", id);
1913 break;
1914 case TYPE_DISK:
1915 case TYPE_MOD:
1916 node->major = SCSI_DISK0_MAJOR;
1917 snprintf(node->dev_name, sizeof(node->dev_name), "sd#%04lx", id);
1918 break;
1919 case TYPE_ROM:
1920 case TYPE_WORM:
1921 node->major = SCSI_CDROM_MAJOR;
1922 snprintf(node->dev_name, sizeof(node->dev_name), "sr#%04lx", id);
1923 break;
1924 default:
1925 node->major = SCSI_GENERIC_MAJOR;
1926 snprintf(node->dev_name, sizeof(node->dev_name), "sg#%04lx", id);
1927 break;
1928 }
1929 *tail = node; tail = &node->next;
1930 info->ndev++;
1931 info->host = dev->host;
1932 }
1933
1934 *tail = NULL;
1935 if (info->ndev == 0) {
1936 nsp_msg(KERN_INFO, "no SCSI devices found");
1937 }
1938 nsp_dbg(NSP_DEBUG_INIT, "host=0x%p", host);
1939#endif
1940
1941 /* Finally, report what we've done */
1942 printk(KERN_INFO "nsp_cs: index 0x%02x: Vcc %d.%d",
1943 link->conf.ConfigIndex,
1944 link->conf.Vcc/10, link->conf.Vcc%10);
1945 if (link->conf.Vpp1) {
1946 printk(", Vpp %d.%d", link->conf.Vpp1/10, link->conf.Vpp1%10);
1947 }
1948 if (link->conf.Attributes & CONF_ENABLE_IRQ) {
1949 printk(", irq %d", link->irq.AssignedIRQ);
1950 }
1951 if (link->io.NumPorts1) {
1952 printk(", io 0x%04x-0x%04x", link->io.BasePort1,
1953 link->io.BasePort1+link->io.NumPorts1-1);
1954 }
1955 if (link->io.NumPorts2)
1956 printk(" & 0x%04x-0x%04x", link->io.BasePort2,
1957 link->io.BasePort2+link->io.NumPorts2-1);
1958 if (link->win)
1959 printk(", mem 0x%06lx-0x%06lx", req.Base,
1960 req.Base+req.Size-1);
1961 printk("\n");
1962
1963 link->state &= ~DEV_CONFIG_PENDING;
1964 return;
1965
1966 cs_failed:
1967 nsp_dbg(NSP_DEBUG_INIT, "config fail");
1968 cs_error(link->handle, last_fn, last_ret);
1969 nsp_cs_release(link);
1970
1971 return;
1972} /* nsp_cs_config */
1973#undef CS_CHECK
1974
1975
1976/*======================================================================
1977 After a card is removed, nsp_cs_release() will unregister the net
1978 device, and release the PCMCIA configuration. If the device is
1979 still open, this will be postponed until it is closed.
1980======================================================================*/
1981static void nsp_cs_release(dev_link_t *link)
1982{
1983 scsi_info_t *info = link->priv;
1984 nsp_hw_data *data = NULL;
1985
1986 if (info->host == NULL) {
1987 nsp_msg(KERN_DEBUG, "unexpected card release call.");
1988 } else {
1989 data = (nsp_hw_data *)info->host->hostdata;
1990 }
1991
1992 nsp_dbg(NSP_DEBUG_INIT, "link=0x%p", link);
1993
1994 /* Unlink the device chain */
1995#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,2))
1996 if (info->host != NULL) {
1997 scsi_remove_host(info->host);
1998 }
1999#else
2000 scsi_unregister_host(&nsp_driver_template);
2001#endif
2002 link->dev = NULL;
2003
2004 if (link->win) {
2005 if (data != NULL) {
2006 iounmap((void *)(data->MmioAddress));
2007 }
2008 pcmcia_release_window(link->win);
2009 }
2010 pcmcia_release_configuration(link->handle);
2011 if (link->io.NumPorts1) {
2012 pcmcia_release_io(link->handle, &link->io);
2013 }
2014 if (link->irq.AssignedIRQ) {
2015 pcmcia_release_irq(link->handle, &link->irq);
2016 }
2017 link->state &= ~DEV_CONFIG;
2018#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,2))
2019 if (info->host != NULL) {
2020 scsi_host_put(info->host);
2021 }
2022#endif
2023} /* nsp_cs_release */
2024
2025/*======================================================================
2026
2027 The card status event handler. Mostly, this schedules other
2028 stuff to run after an event is received. A CARD_REMOVAL event
2029 also sets some flags to discourage the net drivers from trying
2030 to talk to the card any more.
2031
2032 When a CARD_REMOVAL event is received, we immediately set a flag
2033 to block future accesses to this device. All the functions that
2034 actually access the device should check this flag to make sure
2035 the card is still present.
2036
2037======================================================================*/
2038static int nsp_cs_event(event_t event,
2039 int priority,
2040 event_callback_args_t *args)
2041{
2042 dev_link_t *link = args->client_data;
2043 scsi_info_t *info = link->priv;
2044 nsp_hw_data *data;
2045
2046 nsp_dbg(NSP_DEBUG_INIT, "in, event=0x%08x", event);
2047
2048 switch (event) {
2049 case CS_EVENT_CARD_REMOVAL:
2050 nsp_dbg(NSP_DEBUG_INIT, "event: remove");
2051 link->state &= ~DEV_PRESENT;
2052 if (link->state & DEV_CONFIG) {
2053 ((scsi_info_t *)link->priv)->stop = 1;
2054 nsp_cs_release(link);
2055 }
2056 break;
2057
2058 case CS_EVENT_CARD_INSERTION:
2059 nsp_dbg(NSP_DEBUG_INIT, "event: insert");
2060 link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
2061#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,68))
2062 info->bus = args->bus;
2063#endif
2064 nsp_cs_config(link);
2065 break;
2066
2067 case CS_EVENT_PM_SUSPEND:
2068 nsp_dbg(NSP_DEBUG_INIT, "event: suspend");
2069 link->state |= DEV_SUSPEND;
2070 /* Fall through... */
2071 case CS_EVENT_RESET_PHYSICAL:
2072 /* Mark the device as stopped, to block IO until later */
2073 nsp_dbg(NSP_DEBUG_INIT, "event: reset physical");
2074
2075 if (info->host != NULL) {
2076 nsp_msg(KERN_INFO, "clear SDTR status");
2077
2078 data = (nsp_hw_data *)info->host->hostdata;
2079
2080 nsphw_init_sync(data);
2081 }
2082
2083 info->stop = 1;
2084 if (link->state & DEV_CONFIG) {
2085 pcmcia_release_configuration(link->handle);
2086 }
2087 break;
2088
2089 case CS_EVENT_PM_RESUME:
2090 nsp_dbg(NSP_DEBUG_INIT, "event: resume");
2091 link->state &= ~DEV_SUSPEND;
2092 /* Fall through... */
2093 case CS_EVENT_CARD_RESET:
2094 nsp_dbg(NSP_DEBUG_INIT, "event: reset");
2095 if (link->state & DEV_CONFIG) {
2096 pcmcia_request_configuration(link->handle, &link->conf);
2097 }
2098 info->stop = 0;
2099
2100 if (info->host != NULL) {
2101 nsp_msg(KERN_INFO, "reset host and bus");
2102
2103 data = (nsp_hw_data *)info->host->hostdata;
2104
2105 nsphw_init (data);
2106 nsp_bus_reset(data);
2107 }
2108
2109 break;
2110
2111 default:
2112 nsp_dbg(NSP_DEBUG_INIT, "event: unknown");
2113 break;
2114 }
2115 nsp_dbg(NSP_DEBUG_INIT, "end");
2116 return 0;
2117} /* nsp_cs_event */
2118
2119/*======================================================================*
2120 * module entry point
2121 *====================================================================*/
2122#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,68))
Dominik Brodowskiaba14102005-06-27 16:28:40 -07002123static struct pcmcia_device_id nsp_cs_ids[] = {
2124 PCMCIA_DEVICE_PROD_ID123("IO DATA", "CBSC16 ", "1", 0x547e66dc, 0x0d63a3fd, 0x51de003a),
2125 PCMCIA_DEVICE_PROD_ID123("KME ", "SCSI-CARD-001", "1", 0x534c02bc, 0x52008408, 0x51de003a),
2126 PCMCIA_DEVICE_PROD_ID123("KME ", "SCSI-CARD-002", "1", 0x534c02bc, 0xcb09d5b2, 0x51de003a),
2127 PCMCIA_DEVICE_PROD_ID123("KME ", "SCSI-CARD-003", "1", 0x534c02bc, 0xbc0ee524, 0x51de003a),
2128 PCMCIA_DEVICE_PROD_ID123("KME ", "SCSI-CARD-004", "1", 0x534c02bc, 0x226a7087, 0x51de003a),
2129 PCMCIA_DEVICE_PROD_ID123("WBT", "NinjaSCSI-3", "R1.0", 0xc7ba805f, 0xfdc7c97d, 0x6973710e),
2130 PCMCIA_DEVICE_PROD_ID123("WORKBIT", "UltraNinja-16", "1", 0x28191418, 0xb70f4b09, 0x51de003a),
2131 PCMCIA_DEVICE_NULL
2132};
2133MODULE_DEVICE_TABLE(pcmcia, nsp_cs_ids);
2134
Linus Torvalds1da177e2005-04-16 15:20:36 -07002135static struct pcmcia_driver nsp_driver = {
Dominik Brodowski1e212f32005-07-07 17:59:00 -07002136 .owner = THIS_MODULE,
2137 .drv = {
2138 .name = "nsp_cs",
Linus Torvalds1da177e2005-04-16 15:20:36 -07002139 },
Dominik Brodowski1e212f32005-07-07 17:59:00 -07002140 .attach = nsp_cs_attach,
2141 .event = nsp_cs_event,
2142 .detach = nsp_cs_detach,
Dominik Brodowskiaba14102005-06-27 16:28:40 -07002143 .id_table = nsp_cs_ids,
Linus Torvalds1da177e2005-04-16 15:20:36 -07002144};
2145#endif
2146
2147static int __init nsp_cs_init(void)
2148{
2149#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,68))
2150 nsp_msg(KERN_INFO, "loading...");
2151
2152 return pcmcia_register_driver(&nsp_driver);
2153#else
2154 servinfo_t serv;
2155
2156 nsp_msg(KERN_INFO, "loading...");
2157 pcmcia_get_card_services_info(&serv);
Pavel Roskin2ffe6e22005-07-07 17:59:04 -07002158 if (serv.Revision != CS_RELEASE_CODE) {
2159 nsp_msg(KERN_DEBUG, "Card Services release does not match!");
2160 return -EINVAL;
2161 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002162 register_pcmcia_driver(&dev_info, &nsp_cs_attach, &nsp_cs_detach);
2163
2164 nsp_dbg(NSP_DEBUG_INIT, "out");
2165 return 0;
2166#endif
2167}
2168
2169static void __exit nsp_cs_exit(void)
2170{
2171 nsp_msg(KERN_INFO, "unloading...");
2172
2173#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,68))
2174 pcmcia_unregister_driver(&nsp_driver);
2175 BUG_ON(dev_list != NULL);
2176#else
2177 unregister_pcmcia_driver(&dev_info);
2178 /* XXX: this really needs to move into generic code.. */
2179 while (dev_list != NULL) {
2180 if (dev_list->state & DEV_CONFIG) {
2181 nsp_cs_release(dev_list);
2182 }
2183 nsp_cs_detach(dev_list);
2184 }
2185#endif
2186}
2187
2188
2189module_init(nsp_cs_init)
2190module_exit(nsp_cs_exit)
2191
2192/* end */