1
0
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:
Poul-Henning Kamp 1994-12-16 06:03:28 +00:00
parent 75a128283a
commit a31f80dc67
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=5118
4 changed files with 219 additions and 111 deletions

View File

@ -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,

View File

@ -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. ? */

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: 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;

View File

@ -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));
}