blob: 85f2394ffc3e352042ef1bb26c0da5f97198f8a4 [file] [log] [blame]
Linus Torvalds1da177e2005-04-16 15:20:36 -07001/* aha152x.c -- Adaptec AHA-152x driver
2 * Author: Jürgen E. Fischer, fischer@norbit.de
3 * Copyright 1993-2004 Jürgen E. Fischer
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License as published by the
7 * Free Software Foundation; either version 2, or (at your option) any
8 * later version.
9 *
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * General Public License for more details.
14 *
15 *
16 * $Id: aha152x.c,v 2.7 2004/01/24 11:42:59 fischer Exp $
17 *
18 * $Log: aha152x.c,v $
19 * Revision 2.7 2004/01/24 11:42:59 fischer
20 * - gather code that is not used by PCMCIA at the end
21 * - move request_region for !PCMCIA case to detection
22 * - migration to new scsi host api (remove legacy code)
23 * - free host scribble before scsi_done
24 * - fix error handling
25 * - one isapnp device added to id_table
26 *
27 * Revision 2.6 2003/10/30 20:52:47 fischer
28 * - interfaces changes for kernel 2.6
29 * - aha152x_probe_one introduced for pcmcia stub
30 * - fixed pnpdev handling
31 * - instead of allocation a new one, reuse command for request sense after check condition and reset
32 * - fixes race in is_complete
33 *
34 * Revision 2.5 2002/04/14 11:24:53 fischer
35 * - isapnp support
36 * - abort fixed
37 * - 2.5 support
38 *
39 * Revision 2.4 2000/12/16 12:53:56 fischer
40 * - allow REQUEST SENSE to be queued
41 * - handle shared PCI interrupts
42 *
43 * Revision 2.3 2000/11/04 16:40:26 fischer
44 * - handle data overruns
45 * - extend timeout for data phases
46 *
47 * Revision 2.2 2000/08/08 19:54:53 fischer
48 * - minor changes
49 *
50 * Revision 2.1 2000/05/17 16:23:17 fischer
51 * - signature update
52 * - fix for data out w/o scatter gather
53 *
54 * Revision 2.0 1999/12/25 15:07:32 fischer
55 * - interrupt routine completly reworked
56 * - basic support for new eh code
57 *
58 * Revision 1.21 1999/11/10 23:46:36 fischer
59 * - default to synchronous operation
60 * - synchronous negotiation fixed
61 * - added timeout to loops
62 * - debugging output can be controlled through procfs
63 *
64 * Revision 1.20 1999/11/07 18:37:31 fischer
65 * - synchronous operation works
66 * - resid support for sg driver
67 *
68 * Revision 1.19 1999/11/02 22:39:59 fischer
69 * - moved leading comments to README.aha152x
70 * - new additional module parameters
71 * - updates for 2.3
72 * - support for the Tripace TC1550 controller
73 * - interrupt handling changed
74 *
75 * Revision 1.18 1996/09/07 20:10:40 fischer
76 * - fixed can_queue handling (multiple outstanding commands working again)
77 *
78 * Revision 1.17 1996/08/17 16:05:14 fischer
79 * - biosparam improved
80 * - interrupt verification
81 * - updated documentation
82 * - cleanups
83 *
84 * Revision 1.16 1996/06/09 00:04:56 root
85 * - added configuration symbols for insmod (aha152x/aha152x1)
86 *
87 * Revision 1.15 1996/04/30 14:52:06 fischer
88 * - proc info fixed
89 * - support for extended translation for >1GB disks
90 *
91 * Revision 1.14 1996/01/17 15:11:20 fischer
92 * - fixed lockup in MESSAGE IN phase after reconnection
93 *
94 * Revision 1.13 1996/01/09 02:15:53 fischer
95 * - some cleanups
96 * - moved request_irq behind controller initialization
97 * (to avoid spurious interrupts)
98 *
99 * Revision 1.12 1995/12/16 12:26:07 fischer
100 * - barrier()s added
101 * - configurable RESET delay added
102 *
103 * Revision 1.11 1995/12/06 21:18:35 fischer
104 * - some minor updates
105 *
106 * Revision 1.10 1995/07/22 19:18:45 fischer
107 * - support for 2 controllers
108 * - started synchronous data transfers (not working yet)
109 *
110 * Revision 1.9 1995/03/18 09:20:24 root
111 * - patches for PCMCIA and modules
112 *
113 * Revision 1.8 1995/01/21 22:07:19 root
114 * - snarf_region => request_region
115 * - aha152x_intr interface change
116 *
117 * Revision 1.7 1995/01/02 23:19:36 root
118 * - updated COMMAND_SIZE to cmd_len
119 * - changed sti() to restore_flags()
120 * - fixed some #ifdef which generated warnings
121 *
122 * Revision 1.6 1994/11/24 20:35:27 root
123 * - problem with odd number of bytes in fifo fixed
124 *
125 * Revision 1.5 1994/10/30 14:39:56 root
126 * - abort code fixed
127 * - debugging improved
128 *
129 * Revision 1.4 1994/09/12 11:33:01 root
130 * - irqaction to request_irq
131 * - abortion updated
132 *
133 * Revision 1.3 1994/08/04 13:53:05 root
134 * - updates for mid-level-driver changes
135 * - accept unexpected BUSFREE phase as error condition
136 * - parity check now configurable
137 *
138 * Revision 1.2 1994/07/03 12:56:36 root
139 * - cleaned up debugging code
140 * - more tweaking on reset delays
141 * - updated abort/reset code (pretty untested...)
142 *
143 * Revision 1.1 1994/05/28 21:18:49 root
144 * - update for mid-level interface change (abort-reset)
145 * - delays after resets adjusted for some slow devices
146 *
147 * Revision 1.0 1994/03/25 12:52:00 root
148 * - Fixed "more data than expected" problem
149 * - added new BIOS signatures
150 *
151 * Revision 0.102 1994/01/31 20:44:12 root
152 * - minor changes in insw/outsw handling
153 *
154 * Revision 0.101 1993/12/13 01:16:27 root
155 * - fixed STATUS phase (non-GOOD stati were dropped sometimes;
156 * fixes problems with CD-ROM sector size detection & media change)
157 *
158 * Revision 0.100 1993/12/10 16:58:47 root
159 * - fix for unsuccessful selections in case of non-continuous id assignments
160 * on the scsi bus.
161 *
162 * Revision 0.99 1993/10/24 16:19:59 root
163 * - fixed DATA IN (rare read errors gone)
164 *
165 * Revision 0.98 1993/10/17 12:54:44 root
166 * - fixed some recent fixes (shame on me)
167 * - moved initialization of scratch area to aha152x_queue
168 *
169 * Revision 0.97 1993/10/09 18:53:53 root
170 * - DATA IN fixed. Rarely left data in the fifo.
171 *
172 * Revision 0.96 1993/10/03 00:53:59 root
173 * - minor changes on DATA IN
174 *
175 * Revision 0.95 1993/09/24 10:36:01 root
176 * - change handling of MSGI after reselection
177 * - fixed sti/cli
178 * - minor changes
179 *
180 * Revision 0.94 1993/09/18 14:08:22 root
181 * - fixed bug in multiple outstanding command code
182 * - changed detection
183 * - support for kernel command line configuration
184 * - reset corrected
185 * - changed message handling
186 *
187 * Revision 0.93 1993/09/15 20:41:19 root
188 * - fixed bugs with multiple outstanding commands
189 *
190 * Revision 0.92 1993/09/13 02:46:33 root
191 * - multiple outstanding commands work (no problems with IBM drive)
192 *
193 * Revision 0.91 1993/09/12 20:51:46 root
194 * added multiple outstanding commands
195 * (some problem with this $%&? IBM device remain)
196 *
197 * Revision 0.9 1993/09/12 11:11:22 root
198 * - corrected auto-configuration
199 * - changed the auto-configuration (added some '#define's)
200 * - added support for dis-/reconnection
201 *
202 * Revision 0.8 1993/09/06 23:09:39 root
203 * - added support for the drive activity light
204 * - minor changes
205 *
206 * Revision 0.7 1993/09/05 14:30:15 root
207 * - improved phase detection
208 * - now using the new snarf_region code of 0.99pl13
209 *
210 * Revision 0.6 1993/09/02 11:01:38 root
211 * first public release; added some signatures and biosparam()
212 *
213 * Revision 0.5 1993/08/30 10:23:30 root
214 * fixed timing problems with my IBM drive
215 *
216 * Revision 0.4 1993/08/29 14:06:52 root
217 * fixed some problems with timeouts due incomplete commands
218 *
219 * Revision 0.3 1993/08/28 15:55:03 root
220 * writing data works too. mounted and worked on a dos partition
221 *
222 * Revision 0.2 1993/08/27 22:42:07 root
223 * reading data works. Mounted a msdos partition.
224 *
225 * Revision 0.1 1993/08/25 13:38:30 root
226 * first "damn thing doesn't work" version
227 *
228 * Revision 0.0 1993/08/14 19:54:25 root
229 * empty function bodies; detect() works.
230 *
231 *
232 **************************************************************************
233
234 see Documentation/scsi/aha152x.txt for configuration details
235
236 **************************************************************************/
237
238#include <linux/module.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -0700239#include <asm/irq.h>
Matthew Wilcox53d5ed62006-10-11 01:22:01 -0700240#include <linux/io.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -0700241#include <linux/blkdev.h>
242#include <asm/system.h>
Christoph Hellwig0f06bb32007-05-13 17:52:12 +0200243#include <linux/completion.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -0700244#include <linux/errno.h>
245#include <linux/string.h>
246#include <linux/wait.h>
247#include <linux/ioport.h>
248#include <linux/delay.h>
249#include <linux/proc_fs.h>
250#include <linux/interrupt.h>
251#include <linux/init.h>
252#include <linux/kernel.h>
253#include <linux/isapnp.h>
254#include <linux/spinlock.h>
255#include <linux/workqueue.h>
James Bottomley5fcda422006-09-14 17:04:58 -0500256#include <linux/list.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -0700257#include <scsi/scsicam.h>
258
259#include "scsi.h"
db9dff32005-04-03 14:53:59 -0500260#include <scsi/scsi_dbg.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -0700261#include <scsi/scsi_host.h>
Matthew Wilcox1abfd372005-12-15 16:22:01 -0500262#include <scsi/scsi_transport_spi.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -0700263#include "aha152x.h"
264
James Bottomley5fcda422006-09-14 17:04:58 -0500265static LIST_HEAD(aha152x_host_list);
266
Linus Torvalds1da177e2005-04-16 15:20:36 -0700267
268/* DEFINES */
269
270/* For PCMCIA cards, always use AUTOCONF */
271#if defined(PCMCIA) || defined(MODULE)
272#if !defined(AUTOCONF)
273#define AUTOCONF
274#endif
275#endif
276
277#if !defined(AUTOCONF) && !defined(SETUP0)
278#error define AUTOCONF or SETUP0
279#endif
280
281#if defined(AHA152X_DEBUG)
282#define DEBUG_DEFAULT debug_eh
283
284#define DPRINTK(when,msgs...) \
285 do { if(HOSTDATA(shpnt)->debug & (when)) printk(msgs); } while(0)
286
287#define DO_LOCK(flags) \
288 do { \
289 if(spin_is_locked(&QLOCK)) { \
290 DPRINTK(debug_intr, DEBUG_LEAD "(%s:%d) already locked at %s:%d\n", CMDINFO(CURRENT_SC), __FUNCTION__, __LINE__, QLOCKER, QLOCKERL); \
291 } \
292 DPRINTK(debug_locks, DEBUG_LEAD "(%s:%d) locking\n", CMDINFO(CURRENT_SC), __FUNCTION__, __LINE__); \
293 spin_lock_irqsave(&QLOCK,flags); \
294 DPRINTK(debug_locks, DEBUG_LEAD "(%s:%d) locked\n", CMDINFO(CURRENT_SC), __FUNCTION__, __LINE__); \
295 QLOCKER=__FUNCTION__; \
296 QLOCKERL=__LINE__; \
297 } while(0)
298
299#define DO_UNLOCK(flags) \
300 do { \
301 DPRINTK(debug_locks, DEBUG_LEAD "(%s:%d) unlocking (locked at %s:%d)\n", CMDINFO(CURRENT_SC), __FUNCTION__, __LINE__, QLOCKER, QLOCKERL); \
302 spin_unlock_irqrestore(&QLOCK,flags); \
303 DPRINTK(debug_locks, DEBUG_LEAD "(%s:%d) unlocked\n", CMDINFO(CURRENT_SC), __FUNCTION__, __LINE__); \
304 QLOCKER="(not locked)"; \
305 QLOCKERL=0; \
306 } while(0)
307
308#else
309#define DPRINTK(when,msgs...)
310#define DO_LOCK(flags) spin_lock_irqsave(&QLOCK,flags)
311#define DO_UNLOCK(flags) spin_unlock_irqrestore(&QLOCK,flags)
312#endif
313
314#define LEAD "(scsi%d:%d:%d) "
315#define WARN_LEAD KERN_WARNING LEAD
316#define INFO_LEAD KERN_INFO LEAD
317#define NOTE_LEAD KERN_NOTICE LEAD
318#define ERR_LEAD KERN_ERR LEAD
319#define DEBUG_LEAD KERN_DEBUG LEAD
320#define CMDINFO(cmd) \
321 (cmd) ? ((cmd)->device->host->host_no) : -1, \
322 (cmd) ? ((cmd)->device->id & 0x0f) : -1, \
323 (cmd) ? ((cmd)->device->lun & 0x07) : -1
324
325#define DELAY_DEFAULT 1000
326
327#if defined(PCMCIA)
328#define IRQ_MIN 0
329#define IRQ_MAX 16
330#else
331#define IRQ_MIN 9
332#if defined(__PPC)
333#define IRQ_MAX (NR_IRQS-1)
334#else
335#define IRQ_MAX 12
336#endif
337#endif
338
339enum {
340 not_issued = 0x0001, /* command not yet issued */
341 selecting = 0x0002, /* target is beeing selected */
342 identified = 0x0004, /* IDENTIFY was sent */
343 disconnected = 0x0008, /* target disconnected */
344 completed = 0x0010, /* target sent COMMAND COMPLETE */
345 aborted = 0x0020, /* ABORT was sent */
346 resetted = 0x0040, /* BUS DEVICE RESET was sent */
347 spiordy = 0x0080, /* waiting for SPIORDY to raise */
348 syncneg = 0x0100, /* synchronous negotiation in progress */
349 aborting = 0x0200, /* ABORT is pending */
350 resetting = 0x0400, /* BUS DEVICE RESET is pending */
351 check_condition = 0x0800, /* requesting sense after CHECK CONDITION */
352};
353
354MODULE_AUTHOR("Jürgen Fischer");
355MODULE_DESCRIPTION(AHA152X_REVID);
356MODULE_LICENSE("GPL");
357
358#if !defined(PCMCIA)
359#if defined(MODULE)
360static int io[] = {0, 0};
361module_param_array(io, int, NULL, 0);
362MODULE_PARM_DESC(io,"base io address of controller");
363
364static int irq[] = {0, 0};
365module_param_array(irq, int, NULL, 0);
366MODULE_PARM_DESC(irq,"interrupt for controller");
367
368static int scsiid[] = {7, 7};
369module_param_array(scsiid, int, NULL, 0);
370MODULE_PARM_DESC(scsiid,"scsi id of controller");
371
372static int reconnect[] = {1, 1};
373module_param_array(reconnect, int, NULL, 0);
374MODULE_PARM_DESC(reconnect,"allow targets to disconnect");
375
376static int parity[] = {1, 1};
377module_param_array(parity, int, NULL, 0);
378MODULE_PARM_DESC(parity,"use scsi parity");
379
380static int sync[] = {1, 1};
381module_param_array(sync, int, NULL, 0);
382MODULE_PARM_DESC(sync,"use synchronous transfers");
383
384static int delay[] = {DELAY_DEFAULT, DELAY_DEFAULT};
385module_param_array(delay, int, NULL, 0);
386MODULE_PARM_DESC(delay,"scsi reset delay");
387
388static int exttrans[] = {0, 0};
389module_param_array(exttrans, int, NULL, 0);
390MODULE_PARM_DESC(exttrans,"use extended translation");
391
392#if !defined(AHA152X_DEBUG)
393static int aha152x[] = {0, 11, 7, 1, 1, 0, DELAY_DEFAULT, 0};
394module_param_array(aha152x, int, NULL, 0);
395MODULE_PARM_DESC(aha152x, "parameters for first controller");
396
397static int aha152x1[] = {0, 11, 7, 1, 1, 0, DELAY_DEFAULT, 0};
398module_param_array(aha152x1, int, NULL, 0);
399MODULE_PARM_DESC(aha152x1, "parameters for second controller");
400#else
401static int debug[] = {DEBUG_DEFAULT, DEBUG_DEFAULT};
402module_param_array(debug, int, NULL, 0);
403MODULE_PARM_DESC(debug, "flags for driver debugging");
404
405static int aha152x[] = {0, 11, 7, 1, 1, 1, DELAY_DEFAULT, 0, DEBUG_DEFAULT};
406module_param_array(aha152x, int, NULL, 0);
407MODULE_PARM_DESC(aha152x, "parameters for first controller");
408
409static int aha152x1[] = {0, 11, 7, 1, 1, 1, DELAY_DEFAULT, 0, DEBUG_DEFAULT};
410module_param_array(aha152x1, int, NULL, 0);
411MODULE_PARM_DESC(aha152x1, "parameters for second controller");
412#endif /* !defined(AHA152X_DEBUG) */
413#endif /* MODULE */
414
415#ifdef __ISAPNP__
416static struct isapnp_device_id id_table[] __devinitdata = {
417 { ISAPNP_ANY_ID, ISAPNP_ANY_ID,
418 ISAPNP_VENDOR('A','D','P'), ISAPNP_FUNCTION(0x1505), 0 },
419 { ISAPNP_ANY_ID, ISAPNP_ANY_ID,
420 ISAPNP_VENDOR('A','D','P'), ISAPNP_FUNCTION(0x1530), 0 },
421 { ISAPNP_DEVICE_SINGLE_END, }
422};
423MODULE_DEVICE_TABLE(isapnp, id_table);
424#endif /* ISAPNP */
425
426#endif /* !PCMCIA */
427
Christoph Hellwigd0be4a7d2005-10-31 18:31:40 +0100428static struct scsi_host_template aha152x_driver_template;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700429
430/*
431 * internal states of the host
432 *
433 */
434enum aha152x_state {
435 idle=0,
436 unknown,
437 seldo,
438 seldi,
439 selto,
440 busfree,
441 msgo,
442 cmd,
443 msgi,
444 status,
445 datai,
446 datao,
447 parerr,
448 rsti,
449 maxstate
450};
451
452/*
453 * current state information of the host
454 *
455 */
456struct aha152x_hostdata {
457 Scsi_Cmnd *issue_SC;
458 /* pending commands to issue */
459
460 Scsi_Cmnd *current_SC;
461 /* current command on the bus */
462
463 Scsi_Cmnd *disconnected_SC;
464 /* commands that disconnected */
465
466 Scsi_Cmnd *done_SC;
467 /* command that was completed */
468
469 spinlock_t lock;
470 /* host lock */
471
472#if defined(AHA152X_DEBUG)
473 const char *locker;
474 /* which function has the lock */
475 int lockerl; /* where did it get it */
476
477 int debug; /* current debugging setting */
478#endif
479
480#if defined(AHA152X_STAT)
481 int total_commands;
482 int disconnections;
483 int busfree_without_any_action;
484 int busfree_without_old_command;
485 int busfree_without_new_command;
486 int busfree_without_done_command;
487 int busfree_with_check_condition;
488 int count[maxstate];
489 int count_trans[maxstate];
490 unsigned long time[maxstate];
491#endif
492
493 int commands; /* current number of commands */
494
495 int reconnect; /* disconnection allowed */
496 int parity; /* parity checking enabled */
497 int synchronous; /* synchronous transferes enabled */
498 int delay; /* reset out delay */
499 int ext_trans; /* extended translation enabled */
500
501 int swint; /* software-interrupt was fired during detect() */
502 int service; /* bh needs to be run */
503 int in_intr; /* bh is running */
504
505 /* current state,
506 previous state,
507 last state different from current state */
508 enum aha152x_state state, prevstate, laststate;
509
510 int target;
511 /* reconnecting target */
512
513 unsigned char syncrate[8];
514 /* current synchronous transfer agreements */
515
516 unsigned char syncneg[8];
517 /* 0: no negotiation;
518 * 1: negotiation in progress;
519 * 2: negotiation completed
520 */
521
522 int cmd_i;
523 /* number of sent bytes of current command */
524
525 int msgi_len;
526 /* number of received message bytes */
527 unsigned char msgi[256];
528 /* received message bytes */
529
530 int msgo_i, msgo_len;
531 /* number of sent bytes and length of current messages */
532 unsigned char msgo[256];
533 /* pending messages */
534
535 int data_len;
536 /* number of sent/received bytes in dataphase */
537
538 unsigned long io_port0;
539 unsigned long io_port1;
540
541#ifdef __ISAPNP__
542 struct pnp_dev *pnpdev;
543#endif
James Bottomley5fcda422006-09-14 17:04:58 -0500544 struct list_head host_list;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700545};
546
547
548/*
549 * host specific command extension
550 *
551 */
552struct aha152x_scdata {
553 Scsi_Cmnd *next; /* next sc in queue */
Christoph Hellwig0f06bb32007-05-13 17:52:12 +0200554 struct completion *done;/* semaphore to block on */
Christoph Hellwig5e13cdf2006-07-08 20:39:30 +0200555 unsigned char cmd_len;
556 unsigned char cmnd[MAX_COMMAND_SIZE];
557 unsigned short use_sg;
558 unsigned request_bufflen;
559 void *request_buffer;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700560};
561
562
563/* access macros for hostdata */
564
565#define HOSTDATA(shpnt) ((struct aha152x_hostdata *) &shpnt->hostdata)
566
567#define HOSTNO ((shpnt)->host_no)
568
569#define CURRENT_SC (HOSTDATA(shpnt)->current_SC)
570#define DONE_SC (HOSTDATA(shpnt)->done_SC)
571#define ISSUE_SC (HOSTDATA(shpnt)->issue_SC)
572#define DISCONNECTED_SC (HOSTDATA(shpnt)->disconnected_SC)
573#define QLOCK (HOSTDATA(shpnt)->lock)
574#define QLOCKER (HOSTDATA(shpnt)->locker)
575#define QLOCKERL (HOSTDATA(shpnt)->lockerl)
576
577#define STATE (HOSTDATA(shpnt)->state)
578#define PREVSTATE (HOSTDATA(shpnt)->prevstate)
579#define LASTSTATE (HOSTDATA(shpnt)->laststate)
580
581#define RECONN_TARGET (HOSTDATA(shpnt)->target)
582
583#define CMD_I (HOSTDATA(shpnt)->cmd_i)
584
585#define MSGO(i) (HOSTDATA(shpnt)->msgo[i])
586#define MSGO_I (HOSTDATA(shpnt)->msgo_i)
587#define MSGOLEN (HOSTDATA(shpnt)->msgo_len)
588#define ADDMSGO(x) (MSGOLEN<256 ? (void)(MSGO(MSGOLEN++)=x) : aha152x_error(shpnt,"MSGO overflow"))
589
590#define MSGI(i) (HOSTDATA(shpnt)->msgi[i])
591#define MSGILEN (HOSTDATA(shpnt)->msgi_len)
592#define ADDMSGI(x) (MSGILEN<256 ? (void)(MSGI(MSGILEN++)=x) : aha152x_error(shpnt,"MSGI overflow"))
593
594#define DATA_LEN (HOSTDATA(shpnt)->data_len)
595
596#define SYNCRATE (HOSTDATA(shpnt)->syncrate[CURRENT_SC->device->id])
597#define SYNCNEG (HOSTDATA(shpnt)->syncneg[CURRENT_SC->device->id])
598
599#define DELAY (HOSTDATA(shpnt)->delay)
600#define EXT_TRANS (HOSTDATA(shpnt)->ext_trans)
601#define TC1550 (HOSTDATA(shpnt)->tc1550)
602#define RECONNECT (HOSTDATA(shpnt)->reconnect)
603#define PARITY (HOSTDATA(shpnt)->parity)
604#define SYNCHRONOUS (HOSTDATA(shpnt)->synchronous)
605
606#define HOSTIOPORT0 (HOSTDATA(shpnt)->io_port0)
607#define HOSTIOPORT1 (HOSTDATA(shpnt)->io_port1)
608
609#define SCDATA(SCpnt) ((struct aha152x_scdata *) (SCpnt)->host_scribble)
610#define SCNEXT(SCpnt) SCDATA(SCpnt)->next
Christoph Hellwig0f06bb32007-05-13 17:52:12 +0200611#define SCSEM(SCpnt) SCDATA(SCpnt)->done
Linus Torvalds1da177e2005-04-16 15:20:36 -0700612
613#define SG_ADDRESS(buffer) ((char *) (page_address((buffer)->page)+(buffer)->offset))
614
615/* state handling */
616static void seldi_run(struct Scsi_Host *shpnt);
617static void seldo_run(struct Scsi_Host *shpnt);
618static void selto_run(struct Scsi_Host *shpnt);
619static void busfree_run(struct Scsi_Host *shpnt);
620
621static void msgo_init(struct Scsi_Host *shpnt);
622static void msgo_run(struct Scsi_Host *shpnt);
623static void msgo_end(struct Scsi_Host *shpnt);
624
625static void cmd_init(struct Scsi_Host *shpnt);
626static void cmd_run(struct Scsi_Host *shpnt);
627static void cmd_end(struct Scsi_Host *shpnt);
628
629static void datai_init(struct Scsi_Host *shpnt);
630static void datai_run(struct Scsi_Host *shpnt);
631static void datai_end(struct Scsi_Host *shpnt);
632
633static void datao_init(struct Scsi_Host *shpnt);
634static void datao_run(struct Scsi_Host *shpnt);
635static void datao_end(struct Scsi_Host *shpnt);
636
637static void status_run(struct Scsi_Host *shpnt);
638
639static void msgi_run(struct Scsi_Host *shpnt);
640static void msgi_end(struct Scsi_Host *shpnt);
641
642static void parerr_run(struct Scsi_Host *shpnt);
643static void rsti_run(struct Scsi_Host *shpnt);
644
645static void is_complete(struct Scsi_Host *shpnt);
646
647/*
648 * driver states
649 *
650 */
651static struct {
652 char *name;
653 void (*init)(struct Scsi_Host *);
654 void (*run)(struct Scsi_Host *);
655 void (*end)(struct Scsi_Host *);
656 int spio;
657} states[] = {
658 { "idle", NULL, NULL, NULL, 0},
659 { "unknown", NULL, NULL, NULL, 0},
660 { "seldo", NULL, seldo_run, NULL, 0},
661 { "seldi", NULL, seldi_run, NULL, 0},
662 { "selto", NULL, selto_run, NULL, 0},
663 { "busfree", NULL, busfree_run, NULL, 0},
664 { "msgo", msgo_init, msgo_run, msgo_end, 1},
665 { "cmd", cmd_init, cmd_run, cmd_end, 1},
666 { "msgi", NULL, msgi_run, msgi_end, 1},
667 { "status", NULL, status_run, NULL, 1},
668 { "datai", datai_init, datai_run, datai_end, 0},
669 { "datao", datao_init, datao_run, datao_end, 0},
670 { "parerr", NULL, parerr_run, NULL, 0},
671 { "rsti", NULL, rsti_run, NULL, 0},
672};
673
674/* setup & interrupt */
David Howells7d12e782006-10-05 14:55:46 +0100675static irqreturn_t intr(int irq, void *dev_id);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700676static void reset_ports(struct Scsi_Host *shpnt);
677static void aha152x_error(struct Scsi_Host *shpnt, char *msg);
678static void done(struct Scsi_Host *shpnt, int error);
679
680/* diagnostics */
681static void disp_ports(struct Scsi_Host *shpnt);
682static void show_command(Scsi_Cmnd * ptr);
683static void show_queues(struct Scsi_Host *shpnt);
684static void disp_enintr(struct Scsi_Host *shpnt);
685
686
687/*
688 * queue services:
689 *
690 */
691static inline void append_SC(Scsi_Cmnd **SC, Scsi_Cmnd *new_SC)
692{
693 Scsi_Cmnd *end;
694
695 SCNEXT(new_SC) = NULL;
696 if (!*SC)
697 *SC = new_SC;
698 else {
699 for (end = *SC; SCNEXT(end); end = SCNEXT(end))
700 ;
701 SCNEXT(end) = new_SC;
702 }
703}
704
705static inline Scsi_Cmnd *remove_first_SC(Scsi_Cmnd ** SC)
706{
707 Scsi_Cmnd *ptr;
708
709 ptr = *SC;
710 if (ptr) {
711 *SC = SCNEXT(*SC);
712 SCNEXT(ptr)=NULL;
713 }
714 return ptr;
715}
716
717static inline Scsi_Cmnd *remove_lun_SC(Scsi_Cmnd ** SC, int target, int lun)
718{
719 Scsi_Cmnd *ptr, *prev;
720
721 for (ptr = *SC, prev = NULL;
722 ptr && ((ptr->device->id != target) || (ptr->device->lun != lun));
723 prev = ptr, ptr = SCNEXT(ptr))
724 ;
725
726 if (ptr) {
727 if (prev)
728 SCNEXT(prev) = SCNEXT(ptr);
729 else
730 *SC = SCNEXT(ptr);
731
732 SCNEXT(ptr)=NULL;
733 }
734
735 return ptr;
736}
737
738static inline Scsi_Cmnd *remove_SC(Scsi_Cmnd **SC, Scsi_Cmnd *SCp)
739{
740 Scsi_Cmnd *ptr, *prev;
741
742 for (ptr = *SC, prev = NULL;
743 ptr && SCp!=ptr;
744 prev = ptr, ptr = SCNEXT(ptr))
745 ;
746
747 if (ptr) {
748 if (prev)
749 SCNEXT(prev) = SCNEXT(ptr);
750 else
751 *SC = SCNEXT(ptr);
752
753 SCNEXT(ptr)=NULL;
754 }
755
756 return ptr;
757}
758
David Howells7d12e782006-10-05 14:55:46 +0100759static irqreturn_t swintr(int irqno, void *dev_id)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700760{
Jeff Garzikc7bec5a2006-10-06 15:00:58 -0400761 struct Scsi_Host *shpnt = dev_id;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700762
763 HOSTDATA(shpnt)->swint++;
764
765 SETPORT(DMACNTRL0, INTEN);
766 return IRQ_HANDLED;
767}
768
769struct Scsi_Host *aha152x_probe_one(struct aha152x_setup *setup)
770{
771 struct Scsi_Host *shpnt;
772
773 shpnt = scsi_host_alloc(&aha152x_driver_template, sizeof(struct aha152x_hostdata));
774 if (!shpnt) {
775 printk(KERN_ERR "aha152x: scsi_host_alloc failed\n");
776 return NULL;
777 }
778
Linus Torvalds1da177e2005-04-16 15:20:36 -0700779 memset(HOSTDATA(shpnt), 0, sizeof *HOSTDATA(shpnt));
James Bottomley5fcda422006-09-14 17:04:58 -0500780 INIT_LIST_HEAD(&HOSTDATA(shpnt)->host_list);
781
782 /* need to have host registered before triggering any interrupt */
783 list_add_tail(&HOSTDATA(shpnt)->host_list, &aha152x_host_list);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700784
785 shpnt->io_port = setup->io_port;
786 shpnt->n_io_port = IO_RANGE;
787 shpnt->irq = setup->irq;
788
789 if (!setup->tc1550) {
790 HOSTIOPORT0 = setup->io_port;
791 HOSTIOPORT1 = setup->io_port;
792 } else {
793 HOSTIOPORT0 = setup->io_port+0x10;
794 HOSTIOPORT1 = setup->io_port-0x10;
795 }
796
797 spin_lock_init(&QLOCK);
798 RECONNECT = setup->reconnect;
799 SYNCHRONOUS = setup->synchronous;
800 PARITY = setup->parity;
801 DELAY = setup->delay;
802 EXT_TRANS = setup->ext_trans;
803
804#if defined(AHA152X_DEBUG)
805 HOSTDATA(shpnt)->debug = setup->debug;
806#endif
807
808 SETPORT(SCSIID, setup->scsiid << 4);
809 shpnt->this_id = setup->scsiid;
810
811 if (setup->reconnect)
812 shpnt->can_queue = AHA152X_MAXQUEUE;
813
814 /* RESET OUT */
815 printk("aha152x: resetting bus...\n");
816 SETPORT(SCSISEQ, SCSIRSTO);
817 mdelay(256);
818 SETPORT(SCSISEQ, 0);
819 mdelay(DELAY);
820
821 reset_ports(shpnt);
822
823 printk(KERN_INFO
824 "aha152x%d%s: "
825 "vital data: rev=%x, "
826 "io=0x%03lx (0x%03lx/0x%03lx), "
827 "irq=%d, "
828 "scsiid=%d, "
829 "reconnect=%s, "
830 "parity=%s, "
831 "synchronous=%s, "
832 "delay=%d, "
833 "extended translation=%s\n",
834 shpnt->host_no, setup->tc1550 ? " (tc1550 mode)" : "",
835 GETPORT(REV) & 0x7,
836 shpnt->io_port, HOSTIOPORT0, HOSTIOPORT1,
837 shpnt->irq,
838 shpnt->this_id,
839 RECONNECT ? "enabled" : "disabled",
840 PARITY ? "enabled" : "disabled",
841 SYNCHRONOUS ? "enabled" : "disabled",
842 DELAY,
843 EXT_TRANS ? "enabled" : "disabled");
844
845 /* not expecting any interrupts */
846 SETPORT(SIMODE0, 0);
847 SETPORT(SIMODE1, 0);
848
Thomas Gleixner1d6f3592006-07-01 19:29:42 -0700849 if( request_irq(shpnt->irq, swintr, IRQF_DISABLED|IRQF_SHARED, "aha152x", shpnt) ) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700850 printk(KERN_ERR "aha152x%d: irq %d busy.\n", shpnt->host_no, shpnt->irq);
851 goto out_host_put;
852 }
853
854 HOSTDATA(shpnt)->swint = 0;
855
856 printk(KERN_INFO "aha152x%d: trying software interrupt, ", shpnt->host_no);
857
858 mb();
859 SETPORT(DMACNTRL0, SWINT|INTEN);
860 mdelay(1000);
861 free_irq(shpnt->irq, shpnt);
862
863 if (!HOSTDATA(shpnt)->swint) {
864 if (TESTHI(DMASTAT, INTSTAT)) {
865 printk("lost.\n");
866 } else {
867 printk("failed.\n");
868 }
869
870 SETPORT(DMACNTRL0, INTEN);
871
872 printk(KERN_ERR "aha152x%d: irq %d possibly wrong. "
873 "Please verify.\n", shpnt->host_no, shpnt->irq);
874 goto out_host_put;
875 }
876 printk("ok.\n");
877
878
879 /* clear interrupts */
880 SETPORT(SSTAT0, 0x7f);
881 SETPORT(SSTAT1, 0xef);
882
Thomas Gleixner1d6f3592006-07-01 19:29:42 -0700883 if ( request_irq(shpnt->irq, intr, IRQF_DISABLED|IRQF_SHARED, "aha152x", shpnt) ) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700884 printk(KERN_ERR "aha152x%d: failed to reassign irq %d.\n", shpnt->host_no, shpnt->irq);
885 goto out_host_put;
886 }
887
888 if( scsi_add_host(shpnt, NULL) ) {
889 free_irq(shpnt->irq, shpnt);
890 printk(KERN_ERR "aha152x%d: failed to add host.\n", shpnt->host_no);
891 goto out_host_put;
892 }
893
894 scsi_scan_host(shpnt);
895
Linus Torvalds1da177e2005-04-16 15:20:36 -0700896 return shpnt;
897
898out_host_put:
James Bottomley5fcda422006-09-14 17:04:58 -0500899 list_del(&HOSTDATA(shpnt)->host_list);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700900 scsi_host_put(shpnt);
901
902 return NULL;
903}
904
905void aha152x_release(struct Scsi_Host *shpnt)
906{
907 if(!shpnt)
908 return;
909
910 if (shpnt->irq)
911 free_irq(shpnt->irq, shpnt);
912
913#if !defined(PCMCIA)
914 if (shpnt->io_port)
915 release_region(shpnt->io_port, IO_RANGE);
916#endif
917
918#ifdef __ISAPNP__
919 if (HOSTDATA(shpnt)->pnpdev)
920 pnp_device_detach(HOSTDATA(shpnt)->pnpdev);
921#endif
922
923 scsi_remove_host(shpnt);
James Bottomley5fcda422006-09-14 17:04:58 -0500924 list_del(&HOSTDATA(shpnt)->host_list);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700925 scsi_host_put(shpnt);
926}
927
928
929/*
930 * setup controller to generate interrupts depending
931 * on current state (lock has to be acquired)
932 *
933 */
934static int setup_expected_interrupts(struct Scsi_Host *shpnt)
935{
936 if(CURRENT_SC) {
937 CURRENT_SC->SCp.phase |= 1 << 16;
938
939 if(CURRENT_SC->SCp.phase & selecting) {
940 DPRINTK(debug_intr, DEBUG_LEAD "expecting: (seldo) (seltimo) (seldi)\n", CMDINFO(CURRENT_SC));
941 SETPORT(SSTAT1, SELTO);
942 SETPORT(SIMODE0, ENSELDO | (DISCONNECTED_SC ? ENSELDI : 0));
943 SETPORT(SIMODE1, ENSELTIMO);
944 } else {
945 DPRINTK(debug_intr, DEBUG_LEAD "expecting: (phase change) (busfree) %s\n", CMDINFO(CURRENT_SC), CURRENT_SC->SCp.phase & spiordy ? "(spiordy)" : "");
946 SETPORT(SIMODE0, (CURRENT_SC->SCp.phase & spiordy) ? ENSPIORDY : 0);
947 SETPORT(SIMODE1, ENPHASEMIS | ENSCSIRST | ENSCSIPERR | ENBUSFREE);
948 }
949 } else if(STATE==seldi) {
950 DPRINTK(debug_intr, DEBUG_LEAD "expecting: (phase change) (identify)\n", CMDINFO(CURRENT_SC));
951 SETPORT(SIMODE0, 0);
952 SETPORT(SIMODE1, ENPHASEMIS | ENSCSIRST | ENSCSIPERR | ENBUSFREE);
953 } else {
954 DPRINTK(debug_intr, DEBUG_LEAD "expecting: %s %s\n",
955 CMDINFO(CURRENT_SC),
956 DISCONNECTED_SC ? "(reselection)" : "",
957 ISSUE_SC ? "(busfree)" : "");
958 SETPORT(SIMODE0, DISCONNECTED_SC ? ENSELDI : 0);
959 SETPORT(SIMODE1, ENSCSIRST | ( (ISSUE_SC||DONE_SC) ? ENBUSFREE : 0));
960 }
961
962 if(!HOSTDATA(shpnt)->in_intr)
963 SETBITS(DMACNTRL0, INTEN);
964
965 return TESTHI(DMASTAT, INTSTAT);
966}
967
968
969/*
970 * Queue a command and setup interrupts for a free bus.
971 */
Christoph Hellwig0f06bb32007-05-13 17:52:12 +0200972static int aha152x_internal_queue(Scsi_Cmnd *SCpnt, struct completion *complete,
973 int phase, void (*done)(Scsi_Cmnd *))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700974{
975 struct Scsi_Host *shpnt = SCpnt->device->host;
976 unsigned long flags;
977
978#if defined(AHA152X_DEBUG)
979 if (HOSTDATA(shpnt)->debug & debug_queue) {
980 printk(INFO_LEAD "queue: %p; cmd_len=%d pieces=%d size=%u cmnd=",
981 CMDINFO(SCpnt), SCpnt, SCpnt->cmd_len, SCpnt->use_sg, SCpnt->request_bufflen);
db9dff32005-04-03 14:53:59 -0500982 __scsi_print_command(SCpnt->cmnd);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700983 }
984#endif
985
986 SCpnt->scsi_done = done;
987 SCpnt->resid = SCpnt->request_bufflen;
988 SCpnt->SCp.phase = not_issued | phase;
989 SCpnt->SCp.Status = CHECK_CONDITION;
990 SCpnt->SCp.Message = 0;
991 SCpnt->SCp.have_data_in = 0;
992 SCpnt->SCp.sent_command = 0;
993
994 if(SCpnt->SCp.phase & (resetting|check_condition)) {
995 if(SCpnt->host_scribble==0 || SCSEM(SCpnt) || SCNEXT(SCpnt)) {
996 printk(ERR_LEAD "cannot reuse command\n", CMDINFO(SCpnt));
997 return FAILED;
998 }
999 } else {
Christoph Hellwig5e13cdf2006-07-08 20:39:30 +02001000 struct aha152x_scdata *sc;
1001
Linus Torvalds1da177e2005-04-16 15:20:36 -07001002 SCpnt->host_scribble = kmalloc(sizeof(struct aha152x_scdata), GFP_ATOMIC);
1003 if(SCpnt->host_scribble==0) {
1004 printk(ERR_LEAD "allocation failed\n", CMDINFO(SCpnt));
1005 return FAILED;
1006 }
Christoph Hellwig5e13cdf2006-07-08 20:39:30 +02001007
1008 sc = SCDATA(SCpnt);
1009 memcpy(sc->cmnd, SCpnt->cmnd, sizeof(sc->cmnd));
1010 sc->request_buffer = SCpnt->request_buffer;
1011 sc->request_bufflen = SCpnt->request_bufflen;
1012 sc->use_sg = SCpnt->use_sg;
1013 sc->cmd_len = SCpnt->cmd_len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001014 }
1015
1016 SCNEXT(SCpnt) = NULL;
Christoph Hellwig0f06bb32007-05-13 17:52:12 +02001017 SCSEM(SCpnt) = complete;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001018
1019 /* setup scratch area
1020 SCp.ptr : buffer pointer
1021 SCp.this_residual : buffer length
1022 SCp.buffer : next buffer
1023 SCp.buffers_residual : left buffers in list
1024 SCp.phase : current state of the command */
1025 if (SCpnt->use_sg) {
1026 SCpnt->SCp.buffer = (struct scatterlist *) SCpnt->request_buffer;
1027 SCpnt->SCp.ptr = SG_ADDRESS(SCpnt->SCp.buffer);
1028 SCpnt->SCp.this_residual = SCpnt->SCp.buffer->length;
1029 SCpnt->SCp.buffers_residual = SCpnt->use_sg - 1;
1030 } else {
1031 SCpnt->SCp.ptr = (char *) SCpnt->request_buffer;
1032 SCpnt->SCp.this_residual = SCpnt->request_bufflen;
1033 SCpnt->SCp.buffer = NULL;
1034 SCpnt->SCp.buffers_residual = 0;
1035 }
1036
1037 DO_LOCK(flags);
1038
1039#if defined(AHA152X_STAT)
1040 HOSTDATA(shpnt)->total_commands++;
1041#endif
1042
1043 /* Turn led on, when this is the first command. */
1044 HOSTDATA(shpnt)->commands++;
1045 if (HOSTDATA(shpnt)->commands==1)
1046 SETPORT(PORTA, 1);
1047
1048 append_SC(&ISSUE_SC, SCpnt);
1049
1050 if(!HOSTDATA(shpnt)->in_intr)
1051 setup_expected_interrupts(shpnt);
1052
1053 DO_UNLOCK(flags);
1054
1055 return 0;
1056}
1057
1058/*
1059 * queue a command
1060 *
1061 */
1062static int aha152x_queue(Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *))
1063{
1064#if 0
1065 if(*SCpnt->cmnd == REQUEST_SENSE) {
1066 SCpnt->result = 0;
1067 done(SCpnt);
1068
1069 return 0;
1070 }
1071#endif
1072
1073 return aha152x_internal_queue(SCpnt, NULL, 0, done);
1074}
1075
1076
1077/*
1078 *
1079 *
1080 */
1081static void reset_done(Scsi_Cmnd *SCpnt)
1082{
1083#if 0
1084 struct Scsi_Host *shpnt = SCpnt->host;
1085 DPRINTK(debug_eh, INFO_LEAD "reset_done called\n", CMDINFO(SCpnt));
1086#endif
1087 if(SCSEM(SCpnt)) {
Christoph Hellwig0f06bb32007-05-13 17:52:12 +02001088 complete(SCSEM(SCpnt));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001089 } else {
Christoph Hellwig0f06bb32007-05-13 17:52:12 +02001090 printk(KERN_ERR "aha152x: reset_done w/o completion\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001091 }
1092}
1093
1094/*
1095 * Abort a command
1096 *
1097 */
1098static int aha152x_abort(Scsi_Cmnd *SCpnt)
1099{
1100 struct Scsi_Host *shpnt = SCpnt->device->host;
1101 Scsi_Cmnd *ptr;
1102 unsigned long flags;
1103
1104#if defined(AHA152X_DEBUG)
1105 if(HOSTDATA(shpnt)->debug & debug_eh) {
1106 printk(DEBUG_LEAD "abort(%p)", CMDINFO(SCpnt), SCpnt);
1107 show_queues(shpnt);
1108 }
1109#endif
1110
1111 DO_LOCK(flags);
1112
1113 ptr=remove_SC(&ISSUE_SC, SCpnt);
1114
1115 if(ptr) {
1116 DPRINTK(debug_eh, DEBUG_LEAD "not yet issued - SUCCESS\n", CMDINFO(SCpnt));
1117
1118 HOSTDATA(shpnt)->commands--;
1119 if (!HOSTDATA(shpnt)->commands)
1120 SETPORT(PORTA, 0);
1121 DO_UNLOCK(flags);
1122
1123 kfree(SCpnt->host_scribble);
1124 SCpnt->host_scribble=NULL;
1125
1126 return SUCCESS;
1127 }
1128
1129 DO_UNLOCK(flags);
1130
1131 /*
1132 * FIXME:
1133 * for current command: queue ABORT for message out and raise ATN
1134 * for disconnected command: pseudo SC with ABORT message or ABORT on reselection?
1135 *
1136 */
1137
1138 printk(ERR_LEAD "cannot abort running or disconnected command\n", CMDINFO(SCpnt));
1139
1140 return FAILED;
1141}
1142
Linus Torvalds1da177e2005-04-16 15:20:36 -07001143/*
1144 * Reset a device
1145 *
1146 */
1147static int aha152x_device_reset(Scsi_Cmnd * SCpnt)
1148{
1149 struct Scsi_Host *shpnt = SCpnt->device->host;
Christoph Hellwig0f06bb32007-05-13 17:52:12 +02001150 DECLARE_COMPLETION(done);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001151 int ret, issued, disconnected;
Christoph Hellwig631c2282006-07-08 20:42:15 +02001152 unsigned char old_cmd_len = SCpnt->cmd_len;
1153 unsigned short old_use_sg = SCpnt->use_sg;
1154 void *old_buffer = SCpnt->request_buffer;
1155 unsigned old_bufflen = SCpnt->request_bufflen;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001156 unsigned long flags;
Christoph Hellwig0f06bb32007-05-13 17:52:12 +02001157 unsigned long timeleft;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001158
1159#if defined(AHA152X_DEBUG)
1160 if(HOSTDATA(shpnt)->debug & debug_eh) {
1161 printk(INFO_LEAD "aha152x_device_reset(%p)", CMDINFO(SCpnt), SCpnt);
1162 show_queues(shpnt);
1163 }
1164#endif
1165
1166 if(CURRENT_SC==SCpnt) {
1167 printk(ERR_LEAD "cannot reset current device\n", CMDINFO(SCpnt));
1168 return FAILED;
1169 }
1170
1171 DO_LOCK(flags);
1172 issued = remove_SC(&ISSUE_SC, SCpnt)==0;
1173 disconnected = issued && remove_SC(&DISCONNECTED_SC, SCpnt);
1174 DO_UNLOCK(flags);
1175
1176 SCpnt->cmd_len = 0;
1177 SCpnt->use_sg = 0;
1178 SCpnt->request_buffer = NULL;
1179 SCpnt->request_bufflen = 0;
1180
Christoph Hellwig0f06bb32007-05-13 17:52:12 +02001181 aha152x_internal_queue(SCpnt, &done, resetting, reset_done);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001182
Christoph Hellwig0f06bb32007-05-13 17:52:12 +02001183 timeleft = wait_for_completion_timeout(&done, 100*HZ);
1184 if (!timeleft) {
1185 /* remove command from issue queue */
1186 DO_LOCK(flags);
1187 remove_SC(&ISSUE_SC, SCpnt);
1188 DO_UNLOCK(flags);
1189 }
Christoph Hellwig631c2282006-07-08 20:42:15 +02001190
1191 SCpnt->cmd_len = old_cmd_len;
1192 SCpnt->use_sg = old_use_sg;
1193 SCpnt->request_buffer = old_buffer;
1194 SCpnt->request_bufflen = old_bufflen;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001195
1196 DO_LOCK(flags);
1197
1198 if(SCpnt->SCp.phase & resetted) {
1199 HOSTDATA(shpnt)->commands--;
1200 if (!HOSTDATA(shpnt)->commands)
1201 SETPORT(PORTA, 0);
1202 kfree(SCpnt->host_scribble);
1203 SCpnt->host_scribble=NULL;
1204
1205 ret = SUCCESS;
1206 } else {
1207 /* requeue */
1208 if(!issued) {
1209 append_SC(&ISSUE_SC, SCpnt);
1210 } else if(disconnected) {
1211 append_SC(&DISCONNECTED_SC, SCpnt);
1212 }
1213
1214 ret = FAILED;
1215 }
1216
1217 DO_UNLOCK(flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001218 return ret;
1219}
1220
1221static void free_hard_reset_SCs(struct Scsi_Host *shpnt, Scsi_Cmnd **SCs)
1222{
1223 Scsi_Cmnd *ptr;
1224
1225 ptr=*SCs;
1226 while(ptr) {
1227 Scsi_Cmnd *next;
1228
1229 if(SCDATA(ptr)) {
1230 next = SCNEXT(ptr);
1231 } else {
1232 printk(DEBUG_LEAD "queue corrupted at %p\n", CMDINFO(ptr), ptr);
1233 next = NULL;
1234 }
1235
1236 if (!ptr->device->soft_reset) {
1237 DPRINTK(debug_eh, DEBUG_LEAD "disconnected command %p removed\n", CMDINFO(ptr), ptr);
1238 remove_SC(SCs, ptr);
1239 HOSTDATA(shpnt)->commands--;
1240 kfree(ptr->host_scribble);
1241 ptr->host_scribble=NULL;
1242 }
1243
1244 ptr = next;
1245 }
1246}
1247
1248/*
1249 * Reset the bus
1250 *
1251 */
Jürgen E. Fischere2482fa2006-02-19 00:31:51 +01001252static int aha152x_bus_reset_host(struct Scsi_Host *shpnt)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001253{
Linus Torvalds1da177e2005-04-16 15:20:36 -07001254 unsigned long flags;
1255
1256 DO_LOCK(flags);
1257
1258#if defined(AHA152X_DEBUG)
1259 if(HOSTDATA(shpnt)->debug & debug_eh) {
Jürgen E. Fischere2482fa2006-02-19 00:31:51 +01001260 printk(KERN_DEBUG "scsi%d: bus reset", shpnt->host_no);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001261 show_queues(shpnt);
1262 }
1263#endif
1264
1265 free_hard_reset_SCs(shpnt, &ISSUE_SC);
1266 free_hard_reset_SCs(shpnt, &DISCONNECTED_SC);
1267
Jürgen E. Fischere2482fa2006-02-19 00:31:51 +01001268 DPRINTK(debug_eh, KERN_DEBUG "scsi%d: resetting bus\n", shpnt->host_no);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001269
1270 SETPORT(SCSISEQ, SCSIRSTO);
1271 mdelay(256);
1272 SETPORT(SCSISEQ, 0);
1273 mdelay(DELAY);
1274
Jürgen E. Fischere2482fa2006-02-19 00:31:51 +01001275 DPRINTK(debug_eh, KERN_DEBUG "scsi%d: bus resetted\n", shpnt->host_no);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001276
1277 setup_expected_interrupts(shpnt);
1278 if(HOSTDATA(shpnt)->commands==0)
1279 SETPORT(PORTA, 0);
1280
1281 DO_UNLOCK(flags);
1282
1283 return SUCCESS;
1284}
1285
Jürgen E. Fischere2482fa2006-02-19 00:31:51 +01001286/*
1287 * Reset the bus
1288 *
1289 */
1290static int aha152x_bus_reset(Scsi_Cmnd *SCpnt)
1291{
1292 return aha152x_bus_reset_host(SCpnt->device->host);
1293}
Linus Torvalds1da177e2005-04-16 15:20:36 -07001294
1295/*
1296 * Restore default values to the AIC-6260 registers and reset the fifos
1297 *
1298 */
1299static void reset_ports(struct Scsi_Host *shpnt)
1300{
1301 unsigned long flags;
1302
1303 /* disable interrupts */
1304 SETPORT(DMACNTRL0, RSTFIFO);
1305
1306 SETPORT(SCSISEQ, 0);
1307
1308 SETPORT(SXFRCTL1, 0);
1309 SETPORT(SCSISIG, 0);
1310 SETRATE(0);
1311
1312 /* clear all interrupt conditions */
1313 SETPORT(SSTAT0, 0x7f);
1314 SETPORT(SSTAT1, 0xef);
1315
1316 SETPORT(SSTAT4, SYNCERR | FWERR | FRERR);
1317
1318 SETPORT(DMACNTRL0, 0);
1319 SETPORT(DMACNTRL1, 0);
1320
1321 SETPORT(BRSTCNTRL, 0xf1);
1322
1323 /* clear SCSI fifos and transfer count */
1324 SETPORT(SXFRCTL0, CH1|CLRCH1|CLRSTCNT);
1325 SETPORT(SXFRCTL0, CH1);
1326
1327 DO_LOCK(flags);
1328 setup_expected_interrupts(shpnt);
1329 DO_UNLOCK(flags);
1330}
1331
1332/*
1333 * Reset the host (bus and controller)
1334 *
1335 */
Jürgen E. Fischere2482fa2006-02-19 00:31:51 +01001336int aha152x_host_reset_host(struct Scsi_Host *shpnt)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001337{
Jürgen E. Fischere2482fa2006-02-19 00:31:51 +01001338 DPRINTK(debug_eh, KERN_DEBUG "scsi%d: host reset\n", shpnt->host_no);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001339
Jürgen E. Fischere2482fa2006-02-19 00:31:51 +01001340 aha152x_bus_reset_host(shpnt);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001341
Jürgen E. Fischere2482fa2006-02-19 00:31:51 +01001342 DPRINTK(debug_eh, KERN_DEBUG "scsi%d: resetting ports\n", shpnt->host_no);
1343 reset_ports(shpnt);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001344
1345 return SUCCESS;
1346}
1347
1348/*
Jürgen E. Fischere2482fa2006-02-19 00:31:51 +01001349 * Reset the host (bus and controller)
1350 *
1351 */
1352static int aha152x_host_reset(Scsi_Cmnd *SCpnt)
1353{
1354 return aha152x_host_reset_host(SCpnt->device->host);
1355}
1356
1357/*
Linus Torvalds1da177e2005-04-16 15:20:36 -07001358 * Return the "logical geometry"
1359 *
1360 */
1361static int aha152x_biosparam(struct scsi_device *sdev, struct block_device *bdev,
1362 sector_t capacity, int *info_array)
1363{
1364 struct Scsi_Host *shpnt = sdev->host;
1365
1366 /* try default translation */
1367 info_array[0] = 64;
1368 info_array[1] = 32;
1369 info_array[2] = (unsigned long)capacity / (64 * 32);
1370
1371 /* for disks >1GB do some guessing */
1372 if (info_array[2] >= 1024) {
1373 int info[3];
1374
1375 /* try to figure out the geometry from the partition table */
1376 if (scsicam_bios_param(bdev, capacity, info) < 0 ||
1377 !((info[0] == 64 && info[1] == 32) || (info[0] == 255 && info[1] == 63))) {
1378 if (EXT_TRANS) {
1379 printk(KERN_NOTICE
1380 "aha152x: unable to verify geometry for disk with >1GB.\n"
1381 " using extended translation.\n");
1382 info_array[0] = 255;
1383 info_array[1] = 63;
1384 info_array[2] = (unsigned long)capacity / (255 * 63);
1385 } else {
1386 printk(KERN_NOTICE
1387 "aha152x: unable to verify geometry for disk with >1GB.\n"
1388 " Using default translation. Please verify yourself.\n"
1389 " Perhaps you need to enable extended translation in the driver.\n"
1390 " See Documentation/scsi/aha152x.txt for details.\n");
1391 }
1392 } else {
1393 info_array[0] = info[0];
1394 info_array[1] = info[1];
1395 info_array[2] = info[2];
1396
1397 if (info[0] == 255 && !EXT_TRANS) {
1398 printk(KERN_NOTICE
1399 "aha152x: current partition table is using extended translation.\n"
1400 " using it also, although it's not explicitly enabled.\n");
1401 }
1402 }
1403 }
1404
1405 return 0;
1406}
1407
1408/*
1409 * Internal done function
1410 *
1411 */
1412static void done(struct Scsi_Host *shpnt, int error)
1413{
1414 if (CURRENT_SC) {
1415 if(DONE_SC)
1416 printk(ERR_LEAD "there's already a completed command %p - will cause abort\n", CMDINFO(CURRENT_SC), DONE_SC);
1417
1418 DONE_SC = CURRENT_SC;
1419 CURRENT_SC = NULL;
1420 DONE_SC->result = error;
1421 } else
1422 printk(KERN_ERR "aha152x: done() called outside of command\n");
1423}
1424
1425static struct work_struct aha152x_tq;
1426
1427/*
1428 * Run service completions on the card with interrupts enabled.
1429 *
1430 */
David Howellsc4028952006-11-22 14:57:56 +00001431static void run(struct work_struct *work)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001432{
James Bottomley5fcda422006-09-14 17:04:58 -05001433 struct aha152x_hostdata *hd;
1434
1435 list_for_each_entry(hd, &aha152x_host_list, host_list) {
1436 struct Scsi_Host *shost = container_of((void *)hd, struct Scsi_Host, hostdata);
1437
1438 is_complete(shost);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001439 }
1440}
1441
1442/*
Jürgen E. Fischere2482fa2006-02-19 00:31:51 +01001443 * Interrupt handler
Linus Torvalds1da177e2005-04-16 15:20:36 -07001444 *
1445 */
David Howells7d12e782006-10-05 14:55:46 +01001446static irqreturn_t intr(int irqno, void *dev_id)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001447{
James Bottomley5fcda422006-09-14 17:04:58 -05001448 struct Scsi_Host *shpnt = (struct Scsi_Host *)dev_id;
Jürgen E. Fischere2482fa2006-02-19 00:31:51 +01001449 unsigned long flags;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001450 unsigned char rev, dmacntrl0;
1451
1452 if (!shpnt) {
1453 printk(KERN_ERR "aha152x: catched interrupt %d for unknown controller.\n", irqno);
1454 return IRQ_NONE;
1455 }
1456
1457 /*
1458 * Read a couple of registers that are known to not be all 1's. If
1459 * we read all 1's (-1), that means that either:
1460 *
1461 * a. The host adapter chip has gone bad, and we cannot control it,
1462 * OR
1463 * b. The host adapter is a PCMCIA card that has been ejected
1464 *
1465 * In either case, we cannot do anything with the host adapter at
1466 * this point in time. So just ignore the interrupt and return.
1467 * In the latter case, the interrupt might actually be meant for
1468 * someone else sharing this IRQ, and that driver will handle it.
1469 */
1470 rev = GETPORT(REV);
1471 dmacntrl0 = GETPORT(DMACNTRL0);
1472 if ((rev == 0xFF) && (dmacntrl0 == 0xFF))
1473 return IRQ_NONE;
1474
Jürgen E. Fischere2482fa2006-02-19 00:31:51 +01001475 if( TESTLO(DMASTAT, INTSTAT) )
1476 return IRQ_NONE;
1477
Linus Torvalds1da177e2005-04-16 15:20:36 -07001478 /* no more interrupts from the controller, while we're busy.
1479 INTEN is restored by the BH handler */
1480 CLRBITS(DMACNTRL0, INTEN);
1481
Jürgen E. Fischere2482fa2006-02-19 00:31:51 +01001482 DO_LOCK(flags);
1483 if( HOSTDATA(shpnt)->service==0 ) {
1484 HOSTDATA(shpnt)->service=1;
1485
1486 /* Poke the BH handler */
David Howellsc4028952006-11-22 14:57:56 +00001487 INIT_WORK(&aha152x_tq, run);
Jürgen E. Fischere2482fa2006-02-19 00:31:51 +01001488 schedule_work(&aha152x_tq);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001489 }
Jürgen E. Fischere2482fa2006-02-19 00:31:51 +01001490 DO_UNLOCK(flags);
1491
Linus Torvalds1da177e2005-04-16 15:20:36 -07001492 return IRQ_HANDLED;
1493}
1494
1495/*
1496 * busfree phase
1497 * - handle completition/disconnection/error of current command
1498 * - start selection for next command (if any)
1499 */
1500static void busfree_run(struct Scsi_Host *shpnt)
1501{
1502 unsigned long flags;
1503#if defined(AHA152X_STAT)
1504 int action=0;
1505#endif
1506
1507 SETPORT(SXFRCTL0, CH1|CLRCH1|CLRSTCNT);
1508 SETPORT(SXFRCTL0, CH1);
1509
1510 SETPORT(SSTAT1, CLRBUSFREE);
1511
1512 if(CURRENT_SC) {
1513#if defined(AHA152X_STAT)
1514 action++;
1515#endif
1516 CURRENT_SC->SCp.phase &= ~syncneg;
1517
1518 if(CURRENT_SC->SCp.phase & completed) {
1519 /* target sent COMMAND COMPLETE */
1520 done(shpnt, (CURRENT_SC->SCp.Status & 0xff) | ((CURRENT_SC->SCp.Message & 0xff) << 8) | (DID_OK << 16));
1521
1522 } else if(CURRENT_SC->SCp.phase & aborted) {
1523 DPRINTK(debug_eh, DEBUG_LEAD "ABORT sent\n", CMDINFO(CURRENT_SC));
1524 done(shpnt, (CURRENT_SC->SCp.Status & 0xff) | ((CURRENT_SC->SCp.Message & 0xff) << 8) | (DID_ABORT << 16));
1525
1526 } else if(CURRENT_SC->SCp.phase & resetted) {
1527 DPRINTK(debug_eh, DEBUG_LEAD "BUS DEVICE RESET sent\n", CMDINFO(CURRENT_SC));
1528 done(shpnt, (CURRENT_SC->SCp.Status & 0xff) | ((CURRENT_SC->SCp.Message & 0xff) << 8) | (DID_RESET << 16));
1529
1530 } else if(CURRENT_SC->SCp.phase & disconnected) {
1531 /* target sent DISCONNECT */
1532 DPRINTK(debug_selection, DEBUG_LEAD "target disconnected at %d/%d\n",
1533 CMDINFO(CURRENT_SC),
1534 CURRENT_SC->resid,
1535 CURRENT_SC->request_bufflen);
1536#if defined(AHA152X_STAT)
1537 HOSTDATA(shpnt)->disconnections++;
1538#endif
1539 append_SC(&DISCONNECTED_SC, CURRENT_SC);
1540 CURRENT_SC->SCp.phase |= 1 << 16;
1541 CURRENT_SC = NULL;
1542
1543 } else {
1544 done(shpnt, DID_ERROR << 16);
1545 }
1546#if defined(AHA152X_STAT)
1547 } else {
1548 HOSTDATA(shpnt)->busfree_without_old_command++;
1549#endif
1550 }
1551
1552 DO_LOCK(flags);
1553
1554 if(DONE_SC) {
1555#if defined(AHA152X_STAT)
1556 action++;
1557#endif
1558
1559 if(DONE_SC->SCp.phase & check_condition) {
Christoph Hellwig5e13cdf2006-07-08 20:39:30 +02001560 struct scsi_cmnd *cmd = HOSTDATA(shpnt)->done_SC;
1561 struct aha152x_scdata *sc = SCDATA(cmd);
1562
Linus Torvalds1da177e2005-04-16 15:20:36 -07001563#if 0
1564 if(HOSTDATA(shpnt)->debug & debug_eh) {
1565 printk(ERR_LEAD "received sense: ", CMDINFO(DONE_SC));
db9dff32005-04-03 14:53:59 -05001566 scsi_print_sense("bh", DONE_SC);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001567 }
1568#endif
1569
1570 /* restore old command */
Christoph Hellwig5e13cdf2006-07-08 20:39:30 +02001571 memcpy(cmd->cmnd, sc->cmnd, sizeof(sc->cmnd));
1572 cmd->request_buffer = sc->request_buffer;
1573 cmd->request_bufflen = sc->request_bufflen;
1574 cmd->use_sg = sc->use_sg;
1575 cmd->cmd_len = sc->cmd_len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001576
Christoph Hellwig5e13cdf2006-07-08 20:39:30 +02001577 cmd->SCp.Status = 0x02;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001578
1579 HOSTDATA(shpnt)->commands--;
1580 if (!HOSTDATA(shpnt)->commands)
1581 SETPORT(PORTA, 0); /* turn led off */
1582 } else if(DONE_SC->SCp.Status==0x02) {
1583#if defined(AHA152X_STAT)
1584 HOSTDATA(shpnt)->busfree_with_check_condition++;
1585#endif
1586#if 0
1587 DPRINTK(debug_eh, ERR_LEAD "CHECK CONDITION found\n", CMDINFO(DONE_SC));
1588#endif
1589
1590 if(!(DONE_SC->SCp.Status & not_issued)) {
1591 Scsi_Cmnd *ptr = DONE_SC;
1592 DONE_SC=NULL;
1593#if 0
1594 DPRINTK(debug_eh, ERR_LEAD "requesting sense\n", CMDINFO(ptr));
1595#endif
1596
1597 ptr->cmnd[0] = REQUEST_SENSE;
1598 ptr->cmnd[1] = 0;
1599 ptr->cmnd[2] = 0;
1600 ptr->cmnd[3] = 0;
1601 ptr->cmnd[4] = sizeof(ptr->sense_buffer);
1602 ptr->cmnd[5] = 0;
1603 ptr->cmd_len = 6;
1604 ptr->use_sg = 0;
1605 ptr->request_buffer = ptr->sense_buffer;
1606 ptr->request_bufflen = sizeof(ptr->sense_buffer);
1607
1608 DO_UNLOCK(flags);
1609 aha152x_internal_queue(ptr, NULL, check_condition, ptr->scsi_done);
1610 DO_LOCK(flags);
1611#if 0
1612 } else {
1613 DPRINTK(debug_eh, ERR_LEAD "command not issued - CHECK CONDITION ignored\n", CMDINFO(DONE_SC));
1614#endif
1615 }
1616 }
1617
1618 if(DONE_SC && DONE_SC->scsi_done) {
1619#if defined(AHA152X_DEBUG)
1620 int hostno=DONE_SC->device->host->host_no;
1621 int id=DONE_SC->device->id & 0xf;
1622 int lun=DONE_SC->device->lun & 0x7;
1623#endif
1624 Scsi_Cmnd *ptr = DONE_SC;
1625 DONE_SC=NULL;
1626
1627 /* turn led off, when no commands are in the driver */
1628 HOSTDATA(shpnt)->commands--;
1629 if (!HOSTDATA(shpnt)->commands)
1630 SETPORT(PORTA, 0); /* turn led off */
1631
1632 if(ptr->scsi_done != reset_done) {
1633 kfree(ptr->host_scribble);
1634 ptr->host_scribble=NULL;
1635 }
1636
1637 DO_UNLOCK(flags);
1638 DPRINTK(debug_done, DEBUG_LEAD "calling scsi_done(%p)\n", hostno, id, lun, ptr);
1639 ptr->scsi_done(ptr);
1640 DPRINTK(debug_done, DEBUG_LEAD "scsi_done(%p) returned\n", hostno, id, lun, ptr);
1641 DO_LOCK(flags);
1642 }
1643
1644 DONE_SC=NULL;
1645#if defined(AHA152X_STAT)
1646 } else {
1647 HOSTDATA(shpnt)->busfree_without_done_command++;
1648#endif
1649 }
1650
1651 if(ISSUE_SC)
1652 CURRENT_SC = remove_first_SC(&ISSUE_SC);
1653
1654 DO_UNLOCK(flags);
1655
1656 if(CURRENT_SC) {
1657#if defined(AHA152X_STAT)
1658 action++;
1659#endif
1660 CURRENT_SC->SCp.phase |= selecting;
1661
1662 DPRINTK(debug_selection, DEBUG_LEAD "selecting target\n", CMDINFO(CURRENT_SC));
1663
1664 /* clear selection timeout */
1665 SETPORT(SSTAT1, SELTO);
1666
1667 SETPORT(SCSIID, (shpnt->this_id << OID_) | CURRENT_SC->device->id);
1668 SETPORT(SXFRCTL1, (PARITY ? ENSPCHK : 0 ) | ENSTIMER);
1669 SETPORT(SCSISEQ, ENSELO | ENAUTOATNO | (DISCONNECTED_SC ? ENRESELI : 0));
1670 } else {
1671#if defined(AHA152X_STAT)
1672 HOSTDATA(shpnt)->busfree_without_new_command++;
1673#endif
1674 SETPORT(SCSISEQ, DISCONNECTED_SC ? ENRESELI : 0);
1675 }
1676
1677#if defined(AHA152X_STAT)
1678 if(!action)
1679 HOSTDATA(shpnt)->busfree_without_any_action++;
1680#endif
1681}
1682
1683/*
1684 * Selection done (OUT)
1685 * - queue IDENTIFY message and SDTR to selected target for message out
1686 * (ATN asserted automagically via ENAUTOATNO in busfree())
1687 */
1688static void seldo_run(struct Scsi_Host *shpnt)
1689{
1690 SETPORT(SCSISIG, 0);
1691 SETPORT(SSTAT1, CLRBUSFREE);
1692 SETPORT(SSTAT1, CLRPHASECHG);
1693
1694 CURRENT_SC->SCp.phase &= ~(selecting|not_issued);
1695
1696 SETPORT(SCSISEQ, 0);
1697
1698 if (TESTLO(SSTAT0, SELDO)) {
1699 printk(ERR_LEAD "aha152x: passing bus free condition\n", CMDINFO(CURRENT_SC));
1700 done(shpnt, DID_NO_CONNECT << 16);
1701 return;
1702 }
1703
1704 SETPORT(SSTAT0, CLRSELDO);
1705
1706 ADDMSGO(IDENTIFY(RECONNECT, CURRENT_SC->device->lun));
1707
1708 if (CURRENT_SC->SCp.phase & aborting) {
1709 ADDMSGO(ABORT);
1710 } else if (CURRENT_SC->SCp.phase & resetting) {
1711 ADDMSGO(BUS_DEVICE_RESET);
1712 } else if (SYNCNEG==0 && SYNCHRONOUS) {
1713 CURRENT_SC->SCp.phase |= syncneg;
Matthew Wilcox6ea3c0b2006-02-07 07:54:46 -07001714 MSGOLEN += spi_populate_sync_msg(&MSGO(MSGOLEN), 50, 8);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001715 SYNCNEG=1; /* negotiation in progress */
1716 }
1717
1718 SETRATE(SYNCRATE);
1719}
1720
1721/*
1722 * Selection timeout
1723 * - return command to mid-level with failure cause
1724 *
1725 */
1726static void selto_run(struct Scsi_Host *shpnt)
1727{
1728 SETPORT(SCSISEQ, 0);
1729 SETPORT(SSTAT1, CLRSELTIMO);
1730
1731 DPRINTK(debug_selection, DEBUG_LEAD "selection timeout\n", CMDINFO(CURRENT_SC));
1732
1733 if(!CURRENT_SC) {
1734 DPRINTK(debug_selection, DEBUG_LEAD "!CURRENT_SC\n", CMDINFO(CURRENT_SC));
1735 return;
1736 }
1737
1738 CURRENT_SC->SCp.phase &= ~selecting;
1739
1740 if (CURRENT_SC->SCp.phase & aborted) {
1741 DPRINTK(debug_selection, DEBUG_LEAD "aborted\n", CMDINFO(CURRENT_SC));
1742 done(shpnt, DID_ABORT << 16);
1743 } else if (TESTLO(SSTAT0, SELINGO)) {
1744 DPRINTK(debug_selection, DEBUG_LEAD "arbitration not won\n", CMDINFO(CURRENT_SC));
1745 done(shpnt, DID_BUS_BUSY << 16);
1746 } else {
1747 /* ARBITRATION won, but SELECTION failed */
1748 DPRINTK(debug_selection, DEBUG_LEAD "selection failed\n", CMDINFO(CURRENT_SC));
1749 done(shpnt, DID_NO_CONNECT << 16);
1750 }
1751}
1752
1753/*
1754 * Selection in done
1755 * - put current command back to issue queue
1756 * (reconnection of a disconnected nexus instead
1757 * of successful selection out)
1758 *
1759 */
1760static void seldi_run(struct Scsi_Host *shpnt)
1761{
1762 int selid;
1763 int target;
1764 unsigned long flags;
1765
1766 SETPORT(SCSISIG, 0);
1767 SETPORT(SSTAT0, CLRSELDI);
1768 SETPORT(SSTAT1, CLRBUSFREE);
1769 SETPORT(SSTAT1, CLRPHASECHG);
1770
1771 if(CURRENT_SC) {
1772 if(!(CURRENT_SC->SCp.phase & not_issued))
1773 printk(ERR_LEAD "command should not have been issued yet\n", CMDINFO(CURRENT_SC));
1774
1775 DPRINTK(debug_selection, ERR_LEAD "command requeued - reselection\n", CMDINFO(CURRENT_SC));
1776
1777 DO_LOCK(flags);
1778 append_SC(&ISSUE_SC, CURRENT_SC);
1779 DO_UNLOCK(flags);
1780
1781 CURRENT_SC = NULL;
1782 }
1783
1784 if(!DISCONNECTED_SC) {
1785 DPRINTK(debug_selection, DEBUG_LEAD "unexpected SELDI ", CMDINFO(CURRENT_SC));
1786 return;
1787 }
1788
1789 RECONN_TARGET=-1;
1790
1791 selid = GETPORT(SELID) & ~(1 << shpnt->this_id);
1792
1793 if (selid==0) {
1794 printk("aha152x%d: target id unknown (%02x)\n", HOSTNO, selid);
1795 return;
1796 }
1797
1798 for(target=7; !(selid & (1 << target)); target--)
1799 ;
1800
1801 if(selid & ~(1 << target)) {
1802 printk("aha152x%d: multiple targets reconnected (%02x)\n",
1803 HOSTNO, selid);
1804 }
1805
1806
1807 SETPORT(SCSIID, (shpnt->this_id << OID_) | target);
1808 SETPORT(SCSISEQ, 0);
1809
1810 SETRATE(HOSTDATA(shpnt)->syncrate[target]);
1811
1812 RECONN_TARGET=target;
1813 DPRINTK(debug_selection, DEBUG_LEAD "target %d reselected (%02x).\n", CMDINFO(CURRENT_SC), target, selid);
1814}
1815
1816/*
1817 * message in phase
1818 * - handle initial message after reconnection to identify
1819 * reconnecting nexus
1820 * - queue command on DISCONNECTED_SC on DISCONNECT message
1821 * - set completed flag on COMMAND COMPLETE
1822 * (other completition code moved to busfree_run)
1823 * - handle response to SDTR
1824 * - clear synchronous transfer agreements on BUS RESET
1825 *
1826 * FIXME: what about SAVE POINTERS, RESTORE POINTERS?
1827 *
1828 */
1829static void msgi_run(struct Scsi_Host *shpnt)
1830{
1831 for(;;) {
1832 int sstat1 = GETPORT(SSTAT1);
1833
1834 if(sstat1 & (PHASECHG|PHASEMIS|BUSFREE) || !(sstat1 & REQINIT))
1835 return;
1836
1837 if(TESTLO(SSTAT0,SPIORDY)) {
1838 DPRINTK(debug_msgi, DEBUG_LEAD "!SPIORDY\n", CMDINFO(CURRENT_SC));
1839 return;
1840 }
1841
1842 ADDMSGI(GETPORT(SCSIDAT));
1843
1844#if defined(AHA152X_DEBUG)
1845 if (HOSTDATA(shpnt)->debug & debug_msgi) {
1846 printk(INFO_LEAD "inbound message %02x ", CMDINFO(CURRENT_SC), MSGI(0));
Matthew Wilcox1abfd372005-12-15 16:22:01 -05001847 spi_print_msg(&MSGI(0));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001848 printk("\n");
1849 }
1850#endif
1851
1852 if(!CURRENT_SC) {
1853 if(LASTSTATE!=seldi) {
1854 printk(KERN_ERR "aha152x%d: message in w/o current command not after reselection\n", HOSTNO);
1855 }
1856
1857 /*
1858 * Handle reselection
1859 */
1860 if(!(MSGI(0) & IDENTIFY_BASE)) {
1861 printk(KERN_ERR "aha152x%d: target didn't identify after reselection\n", HOSTNO);
1862 continue;
1863 }
1864
1865 CURRENT_SC = remove_lun_SC(&DISCONNECTED_SC, RECONN_TARGET, MSGI(0) & 0x3f);
1866
1867 if (!CURRENT_SC) {
1868 show_queues(shpnt);
1869 printk(KERN_ERR "aha152x%d: no disconnected command for target %d/%d\n", HOSTNO, RECONN_TARGET, MSGI(0) & 0x3f);
1870 continue;
1871 }
1872
1873 DPRINTK(debug_msgi, DEBUG_LEAD "target reconnected\n", CMDINFO(CURRENT_SC));
1874
1875 CURRENT_SC->SCp.Message = MSGI(0);
1876 CURRENT_SC->SCp.phase &= ~disconnected;
1877
1878 MSGILEN=0;
1879
1880 /* next message if any */
1881 continue;
1882 }
1883
1884 CURRENT_SC->SCp.Message = MSGI(0);
1885
1886 switch (MSGI(0)) {
1887 case DISCONNECT:
1888 if (!RECONNECT)
1889 printk(WARN_LEAD "target was not allowed to disconnect\n", CMDINFO(CURRENT_SC));
1890
1891 CURRENT_SC->SCp.phase |= disconnected;
1892 break;
1893
1894 case COMMAND_COMPLETE:
1895 if(CURRENT_SC->SCp.phase & completed)
1896 DPRINTK(debug_msgi, DEBUG_LEAD "again COMMAND COMPLETE\n", CMDINFO(CURRENT_SC));
1897
1898 CURRENT_SC->SCp.phase |= completed;
1899 break;
1900
1901 case MESSAGE_REJECT:
1902 if (SYNCNEG==1) {
1903 printk(INFO_LEAD "Synchronous Data Transfer Request was rejected\n", CMDINFO(CURRENT_SC));
1904 SYNCNEG=2; /* negotiation completed */
1905 } else
1906 printk(INFO_LEAD "inbound message (MESSAGE REJECT)\n", CMDINFO(CURRENT_SC));
1907 break;
1908
1909 case SAVE_POINTERS:
1910 break;
1911
1912 case RESTORE_POINTERS:
1913 break;
1914
1915 case EXTENDED_MESSAGE:
1916 if(MSGILEN<2 || MSGILEN<MSGI(1)+2) {
1917 /* not yet completed */
1918 continue;
1919 }
1920
1921 switch (MSGI(2)) {
1922 case EXTENDED_SDTR:
1923 {
1924 long ticks;
1925
1926 if (MSGI(1) != 3) {
1927 printk(ERR_LEAD "SDTR message length!=3\n", CMDINFO(CURRENT_SC));
1928 break;
1929 }
1930
1931 if (!HOSTDATA(shpnt)->synchronous)
1932 break;
1933
1934 printk(INFO_LEAD, CMDINFO(CURRENT_SC));
Matthew Wilcox1abfd372005-12-15 16:22:01 -05001935 spi_print_msg(&MSGI(0));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001936 printk("\n");
1937
1938 ticks = (MSGI(3) * 4 + 49) / 50;
1939
1940 if (syncneg) {
1941 /* negotiation in progress */
1942 if (ticks > 9 || MSGI(4) < 1 || MSGI(4) > 8) {
1943 ADDMSGO(MESSAGE_REJECT);
1944 printk(INFO_LEAD "received Synchronous Data Transfer Request invalid - rejected\n", CMDINFO(CURRENT_SC));
1945 break;
1946 }
1947
1948 SYNCRATE |= ((ticks - 2) << 4) + MSGI(4);
1949 } else if (ticks <= 9 && MSGI(4) >= 1) {
1950 ADDMSGO(EXTENDED_MESSAGE);
1951 ADDMSGO(3);
1952 ADDMSGO(EXTENDED_SDTR);
1953 if (ticks < 4) {
1954 ticks = 4;
1955 ADDMSGO(50);
1956 } else
1957 ADDMSGO(MSGI(3));
1958
1959 if (MSGI(4) > 8)
1960 MSGI(4) = 8;
1961
1962 ADDMSGO(MSGI(4));
1963
1964 SYNCRATE |= ((ticks - 2) << 4) + MSGI(4);
1965 } else {
1966 /* requested SDTR is too slow, do it asynchronously */
1967 printk(INFO_LEAD "Synchronous Data Transfer Request too slow - Rejecting\n", CMDINFO(CURRENT_SC));
1968 ADDMSGO(MESSAGE_REJECT);
1969 }
1970
1971 SYNCNEG=2; /* negotiation completed */
1972 SETRATE(SYNCRATE);
1973 }
1974 break;
1975
1976 case BUS_DEVICE_RESET:
1977 {
1978 int i;
1979
1980 for(i=0; i<8; i++) {
1981 HOSTDATA(shpnt)->syncrate[i]=0;
1982 HOSTDATA(shpnt)->syncneg[i]=0;
1983 }
1984
1985 }
1986 break;
1987
1988 case EXTENDED_MODIFY_DATA_POINTER:
1989 case EXTENDED_EXTENDED_IDENTIFY:
1990 case EXTENDED_WDTR:
1991 default:
1992 ADDMSGO(MESSAGE_REJECT);
1993 break;
1994 }
1995 break;
1996 }
1997
1998 MSGILEN=0;
1999 }
2000}
2001
2002static void msgi_end(struct Scsi_Host *shpnt)
2003{
2004 if(MSGILEN>0)
2005 printk(WARN_LEAD "target left before message completed (%d)\n", CMDINFO(CURRENT_SC), MSGILEN);
2006
2007 if (MSGOLEN > 0 && !(GETPORT(SSTAT1) & BUSFREE)) {
2008 DPRINTK(debug_msgi, DEBUG_LEAD "msgo pending\n", CMDINFO(CURRENT_SC));
2009 SETPORT(SCSISIG, P_MSGI | SIG_ATNO);
2010 }
2011}
2012
2013/*
2014 * message out phase
2015 *
2016 */
2017static void msgo_init(struct Scsi_Host *shpnt)
2018{
2019 if(MSGOLEN==0) {
2020 if((CURRENT_SC->SCp.phase & syncneg) && SYNCNEG==2 && SYNCRATE==0) {
2021 ADDMSGO(IDENTIFY(RECONNECT, CURRENT_SC->device->lun));
2022 } else {
2023 printk(INFO_LEAD "unexpected MESSAGE OUT phase; rejecting\n", CMDINFO(CURRENT_SC));
2024 ADDMSGO(MESSAGE_REJECT);
2025 }
2026 }
2027
2028#if defined(AHA152X_DEBUG)
2029 if(HOSTDATA(shpnt)->debug & debug_msgo) {
2030 int i;
2031
2032 printk(DEBUG_LEAD "messages( ", CMDINFO(CURRENT_SC));
Matthew Wilcox1abfd372005-12-15 16:22:01 -05002033 for (i=0; i<MSGOLEN; i+=spi_print_msg(&MSGO(i)), printk(" "))
Linus Torvalds1da177e2005-04-16 15:20:36 -07002034 ;
2035 printk(")\n");
2036 }
2037#endif
2038}
2039
2040/*
2041 * message out phase
2042 *
2043 */
2044static void msgo_run(struct Scsi_Host *shpnt)
2045{
2046 if(MSGO_I==MSGOLEN)
2047 DPRINTK(debug_msgo, DEBUG_LEAD "messages all sent (%d/%d)\n", CMDINFO(CURRENT_SC), MSGO_I, MSGOLEN);
2048
2049 while(MSGO_I<MSGOLEN) {
2050 DPRINTK(debug_msgo, DEBUG_LEAD "message byte %02x (%d/%d)\n", CMDINFO(CURRENT_SC), MSGO(MSGO_I), MSGO_I, MSGOLEN);
2051
2052 if(TESTLO(SSTAT0, SPIORDY)) {
2053 DPRINTK(debug_msgo, DEBUG_LEAD "!SPIORDY\n", CMDINFO(CURRENT_SC));
2054 return;
2055 }
2056
2057 if (MSGO_I==MSGOLEN-1) {
2058 /* Leave MESSAGE OUT after transfer */
2059 SETPORT(SSTAT1, CLRATNO);
2060 }
2061
2062
2063 if (MSGO(MSGO_I) & IDENTIFY_BASE)
2064 CURRENT_SC->SCp.phase |= identified;
2065
2066 if (MSGO(MSGO_I)==ABORT)
2067 CURRENT_SC->SCp.phase |= aborted;
2068
2069 if (MSGO(MSGO_I)==BUS_DEVICE_RESET)
2070 CURRENT_SC->SCp.phase |= resetted;
2071
2072 SETPORT(SCSIDAT, MSGO(MSGO_I++));
2073 }
2074}
2075
2076static void msgo_end(struct Scsi_Host *shpnt)
2077{
2078 if(MSGO_I<MSGOLEN) {
2079 printk(ERR_LEAD "message sent incompletely (%d/%d)\n", CMDINFO(CURRENT_SC), MSGO_I, MSGOLEN);
2080 if(SYNCNEG==1) {
2081 printk(INFO_LEAD "Synchronous Data Transfer Request was rejected\n", CMDINFO(CURRENT_SC));
2082 SYNCNEG=2;
2083 }
2084 }
2085
2086 MSGO_I = 0;
2087 MSGOLEN = 0;
2088}
2089
2090/*
2091 * command phase
2092 *
2093 */
2094static void cmd_init(struct Scsi_Host *shpnt)
2095{
2096 if (CURRENT_SC->SCp.sent_command) {
2097 printk(ERR_LEAD "command already sent\n", CMDINFO(CURRENT_SC));
2098 done(shpnt, DID_ERROR << 16);
2099 return;
2100 }
2101
2102#if defined(AHA152X_DEBUG)
2103 if (HOSTDATA(shpnt)->debug & debug_cmd) {
2104 printk(DEBUG_LEAD "cmd_init: ", CMDINFO(CURRENT_SC));
db9dff32005-04-03 14:53:59 -05002105 __scsi_print_command(CURRENT_SC->cmnd);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002106 }
2107#endif
2108
2109 CMD_I=0;
2110}
2111
2112/*
2113 * command phase
2114 *
2115 */
2116static void cmd_run(struct Scsi_Host *shpnt)
2117{
2118 if(CMD_I==CURRENT_SC->cmd_len) {
2119 DPRINTK(debug_cmd, DEBUG_LEAD "command already completely sent (%d/%d)", CMDINFO(CURRENT_SC), CMD_I, CURRENT_SC->cmd_len);
2120 disp_ports(shpnt);
2121 }
2122
2123 while(CMD_I<CURRENT_SC->cmd_len) {
2124 DPRINTK(debug_cmd, DEBUG_LEAD "command byte %02x (%d/%d)\n", CMDINFO(CURRENT_SC), CURRENT_SC->cmnd[CMD_I], CMD_I, CURRENT_SC->cmd_len);
2125
2126 if(TESTLO(SSTAT0, SPIORDY)) {
2127 DPRINTK(debug_cmd, DEBUG_LEAD "!SPIORDY\n", CMDINFO(CURRENT_SC));
2128 return;
2129 }
2130
2131 SETPORT(SCSIDAT, CURRENT_SC->cmnd[CMD_I++]);
2132 }
2133}
2134
2135static void cmd_end(struct Scsi_Host *shpnt)
2136{
2137 if(CMD_I<CURRENT_SC->cmd_len)
2138 printk(ERR_LEAD "command sent incompletely (%d/%d)\n", CMDINFO(CURRENT_SC), CMD_I, CURRENT_SC->cmd_len);
2139 else
2140 CURRENT_SC->SCp.sent_command++;
2141}
2142
2143/*
2144 * status phase
2145 *
2146 */
2147static void status_run(struct Scsi_Host *shpnt)
2148{
2149 if(TESTLO(SSTAT0,SPIORDY)) {
2150 DPRINTK(debug_status, DEBUG_LEAD "!SPIORDY\n", CMDINFO(CURRENT_SC));
2151 return;
2152 }
2153
2154 CURRENT_SC->SCp.Status = GETPORT(SCSIDAT);
2155
2156#if defined(AHA152X_DEBUG)
2157 if (HOSTDATA(shpnt)->debug & debug_status) {
2158 printk(DEBUG_LEAD "inbound status %02x ", CMDINFO(CURRENT_SC), CURRENT_SC->SCp.Status);
db9dff32005-04-03 14:53:59 -05002159 scsi_print_status(CURRENT_SC->SCp.Status);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002160 printk("\n");
2161 }
2162#endif
2163}
2164
2165/*
2166 * data in phase
2167 *
2168 */
2169static void datai_init(struct Scsi_Host *shpnt)
2170{
2171 SETPORT(DMACNTRL0, RSTFIFO);
2172 SETPORT(DMACNTRL0, RSTFIFO|ENDMA);
2173
2174 SETPORT(SXFRCTL0, CH1|CLRSTCNT);
2175 SETPORT(SXFRCTL0, CH1|SCSIEN|DMAEN);
2176
2177 SETPORT(SIMODE0, 0);
2178 SETPORT(SIMODE1, ENSCSIPERR | ENSCSIRST | ENPHASEMIS | ENBUSFREE);
2179
2180 DATA_LEN=0;
2181 DPRINTK(debug_datai,
2182 DEBUG_LEAD "datai_init: request_bufflen=%d resid=%d\n",
2183 CMDINFO(CURRENT_SC), CURRENT_SC->request_bufflen, CURRENT_SC->resid);
2184}
2185
2186static void datai_run(struct Scsi_Host *shpnt)
2187{
2188 unsigned long the_time;
2189 int fifodata, data_count;
2190
2191 /*
2192 * loop while the phase persists or the fifos are not empty
2193 *
2194 */
2195 while(TESTLO(DMASTAT, INTSTAT) || TESTLO(DMASTAT, DFIFOEMP) || TESTLO(SSTAT2, SEMPTY)) {
2196 /* FIXME: maybe this should be done by setting up
2197 * STCNT to trigger ENSWRAP interrupt, instead of
2198 * polling for DFIFOFULL
2199 */
2200 the_time=jiffies + 100*HZ;
2201 while(TESTLO(DMASTAT, DFIFOFULL|INTSTAT) && time_before(jiffies,the_time))
2202 barrier();
2203
2204 if(TESTLO(DMASTAT, DFIFOFULL|INTSTAT)) {
2205 printk(ERR_LEAD "datai timeout", CMDINFO(CURRENT_SC));
2206 disp_ports(shpnt);
2207 break;
2208 }
2209
2210 if(TESTHI(DMASTAT, DFIFOFULL)) {
2211 fifodata = 128;
2212 } else {
2213 the_time=jiffies + 100*HZ;
2214 while(TESTLO(SSTAT2, SEMPTY) && time_before(jiffies,the_time))
2215 barrier();
2216
2217 if(TESTLO(SSTAT2, SEMPTY)) {
2218 printk(ERR_LEAD "datai sempty timeout", CMDINFO(CURRENT_SC));
2219 disp_ports(shpnt);
2220 break;
2221 }
2222
2223 fifodata = GETPORT(FIFOSTAT);
2224 }
2225
2226 if(CURRENT_SC->SCp.this_residual>0) {
2227 while(fifodata>0 && CURRENT_SC->SCp.this_residual>0) {
2228 data_count = fifodata>CURRENT_SC->SCp.this_residual ?
2229 CURRENT_SC->SCp.this_residual :
2230 fifodata;
2231 fifodata -= data_count;
2232
2233 if(data_count & 1) {
2234 DPRINTK(debug_datai, DEBUG_LEAD "8bit\n", CMDINFO(CURRENT_SC));
2235 SETPORT(DMACNTRL0, ENDMA|_8BIT);
2236 *CURRENT_SC->SCp.ptr++ = GETPORT(DATAPORT);
2237 CURRENT_SC->SCp.this_residual--;
2238 DATA_LEN++;
2239 SETPORT(DMACNTRL0, ENDMA);
2240 }
2241
2242 if(data_count > 1) {
2243 DPRINTK(debug_datai, DEBUG_LEAD "16bit(%d)\n", CMDINFO(CURRENT_SC), data_count);
2244 data_count >>= 1;
2245 insw(DATAPORT, CURRENT_SC->SCp.ptr, data_count);
2246 CURRENT_SC->SCp.ptr += 2 * data_count;
2247 CURRENT_SC->SCp.this_residual -= 2 * data_count;
2248 DATA_LEN += 2 * data_count;
2249 }
2250
2251 if(CURRENT_SC->SCp.this_residual==0 && CURRENT_SC->SCp.buffers_residual>0) {
2252 /* advance to next buffer */
2253 CURRENT_SC->SCp.buffers_residual--;
2254 CURRENT_SC->SCp.buffer++;
2255 CURRENT_SC->SCp.ptr = SG_ADDRESS(CURRENT_SC->SCp.buffer);
2256 CURRENT_SC->SCp.this_residual = CURRENT_SC->SCp.buffer->length;
2257 }
2258 }
2259 } else if(fifodata>0) {
2260 printk(ERR_LEAD "no buffers left for %d(%d) bytes (data overrun!?)\n", CMDINFO(CURRENT_SC), fifodata, GETPORT(FIFOSTAT));
2261 SETPORT(DMACNTRL0, ENDMA|_8BIT);
2262 while(fifodata>0) {
2263 int data;
2264 data=GETPORT(DATAPORT);
2265 DPRINTK(debug_datai, DEBUG_LEAD "data=%02x\n", CMDINFO(CURRENT_SC), data);
2266 fifodata--;
2267 DATA_LEN++;
2268 }
2269 SETPORT(DMACNTRL0, ENDMA|_8BIT);
2270 }
2271 }
2272
2273 if(TESTLO(DMASTAT, INTSTAT) ||
2274 TESTLO(DMASTAT, DFIFOEMP) ||
2275 TESTLO(SSTAT2, SEMPTY) ||
2276 GETPORT(FIFOSTAT)>0) {
2277 /*
2278 * something went wrong, if there's something left in the fifos
2279 * or the phase didn't change
2280 */
2281 printk(ERR_LEAD "fifos should be empty and phase should have changed\n", CMDINFO(CURRENT_SC));
2282 disp_ports(shpnt);
2283 }
2284
2285 if(DATA_LEN!=GETSTCNT()) {
2286 printk(ERR_LEAD
2287 "manual transfer count differs from automatic (count=%d;stcnt=%d;diff=%d;fifostat=%d)",
2288 CMDINFO(CURRENT_SC), DATA_LEN, GETSTCNT(), GETSTCNT()-DATA_LEN, GETPORT(FIFOSTAT));
2289 disp_ports(shpnt);
2290 mdelay(10000);
2291 }
2292}
2293
2294static void datai_end(struct Scsi_Host *shpnt)
2295{
2296 CURRENT_SC->resid -= GETSTCNT();
2297
2298 DPRINTK(debug_datai,
2299 DEBUG_LEAD "datai_end: request_bufflen=%d resid=%d stcnt=%d\n",
2300 CMDINFO(CURRENT_SC), CURRENT_SC->request_bufflen, CURRENT_SC->resid, GETSTCNT());
2301
2302 SETPORT(SXFRCTL0, CH1|CLRSTCNT);
2303 SETPORT(DMACNTRL0, 0);
2304}
2305
2306/*
2307 * data out phase
2308 *
2309 */
2310static void datao_init(struct Scsi_Host *shpnt)
2311{
2312 SETPORT(DMACNTRL0, WRITE_READ | RSTFIFO);
2313 SETPORT(DMACNTRL0, WRITE_READ | ENDMA);
2314
2315 SETPORT(SXFRCTL0, CH1|CLRSTCNT);
2316 SETPORT(SXFRCTL0, CH1|SCSIEN|DMAEN);
2317
2318 SETPORT(SIMODE0, 0);
2319 SETPORT(SIMODE1, ENSCSIPERR | ENSCSIRST | ENPHASEMIS | ENBUSFREE );
2320
2321 DATA_LEN = CURRENT_SC->resid;
2322
2323 DPRINTK(debug_datao,
2324 DEBUG_LEAD "datao_init: request_bufflen=%d; resid=%d\n",
2325 CMDINFO(CURRENT_SC), CURRENT_SC->request_bufflen, CURRENT_SC->resid);
2326}
2327
2328static void datao_run(struct Scsi_Host *shpnt)
2329{
2330 unsigned long the_time;
2331 int data_count;
2332
2333 /* until phase changes or all data sent */
2334 while(TESTLO(DMASTAT, INTSTAT) && CURRENT_SC->SCp.this_residual>0) {
2335 data_count = 128;
2336 if(data_count > CURRENT_SC->SCp.this_residual)
2337 data_count=CURRENT_SC->SCp.this_residual;
2338
2339 if(TESTLO(DMASTAT, DFIFOEMP)) {
2340 printk(ERR_LEAD "datao fifo not empty (%d)", CMDINFO(CURRENT_SC), GETPORT(FIFOSTAT));
2341 disp_ports(shpnt);
2342 break;
2343 }
2344
2345 if(data_count & 1) {
2346 SETPORT(DMACNTRL0,WRITE_READ|ENDMA|_8BIT);
2347 SETPORT(DATAPORT, *CURRENT_SC->SCp.ptr++);
2348 CURRENT_SC->SCp.this_residual--;
2349 CURRENT_SC->resid--;
2350 SETPORT(DMACNTRL0,WRITE_READ|ENDMA);
2351 }
2352
2353 if(data_count > 1) {
2354 data_count >>= 1;
2355 outsw(DATAPORT, CURRENT_SC->SCp.ptr, data_count);
2356 CURRENT_SC->SCp.ptr += 2 * data_count;
2357 CURRENT_SC->SCp.this_residual -= 2 * data_count;
2358 CURRENT_SC->resid -= 2 * data_count;
2359 }
2360
2361 if(CURRENT_SC->SCp.this_residual==0 && CURRENT_SC->SCp.buffers_residual>0) {
2362 /* advance to next buffer */
2363 CURRENT_SC->SCp.buffers_residual--;
2364 CURRENT_SC->SCp.buffer++;
2365 CURRENT_SC->SCp.ptr = SG_ADDRESS(CURRENT_SC->SCp.buffer);
2366 CURRENT_SC->SCp.this_residual = CURRENT_SC->SCp.buffer->length;
2367 }
2368
2369 the_time=jiffies + 100*HZ;
2370 while(TESTLO(DMASTAT, DFIFOEMP|INTSTAT) && time_before(jiffies,the_time))
2371 barrier();
2372
2373 if(TESTLO(DMASTAT, DFIFOEMP|INTSTAT)) {
2374 printk(ERR_LEAD "dataout timeout", CMDINFO(CURRENT_SC));
2375 disp_ports(shpnt);
2376 break;
2377 }
2378 }
2379}
2380
2381static void datao_end(struct Scsi_Host *shpnt)
2382{
2383 if(TESTLO(DMASTAT, DFIFOEMP)) {
2384 int data_count = (DATA_LEN - CURRENT_SC->resid) - GETSTCNT();
2385
2386 DPRINTK(debug_datao, DEBUG_LEAD "datao: %d bytes to resend (%d written, %d transferred)\n",
2387 CMDINFO(CURRENT_SC),
2388 data_count,
2389 DATA_LEN-CURRENT_SC->resid,
2390 GETSTCNT());
2391
2392 CURRENT_SC->resid += data_count;
2393
2394 if(CURRENT_SC->use_sg) {
2395 data_count -= CURRENT_SC->SCp.ptr - SG_ADDRESS(CURRENT_SC->SCp.buffer);
2396 while(data_count>0) {
2397 CURRENT_SC->SCp.buffer--;
2398 CURRENT_SC->SCp.buffers_residual++;
2399 data_count -= CURRENT_SC->SCp.buffer->length;
2400 }
2401 CURRENT_SC->SCp.ptr = SG_ADDRESS(CURRENT_SC->SCp.buffer) - data_count;
2402 CURRENT_SC->SCp.this_residual = CURRENT_SC->SCp.buffer->length + data_count;
2403 } else {
2404 CURRENT_SC->SCp.ptr -= data_count;
2405 CURRENT_SC->SCp.this_residual += data_count;
2406 }
2407 }
2408
2409 DPRINTK(debug_datao, DEBUG_LEAD "datao_end: request_bufflen=%d; resid=%d; stcnt=%d\n",
2410 CMDINFO(CURRENT_SC),
2411 CURRENT_SC->request_bufflen,
2412 CURRENT_SC->resid,
2413 GETSTCNT());
2414
2415 SETPORT(SXFRCTL0, CH1|CLRCH1|CLRSTCNT);
2416 SETPORT(SXFRCTL0, CH1);
2417
2418 SETPORT(DMACNTRL0, 0);
2419}
2420
2421/*
2422 * figure out what state we're in
2423 *
2424 */
2425static int update_state(struct Scsi_Host *shpnt)
2426{
2427 int dataphase=0;
2428 unsigned int stat0 = GETPORT(SSTAT0);
2429 unsigned int stat1 = GETPORT(SSTAT1);
2430
2431 PREVSTATE = STATE;
2432 STATE=unknown;
2433
2434 if(stat1 & SCSIRSTI) {
2435 STATE=rsti;
2436 SETPORT(SCSISEQ,0);
2437 SETPORT(SSTAT1,SCSIRSTI);
2438 } else if(stat0 & SELDI && PREVSTATE==busfree) {
2439 STATE=seldi;
2440 } else if(stat0 & SELDO && CURRENT_SC && (CURRENT_SC->SCp.phase & selecting)) {
2441 STATE=seldo;
2442 } else if(stat1 & SELTO) {
2443 STATE=selto;
2444 } else if(stat1 & BUSFREE) {
2445 STATE=busfree;
2446 SETPORT(SSTAT1,BUSFREE);
2447 } else if(stat1 & SCSIPERR) {
2448 STATE=parerr;
2449 SETPORT(SSTAT1,SCSIPERR);
2450 } else if(stat1 & REQINIT) {
2451 switch(GETPORT(SCSISIG) & P_MASK) {
2452 case P_MSGI: STATE=msgi; break;
2453 case P_MSGO: STATE=msgo; break;
2454 case P_DATAO: STATE=datao; break;
2455 case P_DATAI: STATE=datai; break;
2456 case P_STATUS: STATE=status; break;
2457 case P_CMD: STATE=cmd; break;
2458 }
2459 dataphase=1;
2460 }
2461
2462 if((stat0 & SELDI) && STATE!=seldi && !dataphase) {
2463 printk(INFO_LEAD "reselection missed?", CMDINFO(CURRENT_SC));
2464 disp_ports(shpnt);
2465 }
2466
2467 if(STATE!=PREVSTATE) {
2468 LASTSTATE=PREVSTATE;
2469 }
2470
2471 return dataphase;
2472}
2473
2474/*
2475 * handle parity error
2476 *
2477 * FIXME: in which phase?
2478 *
2479 */
2480static void parerr_run(struct Scsi_Host *shpnt)
2481{
2482 printk(ERR_LEAD "parity error\n", CMDINFO(CURRENT_SC));
2483 done(shpnt, DID_PARITY << 16);
2484}
2485
2486/*
2487 * handle reset in
2488 *
2489 */
2490static void rsti_run(struct Scsi_Host *shpnt)
2491{
2492 Scsi_Cmnd *ptr;
2493
2494 printk(KERN_NOTICE "aha152x%d: scsi reset in\n", HOSTNO);
2495
2496 ptr=DISCONNECTED_SC;
2497 while(ptr) {
2498 Scsi_Cmnd *next = SCNEXT(ptr);
2499
2500 if (!ptr->device->soft_reset) {
2501 remove_SC(&DISCONNECTED_SC, ptr);
2502
2503 kfree(ptr->host_scribble);
2504 ptr->host_scribble=NULL;
2505
2506 ptr->result = DID_RESET << 16;
2507 ptr->scsi_done(ptr);
2508 }
2509
2510 ptr = next;
2511 }
2512
2513 if(CURRENT_SC && !CURRENT_SC->device->soft_reset)
2514 done(shpnt, DID_RESET << 16 );
2515}
2516
2517
2518/*
2519 * bottom-half handler
2520 *
2521 */
2522static void is_complete(struct Scsi_Host *shpnt)
2523{
2524 int dataphase;
2525 unsigned long flags;
2526 int pending;
2527
Jürgen E. Fischere2482fa2006-02-19 00:31:51 +01002528 if(!shpnt)
2529 return;
2530
Linus Torvalds1da177e2005-04-16 15:20:36 -07002531 DO_LOCK(flags);
Jürgen E. Fischere2482fa2006-02-19 00:31:51 +01002532
2533 if( HOSTDATA(shpnt)->service==0 ) {
2534 DO_UNLOCK(flags);
2535 return;
2536 }
2537
2538 HOSTDATA(shpnt)->service = 0;
2539
Linus Torvalds1da177e2005-04-16 15:20:36 -07002540 if(HOSTDATA(shpnt)->in_intr) {
2541 DO_UNLOCK(flags);
2542 /* aha152x_error never returns.. */
2543 aha152x_error(shpnt, "bottom-half already running!?");
2544 }
2545 HOSTDATA(shpnt)->in_intr++;
2546
2547 /*
2548 * loop while there are interrupt conditions pending
2549 *
2550 */
2551 do {
2552 unsigned long start = jiffies;
2553 DO_UNLOCK(flags);
2554
2555 dataphase=update_state(shpnt);
2556
2557 DPRINTK(debug_phases, LEAD "start %s %s(%s)\n", CMDINFO(CURRENT_SC), states[STATE].name, states[PREVSTATE].name, states[LASTSTATE].name);
2558
2559 /*
2560 * end previous state
2561 *
2562 */
2563 if(PREVSTATE!=STATE && states[PREVSTATE].end)
2564 states[PREVSTATE].end(shpnt);
2565
2566 /*
2567 * disable SPIO mode if previous phase used it
2568 * and this one doesn't
2569 *
2570 */
2571 if(states[PREVSTATE].spio && !states[STATE].spio) {
2572 SETPORT(SXFRCTL0, CH1);
2573 SETPORT(DMACNTRL0, 0);
2574 if(CURRENT_SC)
2575 CURRENT_SC->SCp.phase &= ~spiordy;
2576 }
2577
2578 /*
2579 * accept current dataphase phase
2580 *
2581 */
2582 if(dataphase) {
2583 SETPORT(SSTAT0, REQINIT);
2584 SETPORT(SCSISIG, GETPORT(SCSISIG) & P_MASK);
2585 SETPORT(SSTAT1, PHASECHG);
2586 }
2587
2588 /*
2589 * enable SPIO mode if previous didn't use it
2590 * and this one does
2591 *
2592 */
2593 if(!states[PREVSTATE].spio && states[STATE].spio) {
2594 SETPORT(DMACNTRL0, 0);
2595 SETPORT(SXFRCTL0, CH1|SPIOEN);
2596 if(CURRENT_SC)
2597 CURRENT_SC->SCp.phase |= spiordy;
2598 }
2599
2600 /*
2601 * initialize for new state
2602 *
2603 */
2604 if(PREVSTATE!=STATE && states[STATE].init)
2605 states[STATE].init(shpnt);
2606
2607 /*
2608 * handle current state
2609 *
2610 */
2611 if(states[STATE].run)
2612 states[STATE].run(shpnt);
2613 else
2614 printk(ERR_LEAD "unexpected state (%x)\n", CMDINFO(CURRENT_SC), STATE);
2615
2616 /*
2617 * setup controller to interrupt on
2618 * the next expected condition and
2619 * loop if it's already there
2620 *
2621 */
2622 DO_LOCK(flags);
2623 pending=setup_expected_interrupts(shpnt);
2624#if defined(AHA152X_STAT)
2625 HOSTDATA(shpnt)->count[STATE]++;
2626 if(PREVSTATE!=STATE)
2627 HOSTDATA(shpnt)->count_trans[STATE]++;
2628 HOSTDATA(shpnt)->time[STATE] += jiffies-start;
2629#endif
2630
2631 DPRINTK(debug_phases, LEAD "end %s %s(%s)\n", CMDINFO(CURRENT_SC), states[STATE].name, states[PREVSTATE].name, states[LASTSTATE].name);
2632 } while(pending);
2633
2634 /*
2635 * enable interrupts and leave bottom-half
2636 *
2637 */
2638 HOSTDATA(shpnt)->in_intr--;
2639 SETBITS(DMACNTRL0, INTEN);
2640 DO_UNLOCK(flags);
2641}
2642
2643
2644/*
2645 * Dump the current driver status and panic
2646 */
2647static void aha152x_error(struct Scsi_Host *shpnt, char *msg)
2648{
2649 printk(KERN_EMERG "\naha152x%d: %s\n", HOSTNO, msg);
2650 show_queues(shpnt);
2651 panic("aha152x panic\n");
2652}
2653
2654/*
2655 * Display registers of AIC-6260
2656 */
2657static void disp_ports(struct Scsi_Host *shpnt)
2658{
2659#if defined(AHA152X_DEBUG)
2660 int s;
2661
2662 printk("\n%s: %s(%s) ",
2663 CURRENT_SC ? "busy" : "waiting",
2664 states[STATE].name,
2665 states[PREVSTATE].name);
2666
2667 s = GETPORT(SCSISEQ);
2668 printk("SCSISEQ( ");
2669 if (s & TEMODEO)
2670 printk("TARGET MODE ");
2671 if (s & ENSELO)
2672 printk("SELO ");
2673 if (s & ENSELI)
2674 printk("SELI ");
2675 if (s & ENRESELI)
2676 printk("RESELI ");
2677 if (s & ENAUTOATNO)
2678 printk("AUTOATNO ");
2679 if (s & ENAUTOATNI)
2680 printk("AUTOATNI ");
2681 if (s & ENAUTOATNP)
2682 printk("AUTOATNP ");
2683 if (s & SCSIRSTO)
2684 printk("SCSIRSTO ");
2685 printk(");");
2686
2687 printk(" SCSISIG(");
2688 s = GETPORT(SCSISIG);
2689 switch (s & P_MASK) {
2690 case P_DATAO:
2691 printk("DATA OUT");
2692 break;
2693 case P_DATAI:
2694 printk("DATA IN");
2695 break;
2696 case P_CMD:
2697 printk("COMMAND");
2698 break;
2699 case P_STATUS:
2700 printk("STATUS");
2701 break;
2702 case P_MSGO:
2703 printk("MESSAGE OUT");
2704 break;
2705 case P_MSGI:
2706 printk("MESSAGE IN");
2707 break;
2708 default:
2709 printk("*invalid*");
2710 break;
2711 }
2712
2713 printk("); ");
2714
2715 printk("INTSTAT (%s); ", TESTHI(DMASTAT, INTSTAT) ? "hi" : "lo");
2716
2717 printk("SSTAT( ");
2718 s = GETPORT(SSTAT0);
2719 if (s & TARGET)
2720 printk("TARGET ");
2721 if (s & SELDO)
2722 printk("SELDO ");
2723 if (s & SELDI)
2724 printk("SELDI ");
2725 if (s & SELINGO)
2726 printk("SELINGO ");
2727 if (s & SWRAP)
2728 printk("SWRAP ");
2729 if (s & SDONE)
2730 printk("SDONE ");
2731 if (s & SPIORDY)
2732 printk("SPIORDY ");
2733 if (s & DMADONE)
2734 printk("DMADONE ");
2735
2736 s = GETPORT(SSTAT1);
2737 if (s & SELTO)
2738 printk("SELTO ");
2739 if (s & ATNTARG)
2740 printk("ATNTARG ");
2741 if (s & SCSIRSTI)
2742 printk("SCSIRSTI ");
2743 if (s & PHASEMIS)
2744 printk("PHASEMIS ");
2745 if (s & BUSFREE)
2746 printk("BUSFREE ");
2747 if (s & SCSIPERR)
2748 printk("SCSIPERR ");
2749 if (s & PHASECHG)
2750 printk("PHASECHG ");
2751 if (s & REQINIT)
2752 printk("REQINIT ");
2753 printk("); ");
2754
2755
2756 printk("SSTAT( ");
2757
2758 s = GETPORT(SSTAT0) & GETPORT(SIMODE0);
2759
2760 if (s & TARGET)
2761 printk("TARGET ");
2762 if (s & SELDO)
2763 printk("SELDO ");
2764 if (s & SELDI)
2765 printk("SELDI ");
2766 if (s & SELINGO)
2767 printk("SELINGO ");
2768 if (s & SWRAP)
2769 printk("SWRAP ");
2770 if (s & SDONE)
2771 printk("SDONE ");
2772 if (s & SPIORDY)
2773 printk("SPIORDY ");
2774 if (s & DMADONE)
2775 printk("DMADONE ");
2776
2777 s = GETPORT(SSTAT1) & GETPORT(SIMODE1);
2778
2779 if (s & SELTO)
2780 printk("SELTO ");
2781 if (s & ATNTARG)
2782 printk("ATNTARG ");
2783 if (s & SCSIRSTI)
2784 printk("SCSIRSTI ");
2785 if (s & PHASEMIS)
2786 printk("PHASEMIS ");
2787 if (s & BUSFREE)
2788 printk("BUSFREE ");
2789 if (s & SCSIPERR)
2790 printk("SCSIPERR ");
2791 if (s & PHASECHG)
2792 printk("PHASECHG ");
2793 if (s & REQINIT)
2794 printk("REQINIT ");
2795 printk("); ");
2796
2797 printk("SXFRCTL0( ");
2798
2799 s = GETPORT(SXFRCTL0);
2800 if (s & SCSIEN)
2801 printk("SCSIEN ");
2802 if (s & DMAEN)
2803 printk("DMAEN ");
2804 if (s & CH1)
2805 printk("CH1 ");
2806 if (s & CLRSTCNT)
2807 printk("CLRSTCNT ");
2808 if (s & SPIOEN)
2809 printk("SPIOEN ");
2810 if (s & CLRCH1)
2811 printk("CLRCH1 ");
2812 printk("); ");
2813
2814 printk("SIGNAL( ");
2815
2816 s = GETPORT(SCSISIG);
2817 if (s & SIG_ATNI)
2818 printk("ATNI ");
2819 if (s & SIG_SELI)
2820 printk("SELI ");
2821 if (s & SIG_BSYI)
2822 printk("BSYI ");
2823 if (s & SIG_REQI)
2824 printk("REQI ");
2825 if (s & SIG_ACKI)
2826 printk("ACKI ");
2827 printk("); ");
2828
2829 printk("SELID (%02x), ", GETPORT(SELID));
2830
2831 printk("STCNT (%d), ", GETSTCNT());
2832
2833 printk("SSTAT2( ");
2834
2835 s = GETPORT(SSTAT2);
2836 if (s & SOFFSET)
2837 printk("SOFFSET ");
2838 if (s & SEMPTY)
2839 printk("SEMPTY ");
2840 if (s & SFULL)
2841 printk("SFULL ");
2842 printk("); SFCNT (%d); ", s & (SFULL | SFCNT));
2843
2844 s = GETPORT(SSTAT3);
2845 printk("SCSICNT (%d), OFFCNT(%d), ", (s & 0xf0) >> 4, s & 0x0f);
2846
2847 printk("SSTAT4( ");
2848 s = GETPORT(SSTAT4);
2849 if (s & SYNCERR)
2850 printk("SYNCERR ");
2851 if (s & FWERR)
2852 printk("FWERR ");
2853 if (s & FRERR)
2854 printk("FRERR ");
2855 printk("); ");
2856
2857 printk("DMACNTRL0( ");
2858 s = GETPORT(DMACNTRL0);
2859 printk("%s ", s & _8BIT ? "8BIT" : "16BIT");
2860 printk("%s ", s & DMA ? "DMA" : "PIO");
2861 printk("%s ", s & WRITE_READ ? "WRITE" : "READ");
2862 if (s & ENDMA)
2863 printk("ENDMA ");
2864 if (s & INTEN)
2865 printk("INTEN ");
2866 if (s & RSTFIFO)
2867 printk("RSTFIFO ");
2868 if (s & SWINT)
2869 printk("SWINT ");
2870 printk("); ");
2871
2872 printk("DMASTAT( ");
2873 s = GETPORT(DMASTAT);
2874 if (s & ATDONE)
2875 printk("ATDONE ");
2876 if (s & WORDRDY)
2877 printk("WORDRDY ");
2878 if (s & DFIFOFULL)
2879 printk("DFIFOFULL ");
2880 if (s & DFIFOEMP)
2881 printk("DFIFOEMP ");
2882 printk(")\n");
2883#endif
2884}
2885
2886/*
2887 * display enabled interrupts
2888 */
2889static void disp_enintr(struct Scsi_Host *shpnt)
2890{
2891 int s;
2892
2893 printk(KERN_DEBUG "enabled interrupts ( ");
2894
2895 s = GETPORT(SIMODE0);
2896 if (s & ENSELDO)
2897 printk("ENSELDO ");
2898 if (s & ENSELDI)
2899 printk("ENSELDI ");
2900 if (s & ENSELINGO)
2901 printk("ENSELINGO ");
2902 if (s & ENSWRAP)
2903 printk("ENSWRAP ");
2904 if (s & ENSDONE)
2905 printk("ENSDONE ");
2906 if (s & ENSPIORDY)
2907 printk("ENSPIORDY ");
2908 if (s & ENDMADONE)
2909 printk("ENDMADONE ");
2910
2911 s = GETPORT(SIMODE1);
2912 if (s & ENSELTIMO)
2913 printk("ENSELTIMO ");
2914 if (s & ENATNTARG)
2915 printk("ENATNTARG ");
2916 if (s & ENPHASEMIS)
2917 printk("ENPHASEMIS ");
2918 if (s & ENBUSFREE)
2919 printk("ENBUSFREE ");
2920 if (s & ENSCSIPERR)
2921 printk("ENSCSIPERR ");
2922 if (s & ENPHASECHG)
2923 printk("ENPHASECHG ");
2924 if (s & ENREQINIT)
2925 printk("ENREQINIT ");
2926 printk(")\n");
2927}
2928
2929/*
2930 * Show the command data of a command
2931 */
2932static void show_command(Scsi_Cmnd *ptr)
2933{
Jeff Garzik017560f2005-10-24 18:04:36 -04002934 scmd_printk(KERN_DEBUG, ptr, "%p: cmnd=(", ptr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002935
db9dff32005-04-03 14:53:59 -05002936 __scsi_print_command(ptr->cmnd);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002937
2938 printk(KERN_DEBUG "); request_bufflen=%d; resid=%d; phase |",
2939 ptr->request_bufflen, ptr->resid);
2940
2941 if (ptr->SCp.phase & not_issued)
2942 printk("not issued|");
2943 if (ptr->SCp.phase & selecting)
2944 printk("selecting|");
2945 if (ptr->SCp.phase & identified)
2946 printk("identified|");
2947 if (ptr->SCp.phase & disconnected)
2948 printk("disconnected|");
2949 if (ptr->SCp.phase & completed)
2950 printk("completed|");
2951 if (ptr->SCp.phase & spiordy)
2952 printk("spiordy|");
2953 if (ptr->SCp.phase & syncneg)
2954 printk("syncneg|");
2955 if (ptr->SCp.phase & aborted)
2956 printk("aborted|");
2957 if (ptr->SCp.phase & resetted)
2958 printk("resetted|");
2959 if( SCDATA(ptr) ) {
2960 printk("; next=0x%p\n", SCNEXT(ptr));
2961 } else {
2962 printk("; next=(host scribble NULL)\n");
2963 }
2964}
2965
2966/*
2967 * Dump the queued data
2968 */
2969static void show_queues(struct Scsi_Host *shpnt)
2970{
2971 Scsi_Cmnd *ptr;
2972 unsigned long flags;
2973
2974 DO_LOCK(flags);
2975 printk(KERN_DEBUG "\nqueue status:\nissue_SC:\n");
2976 for (ptr = ISSUE_SC; ptr; ptr = SCNEXT(ptr))
2977 show_command(ptr);
2978 DO_UNLOCK(flags);
2979
2980 printk(KERN_DEBUG "current_SC:\n");
2981 if (CURRENT_SC)
2982 show_command(CURRENT_SC);
2983 else
2984 printk(KERN_DEBUG "none\n");
2985
2986 printk(KERN_DEBUG "disconnected_SC:\n");
2987 for (ptr = DISCONNECTED_SC; ptr; ptr = SCDATA(ptr) ? SCNEXT(ptr) : NULL)
2988 show_command(ptr);
2989
2990 disp_ports(shpnt);
2991 disp_enintr(shpnt);
2992}
2993
2994#undef SPRINTF
2995#define SPRINTF(args...) pos += sprintf(pos, ## args)
2996
2997static int get_command(char *pos, Scsi_Cmnd * ptr)
2998{
2999 char *start = pos;
3000 int i;
3001
3002 SPRINTF("0x%08x: target=%d; lun=%d; cmnd=( ",
3003 (unsigned int) ptr, ptr->device->id, ptr->device->lun);
3004
3005 for (i = 0; i < COMMAND_SIZE(ptr->cmnd[0]); i++)
3006 SPRINTF("0x%02x ", ptr->cmnd[i]);
3007
3008 SPRINTF("); resid=%d; residual=%d; buffers=%d; phase |",
3009 ptr->resid, ptr->SCp.this_residual, ptr->SCp.buffers_residual);
3010
3011 if (ptr->SCp.phase & not_issued)
3012 SPRINTF("not issued|");
3013 if (ptr->SCp.phase & selecting)
3014 SPRINTF("selecting|");
3015 if (ptr->SCp.phase & disconnected)
3016 SPRINTF("disconnected|");
3017 if (ptr->SCp.phase & aborted)
3018 SPRINTF("aborted|");
3019 if (ptr->SCp.phase & identified)
3020 SPRINTF("identified|");
3021 if (ptr->SCp.phase & completed)
3022 SPRINTF("completed|");
3023 if (ptr->SCp.phase & spiordy)
3024 SPRINTF("spiordy|");
3025 if (ptr->SCp.phase & syncneg)
3026 SPRINTF("syncneg|");
3027 SPRINTF("; next=0x%p\n", SCNEXT(ptr));
3028
3029 return (pos - start);
3030}
3031
3032static int get_ports(struct Scsi_Host *shpnt, char *pos)
3033{
3034 char *start = pos;
3035 int s;
3036
3037 SPRINTF("\n%s: %s(%s) ", CURRENT_SC ? "on bus" : "waiting", states[STATE].name, states[PREVSTATE].name);
3038
3039 s = GETPORT(SCSISEQ);
3040 SPRINTF("SCSISEQ( ");
3041 if (s & TEMODEO)
3042 SPRINTF("TARGET MODE ");
3043 if (s & ENSELO)
3044 SPRINTF("SELO ");
3045 if (s & ENSELI)
3046 SPRINTF("SELI ");
3047 if (s & ENRESELI)
3048 SPRINTF("RESELI ");
3049 if (s & ENAUTOATNO)
3050 SPRINTF("AUTOATNO ");
3051 if (s & ENAUTOATNI)
3052 SPRINTF("AUTOATNI ");
3053 if (s & ENAUTOATNP)
3054 SPRINTF("AUTOATNP ");
3055 if (s & SCSIRSTO)
3056 SPRINTF("SCSIRSTO ");
3057 SPRINTF(");");
3058
3059 SPRINTF(" SCSISIG(");
3060 s = GETPORT(SCSISIG);
3061 switch (s & P_MASK) {
3062 case P_DATAO:
3063 SPRINTF("DATA OUT");
3064 break;
3065 case P_DATAI:
3066 SPRINTF("DATA IN");
3067 break;
3068 case P_CMD:
3069 SPRINTF("COMMAND");
3070 break;
3071 case P_STATUS:
3072 SPRINTF("STATUS");
3073 break;
3074 case P_MSGO:
3075 SPRINTF("MESSAGE OUT");
3076 break;
3077 case P_MSGI:
3078 SPRINTF("MESSAGE IN");
3079 break;
3080 default:
3081 SPRINTF("*invalid*");
3082 break;
3083 }
3084
3085 SPRINTF("); ");
3086
3087 SPRINTF("INTSTAT (%s); ", TESTHI(DMASTAT, INTSTAT) ? "hi" : "lo");
3088
3089 SPRINTF("SSTAT( ");
3090 s = GETPORT(SSTAT0);
3091 if (s & TARGET)
3092 SPRINTF("TARGET ");
3093 if (s & SELDO)
3094 SPRINTF("SELDO ");
3095 if (s & SELDI)
3096 SPRINTF("SELDI ");
3097 if (s & SELINGO)
3098 SPRINTF("SELINGO ");
3099 if (s & SWRAP)
3100 SPRINTF("SWRAP ");
3101 if (s & SDONE)
3102 SPRINTF("SDONE ");
3103 if (s & SPIORDY)
3104 SPRINTF("SPIORDY ");
3105 if (s & DMADONE)
3106 SPRINTF("DMADONE ");
3107
3108 s = GETPORT(SSTAT1);
3109 if (s & SELTO)
3110 SPRINTF("SELTO ");
3111 if (s & ATNTARG)
3112 SPRINTF("ATNTARG ");
3113 if (s & SCSIRSTI)
3114 SPRINTF("SCSIRSTI ");
3115 if (s & PHASEMIS)
3116 SPRINTF("PHASEMIS ");
3117 if (s & BUSFREE)
3118 SPRINTF("BUSFREE ");
3119 if (s & SCSIPERR)
3120 SPRINTF("SCSIPERR ");
3121 if (s & PHASECHG)
3122 SPRINTF("PHASECHG ");
3123 if (s & REQINIT)
3124 SPRINTF("REQINIT ");
3125 SPRINTF("); ");
3126
3127
3128 SPRINTF("SSTAT( ");
3129
3130 s = GETPORT(SSTAT0) & GETPORT(SIMODE0);
3131
3132 if (s & TARGET)
3133 SPRINTF("TARGET ");
3134 if (s & SELDO)
3135 SPRINTF("SELDO ");
3136 if (s & SELDI)
3137 SPRINTF("SELDI ");
3138 if (s & SELINGO)
3139 SPRINTF("SELINGO ");
3140 if (s & SWRAP)
3141 SPRINTF("SWRAP ");
3142 if (s & SDONE)
3143 SPRINTF("SDONE ");
3144 if (s & SPIORDY)
3145 SPRINTF("SPIORDY ");
3146 if (s & DMADONE)
3147 SPRINTF("DMADONE ");
3148
3149 s = GETPORT(SSTAT1) & GETPORT(SIMODE1);
3150
3151 if (s & SELTO)
3152 SPRINTF("SELTO ");
3153 if (s & ATNTARG)
3154 SPRINTF("ATNTARG ");
3155 if (s & SCSIRSTI)
3156 SPRINTF("SCSIRSTI ");
3157 if (s & PHASEMIS)
3158 SPRINTF("PHASEMIS ");
3159 if (s & BUSFREE)
3160 SPRINTF("BUSFREE ");
3161 if (s & SCSIPERR)
3162 SPRINTF("SCSIPERR ");
3163 if (s & PHASECHG)
3164 SPRINTF("PHASECHG ");
3165 if (s & REQINIT)
3166 SPRINTF("REQINIT ");
3167 SPRINTF("); ");
3168
3169 SPRINTF("SXFRCTL0( ");
3170
3171 s = GETPORT(SXFRCTL0);
3172 if (s & SCSIEN)
3173 SPRINTF("SCSIEN ");
3174 if (s & DMAEN)
3175 SPRINTF("DMAEN ");
3176 if (s & CH1)
3177 SPRINTF("CH1 ");
3178 if (s & CLRSTCNT)
3179 SPRINTF("CLRSTCNT ");
3180 if (s & SPIOEN)
3181 SPRINTF("SPIOEN ");
3182 if (s & CLRCH1)
3183 SPRINTF("CLRCH1 ");
3184 SPRINTF("); ");
3185
3186 SPRINTF("SIGNAL( ");
3187
3188 s = GETPORT(SCSISIG);
3189 if (s & SIG_ATNI)
3190 SPRINTF("ATNI ");
3191 if (s & SIG_SELI)
3192 SPRINTF("SELI ");
3193 if (s & SIG_BSYI)
3194 SPRINTF("BSYI ");
3195 if (s & SIG_REQI)
3196 SPRINTF("REQI ");
3197 if (s & SIG_ACKI)
3198 SPRINTF("ACKI ");
3199 SPRINTF("); ");
3200
3201 SPRINTF("SELID(%02x), ", GETPORT(SELID));
3202
3203 SPRINTF("STCNT(%d), ", GETSTCNT());
3204
3205 SPRINTF("SSTAT2( ");
3206
3207 s = GETPORT(SSTAT2);
3208 if (s & SOFFSET)
3209 SPRINTF("SOFFSET ");
3210 if (s & SEMPTY)
3211 SPRINTF("SEMPTY ");
3212 if (s & SFULL)
3213 SPRINTF("SFULL ");
3214 SPRINTF("); SFCNT (%d); ", s & (SFULL | SFCNT));
3215
3216 s = GETPORT(SSTAT3);
3217 SPRINTF("SCSICNT (%d), OFFCNT(%d), ", (s & 0xf0) >> 4, s & 0x0f);
3218
3219 SPRINTF("SSTAT4( ");
3220 s = GETPORT(SSTAT4);
3221 if (s & SYNCERR)
3222 SPRINTF("SYNCERR ");
3223 if (s & FWERR)
3224 SPRINTF("FWERR ");
3225 if (s & FRERR)
3226 SPRINTF("FRERR ");
3227 SPRINTF("); ");
3228
3229 SPRINTF("DMACNTRL0( ");
3230 s = GETPORT(DMACNTRL0);
3231 SPRINTF("%s ", s & _8BIT ? "8BIT" : "16BIT");
3232 SPRINTF("%s ", s & DMA ? "DMA" : "PIO");
3233 SPRINTF("%s ", s & WRITE_READ ? "WRITE" : "READ");
3234 if (s & ENDMA)
3235 SPRINTF("ENDMA ");
3236 if (s & INTEN)
3237 SPRINTF("INTEN ");
3238 if (s & RSTFIFO)
3239 SPRINTF("RSTFIFO ");
3240 if (s & SWINT)
3241 SPRINTF("SWINT ");
3242 SPRINTF("); ");
3243
3244 SPRINTF("DMASTAT( ");
3245 s = GETPORT(DMASTAT);
3246 if (s & ATDONE)
3247 SPRINTF("ATDONE ");
3248 if (s & WORDRDY)
3249 SPRINTF("WORDRDY ");
3250 if (s & DFIFOFULL)
3251 SPRINTF("DFIFOFULL ");
3252 if (s & DFIFOEMP)
3253 SPRINTF("DFIFOEMP ");
3254 SPRINTF(")\n");
3255
3256 SPRINTF("enabled interrupts( ");
3257
3258 s = GETPORT(SIMODE0);
3259 if (s & ENSELDO)
3260 SPRINTF("ENSELDO ");
3261 if (s & ENSELDI)
3262 SPRINTF("ENSELDI ");
3263 if (s & ENSELINGO)
3264 SPRINTF("ENSELINGO ");
3265 if (s & ENSWRAP)
3266 SPRINTF("ENSWRAP ");
3267 if (s & ENSDONE)
3268 SPRINTF("ENSDONE ");
3269 if (s & ENSPIORDY)
3270 SPRINTF("ENSPIORDY ");
3271 if (s & ENDMADONE)
3272 SPRINTF("ENDMADONE ");
3273
3274 s = GETPORT(SIMODE1);
3275 if (s & ENSELTIMO)
3276 SPRINTF("ENSELTIMO ");
3277 if (s & ENATNTARG)
3278 SPRINTF("ENATNTARG ");
3279 if (s & ENPHASEMIS)
3280 SPRINTF("ENPHASEMIS ");
3281 if (s & ENBUSFREE)
3282 SPRINTF("ENBUSFREE ");
3283 if (s & ENSCSIPERR)
3284 SPRINTF("ENSCSIPERR ");
3285 if (s & ENPHASECHG)
3286 SPRINTF("ENPHASECHG ");
3287 if (s & ENREQINIT)
3288 SPRINTF("ENREQINIT ");
3289 SPRINTF(")\n");
3290
3291 return (pos - start);
3292}
3293
3294static int aha152x_set_info(char *buffer, int length, struct Scsi_Host *shpnt)
3295{
3296 if(!shpnt || !buffer || length<8 || strncmp("aha152x ", buffer, 8)!=0)
3297 return -EINVAL;
3298
3299#if defined(AHA152X_DEBUG)
3300 if(length>14 && strncmp("debug ", buffer+8, 6)==0) {
3301 int debug = HOSTDATA(shpnt)->debug;
3302
3303 HOSTDATA(shpnt)->debug = simple_strtoul(buffer+14, NULL, 0);
3304
3305 printk(KERN_INFO "aha152x%d: debugging options set to 0x%04x (were 0x%04x)\n", HOSTNO, HOSTDATA(shpnt)->debug, debug);
3306 } else
3307#endif
3308#if defined(AHA152X_STAT)
3309 if(length>13 && strncmp("reset", buffer+8, 5)==0) {
3310 int i;
3311
3312 HOSTDATA(shpnt)->total_commands=0;
3313 HOSTDATA(shpnt)->disconnections=0;
3314 HOSTDATA(shpnt)->busfree_without_any_action=0;
3315 HOSTDATA(shpnt)->busfree_without_old_command=0;
3316 HOSTDATA(shpnt)->busfree_without_new_command=0;
3317 HOSTDATA(shpnt)->busfree_without_done_command=0;
3318 HOSTDATA(shpnt)->busfree_with_check_condition=0;
3319 for (i = idle; i<maxstate; i++) {
3320 HOSTDATA(shpnt)->count[i]=0;
3321 HOSTDATA(shpnt)->count_trans[i]=0;
3322 HOSTDATA(shpnt)->time[i]=0;
3323 }
3324
3325 printk(KERN_INFO "aha152x%d: stats reseted.\n", HOSTNO);
3326
3327 } else
3328#endif
3329 {
3330 return -EINVAL;
3331 }
3332
3333
3334 return length;
3335}
3336
3337#undef SPRINTF
3338#define SPRINTF(args...) \
3339 do { if(pos < buffer + length) pos += sprintf(pos, ## args); } while(0)
3340
3341static int aha152x_proc_info(struct Scsi_Host *shpnt, char *buffer, char **start,
3342 off_t offset, int length, int inout)
3343{
3344 int i;
3345 char *pos = buffer;
3346 Scsi_Cmnd *ptr;
3347 unsigned long flags;
3348 int thislength;
3349
3350 DPRINTK(debug_procinfo,
3351 KERN_DEBUG "aha152x_proc_info: buffer=%p offset=%ld length=%d hostno=%d inout=%d\n",
3352 buffer, offset, length, shpnt->host_no, inout);
3353
3354
3355 if (inout)
3356 return aha152x_set_info(buffer, length, shpnt);
3357
3358 SPRINTF(AHA152X_REVID "\n");
3359
3360 SPRINTF("ioports 0x%04lx to 0x%04lx\n",
3361 shpnt->io_port, shpnt->io_port + shpnt->n_io_port - 1);
3362 SPRINTF("interrupt 0x%02x\n", shpnt->irq);
3363 SPRINTF("disconnection/reconnection %s\n",
3364 RECONNECT ? "enabled" : "disabled");
3365 SPRINTF("parity checking %s\n",
3366 PARITY ? "enabled" : "disabled");
3367 SPRINTF("synchronous transfers %s\n",
3368 SYNCHRONOUS ? "enabled" : "disabled");
3369 SPRINTF("%d commands currently queued\n", HOSTDATA(shpnt)->commands);
3370
3371 if(SYNCHRONOUS) {
3372 SPRINTF("synchronously operating targets (tick=50 ns):\n");
3373 for (i = 0; i < 8; i++)
3374 if (HOSTDATA(shpnt)->syncrate[i] & 0x7f)
3375 SPRINTF("target %d: period %dT/%dns; req/ack offset %d\n",
3376 i,
3377 (((HOSTDATA(shpnt)->syncrate[i] & 0x70) >> 4) + 2),
3378 (((HOSTDATA(shpnt)->syncrate[i] & 0x70) >> 4) + 2) * 50,
3379 HOSTDATA(shpnt)->syncrate[i] & 0x0f);
3380 }
3381#if defined(AHA152X_DEBUG)
3382#define PDEBUG(flags,txt) \
3383 if(HOSTDATA(shpnt)->debug & flags) SPRINTF("(%s) ", txt);
3384
3385 SPRINTF("enabled debugging options: ");
3386
3387 PDEBUG(debug_procinfo, "procinfo");
3388 PDEBUG(debug_queue, "queue");
3389 PDEBUG(debug_intr, "interrupt");
3390 PDEBUG(debug_selection, "selection");
3391 PDEBUG(debug_msgo, "message out");
3392 PDEBUG(debug_msgi, "message in");
3393 PDEBUG(debug_status, "status");
3394 PDEBUG(debug_cmd, "command");
3395 PDEBUG(debug_datai, "data in");
3396 PDEBUG(debug_datao, "data out");
3397 PDEBUG(debug_eh, "eh");
3398 PDEBUG(debug_locks, "locks");
3399 PDEBUG(debug_phases, "phases");
3400
3401 SPRINTF("\n");
3402#endif
3403
3404 SPRINTF("\nqueue status:\n");
3405 DO_LOCK(flags);
3406 if (ISSUE_SC) {
3407 SPRINTF("not yet issued commands:\n");
3408 for (ptr = ISSUE_SC; ptr; ptr = SCNEXT(ptr))
3409 pos += get_command(pos, ptr);
3410 } else
3411 SPRINTF("no not yet issued commands\n");
3412 DO_UNLOCK(flags);
3413
3414 if (CURRENT_SC) {
3415 SPRINTF("current command:\n");
3416 pos += get_command(pos, CURRENT_SC);
3417 } else
3418 SPRINTF("no current command\n");
3419
3420 if (DISCONNECTED_SC) {
3421 SPRINTF("disconnected commands:\n");
3422 for (ptr = DISCONNECTED_SC; ptr; ptr = SCNEXT(ptr))
3423 pos += get_command(pos, ptr);
3424 } else
3425 SPRINTF("no disconnected commands\n");
3426
3427 pos += get_ports(shpnt, pos);
3428
3429#if defined(AHA152X_STAT)
3430 SPRINTF("statistics:\n"
3431 "total commands: %d\n"
3432 "disconnections: %d\n"
3433 "busfree with check condition: %d\n"
3434 "busfree without old command: %d\n"
3435 "busfree without new command: %d\n"
3436 "busfree without done command: %d\n"
3437 "busfree without any action: %d\n"
3438 "state "
3439 "transitions "
3440 "count "
3441 "time\n",
3442 HOSTDATA(shpnt)->total_commands,
3443 HOSTDATA(shpnt)->disconnections,
3444 HOSTDATA(shpnt)->busfree_with_check_condition,
3445 HOSTDATA(shpnt)->busfree_without_old_command,
3446 HOSTDATA(shpnt)->busfree_without_new_command,
3447 HOSTDATA(shpnt)->busfree_without_done_command,
3448 HOSTDATA(shpnt)->busfree_without_any_action);
3449 for(i=0; i<maxstate; i++) {
3450 SPRINTF("%-10s %-12d %-12d %-12ld\n",
3451 states[i].name,
3452 HOSTDATA(shpnt)->count_trans[i],
3453 HOSTDATA(shpnt)->count[i],
3454 HOSTDATA(shpnt)->time[i]);
3455 }
3456#endif
3457
3458 DPRINTK(debug_procinfo, KERN_DEBUG "aha152x_proc_info: pos=%p\n", pos);
3459
3460 thislength = pos - (buffer + offset);
3461 DPRINTK(debug_procinfo, KERN_DEBUG "aha152x_proc_info: length=%d thislength=%d\n", length, thislength);
3462
3463 if(thislength<0) {
3464 DPRINTK(debug_procinfo, KERN_DEBUG "aha152x_proc_info: output too short\n");
3465 *start = NULL;
3466 return 0;
3467 }
3468
3469 thislength = thislength<length ? thislength : length;
3470
3471 DPRINTK(debug_procinfo, KERN_DEBUG "aha152x_proc_info: return %d\n", thislength);
3472
3473 *start = buffer + offset;
3474 return thislength < length ? thislength : length;
3475}
3476
Christoph Hellwigd0be4a7d2005-10-31 18:31:40 +01003477static struct scsi_host_template aha152x_driver_template = {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003478 .module = THIS_MODULE,
3479 .name = AHA152X_REVID,
3480 .proc_name = "aha152x",
3481 .proc_info = aha152x_proc_info,
3482 .queuecommand = aha152x_queue,
3483 .eh_abort_handler = aha152x_abort,
3484 .eh_device_reset_handler = aha152x_device_reset,
3485 .eh_bus_reset_handler = aha152x_bus_reset,
3486 .eh_host_reset_handler = aha152x_host_reset,
3487 .bios_param = aha152x_biosparam,
3488 .can_queue = 1,
3489 .this_id = 7,
3490 .sg_tablesize = SG_ALL,
3491 .cmd_per_lun = 1,
3492 .use_clustering = DISABLE_CLUSTERING,
3493};
3494
3495#if !defined(PCMCIA)
3496static int setup_count;
3497static struct aha152x_setup setup[2];
3498
3499/* possible i/o addresses for the AIC-6260; default first */
3500static unsigned short ports[] = { 0x340, 0x140 };
3501
3502#if !defined(SKIP_BIOSTEST)
3503/* possible locations for the Adaptec BIOS; defaults first */
3504static unsigned int addresses[] =
3505{
3506 0xdc000, /* default first */
3507 0xc8000,
3508 0xcc000,
3509 0xd0000,
3510 0xd4000,
3511 0xd8000,
3512 0xe0000,
3513 0xeb800, /* VTech Platinum SMP */
3514 0xf0000,
3515};
3516
3517/* signatures for various AIC-6[23]60 based controllers.
3518 The point in detecting signatures is to avoid useless and maybe
3519 harmful probes on ports. I'm not sure that all listed boards pass
3520 auto-configuration. For those which fail the BIOS signature is
3521 obsolete, because user intervention to supply the configuration is
3522 needed anyway. May be an information whether or not the BIOS supports
3523 extended translation could be also useful here. */
3524static struct signature {
3525 unsigned char *signature;
3526 int sig_offset;
3527 int sig_length;
3528} signatures[] =
3529{
3530 { "Adaptec AHA-1520 BIOS", 0x102e, 21 },
3531 /* Adaptec 152x */
3532 { "Adaptec AHA-1520B", 0x000b, 17 },
3533 /* Adaptec 152x rev B */
3534 { "Adaptec AHA-1520B", 0x0026, 17 },
3535 /* Iomega Jaz Jet ISA (AIC6370Q) */
3536 { "Adaptec ASW-B626 BIOS", 0x1029, 21 },
3537 /* on-board controller */
3538 { "Adaptec BIOS: ASW-B626", 0x000f, 22 },
3539 /* on-board controller */
3540 { "Adaptec ASW-B626 S2", 0x2e6c, 19 },
3541 /* on-board controller */
3542 { "Adaptec BIOS:AIC-6360", 0x000c, 21 },
3543 /* on-board controller */
3544 { "ScsiPro SP-360 BIOS", 0x2873, 19 },
3545 /* ScsiPro-Controller */
3546 { "GA-400 LOCAL BUS SCSI BIOS", 0x102e, 26 },
3547 /* Gigabyte Local-Bus-SCSI */
3548 { "Adaptec BIOS:AVA-282X", 0x000c, 21 },
3549 /* Adaptec 282x */
3550 { "Adaptec IBM Dock II SCSI", 0x2edd, 24 },
3551 /* IBM Thinkpad Dock II */
3552 { "Adaptec BIOS:AHA-1532P", 0x001c, 22 },
3553 /* IBM Thinkpad Dock II SCSI */
3554 { "DTC3520A Host Adapter BIOS", 0x318a, 26 },
3555 /* DTC 3520A ISA SCSI */
3556};
3557#endif /* !SKIP_BIOSTEST */
3558
3559/*
3560 * Test, if port_base is valid.
3561 *
3562 */
3563static int aha152x_porttest(int io_port)
3564{
3565 int i;
3566
3567 SETPORT(io_port + O_DMACNTRL1, 0); /* reset stack pointer */
3568 for (i = 0; i < 16; i++)
3569 SETPORT(io_port + O_STACK, i);
3570
3571 SETPORT(io_port + O_DMACNTRL1, 0); /* reset stack pointer */
3572 for (i = 0; i < 16 && GETPORT(io_port + O_STACK) == i; i++)
3573 ;
3574
3575 return (i == 16);
3576}
3577
3578static int tc1550_porttest(int io_port)
3579{
3580 int i;
3581
3582 SETPORT(io_port + O_TC_DMACNTRL1, 0); /* reset stack pointer */
3583 for (i = 0; i < 16; i++)
3584 SETPORT(io_port + O_STACK, i);
3585
3586 SETPORT(io_port + O_TC_DMACNTRL1, 0); /* reset stack pointer */
3587 for (i = 0; i < 16 && GETPORT(io_port + O_TC_STACK) == i; i++)
3588 ;
3589
3590 return (i == 16);
3591}
3592
3593
3594static int checksetup(struct aha152x_setup *setup)
3595{
3596 int i;
3597 for (i = 0; i < ARRAY_SIZE(ports) && (setup->io_port != ports[i]); i++)
3598 ;
3599
3600 if (i == ARRAY_SIZE(ports))
3601 return 0;
3602
3603 if ( request_region(setup->io_port, IO_RANGE, "aha152x")==0 ) {
3604 printk(KERN_ERR "aha152x: io port 0x%x busy.\n", setup->io_port);
3605 return 0;
3606 }
3607
3608 if( aha152x_porttest(setup->io_port) ) {
3609 setup->tc1550=0;
3610 } else if( tc1550_porttest(setup->io_port) ) {
3611 setup->tc1550=1;
3612 } else {
3613 release_region(setup->io_port, IO_RANGE);
3614 return 0;
3615 }
3616
3617 release_region(setup->io_port, IO_RANGE);
3618
3619 if ((setup->irq < IRQ_MIN) || (setup->irq > IRQ_MAX))
3620 return 0;
3621
3622 if ((setup->scsiid < 0) || (setup->scsiid > 7))
3623 return 0;
3624
3625 if ((setup->reconnect < 0) || (setup->reconnect > 1))
3626 return 0;
3627
3628 if ((setup->parity < 0) || (setup->parity > 1))
3629 return 0;
3630
3631 if ((setup->synchronous < 0) || (setup->synchronous > 1))
3632 return 0;
3633
3634 if ((setup->ext_trans < 0) || (setup->ext_trans > 1))
3635 return 0;
3636
3637
3638 return 1;
3639}
3640
3641
3642static int __init aha152x_init(void)
3643{
3644 int i, j, ok;
3645#if defined(AUTOCONF)
3646 aha152x_config conf;
3647#endif
3648#ifdef __ISAPNP__
3649 struct pnp_dev *dev=NULL, *pnpdev[2] = {NULL, NULL};
3650#endif
3651
3652 if ( setup_count ) {
3653 printk(KERN_INFO "aha152x: processing commandline: ");
3654
3655 for (i = 0; i<setup_count; i++) {
3656 if (!checksetup(&setup[i])) {
3657 printk(KERN_ERR "\naha152x: %s\n", setup[i].conf);
3658 printk(KERN_ERR "aha152x: invalid line\n");
3659 }
3660 }
3661 printk("ok\n");
3662 }
3663
3664#if defined(SETUP0)
3665 if (setup_count < ARRAY_SIZE(setup)) {
3666 struct aha152x_setup override = SETUP0;
3667
3668 if (setup_count == 0 || (override.io_port != setup[0].io_port)) {
3669 if (!checksetup(&override)) {
3670 printk(KERN_ERR "\naha152x: invalid override SETUP0={0x%x,%d,%d,%d,%d,%d,%d,%d}\n",
3671 override.io_port,
3672 override.irq,
3673 override.scsiid,
3674 override.reconnect,
3675 override.parity,
3676 override.synchronous,
3677 override.delay,
3678 override.ext_trans);
3679 } else
3680 setup[setup_count++] = override;
3681 }
3682 }
3683#endif
3684
3685#if defined(SETUP1)
3686 if (setup_count < ARRAY_SIZE(setup)) {
3687 struct aha152x_setup override = SETUP1;
3688
3689 if (setup_count == 0 || (override.io_port != setup[0].io_port)) {
3690 if (!checksetup(&override)) {
3691 printk(KERN_ERR "\naha152x: invalid override SETUP1={0x%x,%d,%d,%d,%d,%d,%d,%d}\n",
3692 override.io_port,
3693 override.irq,
3694 override.scsiid,
3695 override.reconnect,
3696 override.parity,
3697 override.synchronous,
3698 override.delay,
3699 override.ext_trans);
3700 } else
3701 setup[setup_count++] = override;
3702 }
3703 }
3704#endif
3705
3706#if defined(MODULE)
3707 if (setup_count<ARRAY_SIZE(setup) && (aha152x[0]!=0 || io[0]!=0 || irq[0]!=0)) {
3708 if(aha152x[0]!=0) {
3709 setup[setup_count].conf = "";
3710 setup[setup_count].io_port = aha152x[0];
3711 setup[setup_count].irq = aha152x[1];
3712 setup[setup_count].scsiid = aha152x[2];
3713 setup[setup_count].reconnect = aha152x[3];
3714 setup[setup_count].parity = aha152x[4];
3715 setup[setup_count].synchronous = aha152x[5];
3716 setup[setup_count].delay = aha152x[6];
3717 setup[setup_count].ext_trans = aha152x[7];
3718#if defined(AHA152X_DEBUG)
3719 setup[setup_count].debug = aha152x[8];
3720#endif
3721 } else if(io[0]!=0 || irq[0]!=0) {
3722 if(io[0]!=0) setup[setup_count].io_port = io[0];
3723 if(irq[0]!=0) setup[setup_count].irq = irq[0];
3724
3725 setup[setup_count].scsiid = scsiid[0];
3726 setup[setup_count].reconnect = reconnect[0];
3727 setup[setup_count].parity = parity[0];
3728 setup[setup_count].synchronous = sync[0];
3729 setup[setup_count].delay = delay[0];
3730 setup[setup_count].ext_trans = exttrans[0];
3731#if defined(AHA152X_DEBUG)
3732 setup[setup_count].debug = debug[0];
3733#endif
3734 }
3735
3736 if (checksetup(&setup[setup_count]))
3737 setup_count++;
3738 else
3739 printk(KERN_ERR "aha152x: invalid module params io=0x%x, irq=%d,scsiid=%d,reconnect=%d,parity=%d,sync=%d,delay=%d,exttrans=%d\n",
3740 setup[setup_count].io_port,
3741 setup[setup_count].irq,
3742 setup[setup_count].scsiid,
3743 setup[setup_count].reconnect,
3744 setup[setup_count].parity,
3745 setup[setup_count].synchronous,
3746 setup[setup_count].delay,
3747 setup[setup_count].ext_trans);
3748 }
3749
3750 if (setup_count<ARRAY_SIZE(setup) && (aha152x1[0]!=0 || io[1]!=0 || irq[1]!=0)) {
3751 if(aha152x1[0]!=0) {
3752 setup[setup_count].conf = "";
3753 setup[setup_count].io_port = aha152x1[0];
3754 setup[setup_count].irq = aha152x1[1];
3755 setup[setup_count].scsiid = aha152x1[2];
3756 setup[setup_count].reconnect = aha152x1[3];
3757 setup[setup_count].parity = aha152x1[4];
3758 setup[setup_count].synchronous = aha152x1[5];
3759 setup[setup_count].delay = aha152x1[6];
3760 setup[setup_count].ext_trans = aha152x1[7];
3761#if defined(AHA152X_DEBUG)
3762 setup[setup_count].debug = aha152x1[8];
3763#endif
3764 } else if(io[1]!=0 || irq[1]!=0) {
3765 if(io[1]!=0) setup[setup_count].io_port = io[1];
3766 if(irq[1]!=0) setup[setup_count].irq = irq[1];
3767
3768 setup[setup_count].scsiid = scsiid[1];
3769 setup[setup_count].reconnect = reconnect[1];
3770 setup[setup_count].parity = parity[1];
3771 setup[setup_count].synchronous = sync[1];
3772 setup[setup_count].delay = delay[1];
3773 setup[setup_count].ext_trans = exttrans[1];
3774#if defined(AHA152X_DEBUG)
3775 setup[setup_count].debug = debug[1];
3776#endif
3777 }
3778 if (checksetup(&setup[setup_count]))
3779 setup_count++;
3780 else
3781 printk(KERN_ERR "aha152x: invalid module params io=0x%x, irq=%d,scsiid=%d,reconnect=%d,parity=%d,sync=%d,delay=%d,exttrans=%d\n",
3782 setup[setup_count].io_port,
3783 setup[setup_count].irq,
3784 setup[setup_count].scsiid,
3785 setup[setup_count].reconnect,
3786 setup[setup_count].parity,
3787 setup[setup_count].synchronous,
3788 setup[setup_count].delay,
3789 setup[setup_count].ext_trans);
3790 }
3791#endif
3792
3793#ifdef __ISAPNP__
3794 for(i=0; setup_count<ARRAY_SIZE(setup) && id_table[i].vendor; i++) {
3795 while ( setup_count<ARRAY_SIZE(setup) &&
3796 (dev=pnp_find_dev(NULL, id_table[i].vendor, id_table[i].function, dev)) ) {
3797 if (pnp_device_attach(dev) < 0)
3798 continue;
3799
3800 if (pnp_activate_dev(dev) < 0) {
3801 pnp_device_detach(dev);
3802 continue;
3803 }
3804
3805 if (!pnp_port_valid(dev, 0)) {
3806 pnp_device_detach(dev);
3807 continue;
3808 }
3809
3810 if (setup_count==1 && pnp_port_start(dev, 0)==setup[0].io_port) {
3811 pnp_device_detach(dev);
3812 continue;
3813 }
3814
3815 setup[setup_count].io_port = pnp_port_start(dev, 0);
3816 setup[setup_count].irq = pnp_irq(dev, 0);
3817 setup[setup_count].scsiid = 7;
3818 setup[setup_count].reconnect = 1;
3819 setup[setup_count].parity = 1;
3820 setup[setup_count].synchronous = 1;
3821 setup[setup_count].delay = DELAY_DEFAULT;
3822 setup[setup_count].ext_trans = 0;
3823#if defined(AHA152X_DEBUG)
3824 setup[setup_count].debug = DEBUG_DEFAULT;
3825#endif
3826#if defined(__ISAPNP__)
3827 pnpdev[setup_count] = dev;
3828#endif
3829 printk (KERN_INFO
3830 "aha152x: found ISAPnP adapter at io=0x%03x, irq=%d\n",
3831 setup[setup_count].io_port, setup[setup_count].irq);
3832 setup_count++;
3833 }
3834 }
3835#endif
3836
3837#if defined(AUTOCONF)
3838 if (setup_count<ARRAY_SIZE(setup)) {
3839#if !defined(SKIP_BIOSTEST)
3840 ok = 0;
3841 for (i = 0; i < ARRAY_SIZE(addresses) && !ok; i++) {
3842 void __iomem *p = ioremap(addresses[i], 0x4000);
3843 if (!p)
3844 continue;
3845 for (j = 0; j<ARRAY_SIZE(signatures) && !ok; j++)
3846 ok = check_signature(p + signatures[j].sig_offset,
3847 signatures[j].signature, signatures[j].sig_length);
3848 iounmap(p);
3849 }
3850 if (!ok && setup_count == 0)
3851 return 0;
3852
3853 printk(KERN_INFO "aha152x: BIOS test: passed, ");
3854#else
3855 printk(KERN_INFO "aha152x: ");
3856#endif /* !SKIP_BIOSTEST */
3857
3858 ok = 0;
3859 for (i = 0; i < ARRAY_SIZE(ports) && setup_count < 2; i++) {
3860 if ((setup_count == 1) && (setup[0].io_port == ports[i]))
3861 continue;
3862
3863 if ( request_region(ports[i], IO_RANGE, "aha152x")==0 ) {
3864 printk(KERN_ERR "aha152x: io port 0x%x busy.\n", ports[i]);
3865 continue;
3866 }
3867
3868 if (aha152x_porttest(ports[i])) {
3869 setup[setup_count].tc1550 = 0;
3870
3871 conf.cf_port =
3872 (GETPORT(ports[i] + O_PORTA) << 8) + GETPORT(ports[i] + O_PORTB);
3873 } else if (tc1550_porttest(ports[i])) {
3874 setup[setup_count].tc1550 = 1;
3875
3876 conf.cf_port =
3877 (GETPORT(ports[i] + O_TC_PORTA) << 8) + GETPORT(ports[i] + O_TC_PORTB);
3878 } else {
3879 release_region(ports[i], IO_RANGE);
3880 continue;
3881 }
3882
3883 release_region(ports[i], IO_RANGE);
3884
3885 ok++;
3886 setup[setup_count].io_port = ports[i];
3887 setup[setup_count].irq = IRQ_MIN + conf.cf_irq;
3888 setup[setup_count].scsiid = conf.cf_id;
3889 setup[setup_count].reconnect = conf.cf_tardisc;
3890 setup[setup_count].parity = !conf.cf_parity;
3891 setup[setup_count].synchronous = conf.cf_syncneg;
3892 setup[setup_count].delay = DELAY_DEFAULT;
3893 setup[setup_count].ext_trans = 0;
3894#if defined(AHA152X_DEBUG)
3895 setup[setup_count].debug = DEBUG_DEFAULT;
3896#endif
3897 setup_count++;
3898
3899 }
3900
3901 if (ok)
3902 printk("auto configuration: ok, ");
3903 }
3904#endif
3905
3906 printk("%d controller(s) configured\n", setup_count);
3907
3908 for (i=0; i<setup_count; i++) {
3909 if ( request_region(setup[i].io_port, IO_RANGE, "aha152x") ) {
3910 struct Scsi_Host *shpnt = aha152x_probe_one(&setup[i]);
3911
3912 if( !shpnt ) {
3913 release_region(setup[i].io_port, IO_RANGE);
3914#if defined(__ISAPNP__)
3915 } else if( pnpdev[i] ) {
3916 HOSTDATA(shpnt)->pnpdev=pnpdev[i];
3917 pnpdev[i]=NULL;
3918#endif
3919 }
3920 } else {
3921 printk(KERN_ERR "aha152x: io port 0x%x busy.\n", setup[i].io_port);
3922 }
3923
3924#if defined(__ISAPNP__)
3925 if( pnpdev[i] )
3926 pnp_device_detach(pnpdev[i]);
3927#endif
3928 }
3929
James Bottomley5fcda422006-09-14 17:04:58 -05003930 return 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003931}
3932
3933static void __exit aha152x_exit(void)
3934{
James Bottomley5fcda422006-09-14 17:04:58 -05003935 struct aha152x_hostdata *hd;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003936
James Bottomley5fcda422006-09-14 17:04:58 -05003937 list_for_each_entry(hd, &aha152x_host_list, host_list) {
3938 struct Scsi_Host *shost = container_of((void *)hd, struct Scsi_Host, hostdata);
3939
3940 aha152x_release(shost);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003941 }
3942}
3943
3944module_init(aha152x_init);
3945module_exit(aha152x_exit);
3946
3947#if !defined(MODULE)
3948static int __init aha152x_setup(char *str)
3949{
3950#if defined(AHA152X_DEBUG)
3951 int ints[11];
3952#else
3953 int ints[10];
3954#endif
3955 get_options(str, ARRAY_SIZE(ints), ints);
3956
3957 if(setup_count>=ARRAY_SIZE(setup)) {
3958 printk(KERN_ERR "aha152x: you can only configure up to two controllers\n");
3959 return 1;
3960 }
3961
3962 setup[setup_count].conf = str;
3963 setup[setup_count].io_port = ints[0] >= 1 ? ints[1] : 0x340;
3964 setup[setup_count].irq = ints[0] >= 2 ? ints[2] : 11;
3965 setup[setup_count].scsiid = ints[0] >= 3 ? ints[3] : 7;
3966 setup[setup_count].reconnect = ints[0] >= 4 ? ints[4] : 1;
3967 setup[setup_count].parity = ints[0] >= 5 ? ints[5] : 1;
3968 setup[setup_count].synchronous = ints[0] >= 6 ? ints[6] : 1;
3969 setup[setup_count].delay = ints[0] >= 7 ? ints[7] : DELAY_DEFAULT;
3970 setup[setup_count].ext_trans = ints[0] >= 8 ? ints[8] : 0;
3971#if defined(AHA152X_DEBUG)
3972 setup[setup_count].debug = ints[0] >= 9 ? ints[9] : DEBUG_DEFAULT;
3973 if (ints[0] > 9) {
3974 printk(KERN_NOTICE "aha152x: usage: aha152x=<IOBASE>[,<IRQ>[,<SCSI ID>"
3975 "[,<RECONNECT>[,<PARITY>[,<SYNCHRONOUS>[,<DELAY>[,<EXT_TRANS>[,<DEBUG>]]]]]]]]\n");
3976#else
3977 if (ints[0] > 8) { /*}*/
3978 printk(KERN_NOTICE "aha152x: usage: aha152x=<IOBASE>[,<IRQ>[,<SCSI ID>"
3979 "[,<RECONNECT>[,<PARITY>[,<SYNCHRONOUS>[,<DELAY>[,<EXT_TRANS>]]]]]]]\n");
3980#endif
3981 } else {
3982 setup_count++;
3983 return 0;
3984 }
3985
3986 return 1;
3987}
3988__setup("aha152x=", aha152x_setup);
3989#endif
3990
3991#endif /* !PCMCIA */