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