xref: /csrg-svn/sys/dev/scsi/scsivar.h (revision 63144)
154880Storek /*
2*63144Sbostic  * Copyright (c) 1992, 1993
3*63144Sbostic  *	The Regents of the University of California.  All rights reserved.
454880Storek  *
554880Storek  * This software was developed by the Computer Systems Engineering group
654880Storek  * at Lawrence Berkeley Laboratory under DARPA contract BG 91-66 and
754880Storek  * contributed to Berkeley.
854880Storek  *
955559Storek  * All advertising materials mentioning features or use of this software
1055559Storek  * must display the following acknowledgement:
1155559Storek  *	This product includes software developed by the University of
1255559Storek  *	California, Lawrence Berkeley Laboratories.
1355559Storek  *
1454880Storek  * %sccs.include.redist.c%
1554880Storek  *
16*63144Sbostic  *	@(#)scsivar.h	8.1 (Berkeley) 06/10/93
1754880Storek  *
1857756Storek  * from: $Header: scsivar.h,v 1.7 92/12/02 03:54:05 torek Exp $ (LBL)
1954880Storek  */
2054880Storek 
2154880Storek /*
2254880Storek  * SCSI variables.
2354880Storek  *
2454880Storek  * Each SCSI Host Bus Adapter (hba) has:
2554880Storek  *	a target queue head and tail
2654880Storek  *	eight targets (for units to enqueue on)
2754880Storek  *	a list of all units on all targets
2854880Storek  *	its target number (the number cpu uses in initiating requests)
2954880Storek  *	a driver
3054880Storek  * Each SCSI target has:
3154880Storek  *	a forward link so that it can sit on a SCSI host bus adapter queue
3254880Storek  *	a unit queue head and tail
3354880Storek  * Each SCSI unit has:
3454880Storek  *	a forward link so that it can sit on a SCSI target queue
3554880Storek  *	a driver
3654880Storek  *	an hba & driver (so that we need not chase parent pointers)
3754880Storek  */
3854880Storek 
3954880Storek /*
4054880Storek  * Downcalls.  These are usually made from hba to unit, but can be
4154880Storek  * hba->target->unit (when there are multiple units on a target).
4254880Storek  */
4354880Storek /* device go function (`you got bus') */
4454880Storek typedef void (*scdgo_fn) __P((struct device *, struct scsi_cdb *));
4554880Storek 
4654880Storek /* intr function (`you no got bus no more') */
4754880Storek typedef void (*scintr_fn) __P((struct device *, int stat, int resid));
4854880Storek 
4954880Storek /*
5054880Storek  * Upcalls.  These are usually made from unit to hba, but can be
5154880Storek  * unit->target->hba.
5254880Storek  */
5354880Storek /* bus alloc function (`please get me bus') */
5454880Storek struct sq; struct buf;
5554880Storek typedef void (*scstart_fn) __P((struct device *, struct sq *, struct buf *,
5654880Storek 				scdgo_fn, struct device *));
5754880Storek 
5854880Storek /* bus go function (`I have bus and I set up cmd, so start it up') */
5954880Storek typedef int (*scbusgo_fn) __P((struct device *, int targ,
6054880Storek 				scintr_fn, struct device *,
6154880Storek 				struct buf *, int pad));
6254880Storek 
6354880Storek /* bus release function (`I have bus but do not need it after all') */
6454880Storek typedef void (*scbusrel_fn) __P((struct device *));
6554880Storek 
6654880Storek /*
6754880Storek  * SCSI Queue.  This is an element in a queue of devices (targets
6854880Storek  * and/or units) waiting for the bus.
6954880Storek  */
7054880Storek struct sq {
7154880Storek 	struct	sq *sq_forw;		/* forward link */
7254880Storek 	struct	buf *sq_bp;		/* buffer for transfer */
7354880Storek 	scdgo_fn sq_dgo;		/* device-go to call when got bus */
7454880Storek 	struct	device *sq_dev;		/* device argument to sq_dgo */
7554880Storek };
7654880Storek 
7754880Storek struct hba_softc {
7854880Storek 	struct	device hba_dev;		/* generic part */
7954880Storek 	struct	sq *hba_head, *hba_tail;/* io queue (u's/t's wanting bus) */
8054880Storek 	char	hba_busy;		/* true => will inspect qhead later */
8154880Storek 	struct	targ *hba_targets[8];	/* the 8 possible targets */
8254880Storek 	struct	hbadriver *hba_driver;	/* hba driver */
8354880Storek 	scintr_fn hba_intr;		/* current interrupt function */
8454880Storek 	struct	device *hba_intrdev;	/* arg 0 for hba_intr */
8554880Storek };
8654880Storek 
8754880Storek struct targ {
8854880Storek 	struct	device t_dev;		/* generic part */
8954880Storek 	struct	sq t_forw;		/* forward link, etc, on hba queue */
9054880Storek 	struct	sq *t_head, *t_tail;	/* io queue */
9154880Storek 	char	t_busy;			/* true => will inspect qhead later */
9254880Storek 	char	t_targ;			/* target number */
9354880Storek 	char	t_nunits;		/* count of live units */
9454880Storek 	char	t_firstunit;		/* the first live unit */
9554880Storek 	struct	unit *t_units[8];	/* the 8 possible units */
9654880Storek 	scintr_fn t_intr;		/* current interrupt function */
9754880Storek 	struct	device *t_intrdev;	/* arg 0 for t_intr */
9854880Storek };
9954880Storek 
10054880Storek /* since a unit may be a disk, tape, etc., it has only pointer to dev */
10154880Storek struct unit {
10254880Storek 	struct	device *u_dev;		/* backpointer to generic */
10354880Storek 	int	u_unit;			/* unit number on target */
10454880Storek 	scstart_fn u_start;		/* upcall to get bus */
10554880Storek 	scbusgo_fn u_go;		/* upcall to use bus */
10654880Storek 	scbusrel_fn u_rel;		/* upcall to release bus early */
10754880Storek 	struct	device *u_updev;	/* device for upcalls */
10854880Storek 	struct	sq u_forw;		/* forward link on target or hba q */
10954880Storek 	struct	unitdriver *u_driver;	/* unit driver */
11054880Storek /* the following three fields are copied from target & hba, for quick lookup */
11154880Storek 	int	u_targ;			/* target number */
11254880Storek 	struct	hba_softc *u_hba;	/* hba, from parent */
11354880Storek 	struct	hbadriver *u_hbd;	/* hba driver, from parent */
11454880Storek };
11554880Storek 
11654880Storek /*
11754880Storek  * SCSI hba driver.
11854880Storek  */
11954880Storek struct hbadriver {
12054880Storek 	/* immediate command; should not depend on receiving interrupts */
12154880Storek 	int	(*hd_icmd) __P((struct hba_softc *, int targ,
12254880Storek 				struct scsi_cdb *cmd,
12354880Storek 				caddr_t addr, int len, int rw));
12454880Storek 	/* crash dump: like icmd(B_WRITE), but possibly from physmem */
12554880Storek 	int	(*hd_dump) __P((struct hba_softc *, int targ,
12654880Storek 				struct scsi_cdb *cmd, caddr_t addr, int len));
12754880Storek 	scstart_fn hd_start;	/* allocate DMA & bus */
12854880Storek 	scbusgo_fn hd_go;	/* start DMA xfer on bus */
12954880Storek 	scbusrel_fn hd_rel;	/* release bus early */
13054880Storek 	void	(*hd_reset) __P((struct hba_softc *, int));
13154880Storek };
13254880Storek 
13354880Storek /*
13454880Storek  * SCSI unit driver (`downcalls' from hba to unit).
13554880Storek  */
13654880Storek struct unitdriver {
13754880Storek 	void	(*ud_reset) __P((struct unit *));	/* SCSI bus reset */
13854880Storek };
13954880Storek 
14054880Storek /*
14154880Storek  * The generic SCSI target probe code passes the following to
14254880Storek  * unit configuration `match' routines.
14354880Storek  */
14454880Storek struct scsi_attach_args {
14554880Storek 	int	sa_targ;		/* target number */
14654880Storek 	int	sa_unit;		/* unit number */
14754880Storek 	int	sa_req_status;		/* status from REQUEST SENSE */
14854880Storek 	struct	scsi_sense sa_sn;	/* contents from same */
14954880Storek 	int	sa_inq_status;		/* status from INQUIRY command */
15054880Storek 	struct	scsi_inquiry sa_si;	/* contents from same */
15154880Storek };
15254880Storek 
15354880Storek /*
15454880Storek  * The SCSICMDLEN macro gives the SCSI-standard-defined length of
15554880Storek  * a given SCSI command.  This is 0 if the command is in an undefined
15654880Storek  * group (see scsi.h).
15754880Storek  */
15854880Storek extern const char scsicmdlen[8];
15954880Storek #define	SCSICMDLEN(cmd) scsicmdlen[(cmd) >> 5]
16054880Storek 
16154880Storek /*
16254880Storek  * The SCSIMSGLEN macro gives the SCSI-standard-defined length of
16354880Storek  * a given SCSI message byte.  This is -1 if the message byte is
16454880Storek  * undefined, -3 if it is an identify, -2 for an extended message,
16554880Storek  * 0 if it is normal completion, otherwise positive.
16654880Storek  */
16754880Storek #define	SMLEN_IDENTIFY	-3
16854880Storek #define	SMLEN_EXTENDED	-2
16954880Storek #define	SMLEN_UNDEF	-1
17054880Storek #define	SMLEN_DONE	0
17154880Storek extern const signed char scsimsglen[0x24];
17254880Storek #define	SCSIMSGLEN(msg) ((msg) & MSG_IDENTIFY ? SMLEN_IDENTIFY : \
17354880Storek 			 (msg) > 0x24 ? SMLEN_UNDEF : scsimsglen[msg])
17454880Storek 
17554880Storek /*
17654880Storek  * Declarations for exported functions in scsi_subr.c
17754880Storek  */
17854880Storek int	scsi_test_unit_ready __P((struct hba_softc *, int targ, int unit));
17954880Storek int	scsi_request_sense __P((struct hba_softc *, int, int, caddr_t, int));
18054880Storek void	scsi_hbaattach __P((struct hba_softc *));
18154880Storek void	scsi_establish __P((struct unit *, struct device *, int));
18254880Storek void	scsi_printinq __P((struct scsi_inquiry *));
18354880Storek void	scsi_inq_ansi __P((struct scsi_inq_ansi *, char *, char *, char *));
18454880Storek void	scsi_reset_units __P((struct hba_softc *));
18554880Storek 
18654880Storek #define	SCSI_FOUNDTARGET(hba, targ) { \
18754880Storek 	extern int scsi_targprint(void *, char *); \
18854880Storek 	int _t = targ; \
18954880Storek 	config_found(&(hba)->hba_dev, (void *)&_t, scsi_targprint); \
19054880Storek }
191