mirror of
https://git.FreeBSD.org/src.git
synced 2024-12-15 10:17:20 +00:00
Allocate all scsi-devices on the fly, not just CDs.
Reviewed by: phk Submitted by: rgrimes
This commit is contained in:
parent
75a128283a
commit
a31f80dc67
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=5118
@ -14,12 +14,11 @@
|
||||
*
|
||||
* Ported to run under 386BSD by Julian Elischer (julian@tfs.com) Sept 1992
|
||||
*
|
||||
* $Id: cd.c,v 1.29 1994/11/15 14:49:12 bde Exp $
|
||||
* $Id: cd.c,v 1.30 1994/12/03 22:52:55 phk Exp $
|
||||
*/
|
||||
|
||||
#define SPLCD splbio
|
||||
#define ESUCCESS 0
|
||||
#include <cd.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/param.h>
|
||||
#include <sys/dkbad.h>
|
||||
@ -174,13 +173,6 @@ cdattach(sc_link)
|
||||
|
||||
SC_DEBUG(sc_link, SDEV_DB2, ("cdattach "));
|
||||
|
||||
/*
|
||||
* Fill out any more info in the
|
||||
* Link structure that we can
|
||||
*/
|
||||
unit = next_cd_unit++;
|
||||
sc_link->device = &cd_switch;
|
||||
sc_link->dev_unit = unit;
|
||||
/*
|
||||
* allocate the resources for another drive
|
||||
* if we have already allocate a cd_data pointer we must
|
||||
@ -193,6 +185,7 @@ cdattach(sc_link)
|
||||
* done by changing the malloc to be (next_cd_unit * x) and
|
||||
* the cd_driver.size++ to be +x
|
||||
*/
|
||||
unit = next_cd_unit++;
|
||||
if (unit >= cd_driver.size) {
|
||||
cdrealloc =
|
||||
malloc(sizeof(cd_driver.cd_data) * next_cd_unit,
|
||||
|
107
sys/scsi/sd.c
107
sys/scsi/sd.c
@ -14,12 +14,11 @@
|
||||
*
|
||||
* Ported to run under 386BSD by Julian Elischer (julian@dialix.oz.au) Sept 1992
|
||||
*
|
||||
* $Id: sd.c,v 1.42 1994/11/15 14:47:49 bde Exp $
|
||||
* $Id: sd.c,v 1.43 1994/12/03 22:52:57 phk Exp $
|
||||
*/
|
||||
|
||||
#define SPLSD splbio
|
||||
#define ESUCCESS 0
|
||||
#include <sd.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/param.h>
|
||||
#include <sys/kernel.h>
|
||||
@ -106,7 +105,12 @@ struct sd_data {
|
||||
struct buf buf_queue;
|
||||
u_int32 xfer_block_wait;
|
||||
int dkunit; /* disk stats unit number */
|
||||
} *sd_data[NSD];
|
||||
};
|
||||
|
||||
struct sd_driver {
|
||||
u_int32 size;
|
||||
struct sd_data **sd_data;
|
||||
} sd_driver;
|
||||
|
||||
static u_int32 next_sd_unit = 0;
|
||||
|
||||
@ -124,7 +128,8 @@ static int
|
||||
sd_externalize(struct proc *p, struct kern_devconf *kdc, void *userp,
|
||||
size_t len)
|
||||
{
|
||||
return scsi_externalize(sd_data[kdc->kdc_unit]->sc_link, userp, &len);
|
||||
return scsi_externalize(sd_driver.sd_data[kdc->kdc_unit]->sc_link,
|
||||
userp, &len);
|
||||
}
|
||||
|
||||
static struct kern_devconf kdc_sd_template = {
|
||||
@ -150,9 +155,9 @@ sd_registerdev(int unit)
|
||||
if(dk_ndrive < DK_NDRIVE) {
|
||||
sprintf(dk_names[dk_ndrive], "sd%d", unit);
|
||||
dk_wpms[dk_ndrive] = (8*1024*1024/2);
|
||||
sd_data[unit]->dkunit = dk_ndrive++;
|
||||
sd_driver.sd_data[unit]->dkunit = dk_ndrive++;
|
||||
} else {
|
||||
sd_data[unit]->dkunit = -1;
|
||||
sd_driver.sd_data[unit]->dkunit = -1;
|
||||
}
|
||||
}
|
||||
|
||||
@ -166,26 +171,54 @@ sdattach(sc_link)
|
||||
struct scsi_link *sc_link;
|
||||
{
|
||||
u_int32 unit;
|
||||
struct sd_data *sd;
|
||||
struct sd_data *sd, **sdrealloc;
|
||||
struct disk_parms *dp;
|
||||
|
||||
unit = next_sd_unit++;
|
||||
SC_DEBUG(sc_link, SDEV_DB2, ("sdattach: "));
|
||||
|
||||
/*
|
||||
* Check we have the resources for another drive
|
||||
* allocate the resources for another drive
|
||||
* if we have already allocate a sd_data pointer we must
|
||||
* copy the old pointers into a new region that is
|
||||
* larger and release the old region, aka realloc
|
||||
*/
|
||||
if (unit >= NSD) {
|
||||
printf("Too many scsi disks..(%ld > %d) reconfigure kernel\n",
|
||||
(unit + 1), NSD);
|
||||
return 0;
|
||||
/* XXX
|
||||
* This if will always be true for now, but future code may
|
||||
* preallocate more units to reduce overhead. This would be
|
||||
* done by changing the malloc to be (next_sd_unit * x) and
|
||||
* the sd_driver.size++ to be +x
|
||||
*/
|
||||
unit = next_sd_unit++;
|
||||
if (unit >= sd_driver.size) {
|
||||
sdrealloc =
|
||||
malloc(sizeof(sd_driver.sd_data) * next_sd_unit,
|
||||
M_DEVBUF, M_NOWAIT);
|
||||
if (!sdrealloc) {
|
||||
printf("sd%ld: malloc failed for sdrealloc\n", unit);
|
||||
return (0);
|
||||
}
|
||||
/* Make sure we have something to copy before we copy it */
|
||||
bzero(sdrealloc, sizeof(sd_driver.sd_data) * next_sd_unit);
|
||||
if (sd_driver.size) {
|
||||
bcopy(sd_driver.sd_data, sdrealloc,
|
||||
sizeof(sd_driver.sd_data) * sd_driver.size);
|
||||
free(sd_driver.sd_data, M_DEVBUF);
|
||||
}
|
||||
sd_driver.sd_data = sdrealloc;
|
||||
sd_driver.sd_data[unit] = NULL;
|
||||
sd_driver.size++;
|
||||
}
|
||||
if (sd_data[unit]) {
|
||||
printf("sd%ld: unit already has storage allocated!\n", unit);
|
||||
return 0;
|
||||
if (sd_driver.sd_data[unit]) {
|
||||
printf("sd%ld: Already has storage!\n", unit);
|
||||
return (0);
|
||||
}
|
||||
sd = sd_data[unit] = malloc(sizeof(struct sd_data), M_DEVBUF, M_NOWAIT);
|
||||
/*
|
||||
* alloate the per drive data area
|
||||
*/
|
||||
sd = sd_driver.sd_data[unit] =
|
||||
malloc(sizeof(struct sd_data), M_DEVBUF, M_NOWAIT);
|
||||
if (!sd) {
|
||||
printf("malloc failed in sd.c\n");
|
||||
printf("sd%ld: malloc failed for sd_data\n", unit);
|
||||
return (0);
|
||||
}
|
||||
bzero(sd, sizeof(struct sd_data));
|
||||
@ -231,7 +264,7 @@ sdattach(sc_link)
|
||||
dp->secsiz);
|
||||
sd->flags |= SDINIT;
|
||||
sd_registerdev(unit);
|
||||
return 0;
|
||||
return (1);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -248,13 +281,13 @@ sdopen(dev)
|
||||
|
||||
unit = UNIT(dev);
|
||||
part = PARTITION(dev);
|
||||
sd = sd_data[unit];
|
||||
/*
|
||||
* Check the unit is legal
|
||||
*/
|
||||
if (unit >= NSD) {
|
||||
if (unit >= sd_driver.size) {
|
||||
return (ENXIO);
|
||||
}
|
||||
sd = sd_driver.sd_data[unit];
|
||||
/*
|
||||
* Make sure the disk has been initialised
|
||||
* At some point in the future, get the scsi driver
|
||||
@ -266,8 +299,8 @@ sdopen(dev)
|
||||
sc_link = sd->sc_link;
|
||||
|
||||
SC_DEBUG(sc_link, SDEV_DB1,
|
||||
("sdopen: dev=0x%x (unit %d (of %d),partition %d)\n"
|
||||
,dev, unit, NSD, part));
|
||||
("sdopen: dev=0x%x (unit %d (of %d),partition %d)\n",
|
||||
dev, unit, sd_driver.size, part));
|
||||
|
||||
/*
|
||||
* "unit attention" errors should occur here if the
|
||||
@ -375,7 +408,7 @@ sdclose(dev)
|
||||
|
||||
unit = UNIT(dev);
|
||||
part = PARTITION(dev);
|
||||
sd = sd_data[unit];
|
||||
sd = sd_driver.sd_data[unit];
|
||||
sd->partflags[part] &= ~SDOPEN;
|
||||
sd->openparts &= ~(1 << part);
|
||||
scsi_prevent(sd->sc_link, PR_ALLOW, SCSI_SILENT | SCSI_ERR_OK);
|
||||
@ -395,7 +428,7 @@ void
|
||||
sdminphys(bp)
|
||||
struct buf *bp;
|
||||
{
|
||||
(*(sd_data[UNIT(bp->b_dev)]->sc_link->adapter->scsi_minphys)) (bp);
|
||||
(*(sd_driver.sd_data[UNIT(bp->b_dev)]->sc_link->adapter->scsi_minphys)) (bp);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -414,7 +447,7 @@ sdstrategy(bp)
|
||||
|
||||
sdstrats++;
|
||||
unit = UNIT((bp->b_dev));
|
||||
sd = sd_data[unit];
|
||||
sd = sd_driver.sd_data[unit];
|
||||
SC_DEBUG(sd->sc_link, SDEV_DB2, ("sdstrategy "));
|
||||
SC_DEBUG(sd->sc_link, SDEV_DB1,
|
||||
(" %d bytes @ blk%d\n", bp->b_bcount, bp->b_blkno));
|
||||
@ -531,7 +564,7 @@ void
|
||||
sdstart(unit)
|
||||
u_int32 unit;
|
||||
{
|
||||
register struct sd_data *sd = sd_data[unit];
|
||||
register struct sd_data *sd = sd_driver.sd_data[unit];
|
||||
register struct scsi_link *sc_link = sd->sc_link;
|
||||
struct buf *bp = 0;
|
||||
struct buf *dp;
|
||||
@ -645,7 +678,7 @@ sdioctl(dev_t dev, int cmd, caddr_t addr, int flag)
|
||||
*/
|
||||
unit = UNIT(dev);
|
||||
part = PARTITION(dev);
|
||||
sd = sd_data[unit];
|
||||
sd = sd_driver.sd_data[unit];
|
||||
SC_DEBUG(sd->sc_link, SDEV_DB1, ("sdioctl (0x%x)", cmd));
|
||||
|
||||
/*
|
||||
@ -755,7 +788,7 @@ errval
|
||||
sdgetdisklabel(unsigned char unit)
|
||||
{
|
||||
char *errstring;
|
||||
struct sd_data *sd = sd_data[unit];
|
||||
struct sd_data *sd = sd_driver.sd_data[unit];
|
||||
dev_t dev;
|
||||
|
||||
dev = makedev(0, (unit << UNITSHIFT) + RAWPART);
|
||||
@ -821,6 +854,7 @@ sd_size(unit, flags)
|
||||
struct scsi_read_cap_data rdcap;
|
||||
struct scsi_read_capacity scsi_cmd;
|
||||
u_int32 size;
|
||||
struct sd_data *sd = sd_driver.sd_data[unit];
|
||||
|
||||
/*
|
||||
* make up a scsi command and ask the scsi driver to do
|
||||
@ -833,7 +867,7 @@ sd_size(unit, flags)
|
||||
* If the command works, interpret the result as a 4 byte
|
||||
* number of blocks
|
||||
*/
|
||||
if (scsi_scsi_cmd(sd_data[unit]->sc_link,
|
||||
if (scsi_scsi_cmd(sd->sc_link,
|
||||
(struct scsi_generic *) &scsi_cmd,
|
||||
sizeof(scsi_cmd),
|
||||
(u_char *) & rdcap,
|
||||
@ -862,6 +896,7 @@ sd_reassign_blocks(unit, block)
|
||||
{
|
||||
struct scsi_reassign_blocks scsi_cmd;
|
||||
struct scsi_reassign_blocks_data rbdata;
|
||||
struct sd_data *sd = sd_driver.sd_data[unit];
|
||||
|
||||
bzero(&scsi_cmd, sizeof(scsi_cmd));
|
||||
bzero(&rbdata, sizeof(rbdata));
|
||||
@ -874,7 +909,7 @@ sd_reassign_blocks(unit, block)
|
||||
rbdata.defect_descriptor[0].dlbaddr_1 = ((block >> 8) & 0xff);
|
||||
rbdata.defect_descriptor[0].dlbaddr_0 = ((block) & 0xff);
|
||||
|
||||
return (scsi_scsi_cmd(sd_data[unit]->sc_link,
|
||||
return (scsi_scsi_cmd(sd->sc_link,
|
||||
(struct scsi_generic *) &scsi_cmd,
|
||||
sizeof(scsi_cmd),
|
||||
(u_char *) & rbdata,
|
||||
@ -895,7 +930,7 @@ errval
|
||||
sd_get_parms(unit, flags)
|
||||
int unit, flags;
|
||||
{
|
||||
struct sd_data *sd = sd_data[unit];
|
||||
struct sd_data *sd = sd_driver.sd_data[unit];
|
||||
struct disk_parms *disk_parms = &sd->params;
|
||||
struct scsi_mode_sense scsi_cmd;
|
||||
struct scsi_mode_sense_data {
|
||||
@ -992,10 +1027,10 @@ sdsize(dev_t dev)
|
||||
u_int32 unit = UNIT(dev), part = PARTITION(dev), val;
|
||||
struct sd_data *sd;
|
||||
|
||||
if (unit >= NSD)
|
||||
if (unit >= sd_driver.size)
|
||||
return -1;
|
||||
|
||||
sd = sd_data[unit];
|
||||
sd = sd_driver.sd_data[unit];
|
||||
if (!sd)
|
||||
return -1;
|
||||
if ((sd->flags & SDINIT) == 0)
|
||||
@ -1044,10 +1079,10 @@ sddump(dev_t dev)
|
||||
unit = UNIT(dev); /* eventually support floppies? */
|
||||
part = PARTITION(dev); /* file system */
|
||||
/* check for acceptable drive number */
|
||||
if (unit >= NSD)
|
||||
if (unit >= sd_driver.size)
|
||||
return (ENXIO);
|
||||
|
||||
sd = sd_data[unit];
|
||||
sd = sd_driver.sd_data[unit];
|
||||
if (!sd)
|
||||
return (ENXIO);
|
||||
/* was it ever initialized etc. ? */
|
||||
|
120
sys/scsi/st.c
120
sys/scsi/st.c
@ -12,7 +12,7 @@
|
||||
* on the understanding that TFS is not responsible for the correct
|
||||
* functioning of this software in any circumstances.
|
||||
*
|
||||
* $Id: st.c,v 1.21 1994/10/23 21:27:59 wollman Exp $
|
||||
* $Id: st.c,v 1.22 1994/10/28 13:19:36 jkh Exp $
|
||||
*/
|
||||
|
||||
/*
|
||||
@ -27,8 +27,7 @@
|
||||
*
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <st.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
@ -229,7 +228,7 @@ struct st_data {
|
||||
struct buf *buf_queue; /* the queue of pending IO operations */
|
||||
struct scsi_xfer scsi_xfer; /* scsi xfer struct for this drive */
|
||||
u_int32 xfer_block_wait; /* is a process waiting? */
|
||||
} *st_data[NST];
|
||||
};
|
||||
|
||||
#define ST_INITIALIZED 0x01
|
||||
#define ST_INFO_VALID 0x02
|
||||
@ -255,6 +254,11 @@ struct st_data {
|
||||
ST_FIXEDBLOCKS | ST_READONLY | \
|
||||
ST_FM_WRITTEN | ST_2FM_AT_EOD | ST_PER_ACTION)
|
||||
|
||||
struct st_driver {
|
||||
u_int32 size;
|
||||
struct st_data **st_data;
|
||||
} st_driver;
|
||||
|
||||
static u_int32 next_st_unit = 0;
|
||||
|
||||
static int
|
||||
@ -269,7 +273,8 @@ static int
|
||||
st_externalize(struct proc *p, struct kern_devconf *kdc, void *userp,
|
||||
size_t len)
|
||||
{
|
||||
return scsi_externalize(st_data[kdc->kdc_unit]->sc_link, userp, &len);
|
||||
return scsi_externalize(st_driver.st_data[kdc->kdc_unit]->sc_link,
|
||||
userp, &len);
|
||||
}
|
||||
|
||||
static struct kern_devconf kdc_st_template = {
|
||||
@ -304,28 +309,53 @@ stattach(sc_link)
|
||||
struct scsi_link *sc_link;
|
||||
{
|
||||
u_int32 unit;
|
||||
struct st_data *st;
|
||||
struct st_data *st, **strealloc;
|
||||
|
||||
SC_DEBUG(sc_link, SDEV_DB2, ("stattach: "));
|
||||
|
||||
/*
|
||||
* Check we have the resources for another drive
|
||||
* allocate the resources for another drive
|
||||
* if we have already allocate a st_data pointer we must
|
||||
* copy the old pointers into a new region that is
|
||||
* larger and release the old region, aka realloc
|
||||
*/
|
||||
/* XXX
|
||||
* This if will always be true for now, but future code may
|
||||
* preallocate more units to reduce overhead. This would be
|
||||
* done by changing the malloc to be (next_st_unit * x) and
|
||||
* the st_driver.size++ to be +x
|
||||
*/
|
||||
unit = next_st_unit++;
|
||||
|
||||
if (unit >= NST) {
|
||||
printf("Too many scsi tapes..(%d > %d) reconfigure kernel\n",
|
||||
(unit + 1), NST);
|
||||
return 0;
|
||||
if (unit >= st_driver.size) {
|
||||
strealloc =
|
||||
malloc(sizeof(st_driver.st_data) * next_st_unit,
|
||||
M_DEVBUF, M_NOWAIT);
|
||||
if (!strealloc) {
|
||||
printf("st%ld: malloc failed for strealloc\n", unit);
|
||||
return (0);
|
||||
}
|
||||
/* Make sure we have something to copy before we copy it */
|
||||
bzero(strealloc, sizeof(st_driver.st_data) * next_st_unit);
|
||||
if (st_driver.size) {
|
||||
bcopy(st_driver.st_data, strealloc,
|
||||
sizeof(st_driver.st_data) * st_driver.size);
|
||||
free(st_driver.st_data, M_DEVBUF);
|
||||
}
|
||||
st_driver.st_data = strealloc;
|
||||
st_driver.st_data[unit] = NULL;
|
||||
st_driver.size++;
|
||||
}
|
||||
if (st_data[unit]) {
|
||||
printf("st%d: Already has storage!\n", unit);
|
||||
return 0;
|
||||
if (st_driver.st_data[unit]) {
|
||||
printf("st%ld: Already has storage!\n", unit);
|
||||
return (0);
|
||||
}
|
||||
sc_link->device = &st_switch;
|
||||
sc_link->dev_unit = unit;
|
||||
st = st_data[unit] = malloc(sizeof(struct st_data), M_DEVBUF, M_NOWAIT);
|
||||
/*
|
||||
* allocate the per drive data area
|
||||
*/
|
||||
st = st_driver.st_data[unit] =
|
||||
malloc(sizeof(struct st_data), M_DEVBUF, M_NOWAIT);
|
||||
if (!st) {
|
||||
printf("st%d: malloc failed in st.c\n", unit);
|
||||
printf("st%ld: malloc failed for st_data\n", unit);
|
||||
return 0;
|
||||
}
|
||||
bzero(st, sizeof(struct st_data));
|
||||
@ -334,8 +364,8 @@ stattach(sc_link)
|
||||
* Store information needed to contact our base driver
|
||||
*/
|
||||
st->sc_link = sc_link;
|
||||
|
||||
|
||||
sc_link->device = &st_switch;
|
||||
sc_link->dev_unit = unit;
|
||||
|
||||
/*
|
||||
* Check if the drive is a known criminal and take
|
||||
@ -385,7 +415,7 @@ void
|
||||
st_identify_drive(unit)
|
||||
u_int32 unit;
|
||||
{
|
||||
struct st_data *st = st_data[unit];
|
||||
struct st_data *st = st_driver.st_data[unit];
|
||||
struct scsi_inquiry_data inqbuf;
|
||||
struct rogues *finger;
|
||||
char manu[32];
|
||||
@ -528,10 +558,10 @@ stopen(dev, flags)
|
||||
/*
|
||||
* Check the unit is legal
|
||||
*/
|
||||
if (unit >= NST) {
|
||||
if (unit >= st_driver.size) {
|
||||
return (ENXIO);
|
||||
}
|
||||
st = st_data[unit];
|
||||
st = st_driver.st_data[unit];
|
||||
/*
|
||||
* Make sure the device has been initialised
|
||||
*/
|
||||
@ -540,7 +570,7 @@ stopen(dev, flags)
|
||||
|
||||
sc_link = st->sc_link;
|
||||
SC_DEBUG(sc_link, SDEV_DB1, ("open: dev=0x%x (unit %d (of %d))\n"
|
||||
,dev, unit, NST));
|
||||
,dev, unit, st_driver.size));
|
||||
/*
|
||||
* Only allow one at a time
|
||||
*/
|
||||
@ -617,7 +647,7 @@ stclose(dev)
|
||||
|
||||
unit = UNIT(dev);
|
||||
mode = MODE(dev);
|
||||
st = st_data[unit];
|
||||
st = st_driver.st_data[unit];
|
||||
sc_link = st->sc_link;
|
||||
|
||||
SC_DEBUG(sc_link, SDEV_DB1, ("closing\n"));
|
||||
@ -660,7 +690,7 @@ st_mount_tape(dev, flags)
|
||||
unit = UNIT(dev);
|
||||
mode = MODE(dev);
|
||||
dsty = DSTY(dev);
|
||||
st = st_data[unit];
|
||||
st = st_driver.st_data[unit];
|
||||
sc_link = st->sc_link;
|
||||
|
||||
if (st->flags & ST_MOUNTED)
|
||||
@ -755,7 +785,7 @@ st_mount_tape(dev, flags)
|
||||
void
|
||||
st_unmount(int unit, boolean eject)
|
||||
{
|
||||
struct st_data *st = st_data[unit];
|
||||
struct st_data *st = st_driver.st_data[unit];
|
||||
struct scsi_link *sc_link = st->sc_link;
|
||||
int32 nmarks;
|
||||
|
||||
@ -782,7 +812,7 @@ st_decide_mode(unit, first_read)
|
||||
u_int32 unit;
|
||||
boolean first_read;
|
||||
{
|
||||
struct st_data *st = st_data[unit];
|
||||
struct st_data *st = st_driver.st_data[unit];
|
||||
#ifdef SCSIDEBUG
|
||||
struct scsi_link *sc_link = st->sc_link;
|
||||
#endif
|
||||
@ -919,7 +949,7 @@ void
|
||||
stminphys(bp)
|
||||
struct buf *bp;
|
||||
{
|
||||
(*(st_data[UNIT(bp->b_dev)]->sc_link->adapter->scsi_minphys)) (bp);
|
||||
(*(st_driver.st_data[UNIT(bp->b_dev)]->sc_link->adapter->scsi_minphys)) (bp);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -939,7 +969,7 @@ ststrategy(bp)
|
||||
|
||||
ststrats++;
|
||||
unit = UNIT((bp->b_dev));
|
||||
st = st_data[unit];
|
||||
st = st_driver.st_data[unit];
|
||||
SC_DEBUG(st->sc_link, SDEV_DB1,
|
||||
(" strategy: %d bytes @ blk%d\n", bp->b_bcount, bp->b_blkno));
|
||||
/*
|
||||
@ -1028,7 +1058,7 @@ void
|
||||
ststart(unit)
|
||||
u_int32 unit;
|
||||
{
|
||||
struct st_data *st = st_data[unit];
|
||||
struct st_data *st = st_driver.st_data[unit];
|
||||
struct scsi_link *sc_link = st->sc_link;
|
||||
register struct buf *bp = 0;
|
||||
struct scsi_rw_tape cmd;
|
||||
@ -1175,7 +1205,7 @@ stioctl(dev, cmd, arg, flag)
|
||||
flags = 0; /* give error messages, act on errors etc. */
|
||||
unit = UNIT(dev);
|
||||
dsty = DSTY(dev);
|
||||
st = st_data[unit];
|
||||
st = st_driver.st_data[unit];
|
||||
hold_blksiz = st->blksiz;
|
||||
hold_density = st->density;
|
||||
|
||||
@ -1336,7 +1366,7 @@ st_read(unit, buf, size, flags)
|
||||
char *buf;
|
||||
{
|
||||
struct scsi_rw_tape scsi_cmd;
|
||||
struct st_data *st = st_data[unit];
|
||||
struct st_data *st = st_driver.st_data[unit];
|
||||
|
||||
/*
|
||||
* If it's a null transfer, return immediatly
|
||||
@ -1378,7 +1408,7 @@ st_rd_blk_lim(unit, flags)
|
||||
{
|
||||
struct scsi_blk_limits scsi_cmd;
|
||||
struct scsi_blk_limits_data scsi_blkl;
|
||||
struct st_data *st = st_data[unit];
|
||||
struct st_data *st = st_driver.st_data[unit];
|
||||
errval errno;
|
||||
struct scsi_link *sc_link = st->sc_link;
|
||||
|
||||
@ -1451,7 +1481,7 @@ st_mode_sense(unit, flags)
|
||||
* back when you issue a mode select
|
||||
*/
|
||||
} scsi_sense_page_0;
|
||||
struct st_data *st = st_data[unit];
|
||||
struct st_data *st = st_driver.st_data[unit];
|
||||
struct scsi_link *sc_link = st->sc_link;
|
||||
|
||||
/*
|
||||
@ -1532,7 +1562,7 @@ st_mode_select(unit, flags)
|
||||
struct blk_desc blk_desc;
|
||||
unsigned char sense_data[PAGE_0_SENSE_DATA_SIZE];
|
||||
} dat_page_0;
|
||||
struct st_data *st = st_data[unit];
|
||||
struct st_data *st = st_driver.st_data[unit];
|
||||
|
||||
/*
|
||||
* Define what sort of structure we're working with
|
||||
@ -1587,7 +1617,7 @@ st_space(unit, number, what, flags)
|
||||
{
|
||||
errval error;
|
||||
struct scsi_space scsi_cmd;
|
||||
struct st_data *st = st_data[unit];
|
||||
struct st_data *st = st_driver.st_data[unit];
|
||||
|
||||
switch ((int)what) {
|
||||
case SP_BLKS:
|
||||
@ -1660,7 +1690,7 @@ st_write_filemarks(unit, number, flags)
|
||||
int32 number;
|
||||
{
|
||||
struct scsi_write_filemarks scsi_cmd;
|
||||
struct st_data *st = st_data[unit];
|
||||
struct st_data *st = st_driver.st_data[unit];
|
||||
|
||||
/*
|
||||
* It's hard to write a negative number of file marks.
|
||||
@ -1713,7 +1743,7 @@ st_chkeod(unit, position, nmarks, flags)
|
||||
u_int32 flags;
|
||||
{
|
||||
errval error;
|
||||
struct st_data *st = st_data[unit];
|
||||
struct st_data *st = st_driver.st_data[unit];
|
||||
|
||||
switch ((int)(st->flags & (ST_WRITTEN | ST_FM_WRITTEN | ST_2FM_AT_EOD))) {
|
||||
default:
|
||||
@ -1740,7 +1770,7 @@ st_load(unit, type, flags)
|
||||
u_int32 unit, type, flags;
|
||||
{
|
||||
struct scsi_load scsi_cmd;
|
||||
struct st_data *st = st_data[unit];
|
||||
struct st_data *st = st_driver.st_data[unit];
|
||||
struct scsi_link *sc_link = st->sc_link;
|
||||
|
||||
bzero(&scsi_cmd, sizeof(scsi_cmd));
|
||||
@ -1777,7 +1807,7 @@ st_rewind(unit, immed, flags)
|
||||
boolean immed;
|
||||
{
|
||||
struct scsi_rewind scsi_cmd;
|
||||
struct st_data *st = st_data[unit];
|
||||
struct st_data *st = st_driver.st_data[unit];
|
||||
errval error;
|
||||
int32 nmarks;
|
||||
|
||||
@ -1808,7 +1838,7 @@ st_erase(unit, immed, flags)
|
||||
boolean immed;
|
||||
{
|
||||
struct scsi_erase scsi_cmd;
|
||||
struct st_data *st = st_data[unit];
|
||||
struct st_data *st = st_driver.st_data[unit];
|
||||
errval error;
|
||||
int32 nmarks;
|
||||
|
||||
@ -1860,7 +1890,7 @@ st_interpret_sense(xs)
|
||||
boolean silent = xs->flags & SCSI_SILENT;
|
||||
struct buf *bp = xs->bp;
|
||||
u_int32 unit = sc_link->dev_unit;
|
||||
struct st_data *st = st_data[unit];
|
||||
struct st_data *st = st_driver.st_data[unit];
|
||||
u_int32 key;
|
||||
int32 info;
|
||||
|
||||
@ -2003,7 +2033,7 @@ errval
|
||||
st_touch_tape(unit)
|
||||
u_int32 unit;
|
||||
{
|
||||
struct st_data *st = st_data[unit];
|
||||
struct st_data *st = st_driver.st_data[unit];
|
||||
char *buf;
|
||||
u_int32 readsiz;
|
||||
errval errno;
|
||||
|
@ -2,16 +2,16 @@
|
||||
* Dummy driver for a device we can't identify.
|
||||
* by Julian Elischer (julian@tfs.com)
|
||||
*
|
||||
* $Id: uk.c,v 1.3 1993/12/19 00:55:01 wollman Exp $
|
||||
* $Id: uk.c,v 1.4 1994/08/13 03:50:31 wollman Exp $
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/errno.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/malloc.h>
|
||||
#include <scsi/scsi_all.h>
|
||||
#include <scsi/scsiconf.h>
|
||||
#define NUK 16
|
||||
|
||||
/*
|
||||
* This driver is so simple it uses all the default services
|
||||
@ -29,10 +29,14 @@ struct scsi_device uk_switch =
|
||||
|
||||
struct uk_data {
|
||||
u_int32 flags;
|
||||
struct scsi_link *sc_link; /* all the inter level info */
|
||||
} uk_data[NUK];
|
||||
|
||||
#define UK_KNOWN 0x02
|
||||
struct scsi_link *sc_link; /* all the inter level info */
|
||||
};
|
||||
|
||||
struct uk_driver {
|
||||
u_int32 size;
|
||||
struct uk_data **uk_data;
|
||||
} uk_driver;
|
||||
|
||||
static u_int32 next_uk_unit = 0;
|
||||
|
||||
@ -45,30 +49,69 @@ ukattach(sc_link)
|
||||
struct scsi_link *sc_link;
|
||||
{
|
||||
u_int32 unit, i, stat;
|
||||
struct uk_data *uk, **ukrealloc;
|
||||
unsigned char *tbl;
|
||||
|
||||
SC_DEBUG(sc_link, SDEV_DB2, ("ukattach: "));
|
||||
|
||||
/*
|
||||
* Check we have the resources for another drive
|
||||
* allocate the resources for another drive
|
||||
* if we have already allocate a uk_data pointer we must
|
||||
* copy the old pointers into a new region that is
|
||||
* larger and release the old region, aka realloc
|
||||
*/
|
||||
/* XXX
|
||||
* This if will always be true for now, but future code may
|
||||
* preallocate more units to reduce overhead. This would be
|
||||
* done by changing the malloc to be (next_uk_unit * x) and
|
||||
* the uk_driver.size++ to be +x
|
||||
*/
|
||||
unit = next_uk_unit++;
|
||||
if (unit >= NUK) {
|
||||
printf("Too many unknown devices..(%d > %d) reconfigure kernel\n",
|
||||
(unit + 1), NUK);
|
||||
if (unit >= uk_driver.size) {
|
||||
ukrealloc =
|
||||
malloc(sizeof(uk_driver.uk_data) * next_uk_unit,
|
||||
M_DEVBUF, M_NOWAIT);
|
||||
if (!ukrealloc) {
|
||||
printf("uk%ld: malloc failed for ukrealloc\n", unit);
|
||||
return (0);
|
||||
}
|
||||
/* Make sure we have something to copy before we copy it */
|
||||
bzero(ukrealloc, sizeof(uk_driver.uk_data) * next_uk_unit);
|
||||
if (uk_driver.size) {
|
||||
bcopy(uk_driver.uk_data, ukrealloc,
|
||||
sizeof(uk_driver.uk_data) * uk_driver.size);
|
||||
free(uk_driver.uk_data, M_DEVBUF);
|
||||
}
|
||||
uk_driver.uk_data = ukrealloc;
|
||||
uk_driver.uk_data[unit] = NULL;
|
||||
uk_driver.size++;
|
||||
}
|
||||
if (uk_driver.uk_data[unit]) {
|
||||
printf("uk%ld: Already has storage!\n", unit);
|
||||
return (0);
|
||||
}
|
||||
/*
|
||||
* alloate the per drive data area
|
||||
*/
|
||||
uk = uk_driver.uk_data[unit] =
|
||||
malloc(sizeof(struct uk_data), M_DEVBUF, M_NOWAIT);
|
||||
if (!uk) {
|
||||
printf("uk%ld: malloc failed for uk_data\n", unit);
|
||||
return (0);
|
||||
}
|
||||
bzero(uk, sizeof(struct uk_data));
|
||||
|
||||
/*
|
||||
* Store information needed to contact our base driver
|
||||
*/
|
||||
uk_data[unit].sc_link = sc_link;
|
||||
uk->sc_link = sc_link;
|
||||
sc_link->device = &uk_switch;
|
||||
sc_link->dev_unit = unit;
|
||||
|
||||
printf("uk%d: unknown device\n", unit);
|
||||
uk_data[unit].flags = UK_KNOWN;
|
||||
uk->flags = UK_KNOWN;
|
||||
|
||||
return 1; /* XXX ??? */
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
@ -80,21 +123,23 @@ ukopen(dev)
|
||||
{
|
||||
errval errcode = 0;
|
||||
u_int32 unit, mode;
|
||||
struct uk_data *uk;
|
||||
struct scsi_link *sc_link;
|
||||
unit = minor(dev);
|
||||
|
||||
/*
|
||||
* Check the unit is legal
|
||||
*/
|
||||
if (unit >= NUK) {
|
||||
printf("uk%d: uk %d > %d\n", unit, unit, NUK);
|
||||
if (unit >= uk_driver.size) {
|
||||
printf("uk%d: uk %d > %d\n", unit, unit, uk_driver.size);
|
||||
return ENXIO;
|
||||
}
|
||||
uk = uk_driver.uk_data[unit];
|
||||
|
||||
/*
|
||||
* Make sure the device has been initialised
|
||||
*/
|
||||
if((uk_data[unit].flags & UK_KNOWN) == 0) {
|
||||
if((!uk) || (!(uk->flags & UK_KNOWN))) {
|
||||
printf("uk%d: not set up\n", unit);
|
||||
return ENXIO;
|
||||
}
|
||||
@ -102,14 +147,14 @@ ukopen(dev)
|
||||
/*
|
||||
* Only allow one at a time
|
||||
*/
|
||||
sc_link = uk_data[unit].sc_link;
|
||||
sc_link = uk->sc_link;
|
||||
if (sc_link->flags & SDEV_OPEN) {
|
||||
printf("uk%d: already open\n", unit);
|
||||
return ENXIO;
|
||||
}
|
||||
sc_link->flags |= SDEV_OPEN;
|
||||
SC_DEBUG(sc_link, SDEV_DB1, ("ukopen: dev=0x%x (unit %d (of %d))\n"
|
||||
,dev, unit, NUK));
|
||||
SC_DEBUG(sc_link, SDEV_DB1, ("ukopen: dev=0x%x (unit %d (of %d))\n",
|
||||
dev, unit, uk_driver.size));
|
||||
/*
|
||||
* Catch any unit attention errors.
|
||||
*/
|
||||
@ -124,10 +169,13 @@ errval
|
||||
ukclose(dev)
|
||||
dev_t dev;
|
||||
{
|
||||
unsigned char unit = 0, mode; /* XXX !!! XXX FIXME!!! 0??? */
|
||||
u_int32 unit = minor(dev);
|
||||
unsigned mode; /* XXX !!! XXX FIXME!!! 0??? */
|
||||
struct uk_data *uk;
|
||||
struct scsi_link *sc_link;
|
||||
|
||||
sc_link = uk_data[unit].sc_link;
|
||||
uk = uk_driver.uk_data[unit];
|
||||
sc_link = uk->sc_link;
|
||||
|
||||
SC_DEBUG(sc_link, SDEV_DB1, ("Closing device"));
|
||||
sc_link->flags &= ~SDEV_OPEN;
|
||||
@ -146,13 +194,15 @@ ukioctl(dev, cmd, arg, mode)
|
||||
int mode;
|
||||
{
|
||||
unsigned char unit;
|
||||
struct uk_data *uk;
|
||||
struct scsi_link *sc_link;
|
||||
|
||||
/*
|
||||
* Find the device that the user is talking about
|
||||
*/
|
||||
unit = minor(dev);
|
||||
sc_link = uk_data[unit].sc_link;
|
||||
uk = uk_driver.uk_data[unit];
|
||||
sc_link = uk->sc_link;
|
||||
return(scsi_do_ioctl(sc_link,cmd,arg,mode));
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user