brintos

brintos / linux-shallow public Read only

0
0
Text · 82.7 KiB · a0fb330 Raw
3429 lines · c
1// SPDX-License-Identifier: GPL-2.0-or-later2/* aha152x.c -- Adaptec AHA-152x driver3 * Author: Jürgen E. Fischer, fischer@norbit.de4 * Copyright 1993-2004 Jürgen E. Fischer5 *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  fischer10 * - gather code that is not used by PCMCIA at the end11 * - move request_region for !PCMCIA case to detection12 * - migration to new scsi host api (remove legacy code)13 * - free host scribble before scsi_done14 * - fix error handling15 * - one isapnp device added to id_table16 *17 * Revision 2.6  2003/10/30 20:52:47  fischer18 * - interfaces changes for kernel 2.619 * - aha152x_probe_one introduced for pcmcia stub20 * - fixed pnpdev handling21 * - instead of allocation a new one, reuse command for request sense after check condition and reset22 * - fixes race in is_complete23 *24 * Revision 2.5  2002/04/14 11:24:53  fischer25 * - isapnp support26 * - abort fixed27 * - 2.5 support28 *29 * Revision 2.4  2000/12/16 12:53:56  fischer30 * - allow REQUEST SENSE to be queued31 * - handle shared PCI interrupts32 *33 * Revision 2.3  2000/11/04 16:40:26  fischer34 * - handle data overruns35 * - extend timeout for data phases36 *37 * Revision 2.2  2000/08/08 19:54:53  fischer38 * - minor changes39 *40 * Revision 2.1  2000/05/17 16:23:17  fischer41 * - signature update42 * - fix for data out w/o scatter gather43 *44 * Revision 2.0  1999/12/25 15:07:32  fischer45 * - interrupt routine completly reworked46 * - basic support for new eh code47 *48 * Revision 1.21  1999/11/10 23:46:36  fischer49 * - default to synchronous operation50 * - synchronous negotiation fixed51 * - added timeout to loops52 * - debugging output can be controlled through procfs53 *54 * Revision 1.20  1999/11/07 18:37:31  fischer55 * - synchronous operation works56 * - resid support for sg driver57 *58 * Revision 1.19  1999/11/02 22:39:59  fischer59 * - moved leading comments to README.aha152x60 * - new additional module parameters61 * - updates for 2.362 * - support for the Tripace TC1550 controller63 * - interrupt handling changed64 *65 * Revision 1.18  1996/09/07 20:10:40  fischer66 * - fixed can_queue handling (multiple outstanding commands working again)67 *68 * Revision 1.17  1996/08/17 16:05:14  fischer69 * - biosparam improved70 * - interrupt verification71 * - updated documentation72 * - cleanups73 *74 * Revision 1.16  1996/06/09 00:04:56  root75 * - added configuration symbols for insmod (aha152x/aha152x1)76 *77 * Revision 1.15  1996/04/30 14:52:06  fischer78 * - proc info fixed79 * - support for extended translation for >1GB disks80 *81 * Revision 1.14  1996/01/17  15:11:20  fischer82 * - fixed lockup in MESSAGE IN phase after reconnection83 *84 * Revision 1.13  1996/01/09  02:15:53  fischer85 * - some cleanups86 * - moved request_irq behind controller initialization87 *   (to avoid spurious interrupts)88 *89 * Revision 1.12  1995/12/16  12:26:07  fischer90 * - barrier()s added91 * - configurable RESET delay added92 *93 * Revision 1.11  1995/12/06  21:18:35  fischer94 * - some minor updates95 *96 * Revision 1.10  1995/07/22  19:18:45  fischer97 * - support for 2 controllers98 * - started synchronous data transfers (not working yet)99 *100 * Revision 1.9  1995/03/18  09:20:24  root101 * - patches for PCMCIA and modules102 *103 * Revision 1.8  1995/01/21  22:07:19  root104 * - snarf_region => request_region105 * - aha152x_intr interface change106 *107 * Revision 1.7  1995/01/02  23:19:36  root108 * - updated COMMAND_SIZE to cmd_len109 * - changed sti() to restore_flags()110 * - fixed some #ifdef which generated warnings111 *112 * Revision 1.6  1994/11/24  20:35:27  root113 * - problem with odd number of bytes in fifo fixed114 *115 * Revision 1.5  1994/10/30  14:39:56  root116 * - abort code fixed117 * - debugging improved118 *119 * Revision 1.4  1994/09/12  11:33:01  root120 * - irqaction to request_irq121 * - abortion updated122 *123 * Revision 1.3  1994/08/04  13:53:05  root124 * - updates for mid-level-driver changes125 * - accept unexpected BUSFREE phase as error condition126 * - parity check now configurable127 *128 * Revision 1.2  1994/07/03  12:56:36  root129 * - cleaned up debugging code130 * - more tweaking on reset delays131 * - updated abort/reset code (pretty untested...)132 *133 * Revision 1.1  1994/05/28  21:18:49  root134 * - update for mid-level interface change (abort-reset)135 * - delays after resets adjusted for some slow devices136 *137 * Revision 1.0  1994/03/25  12:52:00  root138 * - Fixed "more data than expected" problem139 * - added new BIOS signatures140 *141 * Revision 0.102  1994/01/31  20:44:12  root142 * - minor changes in insw/outsw handling143 *144 * Revision 0.101  1993/12/13  01:16:27  root145 * - 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  root149 * - fix for unsuccessful selections in case of non-continuous id assignments150 *   on the scsi bus.151 *152 * Revision 0.99  1993/10/24  16:19:59  root153 * - fixed DATA IN (rare read errors gone)154 *155 * Revision 0.98  1993/10/17  12:54:44  root156 * - fixed some recent fixes (shame on me)157 * - moved initialization of scratch area to aha152x_queue158 *159 * Revision 0.97  1993/10/09  18:53:53  root160 * - DATA IN fixed. Rarely left data in the fifo.161 *162 * Revision 0.96  1993/10/03  00:53:59  root163 * - minor changes on DATA IN164 *165 * Revision 0.95  1993/09/24  10:36:01  root166 * - change handling of MSGI after reselection167 * - fixed sti/cli168 * - minor changes169 *170 * Revision 0.94  1993/09/18  14:08:22  root171 * - fixed bug in multiple outstanding command code172 * - changed detection173 * - support for kernel command line configuration174 * - reset corrected175 * - changed message handling176 *177 * Revision 0.93  1993/09/15  20:41:19  root178 * - fixed bugs with multiple outstanding commands179 *180 * Revision 0.92  1993/09/13  02:46:33  root181 * - multiple outstanding commands work (no problems with IBM drive)182 *183 * Revision 0.91  1993/09/12  20:51:46  root184 * added multiple outstanding commands185 * (some problem with this $%&? IBM device remain)186 *187 * Revision 0.9  1993/09/12  11:11:22  root188 * - corrected auto-configuration189 * - changed the auto-configuration (added some '#define's)190 * - added support for dis-/reconnection191 *192 * Revision 0.8  1993/09/06  23:09:39  root193 * - added support for the drive activity light194 * - minor changes195 *196 * Revision 0.7  1993/09/05  14:30:15  root197 * - improved phase detection198 * - now using the new snarf_region code of 0.99pl13199 *200 * Revision 0.6  1993/09/02  11:01:38  root201 * first public release; added some signatures and biosparam()202 *203 * Revision 0.5  1993/08/30  10:23:30  root204 * fixed timing problems with my IBM drive205 *206 * Revision 0.4  1993/08/29  14:06:52  root207 * fixed some problems with timeouts due incomplete commands208 *209 * Revision 0.3  1993/08/28  15:55:03  root210 * writing data works too.  mounted and worked on a dos partition211 *212 * Revision 0.2  1993/08/27  22:42:07  root213 * reading data works.  Mounted a msdos partition.214 *215 * Revision 0.1  1993/08/25  13:38:30  root216 * first "damn thing doesn't work" version217 *218 * Revision 0.0  1993/08/14  19:54:25  root219 * empty function bodies; detect() works.220 *221 **************************************************************************222 223 see Documentation/scsi/aha152x.rst for configuration details224 225 **************************************************************************/226 227#include <linux/module.h>228#include <asm/irq.h>229#include <linux/io.h>230#include <linux/blkdev.h>231#include <linux/completion.h>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>244#include <linux/list.h>245#include <linux/slab.h>246 247#include <scsi/scsi.h>248#include <scsi/scsi_cmnd.h>249#include <scsi/scsi_dbg.h>250#include <scsi/scsi_device.h>251#include <scsi/scsi_eh.h>252#include <scsi/scsi_host.h>253#include <scsi/scsi_tcq.h>254#include <scsi/scsi_transport_spi.h>255#include <scsi/scsicam.h>256#include "aha152x.h"257 258static LIST_HEAD(aha152x_host_list);259 260 261/* DEFINES */262 263/* For PCMCIA cards, always use AUTOCONF */264#if defined(AHA152X_PCMCIA) || defined(MODULE)265#if !defined(AUTOCONF)266#define AUTOCONF267#endif268#endif269 270#if !defined(AUTOCONF) && !defined(SETUP0)271#error define AUTOCONF or SETUP0272#endif273 274#define	DO_LOCK(flags)		spin_lock_irqsave(&QLOCK,flags)275#define	DO_UNLOCK(flags)	spin_unlock_irqrestore(&QLOCK,flags)276 277#define LEAD		"(scsi%d:%d:%d) "278#define INFO_LEAD	KERN_INFO	LEAD279#define CMDINFO(cmd) \280			(cmd) ? ((cmd)->device->host->host_no) : -1, \281                        (cmd) ? ((cmd)->device->id & 0x0f) : -1, \282			(cmd) ? ((u8)(cmd)->device->lun & 0x07) : -1283 284static inline void285CMD_INC_RESID(struct scsi_cmnd *cmd, int inc)286{287	scsi_set_resid(cmd, scsi_get_resid(cmd) + inc);288}289 290#define DELAY_DEFAULT 1000291 292#if defined(AHA152X_PCMCIA)293#define IRQ_MIN 0294#define IRQ_MAX 16295#else296#define IRQ_MIN 9297#if defined(__PPC)298#define IRQ_MAX (nr_irqs-1)299#else300#define IRQ_MAX 12301#endif302#endif303 304enum {305	not_issued	= 0x0001,	/* command not yet issued */306	selecting	= 0x0002,	/* target is being selected */307	identified	= 0x0004,	/* IDENTIFY was sent */308	disconnected	= 0x0008,	/* target disconnected */309	completed	= 0x0010,	/* target sent COMMAND COMPLETE */310	aborted		= 0x0020,	/* ABORT was sent */311	resetted	= 0x0040,	/* BUS DEVICE RESET was sent */312	spiordy		= 0x0080,	/* waiting for SPIORDY to raise */313	syncneg		= 0x0100,	/* synchronous negotiation in progress */314	aborting	= 0x0200,	/* ABORT is pending */315	resetting	= 0x0400,	/* BUS DEVICE RESET is pending */316	check_condition = 0x0800,	/* requesting sense after CHECK CONDITION */317};318 319struct aha152x_cmd_priv {320	char *ptr;321	int this_residual;322	struct scatterlist *buffer;323	int status;324	int message;325	int sent_command;326	int phase;327};328 329static struct aha152x_cmd_priv *aha152x_priv(struct scsi_cmnd *cmd)330{331	return scsi_cmd_priv(cmd);332}333 334MODULE_AUTHOR("Jürgen Fischer");335MODULE_DESCRIPTION(AHA152X_REVID);336MODULE_LICENSE("GPL");337 338#if !defined(AHA152X_PCMCIA)339#if defined(MODULE)340static int io[] = {0, 0};341module_param_hw_array(io, int, ioport, NULL, 0);342MODULE_PARM_DESC(io,"base io address of controller");343 344static int irq[] = {0, 0};345module_param_hw_array(irq, int, irq, NULL, 0);346MODULE_PARM_DESC(irq,"interrupt for controller");347 348static int scsiid[] = {7, 7};349module_param_array(scsiid, int, NULL, 0);350MODULE_PARM_DESC(scsiid,"scsi id of controller");351 352static int reconnect[] = {1, 1};353module_param_array(reconnect, int, NULL, 0);354MODULE_PARM_DESC(reconnect,"allow targets to disconnect");355 356static int parity[] = {1, 1};357module_param_array(parity, int, NULL, 0);358MODULE_PARM_DESC(parity,"use scsi parity");359 360static int sync[] = {1, 1};361module_param_array(sync, int, NULL, 0);362MODULE_PARM_DESC(sync,"use synchronous transfers");363 364static int delay[] = {DELAY_DEFAULT, DELAY_DEFAULT};365module_param_array(delay, int, NULL, 0);366MODULE_PARM_DESC(delay,"scsi reset delay");367 368static int exttrans[] = {0, 0};369module_param_array(exttrans, int, NULL, 0);370MODULE_PARM_DESC(exttrans,"use extended translation");371 372static int aha152x[] = {0, 11, 7, 1, 1, 0, DELAY_DEFAULT, 0};373module_param_array(aha152x, int, NULL, 0);374MODULE_PARM_DESC(aha152x, "parameters for first controller");375 376static int aha152x1[] = {0, 11, 7, 1, 1, 0, DELAY_DEFAULT, 0};377module_param_array(aha152x1, int, NULL, 0);378MODULE_PARM_DESC(aha152x1, "parameters for second controller");379#endif /* MODULE */380 381#ifdef __ISAPNP__382static struct isapnp_device_id id_table[] = {383	{ ISAPNP_ANY_ID, ISAPNP_ANY_ID,	ISAPNP_VENDOR('A', 'D', 'P'), ISAPNP_FUNCTION(0x1502), 0 },384	{ ISAPNP_ANY_ID, ISAPNP_ANY_ID,	ISAPNP_VENDOR('A', 'D', 'P'), ISAPNP_FUNCTION(0x1505), 0 },385	{ ISAPNP_ANY_ID, ISAPNP_ANY_ID,	ISAPNP_VENDOR('A', 'D', 'P'), ISAPNP_FUNCTION(0x1510), 0 },386	{ ISAPNP_ANY_ID, ISAPNP_ANY_ID,	ISAPNP_VENDOR('A', 'D', 'P'), ISAPNP_FUNCTION(0x1515), 0 },387	{ ISAPNP_ANY_ID, ISAPNP_ANY_ID,	ISAPNP_VENDOR('A', 'D', 'P'), ISAPNP_FUNCTION(0x1520), 0 },388	{ ISAPNP_ANY_ID, ISAPNP_ANY_ID,	ISAPNP_VENDOR('A', 'D', 'P'), ISAPNP_FUNCTION(0x2015), 0 },389	{ ISAPNP_ANY_ID, ISAPNP_ANY_ID,	ISAPNP_VENDOR('A', 'D', 'P'), ISAPNP_FUNCTION(0x1522), 0 },390	{ ISAPNP_ANY_ID, ISAPNP_ANY_ID,	ISAPNP_VENDOR('A', 'D', 'P'), ISAPNP_FUNCTION(0x2215), 0 },391	{ ISAPNP_ANY_ID, ISAPNP_ANY_ID,	ISAPNP_VENDOR('A', 'D', 'P'), ISAPNP_FUNCTION(0x1530), 0 },392	{ ISAPNP_ANY_ID, ISAPNP_ANY_ID,	ISAPNP_VENDOR('A', 'D', 'P'), ISAPNP_FUNCTION(0x3015), 0 },393	{ ISAPNP_ANY_ID, ISAPNP_ANY_ID,	ISAPNP_VENDOR('A', 'D', 'P'), ISAPNP_FUNCTION(0x1532), 0 },394	{ ISAPNP_ANY_ID, ISAPNP_ANY_ID,	ISAPNP_VENDOR('A', 'D', 'P'), ISAPNP_FUNCTION(0x3215), 0 },395	{ ISAPNP_ANY_ID, ISAPNP_ANY_ID,	ISAPNP_VENDOR('A', 'D', 'P'), ISAPNP_FUNCTION(0x6360), 0 },396	{ ISAPNP_DEVICE_SINGLE_END, }397};398MODULE_DEVICE_TABLE(isapnp, id_table);399#endif /* ISAPNP */400 401#endif /* !AHA152X_PCMCIA */402 403static const struct scsi_host_template aha152x_driver_template;404 405/*406 * internal states of the host407 *408 */409enum aha152x_state {410	idle=0,411	unknown,412	seldo,413	seldi,414	selto,415	busfree,416	msgo,417	cmd,418	msgi,419	status,420	datai,421	datao,422	parerr,423	rsti,424	maxstate425};426 427/*428 * current state information of the host429 *430 */431struct aha152x_hostdata {432	struct scsi_cmnd *issue_SC;433		/* pending commands to issue */434 435	struct scsi_cmnd *current_SC;436		/* current command on the bus */437 438	struct scsi_cmnd *disconnected_SC;439		/* commands that disconnected */440 441	struct scsi_cmnd *done_SC;442		/* command that was completed */443 444	spinlock_t lock;445		/* host lock */446 447#if defined(AHA152X_STAT)448	int	      total_commands;449	int	      disconnections;450	int	      busfree_without_any_action;451	int	      busfree_without_old_command;452	int	      busfree_without_new_command;453	int	      busfree_without_done_command;454	int	      busfree_with_check_condition;455	int	      count[maxstate];456	int	      count_trans[maxstate];457	unsigned long time[maxstate];458#endif459 460	int commands;		/* current number of commands */461 462	int reconnect;		/* disconnection allowed */463	int parity;		/* parity checking enabled */464	int synchronous;	/* synchronous transferes enabled */465	int delay;		/* reset out delay */466	int ext_trans;		/* extended translation enabled */467 468	int swint;		/* software-interrupt was fired during detect() */469	int service;		/* bh needs to be run */470	int in_intr;		/* bh is running */471 472	/* current state,473	   previous state,474	   last state different from current state */475	enum aha152x_state state, prevstate, laststate;476 477	int target;478		/* reconnecting target */479 480	unsigned char syncrate[8];481		/* current synchronous transfer agreements */482 483	unsigned char syncneg[8];484		/* 0: no negotiation;485		 * 1: negotiation in progress;486		 * 2: negotiation completed487		 */488 489	int cmd_i;490		/* number of sent bytes of current command */491 492	int msgi_len;493		/* number of received message bytes */494	unsigned char msgi[256];495		/* received message bytes */496 497	int msgo_i, msgo_len;498		/* number of sent bytes and length of current messages */499	unsigned char msgo[256];500		/* pending messages */501 502	int data_len;503		/* number of sent/received bytes in dataphase */504 505	unsigned long io_port0;506	unsigned long io_port1;507 508#ifdef __ISAPNP__509	struct pnp_dev *pnpdev;510#endif511	struct list_head host_list;512};513 514 515/*516 * host specific command extension517 *518 */519struct aha152x_scdata {520	struct scsi_cmnd *next;	/* next sc in queue */521	struct completion *done;/* semaphore to block on */522	struct scsi_eh_save ses;523};524 525/* access macros for hostdata */526 527#define HOSTDATA(shpnt)		((struct aha152x_hostdata *) &shpnt->hostdata)528 529#define HOSTNO			((shpnt)->host_no)530 531#define CURRENT_SC		(HOSTDATA(shpnt)->current_SC)532#define DONE_SC			(HOSTDATA(shpnt)->done_SC)533#define ISSUE_SC		(HOSTDATA(shpnt)->issue_SC)534#define DISCONNECTED_SC		(HOSTDATA(shpnt)->disconnected_SC)535#define QLOCK			(HOSTDATA(shpnt)->lock)536#define QLOCKER			(HOSTDATA(shpnt)->locker)537#define QLOCKERL		(HOSTDATA(shpnt)->lockerl)538 539#define STATE			(HOSTDATA(shpnt)->state)540#define PREVSTATE		(HOSTDATA(shpnt)->prevstate)541#define LASTSTATE		(HOSTDATA(shpnt)->laststate)542 543#define RECONN_TARGET		(HOSTDATA(shpnt)->target)544 545#define CMD_I			(HOSTDATA(shpnt)->cmd_i)546 547#define MSGO(i)			(HOSTDATA(shpnt)->msgo[i])548#define MSGO_I			(HOSTDATA(shpnt)->msgo_i)549#define MSGOLEN			(HOSTDATA(shpnt)->msgo_len)550#define ADDMSGO(x)		(MSGOLEN<256 ? (void)(MSGO(MSGOLEN++)=x) : aha152x_error(shpnt,"MSGO overflow"))551 552#define MSGI(i)			(HOSTDATA(shpnt)->msgi[i])553#define MSGILEN			(HOSTDATA(shpnt)->msgi_len)554#define ADDMSGI(x)		(MSGILEN<256 ? (void)(MSGI(MSGILEN++)=x) : aha152x_error(shpnt,"MSGI overflow"))555 556#define DATA_LEN		(HOSTDATA(shpnt)->data_len)557 558#define SYNCRATE		(HOSTDATA(shpnt)->syncrate[CURRENT_SC->device->id])559#define SYNCNEG			(HOSTDATA(shpnt)->syncneg[CURRENT_SC->device->id])560 561#define DELAY			(HOSTDATA(shpnt)->delay)562#define EXT_TRANS		(HOSTDATA(shpnt)->ext_trans)563#define TC1550			(HOSTDATA(shpnt)->tc1550)564#define RECONNECT		(HOSTDATA(shpnt)->reconnect)565#define PARITY			(HOSTDATA(shpnt)->parity)566#define SYNCHRONOUS		(HOSTDATA(shpnt)->synchronous)567 568#define HOSTIOPORT0		(HOSTDATA(shpnt)->io_port0)569#define HOSTIOPORT1		(HOSTDATA(shpnt)->io_port1)570 571#define SCDATA(SCpnt)		((struct aha152x_scdata *) (SCpnt)->host_scribble)572#define SCNEXT(SCpnt)		SCDATA(SCpnt)->next573#define SCSEM(SCpnt)		SCDATA(SCpnt)->done574 575#define SG_ADDRESS(buffer)	((char *) sg_virt((buffer)))576 577/* state handling */578static void seldi_run(struct Scsi_Host *shpnt);579static void seldo_run(struct Scsi_Host *shpnt);580static void selto_run(struct Scsi_Host *shpnt);581static void busfree_run(struct Scsi_Host *shpnt);582 583static void msgo_init(struct Scsi_Host *shpnt);584static void msgo_run(struct Scsi_Host *shpnt);585static void msgo_end(struct Scsi_Host *shpnt);586 587static void cmd_init(struct Scsi_Host *shpnt);588static void cmd_run(struct Scsi_Host *shpnt);589static void cmd_end(struct Scsi_Host *shpnt);590 591static void datai_init(struct Scsi_Host *shpnt);592static void datai_run(struct Scsi_Host *shpnt);593static void datai_end(struct Scsi_Host *shpnt);594 595static void datao_init(struct Scsi_Host *shpnt);596static void datao_run(struct Scsi_Host *shpnt);597static void datao_end(struct Scsi_Host *shpnt);598 599static void status_run(struct Scsi_Host *shpnt);600 601static void msgi_run(struct Scsi_Host *shpnt);602static void msgi_end(struct Scsi_Host *shpnt);603 604static void parerr_run(struct Scsi_Host *shpnt);605static void rsti_run(struct Scsi_Host *shpnt);606 607static void is_complete(struct Scsi_Host *shpnt);608 609/*610 * driver states611 *612 */613static struct {614	char		*name;615	void		(*init)(struct Scsi_Host *);616	void		(*run)(struct Scsi_Host *);617	void		(*end)(struct Scsi_Host *);618	int		spio;619} states[] = {620	{ "idle",	NULL,		NULL,		NULL,		0},621	{ "unknown",	NULL,		NULL,		NULL,		0},622	{ "seldo",	NULL,		seldo_run,	NULL,		0},623	{ "seldi",	NULL,		seldi_run,	NULL,		0},624	{ "selto",	NULL,		selto_run,	NULL,		0},625	{ "busfree",	NULL,		busfree_run,	NULL,		0},626	{ "msgo",	msgo_init,	msgo_run,	msgo_end,	1},627	{ "cmd",	cmd_init,	cmd_run,	cmd_end,	1},628	{ "msgi",	NULL,		msgi_run,	msgi_end,	1},629	{ "status",	NULL,		status_run,	NULL,		1},630	{ "datai",	datai_init,	datai_run,	datai_end,	0},631	{ "datao",	datao_init,	datao_run,	datao_end,	0},632	{ "parerr",	NULL,		parerr_run,	NULL,		0},633	{ "rsti",	NULL,		rsti_run,	NULL,		0},634};635 636/* setup & interrupt */637static irqreturn_t intr(int irq, void *dev_id);638static void reset_ports(struct Scsi_Host *shpnt);639static void aha152x_error(struct Scsi_Host *shpnt, char *msg);640static void done(struct Scsi_Host *shpnt, unsigned char status_byte,641		 unsigned char host_byte);642 643/* diagnostics */644static void show_command(struct scsi_cmnd * ptr);645static void show_queues(struct Scsi_Host *shpnt);646static void disp_enintr(struct Scsi_Host *shpnt);647 648 649/*650 *  queue services:651 *652 */653static inline void append_SC(struct scsi_cmnd **SC, struct scsi_cmnd *new_SC)654{655	struct scsi_cmnd *end;656 657	SCNEXT(new_SC) = NULL;658	if (!*SC)659		*SC = new_SC;660	else {661		for (end = *SC; SCNEXT(end); end = SCNEXT(end))662			;663		SCNEXT(end) = new_SC;664	}665}666 667static inline struct scsi_cmnd *remove_first_SC(struct scsi_cmnd ** SC)668{669	struct scsi_cmnd *ptr;670 671	ptr = *SC;672	if (ptr) {673		*SC = SCNEXT(*SC);674		SCNEXT(ptr)=NULL;675	}676	return ptr;677}678 679static inline struct scsi_cmnd *remove_lun_SC(struct scsi_cmnd ** SC,680					      int target, int lun)681{682	struct scsi_cmnd *ptr, *prev;683 684	for (ptr = *SC, prev = NULL;685	     ptr && ((ptr->device->id != target) || (ptr->device->lun != lun));686	     prev = ptr, ptr = SCNEXT(ptr))687	     ;688 689	if (ptr) {690		if (prev)691			SCNEXT(prev) = SCNEXT(ptr);692		else693			*SC = SCNEXT(ptr);694 695		SCNEXT(ptr)=NULL;696	}697 698	return ptr;699}700 701static inline struct scsi_cmnd *remove_SC(struct scsi_cmnd **SC,702					  struct scsi_cmnd *SCp)703{704	struct scsi_cmnd *ptr, *prev;705 706	for (ptr = *SC, prev = NULL;707	     ptr && SCp!=ptr;708	     prev = ptr, ptr = SCNEXT(ptr))709	     ;710 711	if (ptr) {712		if (prev)713			SCNEXT(prev) = SCNEXT(ptr);714		else715			*SC = SCNEXT(ptr);716 717		SCNEXT(ptr)=NULL;718	}719 720	return ptr;721}722 723static irqreturn_t swintr(int irqno, void *dev_id)724{725	struct Scsi_Host *shpnt = dev_id;726 727	HOSTDATA(shpnt)->swint++;728 729	SETPORT(DMACNTRL0, INTEN);730	return IRQ_HANDLED;731}732 733struct Scsi_Host *aha152x_probe_one(struct aha152x_setup *setup)734{735	struct Scsi_Host *shpnt;736 737	shpnt = scsi_host_alloc(&aha152x_driver_template, sizeof(struct aha152x_hostdata));738	if (!shpnt) {739		printk(KERN_ERR "aha152x: scsi_host_alloc failed\n");740		return NULL;741	}742 743	memset(HOSTDATA(shpnt), 0, sizeof *HOSTDATA(shpnt));744	INIT_LIST_HEAD(&HOSTDATA(shpnt)->host_list);745 746	/* need to have host registered before triggering any interrupt */747	list_add_tail(&HOSTDATA(shpnt)->host_list, &aha152x_host_list);748 749	shpnt->no_highmem = true;750	shpnt->io_port   = setup->io_port;751	shpnt->n_io_port = IO_RANGE;752	shpnt->irq       = setup->irq;753 754	if (!setup->tc1550) {755		HOSTIOPORT0 = setup->io_port;756		HOSTIOPORT1 = setup->io_port;757	} else {758		HOSTIOPORT0 = setup->io_port+0x10;759		HOSTIOPORT1 = setup->io_port-0x10;760	}761 762	spin_lock_init(&QLOCK);763	RECONNECT   = setup->reconnect;764	SYNCHRONOUS = setup->synchronous;765	PARITY      = setup->parity;766	DELAY       = setup->delay;767	EXT_TRANS   = setup->ext_trans;768 769	SETPORT(SCSIID, setup->scsiid << 4);770	shpnt->this_id = setup->scsiid;771 772	if (setup->reconnect)773		shpnt->can_queue = AHA152X_MAXQUEUE;774 775	/* RESET OUT */776	printk("aha152x: resetting bus...\n");777	SETPORT(SCSISEQ, SCSIRSTO);778	mdelay(256);779	SETPORT(SCSISEQ, 0);780	mdelay(DELAY);781 782	reset_ports(shpnt);783 784	printk(KERN_INFO785	       "aha152x%d%s: "786	       "vital data: rev=%x, "787	       "io=0x%03lx (0x%03lx/0x%03lx), "788	       "irq=%d, "789	       "scsiid=%d, "790	       "reconnect=%s, "791	       "parity=%s, "792	       "synchronous=%s, "793	       "delay=%d, "794	       "extended translation=%s\n",795	       shpnt->host_no, setup->tc1550 ? " (tc1550 mode)" : "",796	       GETPORT(REV) & 0x7,797	       shpnt->io_port, HOSTIOPORT0, HOSTIOPORT1,798	       shpnt->irq,799	       shpnt->this_id,800	       RECONNECT ? "enabled" : "disabled",801	       PARITY ? "enabled" : "disabled",802	       SYNCHRONOUS ? "enabled" : "disabled",803	       DELAY,804	       EXT_TRANS ? "enabled" : "disabled");805 806	/* not expecting any interrupts */807	SETPORT(SIMODE0, 0);808	SETPORT(SIMODE1, 0);809 810	if (request_irq(shpnt->irq, swintr, IRQF_SHARED, "aha152x", shpnt)) {811		printk(KERN_ERR "aha152x%d: irq %d busy.\n", shpnt->host_no, shpnt->irq);812		goto out_host_put;813	}814 815	HOSTDATA(shpnt)->swint = 0;816 817	printk(KERN_INFO "aha152x%d: trying software interrupt, ", shpnt->host_no);818 819	mb();820	SETPORT(DMACNTRL0, SWINT|INTEN);821	mdelay(1000);822	free_irq(shpnt->irq, shpnt);823 824	if (!HOSTDATA(shpnt)->swint) {825		if (TESTHI(DMASTAT, INTSTAT)) {826			printk("lost.\n");827		} else {828			printk("failed.\n");829		}830 831		SETPORT(DMACNTRL0, INTEN);832 833		printk(KERN_ERR "aha152x%d: irq %d possibly wrong.  "834				"Please verify.\n", shpnt->host_no, shpnt->irq);835		goto out_host_put;836	}837	printk("ok.\n");838 839 840	/* clear interrupts */841	SETPORT(SSTAT0, 0x7f);842	SETPORT(SSTAT1, 0xef);843 844	if (request_irq(shpnt->irq, intr, IRQF_SHARED, "aha152x", shpnt)) {845		printk(KERN_ERR "aha152x%d: failed to reassign irq %d.\n", shpnt->host_no, shpnt->irq);846		goto out_host_put;847	}848 849	if( scsi_add_host(shpnt, NULL) ) {850		free_irq(shpnt->irq, shpnt);851		printk(KERN_ERR "aha152x%d: failed to add host.\n", shpnt->host_no);852		goto out_host_put;853	}854 855	scsi_scan_host(shpnt);856 857	return shpnt;858 859out_host_put:860	list_del(&HOSTDATA(shpnt)->host_list);861	scsi_host_put(shpnt);862 863	return NULL;864}865 866void aha152x_release(struct Scsi_Host *shpnt)867{868	if (!shpnt)869		return;870 871	scsi_remove_host(shpnt);872	if (shpnt->irq)873		free_irq(shpnt->irq, shpnt);874 875#if !defined(AHA152X_PCMCIA)876	if (shpnt->io_port)877		release_region(shpnt->io_port, IO_RANGE);878#endif879 880#ifdef __ISAPNP__881	if (HOSTDATA(shpnt)->pnpdev)882		pnp_device_detach(HOSTDATA(shpnt)->pnpdev);883#endif884 885	list_del(&HOSTDATA(shpnt)->host_list);886	scsi_host_put(shpnt);887}888 889 890/*891 * setup controller to generate interrupts depending892 * on current state (lock has to be acquired)893 *894 */895static int setup_expected_interrupts(struct Scsi_Host *shpnt)896{897	if(CURRENT_SC) {898		struct aha152x_cmd_priv *acp = aha152x_priv(CURRENT_SC);899 900		acp->phase |= 1 << 16;901 902		if (acp->phase & selecting) {903			SETPORT(SSTAT1, SELTO);904			SETPORT(SIMODE0, ENSELDO | (DISCONNECTED_SC ? ENSELDI : 0));905			SETPORT(SIMODE1, ENSELTIMO);906		} else {907			SETPORT(SIMODE0, (acp->phase & spiordy) ? ENSPIORDY : 0);908			SETPORT(SIMODE1, ENPHASEMIS | ENSCSIRST | ENSCSIPERR | ENBUSFREE);909		}910	} else if(STATE==seldi) {911		SETPORT(SIMODE0, 0);912		SETPORT(SIMODE1, ENPHASEMIS | ENSCSIRST | ENSCSIPERR | ENBUSFREE);913	} else {914		SETPORT(SIMODE0, DISCONNECTED_SC ? ENSELDI : 0);915		SETPORT(SIMODE1, ENSCSIRST | ( (ISSUE_SC||DONE_SC) ? ENBUSFREE : 0));916	}917 918	if(!HOSTDATA(shpnt)->in_intr)919		SETBITS(DMACNTRL0, INTEN);920 921	return TESTHI(DMASTAT, INTSTAT);922}923 924 925/*926 *  Queue a command and setup interrupts for a free bus.927 */928static int aha152x_internal_queue(struct scsi_cmnd *SCpnt,929				  struct completion *complete, int phase)930{931	struct aha152x_cmd_priv *acp = aha152x_priv(SCpnt);932	struct Scsi_Host *shpnt = SCpnt->device->host;933	unsigned long flags;934 935	acp->phase        = not_issued | phase;936	acp->status       = 0x1; /* Illegal status by SCSI standard */937	acp->message      = 0;938	acp->sent_command = 0;939 940	if (acp->phase & (resetting | check_condition)) {941		if (!SCpnt->host_scribble || SCSEM(SCpnt) || SCNEXT(SCpnt)) {942			scmd_printk(KERN_ERR, SCpnt, "cannot reuse command\n");943			return FAILED;944		}945	} else {946		SCpnt->host_scribble = kmalloc(sizeof(struct aha152x_scdata), GFP_ATOMIC);947		if(!SCpnt->host_scribble) {948			scmd_printk(KERN_ERR, SCpnt, "allocation failed\n");949			return FAILED;950		}951	}952 953	SCNEXT(SCpnt)		= NULL;954	SCSEM(SCpnt)		= complete;955 956	/* setup scratch area957	   SCp.ptr              : buffer pointer958	   SCp.this_residual    : buffer length959	   SCp.buffer           : next buffer960	   SCp.phase            : current state of the command */961 962	if ((phase & resetting) || !scsi_sglist(SCpnt)) {963		acp->ptr           = NULL;964		acp->this_residual = 0;965		scsi_set_resid(SCpnt, 0);966		acp->buffer        = NULL;967	} else {968		scsi_set_resid(SCpnt, scsi_bufflen(SCpnt));969		acp->buffer        = scsi_sglist(SCpnt);970		acp->ptr           = SG_ADDRESS(acp->buffer);971		acp->this_residual = acp->buffer->length;972	}973 974	DO_LOCK(flags);975 976#if defined(AHA152X_STAT)977	HOSTDATA(shpnt)->total_commands++;978#endif979 980	/* Turn led on, when this is the first command. */981	HOSTDATA(shpnt)->commands++;982	if (HOSTDATA(shpnt)->commands==1)983		SETPORT(PORTA, 1);984 985	append_SC(&ISSUE_SC, SCpnt);986 987	if(!HOSTDATA(shpnt)->in_intr)988		setup_expected_interrupts(shpnt);989 990	DO_UNLOCK(flags);991 992	return 0;993}994 995/*996 *  queue a command997 *998 */999static int aha152x_queue_lck(struct scsi_cmnd *SCpnt)1000{1001	return aha152x_internal_queue(SCpnt, NULL, 0);1002}1003 1004static DEF_SCSI_QCMD(aha152x_queue)1005 1006 1007/*1008 *1009 */1010static void reset_done(struct scsi_cmnd *SCpnt)1011{1012	if(SCSEM(SCpnt)) {1013		complete(SCSEM(SCpnt));1014	} else {1015		printk(KERN_ERR "aha152x: reset_done w/o completion\n");1016	}1017}1018 1019static void aha152x_scsi_done(struct scsi_cmnd *SCpnt)1020{1021	if (aha152x_priv(SCpnt)->phase & resetting)1022		reset_done(SCpnt);1023	else1024		scsi_done(SCpnt);1025}1026 1027/*1028 *  Abort a command1029 *1030 */1031static int aha152x_abort(struct scsi_cmnd *SCpnt)1032{1033	struct Scsi_Host *shpnt = SCpnt->device->host;1034	struct scsi_cmnd *ptr;1035	unsigned long flags;1036 1037	DO_LOCK(flags);1038 1039	ptr=remove_SC(&ISSUE_SC, SCpnt);1040 1041	if(ptr) {1042		HOSTDATA(shpnt)->commands--;1043		if (!HOSTDATA(shpnt)->commands)1044			SETPORT(PORTA, 0);1045		DO_UNLOCK(flags);1046 1047		kfree(SCpnt->host_scribble);1048		SCpnt->host_scribble=NULL;1049 1050		return SUCCESS;1051	}1052 1053	DO_UNLOCK(flags);1054 1055	/*1056	 * FIXME:1057	 * for current command: queue ABORT for message out and raise ATN1058	 * for disconnected command: pseudo SC with ABORT message or ABORT on reselection?1059	 *1060	 */1061 1062	scmd_printk(KERN_ERR, SCpnt,1063		    "cannot abort running or disconnected command\n");1064 1065	return FAILED;1066}1067 1068/*1069 * Reset a device1070 *1071 */1072static int aha152x_device_reset(struct scsi_cmnd * SCpnt)1073{1074	struct Scsi_Host *shpnt = SCpnt->device->host;1075	DECLARE_COMPLETION_ONSTACK(done);1076	int ret, issued, disconnected;1077	unsigned char old_cmd_len = SCpnt->cmd_len;1078	unsigned long flags;1079	unsigned long timeleft;1080 1081	if(CURRENT_SC==SCpnt) {1082		scmd_printk(KERN_ERR, SCpnt, "cannot reset current device\n");1083		return FAILED;1084	}1085 1086	DO_LOCK(flags);1087	issued       = remove_SC(&ISSUE_SC, SCpnt) == NULL;1088	disconnected = issued && remove_SC(&DISCONNECTED_SC, SCpnt);1089	DO_UNLOCK(flags);1090 1091	SCpnt->cmd_len         = 0;1092 1093	aha152x_internal_queue(SCpnt, &done, resetting);1094 1095	timeleft = wait_for_completion_timeout(&done, 100*HZ);1096	if (!timeleft) {1097		/* remove command from issue queue */1098		DO_LOCK(flags);1099		remove_SC(&ISSUE_SC, SCpnt);1100		DO_UNLOCK(flags);1101	}1102 1103	SCpnt->cmd_len         = old_cmd_len;1104 1105	DO_LOCK(flags);1106 1107	if (aha152x_priv(SCpnt)->phase & resetted) {1108		HOSTDATA(shpnt)->commands--;1109		if (!HOSTDATA(shpnt)->commands)1110			SETPORT(PORTA, 0);1111		kfree(SCpnt->host_scribble);1112		SCpnt->host_scribble=NULL;1113 1114		ret = SUCCESS;1115	} else {1116		/* requeue */1117		if(!issued) {1118			append_SC(&ISSUE_SC, SCpnt);1119		} else if(disconnected) {1120			append_SC(&DISCONNECTED_SC, SCpnt);1121		}1122 1123		ret = FAILED;1124	}1125 1126	DO_UNLOCK(flags);1127	return ret;1128}1129 1130static void free_hard_reset_SCs(struct Scsi_Host *shpnt,1131				struct scsi_cmnd **SCs)1132{1133	struct scsi_cmnd *ptr;1134 1135	ptr=*SCs;1136	while(ptr) {1137		struct scsi_cmnd *next;1138 1139		if(SCDATA(ptr)) {1140			next = SCNEXT(ptr);1141		} else {1142			scmd_printk(KERN_DEBUG, ptr,1143				    "queue corrupted at %p\n", ptr);1144			next = NULL;1145		}1146 1147		if (!ptr->device->soft_reset) {1148			remove_SC(SCs, ptr);1149			HOSTDATA(shpnt)->commands--;1150			kfree(ptr->host_scribble);1151			ptr->host_scribble=NULL;1152		}1153 1154		ptr = next;1155	}1156}1157 1158/*1159 * Reset the bus1160 *1161 * AIC-6260 has a hard reset (MRST signal), but apparently1162 * one cannot trigger it via software. So live with1163 * a soft reset; no-one seemed to have cared.1164 */1165static int aha152x_bus_reset_host(struct Scsi_Host *shpnt)1166{1167	unsigned long flags;1168 1169	DO_LOCK(flags);1170 1171	free_hard_reset_SCs(shpnt, &ISSUE_SC);1172	free_hard_reset_SCs(shpnt, &DISCONNECTED_SC);1173 1174	SETPORT(SCSISEQ, SCSIRSTO);1175	mdelay(256);1176	SETPORT(SCSISEQ, 0);1177	mdelay(DELAY);1178 1179	setup_expected_interrupts(shpnt);1180	if(HOSTDATA(shpnt)->commands==0)1181		SETPORT(PORTA, 0);1182 1183	DO_UNLOCK(flags);1184 1185	return SUCCESS;1186}1187 1188/*1189 * Reset the bus1190 *1191 */1192static int aha152x_bus_reset(struct scsi_cmnd *SCpnt)1193{1194	return aha152x_bus_reset_host(SCpnt->device->host);1195}1196 1197/*1198 *  Restore default values to the AIC-6260 registers and reset the fifos1199 *1200 */1201static void reset_ports(struct Scsi_Host *shpnt)1202{1203	unsigned long flags;1204 1205	/* disable interrupts */1206	SETPORT(DMACNTRL0, RSTFIFO);1207 1208	SETPORT(SCSISEQ, 0);1209 1210	SETPORT(SXFRCTL1, 0);1211	SETPORT(SCSISIG, 0);1212	SETRATE(0);1213 1214	/* clear all interrupt conditions */1215	SETPORT(SSTAT0, 0x7f);1216	SETPORT(SSTAT1, 0xef);1217 1218	SETPORT(SSTAT4, SYNCERR | FWERR | FRERR);1219 1220	SETPORT(DMACNTRL0, 0);1221	SETPORT(DMACNTRL1, 0);1222 1223	SETPORT(BRSTCNTRL, 0xf1);1224 1225	/* clear SCSI fifos and transfer count */1226	SETPORT(SXFRCTL0, CH1|CLRCH1|CLRSTCNT);1227	SETPORT(SXFRCTL0, CH1);1228 1229	DO_LOCK(flags);1230	setup_expected_interrupts(shpnt);1231	DO_UNLOCK(flags);1232}1233 1234/*1235 * Reset the host (bus and controller)1236 *1237 */1238int aha152x_host_reset_host(struct Scsi_Host *shpnt)1239{1240	aha152x_bus_reset_host(shpnt);1241	reset_ports(shpnt);1242 1243	return SUCCESS;1244}1245 1246/*1247 * Return the "logical geometry"1248 *1249 */1250static int aha152x_biosparam(struct scsi_device *sdev, struct block_device *bdev,1251		sector_t capacity, int *info_array)1252{1253	struct Scsi_Host *shpnt = sdev->host;1254 1255	/* try default translation */1256	info_array[0] = 64;1257	info_array[1] = 32;1258	info_array[2] = (unsigned long)capacity / (64 * 32);1259 1260	/* for disks >1GB do some guessing */1261	if (info_array[2] >= 1024) {1262		int info[3];1263 1264		/* try to figure out the geometry from the partition table */1265		if (scsicam_bios_param(bdev, capacity, info) < 0 ||1266		    !((info[0] == 64 && info[1] == 32) || (info[0] == 255 && info[1] == 63))) {1267			if (EXT_TRANS) {1268				printk(KERN_NOTICE1269				       "aha152x: unable to verify geometry for disk with >1GB.\n"1270				       "         using extended translation.\n");1271				info_array[0] = 255;1272				info_array[1] = 63;1273				info_array[2] = (unsigned long)capacity / (255 * 63);1274			} else {1275				printk(KERN_NOTICE1276				       "aha152x: unable to verify geometry for disk with >1GB.\n"1277				       "         Using default translation. Please verify yourself.\n"1278				       "         Perhaps you need to enable extended translation in the driver.\n"1279				       "         See Documentation/scsi/aha152x.rst for details.\n");1280			}1281		} else {1282			info_array[0] = info[0];1283			info_array[1] = info[1];1284			info_array[2] = info[2];1285 1286			if (info[0] == 255 && !EXT_TRANS) {1287				printk(KERN_NOTICE1288				       "aha152x: current partition table is using extended translation.\n"1289				       "         using it also, although it's not explicitly enabled.\n");1290			}1291		}1292	}1293 1294	return 0;1295}1296 1297/*1298 *  Internal done function1299 *1300 */1301static void done(struct Scsi_Host *shpnt, unsigned char status_byte,1302		 unsigned char host_byte)1303{1304	if (CURRENT_SC) {1305		if(DONE_SC)1306			scmd_printk(KERN_ERR, CURRENT_SC,1307				    "there's already a completed command %p "1308				    "- will cause abort\n", DONE_SC);1309 1310		DONE_SC = CURRENT_SC;1311		CURRENT_SC = NULL;1312		set_status_byte(DONE_SC, status_byte);1313		set_host_byte(DONE_SC, host_byte);1314	} else1315		printk(KERN_ERR "aha152x: done() called outside of command\n");1316}1317 1318static struct work_struct aha152x_tq;1319 1320/*1321 * Run service completions on the card with interrupts enabled.1322 *1323 */1324static void run(struct work_struct *work)1325{1326	struct aha152x_hostdata *hd;1327 1328	list_for_each_entry(hd, &aha152x_host_list, host_list) {1329		struct Scsi_Host *shost = container_of((void *)hd, struct Scsi_Host, hostdata);1330 1331		is_complete(shost);1332	}1333}1334 1335/*1336 * Interrupt handler1337 *1338 */1339static irqreturn_t intr(int irqno, void *dev_id)1340{1341	struct Scsi_Host *shpnt = dev_id;1342	unsigned long flags;1343	unsigned char rev, dmacntrl0;1344 1345	/*1346	 * Read a couple of registers that are known to not be all 1's. If1347	 * we read all 1's (-1), that means that either:1348	 *1349	 * a. The host adapter chip has gone bad, and we cannot control it,1350	 *	OR1351	 * b. The host adapter is a PCMCIA card that has been ejected1352	 *1353	 * In either case, we cannot do anything with the host adapter at1354	 * this point in time. So just ignore the interrupt and return.1355	 * In the latter case, the interrupt might actually be meant for1356	 * someone else sharing this IRQ, and that driver will handle it.1357	 */1358	rev = GETPORT(REV);1359	dmacntrl0 = GETPORT(DMACNTRL0);1360	if ((rev == 0xFF) && (dmacntrl0 == 0xFF))1361		return IRQ_NONE;1362 1363	if( TESTLO(DMASTAT, INTSTAT) )1364		return IRQ_NONE;1365 1366	/* no more interrupts from the controller, while we're busy.1367	   INTEN is restored by the BH handler */1368	CLRBITS(DMACNTRL0, INTEN);1369 1370	DO_LOCK(flags);1371	if( HOSTDATA(shpnt)->service==0 ) {1372		HOSTDATA(shpnt)->service=1;1373 1374		/* Poke the BH handler */1375		INIT_WORK(&aha152x_tq, run);1376		schedule_work(&aha152x_tq);1377	}1378	DO_UNLOCK(flags);1379 1380	return IRQ_HANDLED;1381}1382 1383/*1384 * busfree phase1385 * - handle completition/disconnection/error of current command1386 * - start selection for next command (if any)1387 */1388static void busfree_run(struct Scsi_Host *shpnt)1389{1390	unsigned long flags;1391#if defined(AHA152X_STAT)1392	int action=0;1393#endif1394 1395	SETPORT(SXFRCTL0, CH1|CLRCH1|CLRSTCNT);1396	SETPORT(SXFRCTL0, CH1);1397 1398	SETPORT(SSTAT1, CLRBUSFREE);1399 1400	if(CURRENT_SC) {1401		struct aha152x_cmd_priv *acp = aha152x_priv(CURRENT_SC);1402 1403#if defined(AHA152X_STAT)1404		action++;1405#endif1406		acp->phase &= ~syncneg;1407 1408		if (acp->phase & completed) {1409			/* target sent COMMAND COMPLETE */1410			done(shpnt, acp->status, DID_OK);1411 1412		} else if (acp->phase & aborted) {1413			done(shpnt, acp->status, DID_ABORT);1414 1415		} else if (acp->phase & resetted) {1416			done(shpnt, acp->status, DID_RESET);1417 1418		} else if (acp->phase & disconnected) {1419			/* target sent DISCONNECT */1420#if defined(AHA152X_STAT)1421			HOSTDATA(shpnt)->disconnections++;1422#endif1423			append_SC(&DISCONNECTED_SC, CURRENT_SC);1424			acp->phase |= 1 << 16;1425			CURRENT_SC = NULL;1426 1427		} else {1428			done(shpnt, SAM_STAT_GOOD, DID_ERROR);1429		}1430#if defined(AHA152X_STAT)1431	} else {1432		HOSTDATA(shpnt)->busfree_without_old_command++;1433#endif1434	}1435 1436	DO_LOCK(flags);1437 1438	if(DONE_SC) {1439#if defined(AHA152X_STAT)1440		action++;1441#endif1442 1443		if (aha152x_priv(DONE_SC)->phase & check_condition) {1444			struct scsi_cmnd *cmd = HOSTDATA(shpnt)->done_SC;1445			struct aha152x_scdata *sc = SCDATA(cmd);1446 1447			scsi_eh_restore_cmnd(cmd, &sc->ses);1448 1449			aha152x_priv(cmd)->status = SAM_STAT_CHECK_CONDITION;1450 1451			HOSTDATA(shpnt)->commands--;1452			if (!HOSTDATA(shpnt)->commands)1453				SETPORT(PORTA, 0);	/* turn led off */1454		} else if (aha152x_priv(DONE_SC)->status == SAM_STAT_CHECK_CONDITION) {1455#if defined(AHA152X_STAT)1456			HOSTDATA(shpnt)->busfree_with_check_condition++;1457#endif1458 1459			if (!(aha152x_priv(DONE_SC)->phase & not_issued)) {1460				struct aha152x_scdata *sc;1461				struct scsi_cmnd *ptr = DONE_SC;1462				DONE_SC=NULL;1463 1464				sc = SCDATA(ptr);1465				/* It was allocated in aha152x_internal_queue? */1466				BUG_ON(!sc);1467				scsi_eh_prep_cmnd(ptr, &sc->ses, NULL, 0, ~0);1468 1469				DO_UNLOCK(flags);1470				aha152x_internal_queue(ptr, NULL, check_condition);1471				DO_LOCK(flags);1472			}1473		}1474 1475		if (DONE_SC) {1476			struct scsi_cmnd *ptr = DONE_SC;1477			DONE_SC=NULL;1478 1479			/* turn led off, when no commands are in the driver */1480			HOSTDATA(shpnt)->commands--;1481			if (!HOSTDATA(shpnt)->commands)1482				SETPORT(PORTA, 0);	/* turn led off */1483 1484			if (!(aha152x_priv(ptr)->phase & resetting)) {1485				kfree(ptr->host_scribble);1486				ptr->host_scribble=NULL;1487			}1488 1489			DO_UNLOCK(flags);1490			aha152x_scsi_done(ptr);1491			DO_LOCK(flags);1492		}1493 1494		DONE_SC=NULL;1495#if defined(AHA152X_STAT)1496	} else {1497		HOSTDATA(shpnt)->busfree_without_done_command++;1498#endif1499	}1500 1501	if(ISSUE_SC)1502		CURRENT_SC = remove_first_SC(&ISSUE_SC);1503 1504	DO_UNLOCK(flags);1505 1506	if(CURRENT_SC) {1507		struct aha152x_cmd_priv *acp = aha152x_priv(CURRENT_SC);1508 1509#if defined(AHA152X_STAT)1510		action++;1511#endif1512		acp->phase |= selecting;1513 1514		/* clear selection timeout */1515		SETPORT(SSTAT1, SELTO);1516 1517		SETPORT(SCSIID, (shpnt->this_id << OID_) | CURRENT_SC->device->id);1518		SETPORT(SXFRCTL1, (PARITY ? ENSPCHK : 0 ) | ENSTIMER);1519		SETPORT(SCSISEQ, ENSELO | ENAUTOATNO | (DISCONNECTED_SC ? ENRESELI : 0));1520	} else {1521#if defined(AHA152X_STAT)1522		HOSTDATA(shpnt)->busfree_without_new_command++;1523#endif1524		SETPORT(SCSISEQ, DISCONNECTED_SC ? ENRESELI : 0);1525	}1526 1527#if defined(AHA152X_STAT)1528	if(!action)1529		HOSTDATA(shpnt)->busfree_without_any_action++;1530#endif1531}1532 1533/*1534 * Selection done (OUT)1535 * - queue IDENTIFY message and SDTR to selected target for message out1536 *   (ATN asserted automagically via ENAUTOATNO in busfree())1537 */1538static void seldo_run(struct Scsi_Host *shpnt)1539{1540	struct aha152x_cmd_priv *acp = aha152x_priv(CURRENT_SC);1541 1542	SETPORT(SCSISIG, 0);1543	SETPORT(SSTAT1, CLRBUSFREE);1544	SETPORT(SSTAT1, CLRPHASECHG);1545 1546	acp->phase &= ~(selecting | not_issued);1547 1548	SETPORT(SCSISEQ, 0);1549 1550	if (TESTLO(SSTAT0, SELDO)) {1551		scmd_printk(KERN_ERR, CURRENT_SC,1552			    "aha152x: passing bus free condition\n");1553		done(shpnt, SAM_STAT_GOOD, DID_NO_CONNECT);1554		return;1555	}1556 1557	SETPORT(SSTAT0, CLRSELDO);1558 1559	ADDMSGO(IDENTIFY(RECONNECT, CURRENT_SC->device->lun));1560 1561	if (acp->phase & aborting) {1562		ADDMSGO(ABORT);1563	} else if (acp->phase & resetting) {1564		ADDMSGO(BUS_DEVICE_RESET);1565	} else if (SYNCNEG==0 && SYNCHRONOUS) {1566		acp->phase |= syncneg;1567		MSGOLEN += spi_populate_sync_msg(&MSGO(MSGOLEN), 50, 8);1568		SYNCNEG=1;		/* negotiation in progress */1569	}1570 1571	SETRATE(SYNCRATE);1572}1573 1574/*1575 * Selection timeout1576 * - return command to mid-level with failure cause1577 *1578 */1579static void selto_run(struct Scsi_Host *shpnt)1580{1581	struct aha152x_cmd_priv *acp;1582 1583	SETPORT(SCSISEQ, 0);1584	SETPORT(SSTAT1, CLRSELTIMO);1585 1586	if (!CURRENT_SC)1587		return;1588 1589	acp = aha152x_priv(CURRENT_SC);1590	acp->phase &= ~selecting;1591 1592	if (acp->phase & aborted)1593		done(shpnt, SAM_STAT_GOOD, DID_ABORT);1594	else if (TESTLO(SSTAT0, SELINGO))1595		done(shpnt, SAM_STAT_GOOD, DID_BUS_BUSY);1596	else1597		/* ARBITRATION won, but SELECTION failed */1598		done(shpnt, SAM_STAT_GOOD, DID_NO_CONNECT);1599}1600 1601/*1602 * Selection in done1603 * - put current command back to issue queue1604 *   (reconnection of a disconnected nexus instead1605 *    of successful selection out)1606 *1607 */1608static void seldi_run(struct Scsi_Host *shpnt)1609{1610	int selid;1611	int target;1612	unsigned long flags;1613 1614	SETPORT(SCSISIG, 0);1615	SETPORT(SSTAT0, CLRSELDI);1616	SETPORT(SSTAT1, CLRBUSFREE);1617	SETPORT(SSTAT1, CLRPHASECHG);1618 1619	if(CURRENT_SC) {1620		struct aha152x_cmd_priv *acp = aha152x_priv(CURRENT_SC);1621 1622		if (!(acp->phase & not_issued))1623			scmd_printk(KERN_ERR, CURRENT_SC,1624				    "command should not have been issued yet\n");1625 1626		DO_LOCK(flags);1627		append_SC(&ISSUE_SC, CURRENT_SC);1628		DO_UNLOCK(flags);1629 1630		CURRENT_SC = NULL;1631	}1632 1633	if (!DISCONNECTED_SC)1634		return;1635 1636	RECONN_TARGET=-1;1637 1638	selid = GETPORT(SELID) & ~(1 << shpnt->this_id);1639 1640	if (selid==0) {1641		shost_printk(KERN_INFO, shpnt,1642			     "target id unknown (%02x)\n", selid);1643		return;1644	}1645 1646	for(target=7; !(selid & (1 << target)); target--)1647		;1648 1649	if(selid & ~(1 << target)) {1650		shost_printk(KERN_INFO, shpnt,1651			     "multiple targets reconnected (%02x)\n", selid);1652	}1653 1654 1655	SETPORT(SCSIID, (shpnt->this_id << OID_) | target);1656	SETPORT(SCSISEQ, 0);1657 1658	SETRATE(HOSTDATA(shpnt)->syncrate[target]);1659 1660	RECONN_TARGET=target;1661}1662 1663/*1664 * message in phase1665 * - handle initial message after reconnection to identify1666 *   reconnecting nexus1667 * - queue command on DISCONNECTED_SC on DISCONNECT message1668 * - set completed flag on COMMAND COMPLETE1669 *   (other completition code moved to busfree_run)1670 * - handle response to SDTR1671 * - clear synchronous transfer agreements on BUS RESET1672 *1673 * FIXME: what about SAVE POINTERS, RESTORE POINTERS?1674 *1675 */1676static void msgi_run(struct Scsi_Host *shpnt)1677{1678	for(;;) {1679		struct aha152x_cmd_priv *acp;1680		int sstat1 = GETPORT(SSTAT1);1681 1682		if(sstat1 & (PHASECHG|PHASEMIS|BUSFREE) || !(sstat1 & REQINIT))1683			return;1684 1685		if (TESTLO(SSTAT0, SPIORDY))1686			return;1687 1688		ADDMSGI(GETPORT(SCSIDAT));1689 1690		if(!CURRENT_SC) {1691			if(LASTSTATE!=seldi) {1692				shost_printk(KERN_ERR, shpnt,1693					     "message in w/o current command"1694					     " not after reselection\n");1695			}1696 1697			/*1698			 * Handle reselection1699			 */1700			if(!(MSGI(0) & IDENTIFY_BASE)) {1701				shost_printk(KERN_ERR, shpnt,1702					     "target didn't identify after reselection\n");1703				continue;1704			}1705 1706			CURRENT_SC = remove_lun_SC(&DISCONNECTED_SC, RECONN_TARGET, MSGI(0) & 0x3f);1707 1708			if (!CURRENT_SC) {1709				show_queues(shpnt);1710				shost_printk(KERN_ERR, shpnt,1711					     "no disconnected command"1712					     " for target %d/%d\n",1713					     RECONN_TARGET, MSGI(0) & 0x3f);1714				continue;1715			}1716 1717			acp = aha152x_priv(CURRENT_SC);1718			acp->message = MSGI(0);1719			acp->phase &= ~disconnected;1720 1721			MSGILEN=0;1722 1723			/* next message if any */1724			continue;1725		}1726 1727		acp = aha152x_priv(CURRENT_SC);1728		acp->message = MSGI(0);1729 1730		switch (MSGI(0)) {1731		case DISCONNECT:1732			if (!RECONNECT)1733				scmd_printk(KERN_WARNING, CURRENT_SC,1734					    "target was not allowed to disconnect\n");1735 1736			acp->phase |= disconnected;1737			break;1738 1739		case COMMAND_COMPLETE:1740			acp->phase |= completed;1741			break;1742 1743		case MESSAGE_REJECT:1744			if (SYNCNEG==1) {1745				scmd_printk(KERN_INFO, CURRENT_SC,1746					    "Synchronous Data Transfer Request"1747					    " was rejected\n");1748				SYNCNEG=2;	/* negotiation completed */1749			} else1750				scmd_printk(KERN_INFO, CURRENT_SC,1751					    "inbound message (MESSAGE REJECT)\n");1752			break;1753 1754		case SAVE_POINTERS:1755			break;1756 1757		case RESTORE_POINTERS:1758			break;1759 1760		case EXTENDED_MESSAGE:1761			if(MSGILEN<2 || MSGILEN<MSGI(1)+2) {1762				/* not yet completed */1763				continue;1764			}1765 1766			switch (MSGI(2)) {1767			case EXTENDED_SDTR:1768				{1769					long ticks;1770 1771					if (MSGI(1) != 3) {1772						scmd_printk(KERN_ERR, CURRENT_SC,1773							    "SDTR message length!=3\n");1774						break;1775					}1776 1777					if (!HOSTDATA(shpnt)->synchronous)1778						break;1779 1780					printk(INFO_LEAD, CMDINFO(CURRENT_SC));1781					spi_print_msg(&MSGI(0));1782					printk("\n");1783 1784					ticks = (MSGI(3) * 4 + 49) / 50;1785 1786					if (syncneg) {1787						/* negotiation in progress */1788						if (ticks > 9 || MSGI(4) < 1 || MSGI(4) > 8) {1789							ADDMSGO(MESSAGE_REJECT);1790							scmd_printk(KERN_INFO,1791								    CURRENT_SC,1792								    "received Synchronous Data Transfer Request invalid - rejected\n");1793							break;1794						}1795 1796						SYNCRATE |= ((ticks - 2) << 4) + MSGI(4);1797					} else if (ticks <= 9 && MSGI(4) >= 1) {1798						ADDMSGO(EXTENDED_MESSAGE);1799						ADDMSGO(3);1800						ADDMSGO(EXTENDED_SDTR);1801						if (ticks < 4) {1802							ticks = 4;1803							ADDMSGO(50);1804						} else1805							ADDMSGO(MSGI(3));1806 1807						if (MSGI(4) > 8)1808							MSGI(4) = 8;1809 1810						ADDMSGO(MSGI(4));1811 1812						SYNCRATE |= ((ticks - 2) << 4) + MSGI(4);1813					} else {1814						/* requested SDTR is too slow, do it asynchronously */1815						scmd_printk(KERN_INFO,1816							    CURRENT_SC,1817							    "Synchronous Data Transfer Request too slow - Rejecting\n");1818						ADDMSGO(MESSAGE_REJECT);1819					}1820 1821					/* negotiation completed */1822					SYNCNEG=2;1823					SETRATE(SYNCRATE);1824				}1825				break;1826 1827			case BUS_DEVICE_RESET:1828				{1829					int i;1830 1831					for(i=0; i<8; i++) {1832						HOSTDATA(shpnt)->syncrate[i]=0;1833						HOSTDATA(shpnt)->syncneg[i]=0;1834					}1835 1836				}1837				break;1838 1839			case EXTENDED_MODIFY_DATA_POINTER:1840			case EXTENDED_EXTENDED_IDENTIFY:1841			case EXTENDED_WDTR:1842			default:1843				ADDMSGO(MESSAGE_REJECT);1844				break;1845			}1846			break;1847		}1848 1849		MSGILEN=0;1850	}1851}1852 1853static void msgi_end(struct Scsi_Host *shpnt)1854{1855	if(MSGILEN>0)1856		scmd_printk(KERN_WARNING, CURRENT_SC,1857			    "target left before message completed (%d)\n",1858			    MSGILEN);1859 1860	if (MSGOLEN > 0 && !(GETPORT(SSTAT1) & BUSFREE))1861		SETPORT(SCSISIG, P_MSGI | SIG_ATNO);1862}1863 1864/*1865 * message out phase1866 *1867 */1868static void msgo_init(struct Scsi_Host *shpnt)1869{1870	if(MSGOLEN==0) {1871		if ((aha152x_priv(CURRENT_SC)->phase & syncneg) &&1872		    SYNCNEG == 2 && SYNCRATE == 0) {1873			ADDMSGO(IDENTIFY(RECONNECT, CURRENT_SC->device->lun));1874		} else {1875			scmd_printk(KERN_INFO, CURRENT_SC,1876				    "unexpected MESSAGE OUT phase; rejecting\n");1877			ADDMSGO(MESSAGE_REJECT);1878		}1879	}1880 1881}1882 1883/*1884 * message out phase1885 *1886 */1887static void msgo_run(struct Scsi_Host *shpnt)1888{1889	struct aha152x_cmd_priv *acp = aha152x_priv(CURRENT_SC);1890 1891	while(MSGO_I<MSGOLEN) {1892		if (TESTLO(SSTAT0, SPIORDY))1893			return;1894 1895		if (MSGO_I==MSGOLEN-1) {1896			/* Leave MESSAGE OUT after transfer */1897			SETPORT(SSTAT1, CLRATNO);1898		}1899 1900 1901		if (MSGO(MSGO_I) & IDENTIFY_BASE)1902			acp->phase |= identified;1903 1904		if (MSGO(MSGO_I)==ABORT)1905			acp->phase |= aborted;1906 1907		if (MSGO(MSGO_I)==BUS_DEVICE_RESET)1908			acp->phase |= resetted;1909 1910		SETPORT(SCSIDAT, MSGO(MSGO_I++));1911	}1912}1913 1914static void msgo_end(struct Scsi_Host *shpnt)1915{1916	if(MSGO_I<MSGOLEN) {1917		scmd_printk(KERN_ERR, CURRENT_SC,1918			    "message sent incompletely (%d/%d)\n",1919			    MSGO_I, MSGOLEN);1920		if(SYNCNEG==1) {1921			scmd_printk(KERN_INFO, CURRENT_SC,1922				    "Synchronous Data Transfer Request was rejected\n");1923			SYNCNEG=2;1924		}1925	}1926 1927	MSGO_I  = 0;1928	MSGOLEN = 0;1929}1930 1931/*1932 * command phase1933 *1934 */1935static void cmd_init(struct Scsi_Host *shpnt)1936{1937	if (aha152x_priv(CURRENT_SC)->sent_command) {1938		scmd_printk(KERN_ERR, CURRENT_SC,1939			    "command already sent\n");1940		done(shpnt, SAM_STAT_GOOD, DID_ERROR);1941		return;1942	}1943 1944	CMD_I=0;1945}1946 1947/*1948 * command phase1949 *1950 */1951static void cmd_run(struct Scsi_Host *shpnt)1952{1953	while(CMD_I<CURRENT_SC->cmd_len) {1954		if (TESTLO(SSTAT0, SPIORDY))1955			return;1956 1957		SETPORT(SCSIDAT, CURRENT_SC->cmnd[CMD_I++]);1958	}1959}1960 1961static void cmd_end(struct Scsi_Host *shpnt)1962{1963	if(CMD_I<CURRENT_SC->cmd_len)1964		scmd_printk(KERN_ERR, CURRENT_SC,1965			    "command sent incompletely (%d/%d)\n",1966			    CMD_I, CURRENT_SC->cmd_len);1967	else1968		aha152x_priv(CURRENT_SC)->sent_command++;1969}1970 1971/*1972 * status phase1973 *1974 */1975static void status_run(struct Scsi_Host *shpnt)1976{1977	if (TESTLO(SSTAT0, SPIORDY))1978		return;1979 1980	aha152x_priv(CURRENT_SC)->status = GETPORT(SCSIDAT);1981 1982}1983 1984/*1985 * data in phase1986 *1987 */1988static void datai_init(struct Scsi_Host *shpnt)1989{1990	SETPORT(DMACNTRL0, RSTFIFO);1991	SETPORT(DMACNTRL0, RSTFIFO|ENDMA);1992 1993	SETPORT(SXFRCTL0, CH1|CLRSTCNT);1994	SETPORT(SXFRCTL0, CH1|SCSIEN|DMAEN);1995 1996	SETPORT(SIMODE0, 0);1997	SETPORT(SIMODE1, ENSCSIPERR | ENSCSIRST | ENPHASEMIS | ENBUSFREE);1998 1999	DATA_LEN=0;2000}2001 2002static void datai_run(struct Scsi_Host *shpnt)2003{2004	struct aha152x_cmd_priv *acp;2005	unsigned long the_time;2006	int fifodata, data_count;2007 2008	/*2009	 * loop while the phase persists or the fifos are not empty2010	 *2011	 */2012	while(TESTLO(DMASTAT, INTSTAT) || TESTLO(DMASTAT, DFIFOEMP) || TESTLO(SSTAT2, SEMPTY)) {2013		/* FIXME: maybe this should be done by setting up2014		 * STCNT to trigger ENSWRAP interrupt, instead of2015		 * polling for DFIFOFULL2016		 */2017		the_time=jiffies + 100*HZ;2018		while(TESTLO(DMASTAT, DFIFOFULL|INTSTAT) && time_before(jiffies,the_time))2019			barrier();2020 2021		if(TESTLO(DMASTAT, DFIFOFULL|INTSTAT)) {2022			scmd_printk(KERN_ERR, CURRENT_SC, "datai timeout\n");2023			break;2024		}2025 2026		if(TESTHI(DMASTAT, DFIFOFULL)) {2027			fifodata = 128;2028		} else {2029			the_time=jiffies + 100*HZ;2030			while(TESTLO(SSTAT2, SEMPTY) && time_before(jiffies,the_time))2031				barrier();2032 2033			if(TESTLO(SSTAT2, SEMPTY)) {2034				scmd_printk(KERN_ERR, CURRENT_SC,2035					    "datai sempty timeout");2036				break;2037			}2038 2039			fifodata = GETPORT(FIFOSTAT);2040		}2041 2042		acp = aha152x_priv(CURRENT_SC);2043		if (acp->this_residual > 0) {2044			while (fifodata > 0 && acp->this_residual > 0) {2045				data_count = fifodata > acp->this_residual ?2046						acp->this_residual : fifodata;2047				fifodata -= data_count;2048 2049				if (data_count & 1) {2050					SETPORT(DMACNTRL0, ENDMA|_8BIT);2051					*acp->ptr++ = GETPORT(DATAPORT);2052					acp->this_residual--;2053					DATA_LEN++;2054					SETPORT(DMACNTRL0, ENDMA);2055				}2056 2057				if (data_count > 1) {2058					data_count >>= 1;2059					insw(DATAPORT, acp->ptr, data_count);2060					acp->ptr += 2 * data_count;2061					acp->this_residual -= 2 * data_count;2062					DATA_LEN += 2 * data_count;2063				}2064 2065				if (acp->this_residual == 0 &&2066				    !sg_is_last(acp->buffer)) {2067					/* advance to next buffer */2068					acp->buffer = sg_next(acp->buffer);2069					acp->ptr = SG_ADDRESS(acp->buffer);2070					acp->this_residual = acp->buffer->length;2071				}2072			}2073		} else if (fifodata > 0) {2074			scmd_printk(KERN_ERR, CURRENT_SC,2075				    "no buffers left for %d(%d) bytes"2076				    " (data overrun!?)\n",2077				    fifodata, GETPORT(FIFOSTAT));2078			SETPORT(DMACNTRL0, ENDMA|_8BIT);2079			while(fifodata>0) {2080				GETPORT(DATAPORT);2081				fifodata--;2082				DATA_LEN++;2083			}2084			SETPORT(DMACNTRL0, ENDMA|_8BIT);2085		}2086	}2087 2088	if(TESTLO(DMASTAT, INTSTAT) ||2089	   TESTLO(DMASTAT, DFIFOEMP) ||2090	   TESTLO(SSTAT2, SEMPTY) ||2091	   GETPORT(FIFOSTAT)>0) {2092		/*2093		 * something went wrong, if there's something left in the fifos2094		 * or the phase didn't change2095		 */2096		scmd_printk(KERN_ERR, CURRENT_SC,2097			    "fifos should be empty and phase should have changed\n");2098	}2099 2100	if(DATA_LEN!=GETSTCNT()) {2101		scmd_printk(KERN_ERR, CURRENT_SC,2102			    "manual transfer count differs from automatic "2103			    "(count=%d;stcnt=%d;diff=%d;fifostat=%d)",2104			    DATA_LEN, GETSTCNT(), GETSTCNT()-DATA_LEN,2105			    GETPORT(FIFOSTAT));2106		mdelay(10000);2107	}2108}2109 2110static void datai_end(struct Scsi_Host *shpnt)2111{2112	CMD_INC_RESID(CURRENT_SC, -GETSTCNT());2113 2114	SETPORT(SXFRCTL0, CH1|CLRSTCNT);2115	SETPORT(DMACNTRL0, 0);2116}2117 2118/*2119 * data out phase2120 *2121 */2122static void datao_init(struct Scsi_Host *shpnt)2123{2124	SETPORT(DMACNTRL0, WRITE_READ | RSTFIFO);2125	SETPORT(DMACNTRL0, WRITE_READ | ENDMA);2126 2127	SETPORT(SXFRCTL0, CH1|CLRSTCNT);2128	SETPORT(SXFRCTL0, CH1|SCSIEN|DMAEN);2129 2130	SETPORT(SIMODE0, 0);2131	SETPORT(SIMODE1, ENSCSIPERR | ENSCSIRST | ENPHASEMIS | ENBUSFREE );2132 2133	DATA_LEN = scsi_get_resid(CURRENT_SC);2134}2135 2136static void datao_run(struct Scsi_Host *shpnt)2137{2138	struct aha152x_cmd_priv *acp = aha152x_priv(CURRENT_SC);2139	unsigned long the_time;2140	int data_count;2141 2142	/* until phase changes or all data sent */2143	while (TESTLO(DMASTAT, INTSTAT) && acp->this_residual > 0) {2144		data_count = 128;2145		if (data_count > acp->this_residual)2146			data_count = acp->this_residual;2147 2148		if(TESTLO(DMASTAT, DFIFOEMP)) {2149			scmd_printk(KERN_ERR, CURRENT_SC,2150				    "datao fifo not empty (%d)",2151				    GETPORT(FIFOSTAT));2152			break;2153		}2154 2155		if(data_count & 1) {2156			SETPORT(DMACNTRL0,WRITE_READ|ENDMA|_8BIT);2157			SETPORT(DATAPORT, *acp->ptr++);2158			acp->this_residual--;2159			CMD_INC_RESID(CURRENT_SC, -1);2160			SETPORT(DMACNTRL0,WRITE_READ|ENDMA);2161		}2162 2163		if(data_count > 1) {2164			data_count >>= 1;2165			outsw(DATAPORT, acp->ptr, data_count);2166			acp->ptr += 2 * data_count;2167			acp->this_residual -= 2 * data_count;2168			CMD_INC_RESID(CURRENT_SC, -2 * data_count);2169		}2170 2171		if (acp->this_residual == 0 && !sg_is_last(acp->buffer)) {2172			/* advance to next buffer */2173			acp->buffer = sg_next(acp->buffer);2174			acp->ptr = SG_ADDRESS(acp->buffer);2175			acp->this_residual = acp->buffer->length;2176		}2177 2178		the_time=jiffies + 100*HZ;2179		while(TESTLO(DMASTAT, DFIFOEMP|INTSTAT) && time_before(jiffies,the_time))2180			barrier();2181 2182		if(TESTLO(DMASTAT, DFIFOEMP|INTSTAT)) {2183			scmd_printk(KERN_ERR, CURRENT_SC, "dataout timeout\n");2184			break;2185		}2186	}2187}2188 2189static void datao_end(struct Scsi_Host *shpnt)2190{2191	struct aha152x_cmd_priv *acp = aha152x_priv(CURRENT_SC);2192 2193	if(TESTLO(DMASTAT, DFIFOEMP)) {2194		u32 datao_cnt = GETSTCNT();2195		int datao_out = DATA_LEN - scsi_get_resid(CURRENT_SC);2196		int done;2197		struct scatterlist *sg = scsi_sglist(CURRENT_SC);2198 2199		CMD_INC_RESID(CURRENT_SC, datao_out - datao_cnt);2200 2201		done = scsi_bufflen(CURRENT_SC) - scsi_get_resid(CURRENT_SC);2202		/* Locate the first SG entry not yet sent */2203		while (done > 0 && !sg_is_last(sg)) {2204			if (done < sg->length)2205				break;2206			done -= sg->length;2207			sg = sg_next(sg);2208		}2209 2210		acp->buffer = sg;2211		acp->ptr = SG_ADDRESS(acp->buffer) + done;2212		acp->this_residual = acp->buffer->length - done;2213	}2214 2215	SETPORT(SXFRCTL0, CH1|CLRCH1|CLRSTCNT);2216	SETPORT(SXFRCTL0, CH1);2217 2218	SETPORT(DMACNTRL0, 0);2219}2220 2221/*2222 * figure out what state we're in2223 *2224 */2225static int update_state(struct Scsi_Host *shpnt)2226{2227	int dataphase=0;2228	unsigned int stat0 = GETPORT(SSTAT0);2229	unsigned int stat1 = GETPORT(SSTAT1);2230 2231	PREVSTATE = STATE;2232	STATE=unknown;2233 2234	if(stat1 & SCSIRSTI) {2235		STATE=rsti;2236		SETPORT(SCSISEQ,0);2237		SETPORT(SSTAT1,SCSIRSTI);2238	} else if (stat0 & SELDI && PREVSTATE == busfree) {2239		STATE=seldi;2240	} else if (stat0 & SELDO && CURRENT_SC &&2241		   (aha152x_priv(CURRENT_SC)->phase & selecting)) {2242		STATE=seldo;2243	} else if(stat1 & SELTO) {2244		STATE=selto;2245	} else if(stat1 & BUSFREE) {2246		STATE=busfree;2247		SETPORT(SSTAT1,BUSFREE);2248	} else if(stat1 & SCSIPERR) {2249		STATE=parerr;2250		SETPORT(SSTAT1,SCSIPERR);2251	} else if(stat1 & REQINIT) {2252		switch(GETPORT(SCSISIG) & P_MASK) {2253		case P_MSGI:	STATE=msgi;	break;2254		case P_MSGO:	STATE=msgo;	break;2255		case P_DATAO:	STATE=datao;	break;2256		case P_DATAI:	STATE=datai;	break;2257		case P_STATUS:	STATE=status;	break;2258		case P_CMD:	STATE=cmd;	break;2259		}2260		dataphase=1;2261	}2262 2263	if((stat0 & SELDI) && STATE!=seldi && !dataphase) {2264		scmd_printk(KERN_INFO, CURRENT_SC, "reselection missed?");2265	}2266 2267	if(STATE!=PREVSTATE) {2268		LASTSTATE=PREVSTATE;2269	}2270 2271	return dataphase;2272}2273 2274/*2275 * handle parity error2276 *2277 * FIXME: in which phase?2278 *2279 */2280static void parerr_run(struct Scsi_Host *shpnt)2281{2282	scmd_printk(KERN_ERR, CURRENT_SC, "parity error\n");2283	done(shpnt, SAM_STAT_GOOD, DID_PARITY);2284}2285 2286/*2287 * handle reset in2288 *2289 */2290static void rsti_run(struct Scsi_Host *shpnt)2291{2292	struct scsi_cmnd *ptr;2293 2294	shost_printk(KERN_NOTICE, shpnt, "scsi reset in\n");2295 2296	ptr=DISCONNECTED_SC;2297	while(ptr) {2298		struct scsi_cmnd *next = SCNEXT(ptr);2299 2300		if (!ptr->device->soft_reset) {2301			remove_SC(&DISCONNECTED_SC, ptr);2302 2303			kfree(ptr->host_scribble);2304			ptr->host_scribble=NULL;2305 2306			set_host_byte(ptr, DID_RESET);2307			aha152x_scsi_done(ptr);2308		}2309 2310		ptr = next;2311	}2312 2313	if(CURRENT_SC && !CURRENT_SC->device->soft_reset)2314		done(shpnt, SAM_STAT_GOOD, DID_RESET);2315}2316 2317 2318/*2319 * bottom-half handler2320 *2321 */2322static void is_complete(struct Scsi_Host *shpnt)2323{2324	int dataphase;2325	unsigned long flags;2326	int pending;2327 2328	if(!shpnt)2329		return;2330 2331	DO_LOCK(flags);2332 2333	if( HOSTDATA(shpnt)->service==0 )  {2334		DO_UNLOCK(flags);2335		return;2336	}2337 2338	HOSTDATA(shpnt)->service = 0;2339 2340	if(HOSTDATA(shpnt)->in_intr) {2341		DO_UNLOCK(flags);2342		/* aha152x_error never returns.. */2343		aha152x_error(shpnt, "bottom-half already running!?");2344	}2345	HOSTDATA(shpnt)->in_intr++;2346 2347	/*2348	 * loop while there are interrupt conditions pending2349	 *2350	 */2351	do {2352		unsigned long start = jiffies;2353		DO_UNLOCK(flags);2354 2355		dataphase=update_state(shpnt);2356 2357		/*2358		 * end previous state2359		 *2360		 */2361		if(PREVSTATE!=STATE && states[PREVSTATE].end)2362			states[PREVSTATE].end(shpnt);2363 2364		/*2365		 * disable SPIO mode if previous phase used it2366		 * and this one doesn't2367		 *2368		 */2369		if(states[PREVSTATE].spio && !states[STATE].spio) {2370			SETPORT(SXFRCTL0, CH1);2371			SETPORT(DMACNTRL0, 0);2372			if(CURRENT_SC)2373				aha152x_priv(CURRENT_SC)->phase &= ~spiordy;2374		}2375 2376		/*2377		 * accept current dataphase phase2378		 *2379		 */2380		if(dataphase) {2381			SETPORT(SSTAT0, REQINIT);2382			SETPORT(SCSISIG, GETPORT(SCSISIG) & P_MASK);2383			SETPORT(SSTAT1, PHASECHG);2384		}2385 2386		/*2387		 * enable SPIO mode if previous didn't use it2388		 * and this one does2389		 *2390		 */2391		if(!states[PREVSTATE].spio && states[STATE].spio) {2392			SETPORT(DMACNTRL0, 0);2393			SETPORT(SXFRCTL0, CH1|SPIOEN);2394			if(CURRENT_SC)2395				aha152x_priv(CURRENT_SC)->phase |= spiordy;2396		}2397 2398		/*2399		 * initialize for new state2400		 *2401		 */2402		if(PREVSTATE!=STATE && states[STATE].init)2403			states[STATE].init(shpnt);2404 2405		/*2406		 * handle current state2407		 *2408		 */2409		if(states[STATE].run)2410			states[STATE].run(shpnt);2411		else2412			scmd_printk(KERN_ERR, CURRENT_SC,2413				    "unexpected state (%x)\n", STATE);2414 2415		/*2416		 * setup controller to interrupt on2417		 * the next expected condition and2418		 * loop if it's already there2419		 *2420		 */2421		DO_LOCK(flags);2422		pending=setup_expected_interrupts(shpnt);2423#if defined(AHA152X_STAT)2424		HOSTDATA(shpnt)->count[STATE]++;2425		if(PREVSTATE!=STATE)2426			HOSTDATA(shpnt)->count_trans[STATE]++;2427		HOSTDATA(shpnt)->time[STATE] += jiffies-start;2428#endif2429 2430	} while(pending);2431 2432	/*2433	 * enable interrupts and leave bottom-half2434	 *2435	 */2436	HOSTDATA(shpnt)->in_intr--;2437	SETBITS(DMACNTRL0, INTEN);2438	DO_UNLOCK(flags);2439}2440 2441 2442/*2443 * Dump the current driver status and panic2444 */2445static void aha152x_error(struct Scsi_Host *shpnt, char *msg)2446{2447	shost_printk(KERN_EMERG, shpnt, "%s\n", msg);2448	show_queues(shpnt);2449	panic("aha152x panic\n");2450}2451 2452/*2453 * display enabled interrupts2454 */2455static void disp_enintr(struct Scsi_Host *shpnt)2456{2457	int s0, s1;2458 2459	s0 = GETPORT(SIMODE0);2460	s1 = GETPORT(SIMODE1);2461 2462	shost_printk(KERN_DEBUG, shpnt,2463		     "enabled interrupts (%s%s%s%s%s%s%s%s%s%s%s%s%s%s)\n",2464		     (s0 & ENSELDO) ? "ENSELDO " : "",2465		     (s0 & ENSELDI) ? "ENSELDI " : "",2466		     (s0 & ENSELINGO) ? "ENSELINGO " : "",2467		     (s0 & ENSWRAP) ? "ENSWRAP " : "",2468		     (s0 & ENSDONE) ? "ENSDONE " : "",2469		     (s0 & ENSPIORDY) ? "ENSPIORDY " : "",2470		     (s0 & ENDMADONE) ? "ENDMADONE " : "",2471		     (s1 & ENSELTIMO) ? "ENSELTIMO " : "",2472		     (s1 & ENATNTARG) ? "ENATNTARG " : "",2473		     (s1 & ENPHASEMIS) ? "ENPHASEMIS " : "",2474		     (s1 & ENBUSFREE) ? "ENBUSFREE " : "",2475		     (s1 & ENSCSIPERR) ? "ENSCSIPERR " : "",2476		     (s1 & ENPHASECHG) ? "ENPHASECHG " : "",2477		     (s1 & ENREQINIT) ? "ENREQINIT " : "");2478}2479 2480/*2481 * Show the command data of a command2482 */2483static void show_command(struct scsi_cmnd *ptr)2484{2485	const int phase = aha152x_priv(ptr)->phase;2486 2487	scsi_print_command(ptr);2488	scmd_printk(KERN_DEBUG, ptr,2489		    "request_bufflen=%d; resid=%d; "2490		    "phase |%s%s%s%s%s%s%s%s%s; next=0x%p",2491		    scsi_bufflen(ptr), scsi_get_resid(ptr),2492		    phase & not_issued ? "not issued|" : "",2493		    phase & selecting ? "selecting|" : "",2494		    phase & identified ? "identified|" : "",2495		    phase & disconnected ? "disconnected|" : "",2496		    phase & completed ? "completed|" : "",2497		    phase & spiordy ? "spiordy|" : "",2498		    phase & syncneg ? "syncneg|" : "",2499		    phase & aborted ? "aborted|" : "",2500		    phase & resetted ? "resetted|" : "",2501		    SCDATA(ptr) ? SCNEXT(ptr) : NULL);2502}2503 2504/*2505 * Dump the queued data2506 */2507static void show_queues(struct Scsi_Host *shpnt)2508{2509	struct scsi_cmnd *ptr;2510	unsigned long flags;2511 2512	DO_LOCK(flags);2513	printk(KERN_DEBUG "\nqueue status:\nissue_SC:\n");2514	for (ptr = ISSUE_SC; ptr; ptr = SCNEXT(ptr))2515		show_command(ptr);2516	DO_UNLOCK(flags);2517 2518	printk(KERN_DEBUG "current_SC:\n");2519	if (CURRENT_SC)2520		show_command(CURRENT_SC);2521	else2522		printk(KERN_DEBUG "none\n");2523 2524	printk(KERN_DEBUG "disconnected_SC:\n");2525	for (ptr = DISCONNECTED_SC; ptr; ptr = SCDATA(ptr) ? SCNEXT(ptr) : NULL)2526		show_command(ptr);2527 2528	disp_enintr(shpnt);2529}2530 2531static void get_command(struct seq_file *m, struct scsi_cmnd * ptr)2532{2533	struct aha152x_cmd_priv *acp = aha152x_priv(ptr);2534	const int phase = acp->phase;2535	int i;2536 2537	seq_printf(m, "%p: target=%d; lun=%d; cmnd=( ",2538		ptr, ptr->device->id, (u8)ptr->device->lun);2539 2540	for (i = 0; i < COMMAND_SIZE(ptr->cmnd[0]); i++)2541		seq_printf(m, "0x%02x ", ptr->cmnd[i]);2542 2543	seq_printf(m, "); resid=%d; residual=%d; buffers=%d; phase |",2544		scsi_get_resid(ptr), acp->this_residual,2545		sg_nents(acp->buffer) - 1);2546 2547	if (phase & not_issued)2548		seq_puts(m, "not issued|");2549	if (phase & selecting)2550		seq_puts(m, "selecting|");2551	if (phase & disconnected)2552		seq_puts(m, "disconnected|");2553	if (phase & aborted)2554		seq_puts(m, "aborted|");2555	if (phase & identified)2556		seq_puts(m, "identified|");2557	if (phase & completed)2558		seq_puts(m, "completed|");2559	if (phase & spiordy)2560		seq_puts(m, "spiordy|");2561	if (phase & syncneg)2562		seq_puts(m, "syncneg|");2563	seq_printf(m, "; next=0x%p\n", SCNEXT(ptr));2564}2565 2566static void get_ports(struct seq_file *m, struct Scsi_Host *shpnt)2567{2568	int s;2569 2570	seq_printf(m, "\n%s: %s(%s) ", CURRENT_SC ? "on bus" : "waiting", states[STATE].name, states[PREVSTATE].name);2571 2572	s = GETPORT(SCSISEQ);2573	seq_puts(m, "SCSISEQ( ");2574	if (s & TEMODEO)2575		seq_puts(m, "TARGET MODE ");2576	if (s & ENSELO)2577		seq_puts(m, "SELO ");2578	if (s & ENSELI)2579		seq_puts(m, "SELI ");2580	if (s & ENRESELI)2581		seq_puts(m, "RESELI ");2582	if (s & ENAUTOATNO)2583		seq_puts(m, "AUTOATNO ");2584	if (s & ENAUTOATNI)2585		seq_puts(m, "AUTOATNI ");2586	if (s & ENAUTOATNP)2587		seq_puts(m, "AUTOATNP ");2588	if (s & SCSIRSTO)2589		seq_puts(m, "SCSIRSTO ");2590	seq_puts(m, ");");2591 2592	seq_puts(m, " SCSISIG(");2593	s = GETPORT(SCSISIG);2594	switch (s & P_MASK) {2595	case P_DATAO:2596		seq_puts(m, "DATA OUT");2597		break;2598	case P_DATAI:2599		seq_puts(m, "DATA IN");2600		break;2601	case P_CMD:2602		seq_puts(m, "COMMAND");2603		break;2604	case P_STATUS:2605		seq_puts(m, "STATUS");2606		break;2607	case P_MSGO:2608		seq_puts(m, "MESSAGE OUT");2609		break;2610	case P_MSGI:2611		seq_puts(m, "MESSAGE IN");2612		break;2613	default:2614		seq_puts(m, "*invalid*");2615		break;2616	}2617 2618	seq_puts(m, "); ");2619 2620	seq_printf(m, "INTSTAT (%s); ", TESTHI(DMASTAT, INTSTAT) ? "hi" : "lo");2621 2622	seq_puts(m, "SSTAT( ");2623	s = GETPORT(SSTAT0);2624	if (s & TARGET)2625		seq_puts(m, "TARGET ");2626	if (s & SELDO)2627		seq_puts(m, "SELDO ");2628	if (s & SELDI)2629		seq_puts(m, "SELDI ");2630	if (s & SELINGO)2631		seq_puts(m, "SELINGO ");2632	if (s & SWRAP)2633		seq_puts(m, "SWRAP ");2634	if (s & SDONE)2635		seq_puts(m, "SDONE ");2636	if (s & SPIORDY)2637		seq_puts(m, "SPIORDY ");2638	if (s & DMADONE)2639		seq_puts(m, "DMADONE ");2640 2641	s = GETPORT(SSTAT1);2642	if (s & SELTO)2643		seq_puts(m, "SELTO ");2644	if (s & ATNTARG)2645		seq_puts(m, "ATNTARG ");2646	if (s & SCSIRSTI)2647		seq_puts(m, "SCSIRSTI ");2648	if (s & PHASEMIS)2649		seq_puts(m, "PHASEMIS ");2650	if (s & BUSFREE)2651		seq_puts(m, "BUSFREE ");2652	if (s & SCSIPERR)2653		seq_puts(m, "SCSIPERR ");2654	if (s & PHASECHG)2655		seq_puts(m, "PHASECHG ");2656	if (s & REQINIT)2657		seq_puts(m, "REQINIT ");2658	seq_puts(m, "); ");2659 2660 2661	seq_puts(m, "SSTAT( ");2662 2663	s = GETPORT(SSTAT0) & GETPORT(SIMODE0);2664 2665	if (s & TARGET)2666		seq_puts(m, "TARGET ");2667	if (s & SELDO)2668		seq_puts(m, "SELDO ");2669	if (s & SELDI)2670		seq_puts(m, "SELDI ");2671	if (s & SELINGO)2672		seq_puts(m, "SELINGO ");2673	if (s & SWRAP)2674		seq_puts(m, "SWRAP ");2675	if (s & SDONE)2676		seq_puts(m, "SDONE ");2677	if (s & SPIORDY)2678		seq_puts(m, "SPIORDY ");2679	if (s & DMADONE)2680		seq_puts(m, "DMADONE ");2681 2682	s = GETPORT(SSTAT1) & GETPORT(SIMODE1);2683 2684	if (s & SELTO)2685		seq_puts(m, "SELTO ");2686	if (s & ATNTARG)2687		seq_puts(m, "ATNTARG ");2688	if (s & SCSIRSTI)2689		seq_puts(m, "SCSIRSTI ");2690	if (s & PHASEMIS)2691		seq_puts(m, "PHASEMIS ");2692	if (s & BUSFREE)2693		seq_puts(m, "BUSFREE ");2694	if (s & SCSIPERR)2695		seq_puts(m, "SCSIPERR ");2696	if (s & PHASECHG)2697		seq_puts(m, "PHASECHG ");2698	if (s & REQINIT)2699		seq_puts(m, "REQINIT ");2700	seq_puts(m, "); ");2701 2702	seq_puts(m, "SXFRCTL0( ");2703 2704	s = GETPORT(SXFRCTL0);2705	if (s & SCSIEN)2706		seq_puts(m, "SCSIEN ");2707	if (s & DMAEN)2708		seq_puts(m, "DMAEN ");2709	if (s & CH1)2710		seq_puts(m, "CH1 ");2711	if (s & CLRSTCNT)2712		seq_puts(m, "CLRSTCNT ");2713	if (s & SPIOEN)2714		seq_puts(m, "SPIOEN ");2715	if (s & CLRCH1)2716		seq_puts(m, "CLRCH1 ");2717	seq_puts(m, "); ");2718 2719	seq_puts(m, "SIGNAL( ");2720 2721	s = GETPORT(SCSISIG);2722	if (s & SIG_ATNI)2723		seq_puts(m, "ATNI ");2724	if (s & SIG_SELI)2725		seq_puts(m, "SELI ");2726	if (s & SIG_BSYI)2727		seq_puts(m, "BSYI ");2728	if (s & SIG_REQI)2729		seq_puts(m, "REQI ");2730	if (s & SIG_ACKI)2731		seq_puts(m, "ACKI ");2732	seq_puts(m, "); ");2733 2734	seq_printf(m, "SELID(%02x), ", GETPORT(SELID));2735 2736	seq_printf(m, "STCNT(%d), ", GETSTCNT());2737 2738	seq_puts(m, "SSTAT2( ");2739 2740	s = GETPORT(SSTAT2);2741	if (s & SOFFSET)2742		seq_puts(m, "SOFFSET ");2743	if (s & SEMPTY)2744		seq_puts(m, "SEMPTY ");2745	if (s & SFULL)2746		seq_puts(m, "SFULL ");2747	seq_printf(m, "); SFCNT (%d); ", s & (SFULL | SFCNT));2748 2749	s = GETPORT(SSTAT3);2750	seq_printf(m, "SCSICNT (%d), OFFCNT(%d), ", (s & 0xf0) >> 4, s & 0x0f);2751 2752	seq_puts(m, "SSTAT4( ");2753	s = GETPORT(SSTAT4);2754	if (s & SYNCERR)2755		seq_puts(m, "SYNCERR ");2756	if (s & FWERR)2757		seq_puts(m, "FWERR ");2758	if (s & FRERR)2759		seq_puts(m, "FRERR ");2760	seq_puts(m, "); ");2761 2762	seq_puts(m, "DMACNTRL0( ");2763	s = GETPORT(DMACNTRL0);2764	seq_printf(m, "%s ", s & _8BIT ? "8BIT" : "16BIT");2765	seq_printf(m, "%s ", s & DMA ? "DMA" : "PIO");2766	seq_printf(m, "%s ", s & WRITE_READ ? "WRITE" : "READ");2767	if (s & ENDMA)2768		seq_puts(m, "ENDMA ");2769	if (s & INTEN)2770		seq_puts(m, "INTEN ");2771	if (s & RSTFIFO)2772		seq_puts(m, "RSTFIFO ");2773	if (s & SWINT)2774		seq_puts(m, "SWINT ");2775	seq_puts(m, "); ");2776 2777	seq_puts(m, "DMASTAT( ");2778	s = GETPORT(DMASTAT);2779	if (s & ATDONE)2780		seq_puts(m, "ATDONE ");2781	if (s & WORDRDY)2782		seq_puts(m, "WORDRDY ");2783	if (s & DFIFOFULL)2784		seq_puts(m, "DFIFOFULL ");2785	if (s & DFIFOEMP)2786		seq_puts(m, "DFIFOEMP ");2787	seq_puts(m, ")\n");2788 2789	seq_puts(m, "enabled interrupts( ");2790 2791	s = GETPORT(SIMODE0);2792	if (s & ENSELDO)2793		seq_puts(m, "ENSELDO ");2794	if (s & ENSELDI)2795		seq_puts(m, "ENSELDI ");2796	if (s & ENSELINGO)2797		seq_puts(m, "ENSELINGO ");2798	if (s & ENSWRAP)2799		seq_puts(m, "ENSWRAP ");2800	if (s & ENSDONE)2801		seq_puts(m, "ENSDONE ");2802	if (s & ENSPIORDY)2803		seq_puts(m, "ENSPIORDY ");2804	if (s & ENDMADONE)2805		seq_puts(m, "ENDMADONE ");2806 2807	s = GETPORT(SIMODE1);2808	if (s & ENSELTIMO)2809		seq_puts(m, "ENSELTIMO ");2810	if (s & ENATNTARG)2811		seq_puts(m, "ENATNTARG ");2812	if (s & ENPHASEMIS)2813		seq_puts(m, "ENPHASEMIS ");2814	if (s & ENBUSFREE)2815		seq_puts(m, "ENBUSFREE ");2816	if (s & ENSCSIPERR)2817		seq_puts(m, "ENSCSIPERR ");2818	if (s & ENPHASECHG)2819		seq_puts(m, "ENPHASECHG ");2820	if (s & ENREQINIT)2821		seq_puts(m, "ENREQINIT ");2822	seq_puts(m, ")\n");2823}2824 2825static int aha152x_set_info(struct Scsi_Host *shpnt, char *buffer, int length)2826{2827	if(!shpnt || !buffer || length<8 || strncmp("aha152x ", buffer, 8)!=0)2828		return -EINVAL;2829 2830#if defined(AHA152X_STAT)2831	if(length>13 && strncmp("reset", buffer+8, 5)==0) {2832		int i;2833 2834		HOSTDATA(shpnt)->total_commands=0;2835		HOSTDATA(shpnt)->disconnections=0;2836		HOSTDATA(shpnt)->busfree_without_any_action=0;2837		HOSTDATA(shpnt)->busfree_without_old_command=0;2838		HOSTDATA(shpnt)->busfree_without_new_command=0;2839		HOSTDATA(shpnt)->busfree_without_done_command=0;2840		HOSTDATA(shpnt)->busfree_with_check_condition=0;2841		for (i = idle; i<maxstate; i++) {2842			HOSTDATA(shpnt)->count[i]=0;2843			HOSTDATA(shpnt)->count_trans[i]=0;2844			HOSTDATA(shpnt)->time[i]=0;2845		}2846 2847		shost_printk(KERN_INFO, shpnt, "aha152x: stats reset.\n");2848 2849	} else2850#endif2851	{2852		return -EINVAL;2853	}2854 2855 2856	return length;2857}2858 2859static int aha152x_show_info(struct seq_file *m, struct Scsi_Host *shpnt)2860{2861	int i;2862	struct scsi_cmnd *ptr;2863	unsigned long flags;2864 2865	seq_puts(m, AHA152X_REVID "\n");2866 2867	seq_printf(m, "ioports 0x%04lx to 0x%04lx\n",2868		shpnt->io_port, shpnt->io_port + shpnt->n_io_port - 1);2869	seq_printf(m, "interrupt 0x%02x\n", shpnt->irq);2870	seq_printf(m, "disconnection/reconnection %s\n",2871		RECONNECT ? "enabled" : "disabled");2872	seq_printf(m, "parity checking %s\n",2873		PARITY ? "enabled" : "disabled");2874	seq_printf(m, "synchronous transfers %s\n",2875		SYNCHRONOUS ? "enabled" : "disabled");2876	seq_printf(m, "%d commands currently queued\n", HOSTDATA(shpnt)->commands);2877 2878	if(SYNCHRONOUS) {2879		seq_puts(m, "synchronously operating targets (tick=50 ns):\n");2880		for (i = 0; i < 8; i++)2881			if (HOSTDATA(shpnt)->syncrate[i] & 0x7f)2882				seq_printf(m, "target %d: period %dT/%dns; req/ack offset %d\n",2883					i,2884					(((HOSTDATA(shpnt)->syncrate[i] & 0x70) >> 4) + 2),2885					(((HOSTDATA(shpnt)->syncrate[i] & 0x70) >> 4) + 2) * 50,2886				    HOSTDATA(shpnt)->syncrate[i] & 0x0f);2887	}2888	seq_puts(m, "\nqueue status:\n");2889	DO_LOCK(flags);2890	if (ISSUE_SC) {2891		seq_puts(m, "not yet issued commands:\n");2892		for (ptr = ISSUE_SC; ptr; ptr = SCNEXT(ptr))2893			get_command(m, ptr);2894	} else2895		seq_puts(m, "no not yet issued commands\n");2896	DO_UNLOCK(flags);2897 2898	if (CURRENT_SC) {2899		seq_puts(m, "current command:\n");2900		get_command(m, CURRENT_SC);2901	} else2902		seq_puts(m, "no current command\n");2903 2904	if (DISCONNECTED_SC) {2905		seq_puts(m, "disconnected commands:\n");2906		for (ptr = DISCONNECTED_SC; ptr; ptr = SCNEXT(ptr))2907			get_command(m, ptr);2908	} else2909		seq_puts(m, "no disconnected commands\n");2910 2911	get_ports(m, shpnt);2912 2913#if defined(AHA152X_STAT)2914	seq_printf(m, "statistics:\n"2915		"total commands:               %d\n"2916		"disconnections:               %d\n"2917		"busfree with check condition: %d\n"2918		"busfree without old command:  %d\n"2919		"busfree without new command:  %d\n"2920		"busfree without done command: %d\n"2921		"busfree without any action:   %d\n"2922		"state      "2923		"transitions  "2924		"count        "2925		"time\n",2926		HOSTDATA(shpnt)->total_commands,2927		HOSTDATA(shpnt)->disconnections,2928		HOSTDATA(shpnt)->busfree_with_check_condition,2929		HOSTDATA(shpnt)->busfree_without_old_command,2930		HOSTDATA(shpnt)->busfree_without_new_command,2931		HOSTDATA(shpnt)->busfree_without_done_command,2932		HOSTDATA(shpnt)->busfree_without_any_action);2933	for(i=0; i<maxstate; i++) {2934		seq_printf(m, "%-10s %-12d %-12d %-12ld\n",2935			states[i].name,2936			HOSTDATA(shpnt)->count_trans[i],2937			HOSTDATA(shpnt)->count[i],2938			HOSTDATA(shpnt)->time[i]);2939	}2940#endif2941	return 0;2942}2943 2944static const struct scsi_host_template aha152x_driver_template = {2945	.module				= THIS_MODULE,2946	.name				= AHA152X_REVID,2947	.proc_name			= "aha152x",2948	.show_info			= aha152x_show_info,2949	.write_info			= aha152x_set_info,2950	.queuecommand			= aha152x_queue,2951	.eh_abort_handler		= aha152x_abort,2952	.eh_device_reset_handler	= aha152x_device_reset,2953	.eh_bus_reset_handler		= aha152x_bus_reset,2954	.bios_param			= aha152x_biosparam,2955	.can_queue			= 1,2956	.this_id			= 7,2957	.sg_tablesize			= SG_ALL,2958	.dma_boundary			= PAGE_SIZE - 1,2959	.cmd_size			= sizeof(struct aha152x_cmd_priv),2960};2961 2962#if !defined(AHA152X_PCMCIA)2963static int setup_count;2964static struct aha152x_setup setup[2];2965 2966/* possible i/o addresses for the AIC-6260; default first */2967static unsigned short ports[] = { 0x340, 0x140 };2968 2969#if !defined(SKIP_BIOSTEST)2970/* possible locations for the Adaptec BIOS; defaults first */2971static unsigned int addresses[] =2972{2973	0xdc000,		/* default first */2974	0xc8000,2975	0xcc000,2976	0xd0000,2977	0xd4000,2978	0xd8000,2979	0xe0000,2980	0xeb800,		/* VTech Platinum SMP */2981	0xf0000,2982};2983 2984/* signatures for various AIC-6[23]60 based controllers.2985   The point in detecting signatures is to avoid useless and maybe2986   harmful probes on ports. I'm not sure that all listed boards pass2987   auto-configuration. For those which fail the BIOS signature is2988   obsolete, because user intervention to supply the configuration is2989   needed anyway.  May be an information whether or not the BIOS supports2990   extended translation could be also useful here. */2991static struct signature {2992	unsigned char *signature;2993	int sig_offset;2994	int sig_length;2995} signatures[] =2996{2997	{ "Adaptec AHA-1520 BIOS",	0x102e, 21 },2998		/* Adaptec 152x */2999	{ "Adaptec AHA-1520B",		0x000b, 17 },3000		/* Adaptec 152x rev B */3001	{ "Adaptec AHA-1520B",		0x0026, 17 },3002		/* Iomega Jaz Jet ISA (AIC6370Q) */3003	{ "Adaptec ASW-B626 BIOS",	0x1029, 21 },3004		/* on-board controller */3005	{ "Adaptec BIOS: ASW-B626",	0x000f, 22 },3006		/* on-board controller */3007	{ "Adaptec ASW-B626 S2",	0x2e6c, 19 },3008		/* on-board controller */3009	{ "Adaptec BIOS:AIC-6360",	0x000c, 21 },3010		/* on-board controller */3011	{ "ScsiPro SP-360 BIOS",	0x2873, 19 },3012		/* ScsiPro-Controller  */3013	{ "GA-400 LOCAL BUS SCSI BIOS", 0x102e, 26 },3014		/* Gigabyte Local-Bus-SCSI */3015	{ "Adaptec BIOS:AVA-282X",	0x000c, 21 },3016		/* Adaptec 282x */3017	{ "Adaptec IBM Dock II SCSI",   0x2edd, 24 },3018		/* IBM Thinkpad Dock II */3019	{ "Adaptec BIOS:AHA-1532P",     0x001c, 22 },3020		/* IBM Thinkpad Dock II SCSI */3021	{ "DTC3520A Host Adapter BIOS", 0x318a, 26 },3022		/* DTC 3520A ISA SCSI */3023};3024#endif /* !SKIP_BIOSTEST */3025 3026/*3027 * Test, if port_base is valid.3028 *3029 */3030static int aha152x_porttest(int io_port)3031{3032	int i;3033 3034	SETPORT(io_port + O_DMACNTRL1, 0);	/* reset stack pointer */3035	for (i = 0; i < 16; i++)3036		SETPORT(io_port + O_STACK, i);3037 3038	SETPORT(io_port + O_DMACNTRL1, 0);	/* reset stack pointer */3039	for (i = 0; i < 16 && GETPORT(io_port + O_STACK) == i; i++)3040		;3041 3042	return (i == 16);3043}3044 3045static int tc1550_porttest(int io_port)3046{3047	int i;3048 3049	SETPORT(io_port + O_TC_DMACNTRL1, 0);	/* reset stack pointer */3050	for (i = 0; i < 16; i++)3051		SETPORT(io_port + O_STACK, i);3052 3053	SETPORT(io_port + O_TC_DMACNTRL1, 0);	/* reset stack pointer */3054	for (i = 0; i < 16 && GETPORT(io_port + O_TC_STACK) == i; i++)3055		;3056 3057	return (i == 16);3058}3059 3060 3061static int checksetup(struct aha152x_setup *setup)3062{3063	int i;3064	for (i = 0; i < ARRAY_SIZE(ports) && (setup->io_port != ports[i]); i++)3065		;3066 3067	if (i == ARRAY_SIZE(ports))3068		return 0;3069 3070	if (!request_region(setup->io_port, IO_RANGE, "aha152x")) {3071		printk(KERN_ERR "aha152x: io port 0x%x busy.\n", setup->io_port);3072		return 0;3073	}3074 3075	if( aha152x_porttest(setup->io_port) ) {3076		setup->tc1550=0;3077	} else if( tc1550_porttest(setup->io_port) ) {3078		setup->tc1550=1;3079	} else {3080		release_region(setup->io_port, IO_RANGE);3081		return 0;3082	}3083 3084	release_region(setup->io_port, IO_RANGE);3085 3086	if ((setup->irq < IRQ_MIN) || (setup->irq > IRQ_MAX))3087		return 0;3088 3089	if ((setup->scsiid < 0) || (setup->scsiid > 7))3090		return 0;3091 3092	if ((setup->reconnect < 0) || (setup->reconnect > 1))3093		return 0;3094 3095	if ((setup->parity < 0) || (setup->parity > 1))3096		return 0;3097 3098	if ((setup->synchronous < 0) || (setup->synchronous > 1))3099		return 0;3100 3101	if ((setup->ext_trans < 0) || (setup->ext_trans > 1))3102		return 0;3103 3104 3105	return 1;3106}3107 3108 3109static int __init aha152x_init(void)3110{3111	int i, j, ok;3112#if defined(AUTOCONF)3113	aha152x_config conf;3114#endif3115#ifdef __ISAPNP__3116	struct pnp_dev *dev=NULL, *pnpdev[2] = {NULL, NULL};3117#endif3118 3119	if ( setup_count ) {3120		printk(KERN_INFO "aha152x: processing commandline: ");3121 3122		for (i = 0; i<setup_count; i++) {3123			if (!checksetup(&setup[i])) {3124				printk(KERN_ERR "\naha152x: %s\n", setup[i].conf);3125				printk(KERN_ERR "aha152x: invalid line\n");3126			}3127		}3128		printk("ok\n");3129	}3130 3131#if defined(SETUP0)3132	if (setup_count < ARRAY_SIZE(setup)) {3133		struct aha152x_setup override = SETUP0;3134 3135		if (setup_count == 0 || (override.io_port != setup[0].io_port)) {3136			if (!checksetup(&override)) {3137				printk(KERN_ERR "\naha152x: invalid override SETUP0={0x%x,%d,%d,%d,%d,%d,%d,%d}\n",3138				       override.io_port,3139				       override.irq,3140				       override.scsiid,3141				       override.reconnect,3142				       override.parity,3143				       override.synchronous,3144				       override.delay,3145				       override.ext_trans);3146			} else3147				setup[setup_count++] = override;3148		}3149	}3150#endif3151 3152#if defined(SETUP1)3153	if (setup_count < ARRAY_SIZE(setup)) {3154		struct aha152x_setup override = SETUP1;3155 3156		if (setup_count == 0 || (override.io_port != setup[0].io_port)) {3157			if (!checksetup(&override)) {3158				printk(KERN_ERR "\naha152x: invalid override SETUP1={0x%x,%d,%d,%d,%d,%d,%d,%d}\n",3159				       override.io_port,3160				       override.irq,3161				       override.scsiid,3162				       override.reconnect,3163				       override.parity,3164				       override.synchronous,3165				       override.delay,3166				       override.ext_trans);3167			} else3168				setup[setup_count++] = override;3169		}3170	}3171#endif3172 3173#if defined(MODULE)3174	if (setup_count<ARRAY_SIZE(setup) && (aha152x[0]!=0 || io[0]!=0 || irq[0]!=0)) {3175		if(aha152x[0]!=0) {3176			setup[setup_count].conf        = "";3177			setup[setup_count].io_port     = aha152x[0];3178			setup[setup_count].irq         = aha152x[1];3179			setup[setup_count].scsiid      = aha152x[2];3180			setup[setup_count].reconnect   = aha152x[3];3181			setup[setup_count].parity      = aha152x[4];3182			setup[setup_count].synchronous = aha152x[5];3183			setup[setup_count].delay       = aha152x[6];3184			setup[setup_count].ext_trans   = aha152x[7];3185		} else if (io[0] != 0 || irq[0] != 0) {3186			if(io[0]!=0)  setup[setup_count].io_port = io[0];3187			if(irq[0]!=0) setup[setup_count].irq     = irq[0];3188 3189			setup[setup_count].scsiid      = scsiid[0];3190			setup[setup_count].reconnect   = reconnect[0];3191			setup[setup_count].parity      = parity[0];3192			setup[setup_count].synchronous = sync[0];3193			setup[setup_count].delay       = delay[0];3194			setup[setup_count].ext_trans   = exttrans[0];3195		}3196 3197		if (checksetup(&setup[setup_count]))3198			setup_count++;3199		else3200			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",3201			       setup[setup_count].io_port,3202			       setup[setup_count].irq,3203			       setup[setup_count].scsiid,3204			       setup[setup_count].reconnect,3205			       setup[setup_count].parity,3206			       setup[setup_count].synchronous,3207			       setup[setup_count].delay,3208			       setup[setup_count].ext_trans);3209	}3210 3211	if (setup_count<ARRAY_SIZE(setup) && (aha152x1[0]!=0 || io[1]!=0 || irq[1]!=0)) {3212		if(aha152x1[0]!=0) {3213			setup[setup_count].conf        = "";3214			setup[setup_count].io_port     = aha152x1[0];3215			setup[setup_count].irq         = aha152x1[1];3216			setup[setup_count].scsiid      = aha152x1[2];3217			setup[setup_count].reconnect   = aha152x1[3];3218			setup[setup_count].parity      = aha152x1[4];3219			setup[setup_count].synchronous = aha152x1[5];3220			setup[setup_count].delay       = aha152x1[6];3221			setup[setup_count].ext_trans   = aha152x1[7];3222		} else if (io[1] != 0 || irq[1] != 0) {3223			if(io[1]!=0)  setup[setup_count].io_port = io[1];3224			if(irq[1]!=0) setup[setup_count].irq     = irq[1];3225 3226			setup[setup_count].scsiid      = scsiid[1];3227			setup[setup_count].reconnect   = reconnect[1];3228			setup[setup_count].parity      = parity[1];3229			setup[setup_count].synchronous = sync[1];3230			setup[setup_count].delay       = delay[1];3231			setup[setup_count].ext_trans   = exttrans[1];3232		}3233		if (checksetup(&setup[setup_count]))3234			setup_count++;3235		else3236			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",3237			       setup[setup_count].io_port,3238			       setup[setup_count].irq,3239			       setup[setup_count].scsiid,3240			       setup[setup_count].reconnect,3241			       setup[setup_count].parity,3242			       setup[setup_count].synchronous,3243			       setup[setup_count].delay,3244			       setup[setup_count].ext_trans);3245	}3246#endif3247 3248#ifdef __ISAPNP__3249	for(i=0; setup_count<ARRAY_SIZE(setup) && id_table[i].vendor; i++) {3250		while ( setup_count<ARRAY_SIZE(setup) &&3251			(dev=pnp_find_dev(NULL, id_table[i].vendor, id_table[i].function, dev)) ) {3252			if (pnp_device_attach(dev) < 0)3253				continue;3254 3255			if (pnp_activate_dev(dev) < 0) {3256				pnp_device_detach(dev);3257				continue;3258			}3259 3260			if (!pnp_port_valid(dev, 0)) {3261				pnp_device_detach(dev);3262				continue;3263			}3264 3265			if (setup_count==1 && pnp_port_start(dev, 0)==setup[0].io_port) {3266				pnp_device_detach(dev);3267				continue;3268			}3269 3270			setup[setup_count].io_port     = pnp_port_start(dev, 0);3271			setup[setup_count].irq         = pnp_irq(dev, 0);3272			setup[setup_count].scsiid      = 7;3273			setup[setup_count].reconnect   = 1;3274			setup[setup_count].parity      = 1;3275			setup[setup_count].synchronous = 1;3276			setup[setup_count].delay       = DELAY_DEFAULT;3277			setup[setup_count].ext_trans   = 0;3278#if defined(__ISAPNP__)3279			pnpdev[setup_count]            = dev;3280#endif3281			printk (KERN_INFO3282				"aha152x: found ISAPnP adapter at io=0x%03x, irq=%d\n",3283				setup[setup_count].io_port, setup[setup_count].irq);3284			setup_count++;3285		}3286	}3287#endif3288 3289#if defined(AUTOCONF)3290	if (setup_count<ARRAY_SIZE(setup)) {3291#if !defined(SKIP_BIOSTEST)3292		ok = 0;3293		for (i = 0; i < ARRAY_SIZE(addresses) && !ok; i++) {3294			void __iomem *p = ioremap(addresses[i], 0x4000);3295			if (!p)3296				continue;3297			for (j = 0; j<ARRAY_SIZE(signatures) && !ok; j++)3298				ok = check_signature(p + signatures[j].sig_offset,3299								signatures[j].signature, signatures[j].sig_length);3300			iounmap(p);3301		}3302		if (!ok && setup_count == 0)3303			return -ENODEV;3304 3305		printk(KERN_INFO "aha152x: BIOS test: passed, ");3306#else3307		printk(KERN_INFO "aha152x: ");3308#endif				/* !SKIP_BIOSTEST */3309 3310		ok = 0;3311		for (i = 0; i < ARRAY_SIZE(ports) && setup_count < 2; i++) {3312			if ((setup_count == 1) && (setup[0].io_port == ports[i]))3313				continue;3314 3315			if (!request_region(ports[i], IO_RANGE, "aha152x")) {3316				printk(KERN_ERR "aha152x: io port 0x%x busy.\n", ports[i]);3317				continue;3318			}3319 3320			if (aha152x_porttest(ports[i])) {3321				setup[setup_count].tc1550  = 0;3322 3323				conf.cf_port =3324				    (GETPORT(ports[i] + O_PORTA) << 8) + GETPORT(ports[i] + O_PORTB);3325			} else if (tc1550_porttest(ports[i])) {3326				setup[setup_count].tc1550  = 1;3327 3328				conf.cf_port =3329				    (GETPORT(ports[i] + O_TC_PORTA) << 8) + GETPORT(ports[i] + O_TC_PORTB);3330			} else {3331				release_region(ports[i], IO_RANGE);3332				continue;3333			}3334 3335			release_region(ports[i], IO_RANGE);3336 3337			ok++;3338			setup[setup_count].io_port = ports[i];3339			setup[setup_count].irq = IRQ_MIN + conf.cf_irq;3340			setup[setup_count].scsiid = conf.cf_id;3341			setup[setup_count].reconnect = conf.cf_tardisc;3342			setup[setup_count].parity = !conf.cf_parity;3343			setup[setup_count].synchronous = conf.cf_syncneg;3344			setup[setup_count].delay = DELAY_DEFAULT;3345			setup[setup_count].ext_trans = 0;3346			setup_count++;3347 3348		}3349 3350		if (ok)3351			printk("auto configuration: ok, ");3352	}3353#endif3354 3355	printk("%d controller(s) configured\n", setup_count);3356 3357	for (i=0; i<setup_count; i++) {3358		if ( request_region(setup[i].io_port, IO_RANGE, "aha152x") ) {3359			struct Scsi_Host *shpnt = aha152x_probe_one(&setup[i]);3360 3361			if( !shpnt ) {3362				release_region(setup[i].io_port, IO_RANGE);3363#if defined(__ISAPNP__)3364			} else if( pnpdev[i] ) {3365				HOSTDATA(shpnt)->pnpdev=pnpdev[i];3366				pnpdev[i]=NULL;3367#endif3368			}3369		} else {3370			printk(KERN_ERR "aha152x: io port 0x%x busy.\n", setup[i].io_port);3371		}3372 3373#if defined(__ISAPNP__)3374		if( pnpdev[i] )3375			pnp_device_detach(pnpdev[i]);3376#endif3377	}3378 3379	return 0;3380}3381 3382static void __exit aha152x_exit(void)3383{3384	struct aha152x_hostdata *hd, *tmp;3385 3386	list_for_each_entry_safe(hd, tmp, &aha152x_host_list, host_list) {3387		struct Scsi_Host *shost = container_of((void *)hd, struct Scsi_Host, hostdata);3388 3389		aha152x_release(shost);3390	}3391}3392 3393module_init(aha152x_init);3394module_exit(aha152x_exit);3395 3396#if !defined(MODULE)3397static int __init aha152x_setup(char *str)3398{3399	int ints[10];3400 3401	get_options(str, ARRAY_SIZE(ints), ints);3402 3403	if(setup_count>=ARRAY_SIZE(setup)) {3404		printk(KERN_ERR "aha152x: you can only configure up to two controllers\n");3405		return 1;3406	}3407 3408	setup[setup_count].conf        = str;3409	setup[setup_count].io_port     = ints[0] >= 1 ? ints[1] : 0x340;3410	setup[setup_count].irq         = ints[0] >= 2 ? ints[2] : 11;3411	setup[setup_count].scsiid      = ints[0] >= 3 ? ints[3] : 7;3412	setup[setup_count].reconnect   = ints[0] >= 4 ? ints[4] : 1;3413	setup[setup_count].parity      = ints[0] >= 5 ? ints[5] : 1;3414	setup[setup_count].synchronous = ints[0] >= 6 ? ints[6] : 1;3415	setup[setup_count].delay       = ints[0] >= 7 ? ints[7] : DELAY_DEFAULT;3416	setup[setup_count].ext_trans   = ints[0] >= 8 ? ints[8] : 0;3417	if (ints[0] > 8)3418		printk(KERN_NOTICE "aha152x: usage: aha152x=<IOBASE>[,<IRQ>[,<SCSI ID>"3419		       "[,<RECONNECT>[,<PARITY>[,<SYNCHRONOUS>[,<DELAY>[,<EXT_TRANS>]]]]]]]\n");3420	else3421		setup_count++;3422 3423	return 1;3424}3425__setup("aha152x=", aha152x_setup);3426#endif3427 3428#endif /* !AHA152X_PCMCIA */3429