Remove hard coded assumption that SCSI busses have 7 targets.

This change forces the controller drivers to allocate a scsibus_data struct
via a call to scsi_alloc_bus(), fill in the adapter_link field, and optionally
modify any other fields of the struct.  Scsi_alloc_bus() initializes all fields
to the default, so the changes in most drivers are very minimal.  For drivers
that support Wide controllers, the maxtarg field will have to be updated to
allow probing of all targets (for an example, look at the aic7xxx driver).

Scsi_attachdevs() now takes a scsibus_data* as its argument instead of an
sc_link*.  This allows us to expand the role of the scsibus_data struct for
other bus level configuration setings (max number of transactions, current
transaction opennings, etc for better tagged queuing support).

Reviewed by: Rodney Grimes <rgrimes>, Peter Dufault <dufault>, Julian Elischer <julian>
This commit is contained in:
gibbs 1995-08-23 23:03:34 +00:00
parent 11e9122e64
commit ae1e6673d9
12 changed files with 176 additions and 38 deletions

View File

@ -14,7 +14,7 @@
*
* commenced: Sun Sep 27 18:14:01 PDT 1992
*
* $Id: aha1742.c,v 1.34 1995/05/30 08:01:07 rgrimes Exp $
* $Id: aha1742.c,v 1.35 1995/07/25 15:53:07 bde Exp $
*/
#include <sys/types.h>
@ -539,6 +539,7 @@ ahb_attach(dev)
{
int unit = dev->id_unit;
struct ahb_data *ahb = ahbdata[unit];
struct scsibus_data *scbus;
/*
* fill in the prototype scsi_link.
@ -548,11 +549,20 @@ ahb_attach(dev)
ahb->sc_link.adapter = &ahb_switch;
ahb->sc_link.device = &ahb_dev;
/*
* Prepare the scsibus_data area for the upperlevel
* scsi code.
*/
scbus = scsi_alloc_bus();
if(!scbus)
return 0;
scbus->adapter_link = &ahb->sc_link;
kdc_ahb[unit].kdc_state = DC_BUSY; /* host adapters are always busy */
/*
* ask the adapter what subunits are present
*/
scsi_attachdevs(&(ahb->sc_link));
scsi_attachdevs(scbus);
return 1;
}

View File

@ -12,7 +12,7 @@
* on the understanding that TFS is not responsible for the correct
* functioning of this software in any circumstances.
*
* $Id: aha1542.c,v 1.44 1995/04/14 15:13:46 dufault Exp $
* $Id: aha1542.c,v 1.45 1995/05/30 08:01:05 rgrimes Exp $
*/
/*
@ -623,6 +623,7 @@ ahaattach(dev)
{
int unit = dev->id_unit;
struct aha_data *aha = ahadata[unit];
struct scsibus_data *scbus;
/*
* fill in the prototype scsi_link.
@ -633,11 +634,20 @@ ahaattach(dev)
aha->sc_link.device = &aha_dev;
aha->sc_link.flags = aha->flags;;
/*
* Prepare the scsibus_data area for the upperlevel
* scsi code.
*/
scbus = scsi_alloc_bus();
if(!scbus)
return 0;
scbus->adapter_link = &aha->sc_link;
/*
* ask the adapter what subunits are present
*/
kdc_aha[unit].kdc_state = DC_BUSY; /* host adapters are always busy */
scsi_attachdevs(&(aha->sc_link));
scsi_attachdevs(scbus);
return 1;
}

View File

@ -14,7 +14,7 @@
*
* commenced: Sun Sep 27 18:14:01 PDT 1992
*
* $Id: aha1742.c,v 1.34 1995/05/30 08:01:07 rgrimes Exp $
* $Id: aha1742.c,v 1.35 1995/07/25 15:53:07 bde Exp $
*/
#include <sys/types.h>
@ -539,6 +539,7 @@ ahb_attach(dev)
{
int unit = dev->id_unit;
struct ahb_data *ahb = ahbdata[unit];
struct scsibus_data *scbus;
/*
* fill in the prototype scsi_link.
@ -548,11 +549,20 @@ ahb_attach(dev)
ahb->sc_link.adapter = &ahb_switch;
ahb->sc_link.device = &ahb_dev;
/*
* Prepare the scsibus_data area for the upperlevel
* scsi code.
*/
scbus = scsi_alloc_bus();
if(!scbus)
return 0;
scbus->adapter_link = &ahb->sc_link;
kdc_ahb[unit].kdc_state = DC_BUSY; /* host adapters are always busy */
/*
* ask the adapter what subunits are present
*/
scsi_attachdevs(&(ahb->sc_link));
scsi_attachdevs(scbus);
return 1;
}

View File

@ -31,7 +31,7 @@
*/
/*
* $Id: aic6360.c,v 1.8 1995/04/12 20:47:35 wollman Exp $
* $Id: aic6360.c,v 1.9 1995/05/30 08:01:12 rgrimes Exp $
*
* Acknowledgements: Many of the algorithms used in this driver are
* inspired by the work of Julian Elischer (julian@tfs.com) and
@ -940,6 +940,7 @@ aicattach(parent, self, aux)
#ifdef __FreeBSD__
int unit = dev->id_unit;
struct aic_data *aic = aicdata[unit];
struct scsibus_data *scbus;
#else
struct isa_attach_args *ia = aux;
struct aic_softc *aic = (void *)self;
@ -963,11 +964,20 @@ aicattach(parent, self, aux)
aic->sc_link.device = &aic_dev;
#ifdef __FreeBSD__
/*
* Prepare the scsibus_data area for the upperlevel
* scsi code.
*/
scbus = scsi_alloc_bus();
if(!scbus)
return 0;
scbus->adapter_link = &aic->sc_link;
/*
* ask the adapter what subunits are present
*/
kdc_aic[unit].kdc_state = DC_BUSY; /* host adapters are always busy */
scsi_attachdevs(&(aic->sc_link));
scsi_attachdevs(scbus);
return 1;
#else

View File

@ -12,7 +12,7 @@
* on the understanding that TFS is not responsible for the correct
* functioning of this software in any circumstances.
*
* $Id: bt742a.c,v 1.38 1995/06/25 17:45:05 joerg Exp $
* $Id: bt742a.c,v 1.39 1995/07/25 16:06:06 bde Exp $
*/
/*
@ -692,6 +692,7 @@ btattach(dev)
{
int unit = dev->id_unit;
struct bt_data *bt = btdata[unit];
struct scsibus_data *scbus;
btprobing = 0;
/*
@ -703,12 +704,22 @@ btattach(dev)
bt->sc_link.device = &bt_dev;
bt->sc_link.flags = SDEV_BOUNCE;
/*
* Prepare the scsibus_data area for the upperlevel
* scsi code.
*/
scbus = scsi_alloc_bus();
/* XXX scbus->magtarg should be adjusted for Wide cards */
if(!scbus)
return 0;
scbus->adapter_link = &bt->sc_link;
kdc_bt[unit].kdc_state = DC_BUSY; /* host adapters are always busy */
/*
* ask the adapter what subunits are present
*/
scsi_attachdevs(&(bt->sc_link));
scsi_attachdevs(scbus);
return 1;
}

View File

@ -495,6 +495,7 @@ int nca_attach (struct isa_device *dev)
{
int unit = dev->id_unit;
adapter_t *z = &ncadata[unit];
struct scsibus_data *scbus;
sprintf (nca_description, "%s SCSI controller", z->name);
printf ("nca%d: type %s%s\n", unit, z->name,
@ -506,9 +507,18 @@ int nca_attach (struct isa_device *dev)
z->sc_link.adapter = &nca_switch;
z->sc_link.device = &nca_dev;
/*
* Prepare the scsibus_data area for the upperlevel
* scsi code.
*/
scbus = scsi_alloc_bus();
if(!scbus)
return 0;
scbus->adapter_link = &z->sc_link;
/* ask the adapter what subunits are present */
nca_kdc[unit].kdc_state = DC_BUSY;
scsi_attachdevs (&(z->sc_link));
scsi_attachdevs (scbus);
return (1);
}

View File

@ -60,7 +60,7 @@
* that category, with the possible exception of scanners and
* some of the older MO drives.
*
* $Id: seagate.c,v 1.8 1995/05/30 08:03:04 rgrimes Exp $
* $Id: seagate.c,v 1.9 1995/07/13 15:01:38 jkh Exp $
*/
/*
@ -547,6 +547,7 @@ int sea_attach (struct isa_device *dev)
{
int unit = dev->id_unit;
adapter_t *z = &seadata[unit];
struct scsibus_data *scbus;
sea_kdc[unit].kdc_state = DC_BUSY; /* host adapters are always busy */
sprintf (sea_description, "%s SCSI controller", z->name);
@ -559,8 +560,17 @@ int sea_attach (struct isa_device *dev)
z->sc_link.adapter = &sea_switch;
z->sc_link.device = &sea_dev;
/*
* Prepare the scsibus_data area for the upperlevel
* scsi code.
*/
scbus = scsi_alloc_bus();
if(!scbus)
return 0;
scbus->adapter_link = &z->sc_link;
/* ask the adapter what subunits are present */
scsi_attachdevs (&(z->sc_link));
scsi_attachdevs (scbus);
return (1);
}

View File

@ -22,7 +22,7 @@
* today: Fri Jun 2 17:21:03 EST 1994
* added 24F support ++sg
*
* $Id: ultra14f.c,v 1.33 1995/05/30 08:03:18 rgrimes Exp $
* $Id: ultra14f.c,v 1.34 1995/07/25 15:53:11 bde Exp $
*/
#include <sys/types.h>
@ -542,6 +542,7 @@ uha_attach(dev)
{
int unit = dev->id_unit;
struct uha_data *uha = uhadata[unit];
struct scsibus_data *scbus;
/*
* fill in the prototype scsi_link.
@ -552,11 +553,20 @@ uha_attach(dev)
uha->sc_link.device = &uha_dev;
uha->sc_link.flags = SDEV_BOUNCE;
/*
* Prepare the scsibus_data area for the upperlevel
* scsi code.
*/
scbus = scsi_alloc_bus();
if(!scbus)
return 0;
scbus->adapter_link = &uha->sc_link;
kdc_uha[unit].kdc_state = DC_BUSY;
/*
* ask the adapter what subunits are present
*/
scsi_attachdevs(&(uha->sc_link));
scsi_attachdevs(scbus);
return 1;
}

View File

@ -616,6 +616,7 @@ wdsattach(struct isa_device *dev)
static u_long versprobe=0; /* max 32 controllers */
int r;
int unit = dev->id_unit;
struct scsibus_data *scbus;
masunit = dev->id_unit;
@ -634,9 +635,18 @@ wdsattach(struct isa_device *dev)
wds[unit].sc_link.device = &wds_dev;
wds[unit].sc_link.flags = SDEV_BOUNCE;
/*
* Prepare the scsibus_data area for the upperlevel
* scsi code.
*/
scbus = scsi_alloc_bus();
if(!scbus)
return 0;
scbus->adapter_link = &wds[unit].sc_link;
kdc_wds[unit].kdc_state = DC_BUSY;
scsi_attachdevs(&wds[unit].sc_link);
scsi_attachdevs(scbus);
return 1;
}

View File

@ -1,6 +1,6 @@
/**************************************************************************
**
** $Id: ncr.c,v 1.40 1995/08/13 14:59:38 se Exp $
** $Id: ncr.c,v 1.41 1995/08/15 20:19:14 se Exp $
**
** Device driver for the NCR 53C810 PCI-SCSI-Controller.
**
@ -1223,7 +1223,7 @@ static void ncr_attach (pcici_t tag, int unit);
static char ident[] =
"\n$Id: ncr.c,v 1.40 1995/08/13 14:59:38 se Exp $\n";
"\n$Id: ncr.c,v 1.41 1995/08/15 20:19:14 se Exp $\n";
u_long ncr_version = NCR_VERSION
+ (u_long) sizeof (struct ncb)
@ -3204,6 +3204,10 @@ static void ncr_attach (pcici_t config_id, int unit)
extern unsigned bio_imask;
#endif
#if (__FreeBSD__ >= 2)
struct scsibus_data *scbus;
#endif
/*
** allocate structure
*/
@ -3380,7 +3384,17 @@ static void ncr_attach (pcici_t config_id, int unit)
#ifdef __NetBSD__
config_found(self, &np->sc_link, ncr_print);
#else /* !__NetBSD__ */
#if (__FreeBSD__ >= 2)
scbus = scsi_alloc_bus();
if(!scbus)
return;
/* XXX scbus->maxtarg should be adjusted based on bus width */
scbus->adapter_link = &np->sc_link;
scsi_attachdevs (scbus);
scbus = NULL; /* Upper-level SCSI code owns this now */
#else
scsi_attachdevs (&np->sc_link);
#endif /* !__FreeBSD__ >= 2 */
#endif /* !__NetBSD__ */
/*

View File

@ -16,7 +16,7 @@
*
* New configuration setup: dufault@hda.com
*
* $Id: scsiconf.c,v 1.32 1995/07/17 23:37:59 gibbs Exp $
* $Id: scsiconf.c,v 1.33 1995/08/16 16:13:53 bde Exp $
*/
#include <sys/types.h>
@ -635,11 +635,11 @@ void scsi_configure_finish(void)
* to get all their devices configured in.
*/
void
scsi_attachdevs(sc_link_proto)
struct scsi_link *sc_link_proto;
scsi_attachdevs(scbus)
struct scsibus_data *scbus;
{
int scsibus;
struct scsibus_data *scbus;
struct scsi_link *sc_link_proto = scbus->adapter_link;
if ( (scsibus = scsi_bus_conf(sc_link_proto)) == -1) {
return;
@ -652,12 +652,17 @@ scsi_attachdevs(sc_link_proto)
sc_link_proto->opennings = 1;
}
sc_link_proto->scsibus = scsibus;
scbus = malloc(sizeof(struct scsibus_data), M_TEMP, M_NOWAIT);
if(scbus == 0 || extend_set(scbusses, scsibus, scbus) == 0) {
/*
* Allocate our target-lun space.
*/
scbus->sc_link = (struct scsi_link *(*)[][8])malloc(
sizeof(struct scsi_link *[scbus->maxtarg + 1][8]),
M_TEMP, M_NOWAIT);
if(scbus == 0 || scbus->sc_link == 0
|| extend_set(scbusses, scsibus, scbus) == 0) {
panic("scsi_attachdevs: malloc");
}
bzero(scbus, sizeof(struct scsibus_data));
scbus->adapter_link = sc_link_proto;
bzero(scbus->sc_link, sizeof(struct scsi_link*[scbus->maxtarg + 1][8]));
#if defined(SCSI_DELAY) && SCSI_DELAY > 2
printf("%s%d waiting for scsi devices to settle\n",
sc_link_proto->adapter->name, sc_link_proto->adapter_unit);
@ -859,6 +864,31 @@ static errval
}
#endif /* NSCTARG > 0 */
/*
* Allocate a scsibus_data structure
* The target/lun area is dynamically allocated in scsi_attachdevs after
* the controller driver has a chance to update the maxtarg field.
*/
struct scsibus_data*
scsi_alloc_bus()
{
struct scsibus_data *scbus;
/*
* Prepare the scsibus_data area for the upperlevel
* scsi code.
*/
scbus = malloc(sizeof(struct scsibus_data), M_TEMP, M_NOWAIT);
if(!scbus) {
printf("scsi_alloc_bus: - cannot malloc!\n");
return NULL;
}
bzero(scbus, sizeof(struct scsibus_data));
/* Setup the defaults */
scbus->maxtarg = 7;
scbus->maxlun = 7;
return scbus;
}
/*
* Probe the requested scsi bus. It must be already set up.
* targ and lun optionally narrow the search if not -1
@ -883,18 +913,18 @@ scsi_probe_bus(int bus, int targ, int lun)
sc_link_proto = scsibus_data->adapter_link;
scsi_addr = sc_link_proto->adapter_targ;
if(targ == -1){
maxtarg = 7;
maxtarg = scsibus_data->maxtarg;
mintarg = 0;
} else {
if((targ < 0 ) || (targ > 7)) return EINVAL;
if((targ < 0 ) || (targ > scsibus_data->maxtarg)) return EINVAL;
maxtarg = mintarg = targ;
}
if(lun == -1){
maxlun = 7;
maxlun = scsibus_data->maxlun;
minlun = 0;
} else {
if((lun < 0 ) || (lun > 7)) return EINVAL;
if((lun < 0 ) || (lun > scsibus_data->maxlun)) return EINVAL;
maxlun = minlun = lun;
}
@ -908,7 +938,7 @@ scsi_probe_bus(int bus, int targ, int lun)
* The spot appears to already have something
* linked in, skip past it. Must be doing a 'reprobe'
*/
if(scsibus_data->sc_link[targ][lun])
if((*scsibus_data->sc_link)[targ][lun])
{/* don't do this one, but check other luns */
maybe_more = 1;
continue;
@ -943,7 +973,7 @@ scsi_probe_bus(int bus, int targ, int lun)
if (scsi_alloc_unit(sc_link)) {
if (scsi_device_attach(sc_link) == 0) {
scsibus_data->sc_link[targ][lun] = sc_link;
(*scsibus_data->sc_link)[targ][lun] = sc_link;
sc_link = NULL; /* it's been used */
}
else
@ -973,7 +1003,7 @@ scsi_link_get(bus, targ, lun)
{
struct scsibus_data *scsibus_data =
(struct scsibus_data *)extend_get(scbusses, bus);
return (scsibus_data) ? scsibus_data->sc_link[targ][lun] : 0;
return (scsibus_data) ? (*scsibus_data->sc_link)[targ][lun] : 0;
}
/* make_readable: Make the inquiry data readable. Anything less than a ' '

View File

@ -14,7 +14,7 @@
*
* Ported to run under 386BSD by Julian Elischer (julian@tfs.com) Sept 1992
*
* $Id: scsiconf.h,v 1.26 1995/05/30 08:13:47 rgrimes Exp $
* $Id: scsiconf.h,v 1.27 1995/07/17 23:38:01 gibbs Exp $
*/
#ifndef SCSI_SCSICONF_H
#define SCSI_SCSICONF_H 1
@ -331,8 +331,10 @@ struct scsi_link
* the others, before they have the rest of the fields filled in
*/
struct scsibus_data {
struct scsi_link *adapter_link; /* prototype supplied by adapter */
struct scsi_link *sc_link[16][8];
u_char maxtarg;
u_char maxlun;
struct scsi_link *adapter_link; /* prototype supplied by adapter */
struct scsi_link *(*sc_link)[][8]; /* dynamically allocated */
};
/*
@ -410,18 +412,19 @@ struct scsi_xfer
#ifdef KERNEL
void *extend_get(struct extend_array *ea, int index);
void scsi_attachdevs __P((struct scsi_link *sc_link_proto));
void scsi_attachdevs __P((struct scsibus_data *scbus));
struct scsi_xfer *get_xs( struct scsi_link *sc_link, u_int32 flags);
void free_xs(struct scsi_xfer *xs, struct scsi_link *sc_link,u_int32 flags);
u_int32 scsi_read_capacity __P(( struct scsi_link *sc_link,
u_int32 *blk_size, u_int32 flags));
errval scsi_test_unit_ready( struct scsi_link *sc_link, u_int32 flags);
errval scsi_test_unit_ready __P(( struct scsi_link *sc_link, u_int32 flags));
errval scsi_reset_target __P((struct scsi_link *));
errval scsi_target_mode __P((struct scsi_link *, int));
errval scsi_change_def( struct scsi_link *sc_link, u_int32 flags);
errval scsi_inquire( struct scsi_link *sc_link,
struct scsi_inquiry_data *inqbuf, u_int32 flags);
errval scsi_prevent( struct scsi_link *sc_link, u_int32 type,u_int32 flags);
struct scsibus_data *scsi_alloc_bus ();
errval scsi_probe_bus __P((int, int, int));
errval scsi_probe_busses __P(( int, int, int));
errval scsi_start_unit( struct scsi_link *sc_link, u_int32 flags);