]> git.proxmox.com Git - mirror_ubuntu-jammy-kernel.git/blame - drivers/scsi/aha152x.c
scsi: target: tcmu: Fix possible page UAF
[mirror_ubuntu-jammy-kernel.git] / drivers / scsi / aha152x.c
CommitLineData
3e0a4e85 1// SPDX-License-Identifier: GPL-2.0-or-later
1da177e4 2/* aha152x.c -- Adaptec AHA-152x driver
96de0e25
JE
3 * Author: Jürgen E. Fischer, fischer@norbit.de
4 * Copyright 1993-2004 Jürgen E. Fischer
1da177e4 5 *
1da177e4
LT
6 * $Id: aha152x.c,v 2.7 2004/01/24 11:42:59 fischer Exp $
7 *
8 * $Log: aha152x.c,v $
9 * Revision 2.7 2004/01/24 11:42:59 fischer
10 * - gather code that is not used by PCMCIA at the end
11 * - move request_region for !PCMCIA case to detection
12 * - migration to new scsi host api (remove legacy code)
13 * - free host scribble before scsi_done
14 * - fix error handling
15 * - one isapnp device added to id_table
16 *
17 * Revision 2.6 2003/10/30 20:52:47 fischer
18 * - interfaces changes for kernel 2.6
19 * - aha152x_probe_one introduced for pcmcia stub
20 * - fixed pnpdev handling
21 * - instead of allocation a new one, reuse command for request sense after check condition and reset
22 * - fixes race in is_complete
23 *
24 * Revision 2.5 2002/04/14 11:24:53 fischer
25 * - isapnp support
26 * - abort fixed
27 * - 2.5 support
28 *
29 * Revision 2.4 2000/12/16 12:53:56 fischer
30 * - allow REQUEST SENSE to be queued
31 * - handle shared PCI interrupts
32 *
33 * Revision 2.3 2000/11/04 16:40:26 fischer
34 * - handle data overruns
35 * - extend timeout for data phases
36 *
37 * Revision 2.2 2000/08/08 19:54:53 fischer
38 * - minor changes
39 *
40 * Revision 2.1 2000/05/17 16:23:17 fischer
41 * - signature update
42 * - fix for data out w/o scatter gather
43 *
44 * Revision 2.0 1999/12/25 15:07:32 fischer
45 * - interrupt routine completly reworked
46 * - basic support for new eh code
47 *
48 * Revision 1.21 1999/11/10 23:46:36 fischer
49 * - default to synchronous operation
50 * - synchronous negotiation fixed
51 * - added timeout to loops
52 * - debugging output can be controlled through procfs
53 *
54 * Revision 1.20 1999/11/07 18:37:31 fischer
55 * - synchronous operation works
56 * - resid support for sg driver
57 *
58 * Revision 1.19 1999/11/02 22:39:59 fischer
59 * - moved leading comments to README.aha152x
60 * - new additional module parameters
61 * - updates for 2.3
62 * - support for the Tripace TC1550 controller
63 * - interrupt handling changed
64 *
65 * Revision 1.18 1996/09/07 20:10:40 fischer
66 * - fixed can_queue handling (multiple outstanding commands working again)
67 *
68 * Revision 1.17 1996/08/17 16:05:14 fischer
69 * - biosparam improved
70 * - interrupt verification
71 * - updated documentation
72 * - cleanups
73 *
74 * Revision 1.16 1996/06/09 00:04:56 root
75 * - added configuration symbols for insmod (aha152x/aha152x1)
76 *
77 * Revision 1.15 1996/04/30 14:52:06 fischer
78 * - proc info fixed
79 * - support for extended translation for >1GB disks
80 *
81 * Revision 1.14 1996/01/17 15:11:20 fischer
82 * - fixed lockup in MESSAGE IN phase after reconnection
83 *
84 * Revision 1.13 1996/01/09 02:15:53 fischer
85 * - some cleanups
86 * - moved request_irq behind controller initialization
87 * (to avoid spurious interrupts)
88 *
89 * Revision 1.12 1995/12/16 12:26:07 fischer
90 * - barrier()s added
91 * - configurable RESET delay added
92 *
93 * Revision 1.11 1995/12/06 21:18:35 fischer
94 * - some minor updates
95 *
96 * Revision 1.10 1995/07/22 19:18:45 fischer
97 * - support for 2 controllers
98 * - started synchronous data transfers (not working yet)
99 *
100 * Revision 1.9 1995/03/18 09:20:24 root
101 * - patches for PCMCIA and modules
102 *
103 * Revision 1.8 1995/01/21 22:07:19 root
104 * - snarf_region => request_region
105 * - aha152x_intr interface change
106 *
107 * Revision 1.7 1995/01/02 23:19:36 root
108 * - updated COMMAND_SIZE to cmd_len
109 * - changed sti() to restore_flags()
110 * - fixed some #ifdef which generated warnings
111 *
112 * Revision 1.6 1994/11/24 20:35:27 root
113 * - problem with odd number of bytes in fifo fixed
114 *
115 * Revision 1.5 1994/10/30 14:39:56 root
116 * - abort code fixed
117 * - debugging improved
118 *
119 * Revision 1.4 1994/09/12 11:33:01 root
120 * - irqaction to request_irq
121 * - abortion updated
122 *
123 * Revision 1.3 1994/08/04 13:53:05 root
124 * - updates for mid-level-driver changes
125 * - accept unexpected BUSFREE phase as error condition
126 * - parity check now configurable
127 *
128 * Revision 1.2 1994/07/03 12:56:36 root
129 * - cleaned up debugging code
130 * - more tweaking on reset delays
131 * - updated abort/reset code (pretty untested...)
132 *
133 * Revision 1.1 1994/05/28 21:18:49 root
134 * - update for mid-level interface change (abort-reset)
135 * - delays after resets adjusted for some slow devices
136 *
137 * Revision 1.0 1994/03/25 12:52:00 root
138 * - Fixed "more data than expected" problem
139 * - added new BIOS signatures
140 *
141 * Revision 0.102 1994/01/31 20:44:12 root
142 * - minor changes in insw/outsw handling
143 *
144 * Revision 0.101 1993/12/13 01:16:27 root
145 * - fixed STATUS phase (non-GOOD stati were dropped sometimes;
146 * fixes problems with CD-ROM sector size detection & media change)
147 *
148 * Revision 0.100 1993/12/10 16:58:47 root
149 * - fix for unsuccessful selections in case of non-continuous id assignments
150 * on the scsi bus.
151 *
152 * Revision 0.99 1993/10/24 16:19:59 root
153 * - fixed DATA IN (rare read errors gone)
154 *
155 * Revision 0.98 1993/10/17 12:54:44 root
156 * - fixed some recent fixes (shame on me)
157 * - moved initialization of scratch area to aha152x_queue
158 *
159 * Revision 0.97 1993/10/09 18:53:53 root
160 * - DATA IN fixed. Rarely left data in the fifo.
161 *
162 * Revision 0.96 1993/10/03 00:53:59 root
163 * - minor changes on DATA IN
164 *
165 * Revision 0.95 1993/09/24 10:36:01 root
166 * - change handling of MSGI after reselection
167 * - fixed sti/cli
168 * - minor changes
169 *
170 * Revision 0.94 1993/09/18 14:08:22 root
171 * - fixed bug in multiple outstanding command code
172 * - changed detection
173 * - support for kernel command line configuration
174 * - reset corrected
175 * - changed message handling
176 *
177 * Revision 0.93 1993/09/15 20:41:19 root
178 * - fixed bugs with multiple outstanding commands
179 *
180 * Revision 0.92 1993/09/13 02:46:33 root
181 * - multiple outstanding commands work (no problems with IBM drive)
182 *
183 * Revision 0.91 1993/09/12 20:51:46 root
184 * added multiple outstanding commands
185 * (some problem with this $%&? IBM device remain)
186 *
187 * Revision 0.9 1993/09/12 11:11:22 root
188 * - corrected auto-configuration
189 * - changed the auto-configuration (added some '#define's)
190 * - added support for dis-/reconnection
191 *
192 * Revision 0.8 1993/09/06 23:09:39 root
193 * - added support for the drive activity light
194 * - minor changes
195 *
196 * Revision 0.7 1993/09/05 14:30:15 root
197 * - improved phase detection
198 * - now using the new snarf_region code of 0.99pl13
199 *
200 * Revision 0.6 1993/09/02 11:01:38 root
201 * first public release; added some signatures and biosparam()
202 *
203 * Revision 0.5 1993/08/30 10:23:30 root
204 * fixed timing problems with my IBM drive
205 *
206 * Revision 0.4 1993/08/29 14:06:52 root
207 * fixed some problems with timeouts due incomplete commands
208 *
209 * Revision 0.3 1993/08/28 15:55:03 root
210 * writing data works too. mounted and worked on a dos partition
211 *
212 * Revision 0.2 1993/08/27 22:42:07 root
213 * reading data works. Mounted a msdos partition.
214 *
215 * Revision 0.1 1993/08/25 13:38:30 root
216 * first "damn thing doesn't work" version
217 *
218 * Revision 0.0 1993/08/14 19:54:25 root
219 * empty function bodies; detect() works.
220 *
1da177e4 221 **************************************************************************
f75ae8ed 222
94b5530f 223 see Documentation/scsi/aha152x.rst for configuration details
1da177e4
LT
224
225 **************************************************************************/
226
227#include <linux/module.h>
1da177e4 228#include <asm/irq.h>
53d5ed62 229#include <linux/io.h>
1da177e4 230#include <linux/blkdev.h>
0f06bb34 231#include <linux/completion.h>
1da177e4
LT
232#include <linux/errno.h>
233#include <linux/string.h>
234#include <linux/wait.h>
235#include <linux/ioport.h>
236#include <linux/delay.h>
237#include <linux/proc_fs.h>
238#include <linux/interrupt.h>
239#include <linux/init.h>
240#include <linux/kernel.h>
241#include <linux/isapnp.h>
242#include <linux/spinlock.h>
243#include <linux/workqueue.h>
5fcda422 244#include <linux/list.h>
5a0e3ad6 245#include <linux/slab.h>
1da177e4
LT
246#include <scsi/scsicam.h>
247
248#include "scsi.h"
db9dff36 249#include <scsi/scsi_dbg.h>
1da177e4 250#include <scsi/scsi_host.h>
1abfd370 251#include <scsi/scsi_transport_spi.h>
73d2cb16 252#include <scsi/scsi_eh.h>
1da177e4
LT
253#include "aha152x.h"
254
5fcda422
JB
255static LIST_HEAD(aha152x_host_list);
256
1da177e4
LT
257
258/* DEFINES */
259
260/* For PCMCIA cards, always use AUTOCONF */
3eb2ebcb 261#if defined(AHA152X_PCMCIA) || defined(MODULE)
1da177e4
LT
262#if !defined(AUTOCONF)
263#define AUTOCONF
264#endif
265#endif
266
267#if !defined(AUTOCONF) && !defined(SETUP0)
268#error define AUTOCONF or SETUP0
269#endif
270
1da177e4
LT
271#define DO_LOCK(flags) spin_lock_irqsave(&QLOCK,flags)
272#define DO_UNLOCK(flags) spin_unlock_irqrestore(&QLOCK,flags)
1da177e4
LT
273
274#define LEAD "(scsi%d:%d:%d) "
1da177e4 275#define INFO_LEAD KERN_INFO LEAD
1da177e4
LT
276#define CMDINFO(cmd) \
277 (cmd) ? ((cmd)->device->host->host_no) : -1, \
278 (cmd) ? ((cmd)->device->id & 0x0f) : -1, \
9cb78c16 279 (cmd) ? ((u8)(cmd)->device->lun & 0x07) : -1
1da177e4 280
2338545a
BH
281static inline void
282CMD_INC_RESID(struct scsi_cmnd *cmd, int inc)
283{
284 scsi_set_resid(cmd, scsi_get_resid(cmd) + inc);
285}
286
1da177e4
LT
287#define DELAY_DEFAULT 1000
288
3eb2ebcb 289#if defined(AHA152X_PCMCIA)
1da177e4
LT
290#define IRQ_MIN 0
291#define IRQ_MAX 16
292#else
293#define IRQ_MIN 9
294#if defined(__PPC)
171ac6ae 295#define IRQ_MAX (nr_irqs-1)
1da177e4
LT
296#else
297#define IRQ_MAX 12
298#endif
299#endif
300
301enum {
302 not_issued = 0x0001, /* command not yet issued */
f75ae8ed 303 selecting = 0x0002, /* target is being selected */
1da177e4
LT
304 identified = 0x0004, /* IDENTIFY was sent */
305 disconnected = 0x0008, /* target disconnected */
f75ae8ed 306 completed = 0x0010, /* target sent COMMAND COMPLETE */
1da177e4
LT
307 aborted = 0x0020, /* ABORT was sent */
308 resetted = 0x0040, /* BUS DEVICE RESET was sent */
309 spiordy = 0x0080, /* waiting for SPIORDY to raise */
310 syncneg = 0x0100, /* synchronous negotiation in progress */
311 aborting = 0x0200, /* ABORT is pending */
312 resetting = 0x0400, /* BUS DEVICE RESET is pending */
313 check_condition = 0x0800, /* requesting sense after CHECK CONDITION */
314};
315
96de0e25 316MODULE_AUTHOR("Jürgen Fischer");
1da177e4
LT
317MODULE_DESCRIPTION(AHA152X_REVID);
318MODULE_LICENSE("GPL");
319
3eb2ebcb 320#if !defined(AHA152X_PCMCIA)
1da177e4
LT
321#if defined(MODULE)
322static int io[] = {0, 0};
88f06b76 323module_param_hw_array(io, int, ioport, NULL, 0);
1da177e4
LT
324MODULE_PARM_DESC(io,"base io address of controller");
325
326static int irq[] = {0, 0};
88f06b76 327module_param_hw_array(irq, int, irq, NULL, 0);
1da177e4
LT
328MODULE_PARM_DESC(irq,"interrupt for controller");
329
330static int scsiid[] = {7, 7};
331module_param_array(scsiid, int, NULL, 0);
332MODULE_PARM_DESC(scsiid,"scsi id of controller");
333
334static int reconnect[] = {1, 1};
335module_param_array(reconnect, int, NULL, 0);
336MODULE_PARM_DESC(reconnect,"allow targets to disconnect");
337
338static int parity[] = {1, 1};
339module_param_array(parity, int, NULL, 0);
340MODULE_PARM_DESC(parity,"use scsi parity");
341
342static int sync[] = {1, 1};
343module_param_array(sync, int, NULL, 0);
344MODULE_PARM_DESC(sync,"use synchronous transfers");
345
346static int delay[] = {DELAY_DEFAULT, DELAY_DEFAULT};
347module_param_array(delay, int, NULL, 0);
348MODULE_PARM_DESC(delay,"scsi reset delay");
349
350static int exttrans[] = {0, 0};
351module_param_array(exttrans, int, NULL, 0);
352MODULE_PARM_DESC(exttrans,"use extended translation");
353
1da177e4
LT
354static int aha152x[] = {0, 11, 7, 1, 1, 0, DELAY_DEFAULT, 0};
355module_param_array(aha152x, int, NULL, 0);
356MODULE_PARM_DESC(aha152x, "parameters for first controller");
357
358static int aha152x1[] = {0, 11, 7, 1, 1, 0, DELAY_DEFAULT, 0};
359module_param_array(aha152x1, int, NULL, 0);
360MODULE_PARM_DESC(aha152x1, "parameters for second controller");
1da177e4
LT
361#endif /* MODULE */
362
363#ifdef __ISAPNP__
6f039790 364static struct isapnp_device_id id_table[] = {
50f87f91
OZ
365 { ISAPNP_ANY_ID, ISAPNP_ANY_ID, ISAPNP_VENDOR('A', 'D', 'P'), ISAPNP_FUNCTION(0x1502), 0 },
366 { ISAPNP_ANY_ID, ISAPNP_ANY_ID, ISAPNP_VENDOR('A', 'D', 'P'), ISAPNP_FUNCTION(0x1505), 0 },
367 { ISAPNP_ANY_ID, ISAPNP_ANY_ID, ISAPNP_VENDOR('A', 'D', 'P'), ISAPNP_FUNCTION(0x1510), 0 },
368 { ISAPNP_ANY_ID, ISAPNP_ANY_ID, ISAPNP_VENDOR('A', 'D', 'P'), ISAPNP_FUNCTION(0x1515), 0 },
369 { ISAPNP_ANY_ID, ISAPNP_ANY_ID, ISAPNP_VENDOR('A', 'D', 'P'), ISAPNP_FUNCTION(0x1520), 0 },
370 { ISAPNP_ANY_ID, ISAPNP_ANY_ID, ISAPNP_VENDOR('A', 'D', 'P'), ISAPNP_FUNCTION(0x2015), 0 },
371 { ISAPNP_ANY_ID, ISAPNP_ANY_ID, ISAPNP_VENDOR('A', 'D', 'P'), ISAPNP_FUNCTION(0x1522), 0 },
372 { ISAPNP_ANY_ID, ISAPNP_ANY_ID, ISAPNP_VENDOR('A', 'D', 'P'), ISAPNP_FUNCTION(0x2215), 0 },
373 { ISAPNP_ANY_ID, ISAPNP_ANY_ID, ISAPNP_VENDOR('A', 'D', 'P'), ISAPNP_FUNCTION(0x1530), 0 },
374 { ISAPNP_ANY_ID, ISAPNP_ANY_ID, ISAPNP_VENDOR('A', 'D', 'P'), ISAPNP_FUNCTION(0x3015), 0 },
375 { ISAPNP_ANY_ID, ISAPNP_ANY_ID, ISAPNP_VENDOR('A', 'D', 'P'), ISAPNP_FUNCTION(0x1532), 0 },
376 { ISAPNP_ANY_ID, ISAPNP_ANY_ID, ISAPNP_VENDOR('A', 'D', 'P'), ISAPNP_FUNCTION(0x3215), 0 },
377 { ISAPNP_ANY_ID, ISAPNP_ANY_ID, ISAPNP_VENDOR('A', 'D', 'P'), ISAPNP_FUNCTION(0x6360), 0 },
1da177e4
LT
378 { ISAPNP_DEVICE_SINGLE_END, }
379};
380MODULE_DEVICE_TABLE(isapnp, id_table);
381#endif /* ISAPNP */
382
3eb2ebcb 383#endif /* !AHA152X_PCMCIA */
1da177e4 384
d0be4a7d 385static struct scsi_host_template aha152x_driver_template;
1da177e4
LT
386
387/*
388 * internal states of the host
389 *
f75ae8ed 390 */
1da177e4
LT
391enum aha152x_state {
392 idle=0,
393 unknown,
394 seldo,
395 seldi,
396 selto,
397 busfree,
398 msgo,
399 cmd,
400 msgi,
401 status,
402 datai,
403 datao,
404 parerr,
405 rsti,
406 maxstate
407};
408
409/*
410 * current state information of the host
411 *
412 */
413struct aha152x_hostdata {
91ebc1fa 414 struct scsi_cmnd *issue_SC;
1da177e4
LT
415 /* pending commands to issue */
416
91ebc1fa 417 struct scsi_cmnd *current_SC;
1da177e4
LT
418 /* current command on the bus */
419
91ebc1fa 420 struct scsi_cmnd *disconnected_SC;
1da177e4
LT
421 /* commands that disconnected */
422
91ebc1fa 423 struct scsi_cmnd *done_SC;
1da177e4
LT
424 /* command that was completed */
425
426 spinlock_t lock;
427 /* host lock */
428
1da177e4 429#if defined(AHA152X_STAT)
f75ae8ed 430 int total_commands;
1da177e4
LT
431 int disconnections;
432 int busfree_without_any_action;
433 int busfree_without_old_command;
434 int busfree_without_new_command;
435 int busfree_without_done_command;
436 int busfree_with_check_condition;
f75ae8ed
HR
437 int count[maxstate];
438 int count_trans[maxstate];
1da177e4
LT
439 unsigned long time[maxstate];
440#endif
441
442 int commands; /* current number of commands */
443
444 int reconnect; /* disconnection allowed */
445 int parity; /* parity checking enabled */
446 int synchronous; /* synchronous transferes enabled */
447 int delay; /* reset out delay */
448 int ext_trans; /* extended translation enabled */
449
f75ae8ed 450 int swint; /* software-interrupt was fired during detect() */
1da177e4
LT
451 int service; /* bh needs to be run */
452 int in_intr; /* bh is running */
453
454 /* current state,
455 previous state,
456 last state different from current state */
457 enum aha152x_state state, prevstate, laststate;
458
459 int target;
460 /* reconnecting target */
461
462 unsigned char syncrate[8];
463 /* current synchronous transfer agreements */
464
465 unsigned char syncneg[8];
466 /* 0: no negotiation;
467 * 1: negotiation in progress;
468 * 2: negotiation completed
469 */
470
471 int cmd_i;
472 /* number of sent bytes of current command */
473
474 int msgi_len;
475 /* number of received message bytes */
476 unsigned char msgi[256];
477 /* received message bytes */
478
f75ae8ed 479 int msgo_i, msgo_len;
1da177e4
LT
480 /* number of sent bytes and length of current messages */
481 unsigned char msgo[256];
482 /* pending messages */
483
484 int data_len;
485 /* number of sent/received bytes in dataphase */
486
487 unsigned long io_port0;
488 unsigned long io_port1;
489
490#ifdef __ISAPNP__
491 struct pnp_dev *pnpdev;
492#endif
5fcda422 493 struct list_head host_list;
1da177e4
LT
494};
495
496
497/*
498 * host specific command extension
499 *
500 */
501struct aha152x_scdata {
91ebc1fa 502 struct scsi_cmnd *next; /* next sc in queue */
0f06bb34 503 struct completion *done;/* semaphore to block on */
73d2cb16 504 struct scsi_eh_save ses;
1da177e4
LT
505};
506
1da177e4
LT
507/* access macros for hostdata */
508
509#define HOSTDATA(shpnt) ((struct aha152x_hostdata *) &shpnt->hostdata)
510
511#define HOSTNO ((shpnt)->host_no)
512
513#define CURRENT_SC (HOSTDATA(shpnt)->current_SC)
514#define DONE_SC (HOSTDATA(shpnt)->done_SC)
515#define ISSUE_SC (HOSTDATA(shpnt)->issue_SC)
516#define DISCONNECTED_SC (HOSTDATA(shpnt)->disconnected_SC)
517#define QLOCK (HOSTDATA(shpnt)->lock)
518#define QLOCKER (HOSTDATA(shpnt)->locker)
519#define QLOCKERL (HOSTDATA(shpnt)->lockerl)
520
521#define STATE (HOSTDATA(shpnt)->state)
522#define PREVSTATE (HOSTDATA(shpnt)->prevstate)
523#define LASTSTATE (HOSTDATA(shpnt)->laststate)
524
525#define RECONN_TARGET (HOSTDATA(shpnt)->target)
526
527#define CMD_I (HOSTDATA(shpnt)->cmd_i)
528
529#define MSGO(i) (HOSTDATA(shpnt)->msgo[i])
530#define MSGO_I (HOSTDATA(shpnt)->msgo_i)
531#define MSGOLEN (HOSTDATA(shpnt)->msgo_len)
532#define ADDMSGO(x) (MSGOLEN<256 ? (void)(MSGO(MSGOLEN++)=x) : aha152x_error(shpnt,"MSGO overflow"))
533
534#define MSGI(i) (HOSTDATA(shpnt)->msgi[i])
535#define MSGILEN (HOSTDATA(shpnt)->msgi_len)
536#define ADDMSGI(x) (MSGILEN<256 ? (void)(MSGI(MSGILEN++)=x) : aha152x_error(shpnt,"MSGI overflow"))
537
538#define DATA_LEN (HOSTDATA(shpnt)->data_len)
539
540#define SYNCRATE (HOSTDATA(shpnt)->syncrate[CURRENT_SC->device->id])
541#define SYNCNEG (HOSTDATA(shpnt)->syncneg[CURRENT_SC->device->id])
542
543#define DELAY (HOSTDATA(shpnt)->delay)
544#define EXT_TRANS (HOSTDATA(shpnt)->ext_trans)
545#define TC1550 (HOSTDATA(shpnt)->tc1550)
546#define RECONNECT (HOSTDATA(shpnt)->reconnect)
547#define PARITY (HOSTDATA(shpnt)->parity)
548#define SYNCHRONOUS (HOSTDATA(shpnt)->synchronous)
549
550#define HOSTIOPORT0 (HOSTDATA(shpnt)->io_port0)
551#define HOSTIOPORT1 (HOSTDATA(shpnt)->io_port1)
552
553#define SCDATA(SCpnt) ((struct aha152x_scdata *) (SCpnt)->host_scribble)
554#define SCNEXT(SCpnt) SCDATA(SCpnt)->next
0f06bb34 555#define SCSEM(SCpnt) SCDATA(SCpnt)->done
1da177e4 556
45711f1a 557#define SG_ADDRESS(buffer) ((char *) sg_virt((buffer)))
1da177e4
LT
558
559/* state handling */
560static void seldi_run(struct Scsi_Host *shpnt);
561static void seldo_run(struct Scsi_Host *shpnt);
562static void selto_run(struct Scsi_Host *shpnt);
563static void busfree_run(struct Scsi_Host *shpnt);
564
565static void msgo_init(struct Scsi_Host *shpnt);
566static void msgo_run(struct Scsi_Host *shpnt);
567static void msgo_end(struct Scsi_Host *shpnt);
568
569static void cmd_init(struct Scsi_Host *shpnt);
570static void cmd_run(struct Scsi_Host *shpnt);
571static void cmd_end(struct Scsi_Host *shpnt);
572
573static void datai_init(struct Scsi_Host *shpnt);
574static void datai_run(struct Scsi_Host *shpnt);
575static void datai_end(struct Scsi_Host *shpnt);
576
577static void datao_init(struct Scsi_Host *shpnt);
578static void datao_run(struct Scsi_Host *shpnt);
579static void datao_end(struct Scsi_Host *shpnt);
580
581static void status_run(struct Scsi_Host *shpnt);
582
583static void msgi_run(struct Scsi_Host *shpnt);
584static void msgi_end(struct Scsi_Host *shpnt);
585
586static void parerr_run(struct Scsi_Host *shpnt);
587static void rsti_run(struct Scsi_Host *shpnt);
588
589static void is_complete(struct Scsi_Host *shpnt);
590
591/*
592 * driver states
593 *
594 */
595static struct {
596 char *name;
597 void (*init)(struct Scsi_Host *);
598 void (*run)(struct Scsi_Host *);
599 void (*end)(struct Scsi_Host *);
600 int spio;
601} states[] = {
602 { "idle", NULL, NULL, NULL, 0},
603 { "unknown", NULL, NULL, NULL, 0},
604 { "seldo", NULL, seldo_run, NULL, 0},
605 { "seldi", NULL, seldi_run, NULL, 0},
606 { "selto", NULL, selto_run, NULL, 0},
607 { "busfree", NULL, busfree_run, NULL, 0},
608 { "msgo", msgo_init, msgo_run, msgo_end, 1},
609 { "cmd", cmd_init, cmd_run, cmd_end, 1},
610 { "msgi", NULL, msgi_run, msgi_end, 1},
611 { "status", NULL, status_run, NULL, 1},
612 { "datai", datai_init, datai_run, datai_end, 0},
613 { "datao", datao_init, datao_run, datao_end, 0},
614 { "parerr", NULL, parerr_run, NULL, 0},
615 { "rsti", NULL, rsti_run, NULL, 0},
616};
617
618/* setup & interrupt */
7d12e780 619static irqreturn_t intr(int irq, void *dev_id);
1da177e4
LT
620static void reset_ports(struct Scsi_Host *shpnt);
621static void aha152x_error(struct Scsi_Host *shpnt, char *msg);
aec166fd 622static void done(struct Scsi_Host *shpnt, unsigned char status_byte,
fdabe57d 623 unsigned char host_byte);
1da177e4
LT
624
625/* diagnostics */
91ebc1fa 626static void show_command(struct scsi_cmnd * ptr);
1da177e4
LT
627static void show_queues(struct Scsi_Host *shpnt);
628static void disp_enintr(struct Scsi_Host *shpnt);
629
630
631/*
632 * queue services:
633 *
634 */
91ebc1fa 635static inline void append_SC(struct scsi_cmnd **SC, struct scsi_cmnd *new_SC)
1da177e4 636{
91ebc1fa 637 struct scsi_cmnd *end;
1da177e4
LT
638
639 SCNEXT(new_SC) = NULL;
640 if (!*SC)
641 *SC = new_SC;
642 else {
643 for (end = *SC; SCNEXT(end); end = SCNEXT(end))
644 ;
645 SCNEXT(end) = new_SC;
646 }
647}
648
91ebc1fa 649static inline struct scsi_cmnd *remove_first_SC(struct scsi_cmnd ** SC)
1da177e4 650{
91ebc1fa 651 struct scsi_cmnd *ptr;
1da177e4
LT
652
653 ptr = *SC;
654 if (ptr) {
655 *SC = SCNEXT(*SC);
656 SCNEXT(ptr)=NULL;
657 }
658 return ptr;
659}
660
91ebc1fa
JT
661static inline struct scsi_cmnd *remove_lun_SC(struct scsi_cmnd ** SC,
662 int target, int lun)
1da177e4 663{
91ebc1fa 664 struct scsi_cmnd *ptr, *prev;
1da177e4
LT
665
666 for (ptr = *SC, prev = NULL;
667 ptr && ((ptr->device->id != target) || (ptr->device->lun != lun));
668 prev = ptr, ptr = SCNEXT(ptr))
669 ;
670
671 if (ptr) {
672 if (prev)
673 SCNEXT(prev) = SCNEXT(ptr);
674 else
675 *SC = SCNEXT(ptr);
676
677 SCNEXT(ptr)=NULL;
678 }
679
680 return ptr;
681}
682
91ebc1fa
JT
683static inline struct scsi_cmnd *remove_SC(struct scsi_cmnd **SC,
684 struct scsi_cmnd *SCp)
1da177e4 685{
91ebc1fa 686 struct scsi_cmnd *ptr, *prev;
1da177e4
LT
687
688 for (ptr = *SC, prev = NULL;
689 ptr && SCp!=ptr;
690 prev = ptr, ptr = SCNEXT(ptr))
691 ;
692
693 if (ptr) {
694 if (prev)
695 SCNEXT(prev) = SCNEXT(ptr);
696 else
697 *SC = SCNEXT(ptr);
698
699 SCNEXT(ptr)=NULL;
700 }
701
702 return ptr;
703}
704
7d12e780 705static irqreturn_t swintr(int irqno, void *dev_id)
1da177e4 706{
c7bec5ab 707 struct Scsi_Host *shpnt = dev_id;
1da177e4
LT
708
709 HOSTDATA(shpnt)->swint++;
710
711 SETPORT(DMACNTRL0, INTEN);
712 return IRQ_HANDLED;
713}
714
715struct Scsi_Host *aha152x_probe_one(struct aha152x_setup *setup)
716{
717 struct Scsi_Host *shpnt;
718
719 shpnt = scsi_host_alloc(&aha152x_driver_template, sizeof(struct aha152x_hostdata));
720 if (!shpnt) {
721 printk(KERN_ERR "aha152x: scsi_host_alloc failed\n");
722 return NULL;
723 }
724
1da177e4 725 memset(HOSTDATA(shpnt), 0, sizeof *HOSTDATA(shpnt));
5fcda422
JB
726 INIT_LIST_HEAD(&HOSTDATA(shpnt)->host_list);
727
728 /* need to have host registered before triggering any interrupt */
729 list_add_tail(&HOSTDATA(shpnt)->host_list, &aha152x_host_list);
1da177e4
LT
730
731 shpnt->io_port = setup->io_port;
732 shpnt->n_io_port = IO_RANGE;
733 shpnt->irq = setup->irq;
734
735 if (!setup->tc1550) {
736 HOSTIOPORT0 = setup->io_port;
737 HOSTIOPORT1 = setup->io_port;
738 } else {
739 HOSTIOPORT0 = setup->io_port+0x10;
740 HOSTIOPORT1 = setup->io_port-0x10;
741 }
742
743 spin_lock_init(&QLOCK);
744 RECONNECT = setup->reconnect;
745 SYNCHRONOUS = setup->synchronous;
746 PARITY = setup->parity;
747 DELAY = setup->delay;
748 EXT_TRANS = setup->ext_trans;
749
1da177e4
LT
750 SETPORT(SCSIID, setup->scsiid << 4);
751 shpnt->this_id = setup->scsiid;
752
753 if (setup->reconnect)
754 shpnt->can_queue = AHA152X_MAXQUEUE;
755
756 /* RESET OUT */
757 printk("aha152x: resetting bus...\n");
758 SETPORT(SCSISEQ, SCSIRSTO);
759 mdelay(256);
760 SETPORT(SCSISEQ, 0);
761 mdelay(DELAY);
762
763 reset_ports(shpnt);
764
765 printk(KERN_INFO
766 "aha152x%d%s: "
767 "vital data: rev=%x, "
768 "io=0x%03lx (0x%03lx/0x%03lx), "
769 "irq=%d, "
770 "scsiid=%d, "
771 "reconnect=%s, "
772 "parity=%s, "
773 "synchronous=%s, "
774 "delay=%d, "
775 "extended translation=%s\n",
776 shpnt->host_no, setup->tc1550 ? " (tc1550 mode)" : "",
777 GETPORT(REV) & 0x7,
778 shpnt->io_port, HOSTIOPORT0, HOSTIOPORT1,
779 shpnt->irq,
780 shpnt->this_id,
781 RECONNECT ? "enabled" : "disabled",
782 PARITY ? "enabled" : "disabled",
783 SYNCHRONOUS ? "enabled" : "disabled",
784 DELAY,
785 EXT_TRANS ? "enabled" : "disabled");
786
787 /* not expecting any interrupts */
788 SETPORT(SIMODE0, 0);
789 SETPORT(SIMODE1, 0);
790
4909cc2b 791 if (request_irq(shpnt->irq, swintr, IRQF_SHARED, "aha152x", shpnt)) {
1da177e4
LT
792 printk(KERN_ERR "aha152x%d: irq %d busy.\n", shpnt->host_no, shpnt->irq);
793 goto out_host_put;
794 }
795
796 HOSTDATA(shpnt)->swint = 0;
797
798 printk(KERN_INFO "aha152x%d: trying software interrupt, ", shpnt->host_no);
799
800 mb();
801 SETPORT(DMACNTRL0, SWINT|INTEN);
802 mdelay(1000);
803 free_irq(shpnt->irq, shpnt);
804
805 if (!HOSTDATA(shpnt)->swint) {
806 if (TESTHI(DMASTAT, INTSTAT)) {
807 printk("lost.\n");
808 } else {
809 printk("failed.\n");
810 }
811
812 SETPORT(DMACNTRL0, INTEN);
813
814 printk(KERN_ERR "aha152x%d: irq %d possibly wrong. "
815 "Please verify.\n", shpnt->host_no, shpnt->irq);
816 goto out_host_put;
817 }
818 printk("ok.\n");
819
820
821 /* clear interrupts */
822 SETPORT(SSTAT0, 0x7f);
823 SETPORT(SSTAT1, 0xef);
824
4909cc2b 825 if (request_irq(shpnt->irq, intr, IRQF_SHARED, "aha152x", shpnt)) {
1da177e4
LT
826 printk(KERN_ERR "aha152x%d: failed to reassign irq %d.\n", shpnt->host_no, shpnt->irq);
827 goto out_host_put;
828 }
829
830 if( scsi_add_host(shpnt, NULL) ) {
831 free_irq(shpnt->irq, shpnt);
832 printk(KERN_ERR "aha152x%d: failed to add host.\n", shpnt->host_no);
833 goto out_host_put;
834 }
835
836 scsi_scan_host(shpnt);
837
1da177e4
LT
838 return shpnt;
839
840out_host_put:
5fcda422 841 list_del(&HOSTDATA(shpnt)->host_list);
1da177e4
LT
842 scsi_host_put(shpnt);
843
844 return NULL;
845}
846
847void aha152x_release(struct Scsi_Host *shpnt)
848{
1bd40573 849 if (!shpnt)
1da177e4
LT
850 return;
851
1bd40573 852 scsi_remove_host(shpnt);
1da177e4
LT
853 if (shpnt->irq)
854 free_irq(shpnt->irq, shpnt);
855
3eb2ebcb 856#if !defined(AHA152X_PCMCIA)
1da177e4
LT
857 if (shpnt->io_port)
858 release_region(shpnt->io_port, IO_RANGE);
859#endif
860
861#ifdef __ISAPNP__
862 if (HOSTDATA(shpnt)->pnpdev)
863 pnp_device_detach(HOSTDATA(shpnt)->pnpdev);
864#endif
865
5fcda422 866 list_del(&HOSTDATA(shpnt)->host_list);
1da177e4
LT
867 scsi_host_put(shpnt);
868}
869
870
871/*
872 * setup controller to generate interrupts depending
873 * on current state (lock has to be acquired)
874 *
f75ae8ed 875 */
1da177e4
LT
876static int setup_expected_interrupts(struct Scsi_Host *shpnt)
877{
878 if(CURRENT_SC) {
879 CURRENT_SC->SCp.phase |= 1 << 16;
f75ae8ed 880
1da177e4 881 if(CURRENT_SC->SCp.phase & selecting) {
1da177e4
LT
882 SETPORT(SSTAT1, SELTO);
883 SETPORT(SIMODE0, ENSELDO | (DISCONNECTED_SC ? ENSELDI : 0));
884 SETPORT(SIMODE1, ENSELTIMO);
885 } else {
1da177e4 886 SETPORT(SIMODE0, (CURRENT_SC->SCp.phase & spiordy) ? ENSPIORDY : 0);
f75ae8ed 887 SETPORT(SIMODE1, ENPHASEMIS | ENSCSIRST | ENSCSIPERR | ENBUSFREE);
1da177e4
LT
888 }
889 } else if(STATE==seldi) {
1da177e4 890 SETPORT(SIMODE0, 0);
f75ae8ed 891 SETPORT(SIMODE1, ENPHASEMIS | ENSCSIRST | ENSCSIPERR | ENBUSFREE);
1da177e4 892 } else {
1da177e4
LT
893 SETPORT(SIMODE0, DISCONNECTED_SC ? ENSELDI : 0);
894 SETPORT(SIMODE1, ENSCSIRST | ( (ISSUE_SC||DONE_SC) ? ENBUSFREE : 0));
895 }
896
897 if(!HOSTDATA(shpnt)->in_intr)
898 SETBITS(DMACNTRL0, INTEN);
899
900 return TESTHI(DMASTAT, INTSTAT);
901}
902
903
f75ae8ed 904/*
1da177e4
LT
905 * Queue a command and setup interrupts for a free bus.
906 */
91ebc1fa
JT
907static int aha152x_internal_queue(struct scsi_cmnd *SCpnt,
908 struct completion *complete,
909 int phase, void (*done)(struct scsi_cmnd *))
1da177e4
LT
910{
911 struct Scsi_Host *shpnt = SCpnt->device->host;
912 unsigned long flags;
913
1da177e4 914 SCpnt->scsi_done = done;
1da177e4 915 SCpnt->SCp.phase = not_issued | phase;
0ceb4798 916 SCpnt->SCp.Status = 0x1; /* Ilegal status by SCSI standard */
1da177e4
LT
917 SCpnt->SCp.Message = 0;
918 SCpnt->SCp.have_data_in = 0;
919 SCpnt->SCp.sent_command = 0;
920
921 if(SCpnt->SCp.phase & (resetting|check_condition)) {
172c122d 922 if (!SCpnt->host_scribble || SCSEM(SCpnt) || SCNEXT(SCpnt)) {
f75ae8ed 923 scmd_printk(KERN_ERR, SCpnt, "cannot reuse command\n");
1da177e4
LT
924 return FAILED;
925 }
926 } else {
927 SCpnt->host_scribble = kmalloc(sizeof(struct aha152x_scdata), GFP_ATOMIC);
172c122d 928 if(!SCpnt->host_scribble) {
f75ae8ed 929 scmd_printk(KERN_ERR, SCpnt, "allocation failed\n");
1da177e4
LT
930 return FAILED;
931 }
932 }
933
934 SCNEXT(SCpnt) = NULL;
0f06bb34 935 SCSEM(SCpnt) = complete;
1da177e4
LT
936
937 /* setup scratch area
938 SCp.ptr : buffer pointer
939 SCp.this_residual : buffer length
940 SCp.buffer : next buffer
1da177e4 941 SCp.phase : current state of the command */
66acdb03 942
73d2cb16
BH
943 if ((phase & resetting) || !scsi_sglist(SCpnt)) {
944 SCpnt->SCp.ptr = NULL;
945 SCpnt->SCp.this_residual = 0;
946 scsi_set_resid(SCpnt, 0);
66acdb03 947 SCpnt->SCp.buffer = NULL;
66acdb03 948 } else {
2338545a
BH
949 scsi_set_resid(SCpnt, scsi_bufflen(SCpnt));
950 SCpnt->SCp.buffer = scsi_sglist(SCpnt);
1da177e4
LT
951 SCpnt->SCp.ptr = SG_ADDRESS(SCpnt->SCp.buffer);
952 SCpnt->SCp.this_residual = SCpnt->SCp.buffer->length;
66acdb03 953 }
1da177e4
LT
954
955 DO_LOCK(flags);
956
957#if defined(AHA152X_STAT)
958 HOSTDATA(shpnt)->total_commands++;
959#endif
960
961 /* Turn led on, when this is the first command. */
962 HOSTDATA(shpnt)->commands++;
963 if (HOSTDATA(shpnt)->commands==1)
964 SETPORT(PORTA, 1);
965
966 append_SC(&ISSUE_SC, SCpnt);
967
968 if(!HOSTDATA(shpnt)->in_intr)
969 setup_expected_interrupts(shpnt);
970
971 DO_UNLOCK(flags);
972
973 return 0;
974}
975
976/*
977 * queue a command
978 *
979 */
91ebc1fa
JT
980static int aha152x_queue_lck(struct scsi_cmnd *SCpnt,
981 void (*done)(struct scsi_cmnd *))
1da177e4 982{
1da177e4
LT
983 return aha152x_internal_queue(SCpnt, NULL, 0, done);
984}
985
f281233d
JG
986static DEF_SCSI_QCMD(aha152x_queue)
987
1da177e4
LT
988
989/*
1da177e4
LT
990 *
991 */
91ebc1fa 992static void reset_done(struct scsi_cmnd *SCpnt)
1da177e4 993{
1da177e4 994 if(SCSEM(SCpnt)) {
0f06bb34 995 complete(SCSEM(SCpnt));
1da177e4 996 } else {
0f06bb34 997 printk(KERN_ERR "aha152x: reset_done w/o completion\n");
1da177e4
LT
998 }
999}
1000
1001/*
1002 * Abort a command
1003 *
1004 */
91ebc1fa 1005static int aha152x_abort(struct scsi_cmnd *SCpnt)
1da177e4
LT
1006{
1007 struct Scsi_Host *shpnt = SCpnt->device->host;
91ebc1fa 1008 struct scsi_cmnd *ptr;
1da177e4
LT
1009 unsigned long flags;
1010
1da177e4
LT
1011 DO_LOCK(flags);
1012
1013 ptr=remove_SC(&ISSUE_SC, SCpnt);
1014
1015 if(ptr) {
1da177e4
LT
1016 HOSTDATA(shpnt)->commands--;
1017 if (!HOSTDATA(shpnt)->commands)
1018 SETPORT(PORTA, 0);
1019 DO_UNLOCK(flags);
1020
1021 kfree(SCpnt->host_scribble);
1022 SCpnt->host_scribble=NULL;
1023
1024 return SUCCESS;
f75ae8ed 1025 }
1da177e4
LT
1026
1027 DO_UNLOCK(flags);
1028
1029 /*
1030 * FIXME:
1031 * for current command: queue ABORT for message out and raise ATN
1032 * for disconnected command: pseudo SC with ABORT message or ABORT on reselection?
1033 *
1034 */
1035
f75ae8ed
HR
1036 scmd_printk(KERN_ERR, SCpnt,
1037 "cannot abort running or disconnected command\n");
1da177e4
LT
1038
1039 return FAILED;
1040}
1041
1da177e4
LT
1042/*
1043 * Reset a device
1044 *
1045 */
91ebc1fa 1046static int aha152x_device_reset(struct scsi_cmnd * SCpnt)
1da177e4
LT
1047{
1048 struct Scsi_Host *shpnt = SCpnt->device->host;
0f06bb34 1049 DECLARE_COMPLETION(done);
1da177e4 1050 int ret, issued, disconnected;
631c228c 1051 unsigned char old_cmd_len = SCpnt->cmd_len;
1da177e4 1052 unsigned long flags;
0f06bb34 1053 unsigned long timeleft;
1da177e4 1054
1da177e4 1055 if(CURRENT_SC==SCpnt) {
f75ae8ed 1056 scmd_printk(KERN_ERR, SCpnt, "cannot reset current device\n");
1da177e4
LT
1057 return FAILED;
1058 }
1059
1060 DO_LOCK(flags);
172c122d 1061 issued = remove_SC(&ISSUE_SC, SCpnt) == NULL;
1da177e4
LT
1062 disconnected = issued && remove_SC(&DISCONNECTED_SC, SCpnt);
1063 DO_UNLOCK(flags);
1064
1065 SCpnt->cmd_len = 0;
1da177e4 1066
0f06bb34 1067 aha152x_internal_queue(SCpnt, &done, resetting, reset_done);
1da177e4 1068
0f06bb34
CH
1069 timeleft = wait_for_completion_timeout(&done, 100*HZ);
1070 if (!timeleft) {
1071 /* remove command from issue queue */
1072 DO_LOCK(flags);
1073 remove_SC(&ISSUE_SC, SCpnt);
1074 DO_UNLOCK(flags);
1075 }
631c228c
CH
1076
1077 SCpnt->cmd_len = old_cmd_len;
1da177e4
LT
1078
1079 DO_LOCK(flags);
1080
1081 if(SCpnt->SCp.phase & resetted) {
1082 HOSTDATA(shpnt)->commands--;
1083 if (!HOSTDATA(shpnt)->commands)
1084 SETPORT(PORTA, 0);
1085 kfree(SCpnt->host_scribble);
1086 SCpnt->host_scribble=NULL;
1087
1088 ret = SUCCESS;
1089 } else {
1090 /* requeue */
1091 if(!issued) {
1092 append_SC(&ISSUE_SC, SCpnt);
1093 } else if(disconnected) {
1094 append_SC(&DISCONNECTED_SC, SCpnt);
1095 }
f75ae8ed 1096
1da177e4
LT
1097 ret = FAILED;
1098 }
1099
1100 DO_UNLOCK(flags);
1da177e4
LT
1101 return ret;
1102}
1103
91ebc1fa
JT
1104static void free_hard_reset_SCs(struct Scsi_Host *shpnt,
1105 struct scsi_cmnd **SCs)
1da177e4 1106{
91ebc1fa 1107 struct scsi_cmnd *ptr;
1da177e4
LT
1108
1109 ptr=*SCs;
1110 while(ptr) {
91ebc1fa 1111 struct scsi_cmnd *next;
1da177e4
LT
1112
1113 if(SCDATA(ptr)) {
1114 next = SCNEXT(ptr);
1115 } else {
f75ae8ed
HR
1116 scmd_printk(KERN_DEBUG, ptr,
1117 "queue corrupted at %p\n", ptr);
1da177e4
LT
1118 next = NULL;
1119 }
1120
1121 if (!ptr->device->soft_reset) {
1da177e4
LT
1122 remove_SC(SCs, ptr);
1123 HOSTDATA(shpnt)->commands--;
1124 kfree(ptr->host_scribble);
1125 ptr->host_scribble=NULL;
1126 }
1127
1128 ptr = next;
1129 }
1130}
1131
1132/*
1133 * Reset the bus
1134 *
819f80c9
HR
1135 * AIC-6260 has a hard reset (MRST signal), but apparently
1136 * one cannot trigger it via software. So live with
1137 * a soft reset; no-one seemed to have cared.
1da177e4 1138 */