1. Change driver signatures to full signature for slice support.
2. Add "pt" (processor type) driver. 3. Add "worm" (Write Once) driver for Jordan.
This commit is contained in:
parent
920052bded
commit
f29b7a5d14
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=6890
@ -14,7 +14,7 @@
|
||||
*
|
||||
* Ported to run under 386BSD by Julian Elischer (julian@tfs.com) Sept 1992
|
||||
*
|
||||
* $Id: cd.c,v 1.33 1995/01/08 13:38:28 dufault Exp $
|
||||
* $Id: cd.c,v 1.34 1995/03/01 22:24:39 dufault Exp $
|
||||
*/
|
||||
|
||||
#define SPLCD splbio
|
||||
@ -89,10 +89,12 @@ struct scsi_data {
|
||||
static int cdunit(dev_t dev) { return CDUNIT(dev); }
|
||||
static dev_t cdsetunit(dev_t dev, int unit) { return CDSETUNIT(dev, unit); }
|
||||
|
||||
errval cd_open(dev_t dev, int flags, struct scsi_link *sc_link);
|
||||
errval cd_open(dev_t dev, int flags, int fmt, struct proc *p,
|
||||
struct scsi_link *sc_link);
|
||||
errval cd_ioctl(dev_t dev, int cmd, caddr_t addr, int flag,
|
||||
struct scsi_link *sc_link);
|
||||
errval cd_close(dev_t dev, struct scsi_link *sc_link);
|
||||
struct proc *p, struct scsi_link *sc_link);
|
||||
errval cd_close(dev_t dev, int flag, int fmt, struct proc *p,
|
||||
struct scsi_link *sc_link);
|
||||
void cd_strategy(struct buf *bp, struct scsi_link *sc_link);
|
||||
|
||||
SCSI_DEVICE_ENTRIES(cd)
|
||||
@ -108,6 +110,7 @@ struct scsi_device cd_switch =
|
||||
{0, 0},
|
||||
0, /* Link flags */
|
||||
cdattach,
|
||||
"CD-ROM",
|
||||
cdopen,
|
||||
sizeof(struct scsi_data),
|
||||
T_READONLY,
|
||||
@ -138,7 +141,6 @@ static struct kern_devconf kdc_cd_template = {
|
||||
&kdc_scbus0, /* parent - XXX should be host adapter*/
|
||||
0, /* parentdata */
|
||||
DC_UNKNOWN, /* not supported */
|
||||
"SCSI CD-ROM drive"
|
||||
};
|
||||
|
||||
static inline void
|
||||
@ -150,6 +152,7 @@ cd_registerdev(int unit)
|
||||
if(!kdc) return;
|
||||
*kdc = kdc_cd_template;
|
||||
kdc->kdc_unit = unit;
|
||||
kdc->kdc_description = cd_switch.desc;
|
||||
/* XXX should set parentdata */
|
||||
dev_attach(kdc);
|
||||
if(dk_ndrive < DK_NDRIVE) {
|
||||
@ -209,7 +212,8 @@ cdattach(struct scsi_link *sc_link)
|
||||
* open the device. Make sure the partition info is a up-to-date as can be.
|
||||
*/
|
||||
errval
|
||||
cd_open(dev_t dev, int flags, struct scsi_link *sc_link)
|
||||
cd_open(dev_t dev, int flags, int fmt, struct proc *p,
|
||||
struct scsi_link *sc_link)
|
||||
{
|
||||
errval errcode = 0;
|
||||
u_int32 unit, part;
|
||||
@ -226,7 +230,7 @@ cd_open(dev_t dev, int flags, struct scsi_link *sc_link)
|
||||
return (ENXIO);
|
||||
|
||||
SC_DEBUG(sc_link, SDEV_DB1,
|
||||
("cdopen: dev=0x%x (unit %d,partition %d)\n",
|
||||
("cd_open: dev=0x%x (unit %d,partition %d)\n",
|
||||
dev, unit, part));
|
||||
/*
|
||||
* If it's been invalidated, and not everybody has closed it then
|
||||
@ -240,7 +244,7 @@ cd_open(dev_t dev, int flags, struct scsi_link *sc_link)
|
||||
* Check that it is still responding and ok.
|
||||
* if the media has been changed this will result in a
|
||||
* "unit attention" error which the error code will
|
||||
* disregard because the SDEV_MEDIA_LOADED flag is not yet set
|
||||
* disregard because the SDEV_OPEN flag is not yet set
|
||||
*/
|
||||
scsi_test_unit_ready(sc_link, SCSI_SILENT);
|
||||
|
||||
@ -316,7 +320,8 @@ cd_open(dev_t dev, int flags, struct scsi_link *sc_link)
|
||||
* occurence of an open device
|
||||
*/
|
||||
errval
|
||||
cd_close(dev_t dev, struct scsi_link *sc_link)
|
||||
cd_close(dev_t dev, int flag, int fmt, struct proc *p,
|
||||
struct scsi_link *sc_link)
|
||||
{
|
||||
u_int8 unit, part;
|
||||
struct scsi_data *cd;
|
||||
@ -369,12 +374,6 @@ cd_strategy(struct buf *bp, struct scsi_link *sc_link)
|
||||
bp->b_error = EROFS;
|
||||
goto bad;
|
||||
}
|
||||
/*
|
||||
* If it's a null transfer, return immediatly
|
||||
*/
|
||||
if (bp->b_bcount == 0) {
|
||||
goto done;
|
||||
}
|
||||
/*
|
||||
* Decide which unit and partition we are talking about
|
||||
*/
|
||||
@ -539,7 +538,8 @@ cdstart(unit)
|
||||
* Knows about the internals of this device
|
||||
*/
|
||||
errval
|
||||
cd_ioctl(dev_t dev, int cmd, caddr_t addr, int flag, struct scsi_link *sc_link)
|
||||
cd_ioctl(dev_t dev, int cmd, caddr_t addr, int flag, struct proc *p,
|
||||
struct scsi_link *sc_link)
|
||||
{
|
||||
errval error = 0;
|
||||
u_int8 unit, part;
|
||||
@ -869,7 +869,7 @@ cd_ioctl(dev_t dev, int cmd, caddr_t addr, int flag, struct scsi_link *sc_link)
|
||||
break;
|
||||
default:
|
||||
if(part == RAW_PART || SCSI_SUPER(dev))
|
||||
error = scsi_do_ioctl(dev, cmd, addr, flag, sc_link);
|
||||
error = scsi_do_ioctl(dev, cmd, addr, flag, p, sc_link);
|
||||
else
|
||||
error = ENOTTY;
|
||||
break;
|
||||
|
@ -2,7 +2,7 @@
|
||||
* Written by grefen@?????
|
||||
* Based on scsi drivers by Julian Elischer (julian@tfs.com)
|
||||
*
|
||||
* $Id: ch.c,v 1.13 1995/01/19 21:02:54 ats Exp $
|
||||
* $Id: ch.c,v 1.14 1995/03/01 22:24:40 dufault Exp $
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
@ -46,16 +46,17 @@ struct scsi_data {
|
||||
u_long op_matrix; /* possible opertaions */
|
||||
u_int16 lsterr; /* details of lasterror */
|
||||
u_char stor; /* posible Storage locations */
|
||||
u_int32 initialized;
|
||||
};
|
||||
|
||||
static int chunit(dev_t dev) { return CHUNIT(dev); }
|
||||
static dev_t chsetunit(dev_t dev, int unit) { return CHSETUNIT(dev, unit); }
|
||||
|
||||
errval ch_open(dev_t dev, int flags, struct scsi_link *sc_link);
|
||||
errval ch_open(dev_t dev, int flags, int fmt, struct proc *p,
|
||||
struct scsi_link *sc_link);
|
||||
errval ch_ioctl(dev_t dev, int cmd, caddr_t addr, int flag,
|
||||
struct scsi_link *sc_link);
|
||||
errval ch_close(dev_t dev, struct scsi_link *sc_link);
|
||||
struct proc *p, struct scsi_link *sc_link);
|
||||
errval ch_close(dev_t dev, int flag, int fmt, struct proc *p,
|
||||
struct scsi_link *sc_link);
|
||||
|
||||
SCSI_DEVICE_ENTRIES(ch)
|
||||
|
||||
@ -70,6 +71,7 @@ struct scsi_device ch_switch =
|
||||
{0, 0},
|
||||
0, /* Link flags */
|
||||
chattach,
|
||||
"Medium-Changer",
|
||||
chopen,
|
||||
sizeof(struct scsi_data),
|
||||
T_CHANGER,
|
||||
@ -82,7 +84,6 @@ struct scsi_device ch_switch =
|
||||
};
|
||||
|
||||
#define CH_OPEN 0x01
|
||||
#define CH_KNOWN 0x02
|
||||
|
||||
static int
|
||||
ch_externalize(struct proc *p, struct kern_devconf *kdc, void *userp,
|
||||
@ -99,7 +100,6 @@ static struct kern_devconf kdc_ch_template = {
|
||||
&kdc_scbus0, /* parent */
|
||||
0, /* parentdata */
|
||||
DC_UNKNOWN, /* not supported */
|
||||
"SCSI media changer"
|
||||
};
|
||||
|
||||
static inline void
|
||||
@ -111,6 +111,7 @@ ch_registerdev(int unit)
|
||||
if(!kdc) return;
|
||||
*kdc = kdc_ch_template;
|
||||
kdc->kdc_unit = unit;
|
||||
kdc->kdc_description = ch_switch.desc;
|
||||
dev_attach(kdc);
|
||||
}
|
||||
|
||||
@ -121,7 +122,7 @@ ch_registerdev(int unit)
|
||||
errval
|
||||
chattach(struct scsi_link *sc_link)
|
||||
{
|
||||
u_int32 unit, i, stat;
|
||||
u_int32 unit, i;
|
||||
unsigned char *tbl;
|
||||
|
||||
struct scsi_data *ch = sc_link->sd;
|
||||
@ -134,14 +135,11 @@ chattach(struct scsi_link *sc_link)
|
||||
* request must specify this.
|
||||
*/
|
||||
if ((ch_mode_sense(unit, SCSI_NOSLEEP | SCSI_NOMASK /*| SCSI_SILENT */ ))) {
|
||||
printf("scsi changer :- offline\n");
|
||||
stat = CH_OPEN;
|
||||
printf("offline\n");
|
||||
} else {
|
||||
printf("scsi changer, %d slot(s) %d drive(s) %d arm(s) %d i/e-slot(s)\n",
|
||||
printf("%d slot(s) %d drive(s) %d arm(s) %d i/e-slot(s)\n",
|
||||
ch->slots, ch->drives, ch->chms, ch->imexs);
|
||||
stat = CH_KNOWN;
|
||||
}
|
||||
ch->initialized = 1;
|
||||
ch_registerdev(unit);
|
||||
|
||||
return 0;
|
||||
@ -151,7 +149,8 @@ chattach(struct scsi_link *sc_link)
|
||||
* open the device.
|
||||
*/
|
||||
errval
|
||||
ch_open(dev_t dev, int flags, struct scsi_link *sc_link)
|
||||
ch_open(dev_t dev, int flags, int fmt, struct proc *p,
|
||||
struct scsi_link *sc_link)
|
||||
{
|
||||
errval errcode = 0;
|
||||
u_int32 unit, mode;
|
||||
@ -168,12 +167,6 @@ ch_open(dev_t dev, int flags, struct scsi_link *sc_link)
|
||||
printf("ch%d: already open\n", unit);
|
||||
return EBUSY;
|
||||
}
|
||||
/*
|
||||
* Make sure the device has been initialised
|
||||
*/
|
||||
if (!cd->initialized)
|
||||
return (ENXIO);
|
||||
|
||||
/*
|
||||
* Catch any unit attention errors.
|
||||
*/
|
||||
@ -205,7 +198,8 @@ ch_open(dev_t dev, int flags, struct scsi_link *sc_link)
|
||||
* occurence of an open device
|
||||
*/
|
||||
errval
|
||||
ch_close(dev_t dev, struct scsi_link *sc_link)
|
||||
ch_close(dev_t dev, int flag, int fmt, struct proc *p,
|
||||
struct scsi_link *sc_link)
|
||||
{
|
||||
sc_link->sd->flags = 0;
|
||||
sc_link->flags &= ~SDEV_OPEN;
|
||||
@ -218,7 +212,7 @@ ch_close(dev_t dev, struct scsi_link *sc_link)
|
||||
*/
|
||||
errval
|
||||
ch_ioctl(dev_t dev, int cmd, caddr_t arg, int mode,
|
||||
struct scsi_link *sc_link)
|
||||
struct proc *p, struct scsi_link *sc_link)
|
||||
{
|
||||
/* struct ch_cmd_buf *args; */
|
||||
union scsi_cmd *scsi_cmd;
|
||||
@ -274,7 +268,7 @@ struct scsi_link *sc_link)
|
||||
}
|
||||
}
|
||||
default:
|
||||
return scsi_do_ioctl(dev, cmd, arg, mode, sc_link);
|
||||
return scsi_do_ioctl(dev, cmd, arg, mode, p, sc_link);
|
||||
}
|
||||
return (ret ? ESUCCESS : EIO);
|
||||
}
|
||||
|
214
sys/scsi/pt.c
Normal file
214
sys/scsi/pt.c
Normal file
@ -0,0 +1,214 @@
|
||||
/*
|
||||
* pt: Processor Type driver.
|
||||
*
|
||||
* Copyright (C) 1995, HD Associates, Inc.
|
||||
* PO Box 276
|
||||
* Pepperell, MA 01463
|
||||
* 508 433 5266
|
||||
* dufault@hda.com
|
||||
*
|
||||
* This code is contributed to the University of California at Berkeley:
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $Id:$
|
||||
*/
|
||||
|
||||
/*
|
||||
* XXX dufault@hda.com: We need the "kern devconf" stuff, but I'm not
|
||||
* going to add it until it is done in a simple way that provides
|
||||
* base behavior in scsi_driver.c
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/buf.h>
|
||||
#include <scsi/scsi_all.h>
|
||||
#include <scsi/scsiconf.h>
|
||||
|
||||
struct scsi_data {
|
||||
struct buf *buf_queue; /* the queue of pending IO operations */
|
||||
};
|
||||
|
||||
void ptstart(u_int32 unit);
|
||||
void pt_strategy(struct buf *bp, struct scsi_link *sc_link);
|
||||
|
||||
SCSI_DEVICE_ENTRIES(pt)
|
||||
|
||||
struct scsi_device pt_switch =
|
||||
{
|
||||
NULL,
|
||||
ptstart, /* we have a queue, and this is how we service it */
|
||||
NULL,
|
||||
NULL,
|
||||
"pt",
|
||||
0,
|
||||
{0, 0},
|
||||
SDEV_ONCE_ONLY, /* Only one open allowed */
|
||||
0,
|
||||
"Processor",
|
||||
ptopen,
|
||||
sizeof(struct scsi_data),
|
||||
T_PROCESSOR,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
pt_strategy,
|
||||
};
|
||||
/*
|
||||
* ptstart looks to see if there is a buf waiting for the device
|
||||
* and that the device is not already busy. If both are true,
|
||||
* It dequeues the buf and creates a scsi command to perform the
|
||||
* transfer required. The transfer request will call scsi_done
|
||||
* on completion, which will in turn call this routine again
|
||||
* so that the next queued transfer is performed.
|
||||
* The bufs are queued by the strategy routine (ptstrategy)
|
||||
*
|
||||
* This routine is also called after other non-queued requests
|
||||
* have been made of the scsi driver, to ensure that the queue
|
||||
* continues to be drained.
|
||||
* ptstart() is called at splbio
|
||||
*/
|
||||
void
|
||||
ptstart(unit)
|
||||
u_int32 unit;
|
||||
{
|
||||
struct scsi_link *sc_link = SCSI_LINK(&pt_switch, unit);
|
||||
struct scsi_data *pt = sc_link->sd;
|
||||
register struct buf *bp = 0;
|
||||
struct
|
||||
{
|
||||
#define PROCESSOR_SEND 0x0A
|
||||
#define PROCESSOR_RECEIVE 0x08
|
||||
u_char op_code;
|
||||
u_char byte2;
|
||||
u_char len[3];
|
||||
u_char control;
|
||||
} cmd;
|
||||
|
||||
u_int32 flags;
|
||||
|
||||
SC_DEBUG(sc_link, SDEV_DB2, ("ptstart "));
|
||||
/*
|
||||
* See if there is a buf to do and we are not already
|
||||
* doing one
|
||||
*/
|
||||
while (sc_link->opennings != 0) {
|
||||
|
||||
/* if a special awaits, let it proceed first */
|
||||
if (sc_link->flags & SDEV_WAITING) {
|
||||
sc_link->flags &= ~SDEV_WAITING;
|
||||
wakeup((caddr_t)sc_link);
|
||||
return;
|
||||
}
|
||||
if ((bp = pt->buf_queue) == NULL) {
|
||||
return; /* no work to bother with */
|
||||
}
|
||||
pt->buf_queue = bp->b_actf;
|
||||
|
||||
/*
|
||||
* Fill out the scsi command
|
||||
*/
|
||||
bzero(&cmd, sizeof(cmd));
|
||||
if ((bp->b_flags & B_READ) == B_WRITE) {
|
||||
cmd.op_code = PROCESSOR_SEND;
|
||||
flags = SCSI_DATA_OUT;
|
||||
} else {
|
||||
cmd.op_code = PROCESSOR_RECEIVE;
|
||||
flags = SCSI_DATA_IN;
|
||||
}
|
||||
|
||||
scsi_uto3b(bp->b_bcount, cmd.len);
|
||||
/*
|
||||
* go ask the adapter to do all this for us
|
||||
*/
|
||||
if (scsi_scsi_cmd(sc_link,
|
||||
(struct scsi_generic *) &cmd,
|
||||
sizeof(cmd),
|
||||
(u_char *) bp->b_un.b_addr,
|
||||
bp->b_bcount,
|
||||
0, /* can't retry a read on a tape really */
|
||||
100000,
|
||||
bp,
|
||||
flags | SCSI_NOSLEEP) == SUCCESSFULLY_QUEUED) {
|
||||
} else {
|
||||
badnews:
|
||||
printf("pt%d: oops not queued\n", unit);
|
||||
bp->b_flags |= B_ERROR;
|
||||
bp->b_error = EIO;
|
||||
biodone(bp);
|
||||
}
|
||||
} /* go back and see if we can cram more work in.. */
|
||||
}
|
||||
|
||||
void
|
||||
pt_strategy(struct buf *bp, struct scsi_link *sc_link)
|
||||
{
|
||||
struct buf **dp;
|
||||
unsigned char unit;
|
||||
u_int32 opri;
|
||||
struct scsi_data *pt;
|
||||
|
||||
unit = STUNIT((bp->b_dev));
|
||||
pt = sc_link->sd;
|
||||
|
||||
opri = splbio();
|
||||
|
||||
/*
|
||||
* Use a bounce buffer if necessary
|
||||
*/
|
||||
#ifdef BOUNCE_BUFFERS
|
||||
if (sc_link->flags & SDEV_BOUNCE)
|
||||
vm_bounce_alloc(bp);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Place it in the queue of activities for this tape
|
||||
* at the end (a bit silly because we only have one user..
|
||||
* (but it could fork() ))
|
||||
*/
|
||||
dp = &(pt->buf_queue);
|
||||
while (*dp) {
|
||||
dp = &((*dp)->b_actf);
|
||||
}
|
||||
*dp = bp;
|
||||
bp->b_actf = NULL;
|
||||
|
||||
/*
|
||||
* Tell the device to get going on the transfer if it's
|
||||
* not doing anything, otherwise just wait for completion
|
||||
* (All a bit silly if we're only allowing 1 open but..)
|
||||
*/
|
||||
ptstart(unit);
|
||||
|
||||
splx(opri);
|
||||
return;
|
||||
}
|
@ -8,7 +8,7 @@
|
||||
* file.
|
||||
*
|
||||
* Written by Julian Elischer (julian@dialix.oz.au)
|
||||
* $Id: scsi_base.c,v 1.19 1995/01/31 11:41:44 dufault Exp $
|
||||
* $Id: scsi_base.c,v 1.20 1995/02/15 07:44:07 davidg Exp $
|
||||
*/
|
||||
|
||||
#define SPLSD splbio
|
||||
@ -108,12 +108,16 @@ free_xs(xs, sc_link, flags)
|
||||
}
|
||||
}
|
||||
|
||||
/* XXX dufault: Replace "sd_size" with "scsi_read_capacity"
|
||||
* when bde is done with sd.c
|
||||
*/
|
||||
/*
|
||||
* Find out from the device what its capacity is.
|
||||
*/
|
||||
u_int32
|
||||
scsi_size(sc_link, flags)
|
||||
scsi_read_capacity(sc_link, blk_size, flags)
|
||||
struct scsi_link *sc_link;
|
||||
u_int32 *blk_size;
|
||||
u_int32 flags;
|
||||
{
|
||||
struct scsi_read_cap_data rdcap;
|
||||
@ -145,10 +149,9 @@ scsi_size(sc_link, flags)
|
||||
printf("could not get size\n");
|
||||
return (0);
|
||||
} else {
|
||||
size = rdcap.addr_0 + 1;
|
||||
size += rdcap.addr_1 << 8;
|
||||
size += rdcap.addr_2 << 16;
|
||||
size += rdcap.addr_3 << 24;
|
||||
size = scsi_4btou(&rdcap.addr_3) + 1;
|
||||
if (blk_size)
|
||||
*blk_size = scsi_4btou(&rdcap.length_3);
|
||||
}
|
||||
return (size);
|
||||
}
|
||||
@ -932,9 +935,6 @@ scsi_uto3b(val, bytes)
|
||||
*bytes = val & 0xff;
|
||||
}
|
||||
|
||||
/*
|
||||
* The reverse of scsi_uto3b
|
||||
*/
|
||||
u_int32
|
||||
scsi_3btou(bytes)
|
||||
u_char *bytes;
|
||||
@ -946,9 +946,6 @@ scsi_3btou(bytes)
|
||||
return rc;
|
||||
}
|
||||
|
||||
/*
|
||||
* scsi_3btoi: scsi_3btou for twos complement signed integers:
|
||||
*/
|
||||
int32
|
||||
scsi_3btoi(bytes)
|
||||
u_char *bytes;
|
||||
@ -961,6 +958,48 @@ scsi_3btoi(bytes)
|
||||
return (int32) rc;
|
||||
}
|
||||
|
||||
void
|
||||
scsi_uto2b(val, bytes)
|
||||
u_int32 val;
|
||||
u_char *bytes;
|
||||
{
|
||||
*bytes++ = (val & 0xff00) >> 8;
|
||||
*bytes = val & 0xff;
|
||||
}
|
||||
|
||||
u_int32
|
||||
scsi_2btou(bytes)
|
||||
u_char *bytes;
|
||||
{
|
||||
u_int32 rc;
|
||||
rc = (*bytes++ << 8);
|
||||
rc += *bytes;
|
||||
return rc;
|
||||
}
|
||||
|
||||
void
|
||||
scsi_uto4b(val, bytes)
|
||||
u_int32 val;
|
||||
u_char *bytes;
|
||||
{
|
||||
*bytes++ = (val & 0xff000000) >> 24;
|
||||
*bytes++ = (val & 0xff0000) >> 16;
|
||||
*bytes++ = (val & 0xff00) >> 8;
|
||||
*bytes = val & 0xff;
|
||||
}
|
||||
|
||||
u_int32
|
||||
scsi_4btou(bytes)
|
||||
u_char *bytes;
|
||||
{
|
||||
u_int32 rc;
|
||||
rc = (*bytes++ << 24);
|
||||
rc += (*bytes++ << 16);
|
||||
rc += (*bytes++ << 8);
|
||||
rc += *bytes;
|
||||
return rc;
|
||||
}
|
||||
|
||||
/*
|
||||
* Print out the scsi_link structure's address info.
|
||||
*/
|
||||
|
@ -35,7 +35,7 @@
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $Id: scsi_driver.c,v 1.1 1995/03/01 22:24:41 dufault Exp $
|
||||
* $Id: scsi_driver.c,v 1.2 1995/03/03 21:38:43 dufault Exp $
|
||||
*
|
||||
*/
|
||||
#include <sys/types.h>
|
||||
@ -68,13 +68,16 @@ int scsi_device_attach(struct scsi_link *sc_link)
|
||||
SC_DEBUG(sc_link, SDEV_DB2,
|
||||
("%s%dattach: ", device->name, sc_link->dev_unit));
|
||||
|
||||
sc_print_addr(sc_link);
|
||||
printf("%s ", device->desc);
|
||||
|
||||
dev = scsi_dev_lookup(device->open);
|
||||
|
||||
sc_link->dev = (device->setunit ?
|
||||
(*device->setunit)(dev, sc_link->dev_unit) :
|
||||
makedev(major(dev), sc_link->dev_unit) );
|
||||
|
||||
errcode = (*(device->attach))(sc_link);
|
||||
errcode = (device->attach) ? (*(device->attach))(sc_link) : 0;
|
||||
|
||||
if (errcode == 0)
|
||||
sc_link->flags |= device->link_flags;
|
||||
@ -82,8 +85,9 @@ int scsi_device_attach(struct scsi_link *sc_link)
|
||||
return errcode;
|
||||
}
|
||||
|
||||
errval
|
||||
scsi_open(dev_t dev, int flags, struct scsi_device *device)
|
||||
int
|
||||
scsi_open(dev_t dev, int flags, int fmt, struct proc *p,
|
||||
struct scsi_device *device)
|
||||
{
|
||||
errval errcode;
|
||||
u_int32 unit;
|
||||
@ -102,7 +106,7 @@ scsi_open(dev_t dev, int flags, struct scsi_device *device)
|
||||
return ENXIO;
|
||||
|
||||
errcode = (device->dev_open) ?
|
||||
(*device->dev_open)(dev, flags, sc_link) : 0;
|
||||
(*device->dev_open)(dev, flags, fmt, p, sc_link) : 0;
|
||||
|
||||
if (sc_link->flags & SDEV_ONCE_ONLY) {
|
||||
/*
|
||||
@ -125,8 +129,9 @@ scsi_open(dev_t dev, int flags, struct scsi_device *device)
|
||||
* close the device.. only called if we are the LAST
|
||||
* occurence of an open device
|
||||
*/
|
||||
errval
|
||||
scsi_close(dev_t dev, struct scsi_device *device)
|
||||
int
|
||||
scsi_close(dev_t dev, int flags, int fmt, struct proc *p,
|
||||
struct scsi_device *device)
|
||||
{
|
||||
errval errcode;
|
||||
struct scsi_link *scsi_link = SCSI_LINK(device, GETUNIT(device, dev));
|
||||
@ -134,7 +139,7 @@ scsi_close(dev_t dev, struct scsi_device *device)
|
||||
SC_DEBUG(scsi_link, SDEV_DB1, ("%sclose: Closing device\n", device->name));
|
||||
|
||||
errcode = (device->dev_close) ?
|
||||
(*device->dev_close)(dev, scsi_link) : 0;
|
||||
(*device->dev_close)(dev, flags, fmt, p, scsi_link) : 0;
|
||||
|
||||
if (scsi_link->flags & SDEV_ONCE_ONLY)
|
||||
scsi_link->flags &= ~SDEV_OPEN;
|
||||
@ -142,16 +147,16 @@ scsi_close(dev_t dev, struct scsi_device *device)
|
||||
return errcode;
|
||||
}
|
||||
|
||||
errval
|
||||
scsi_ioctl(dev_t dev, u_int32 cmd, caddr_t arg, int mode,
|
||||
int
|
||||
scsi_ioctl(dev_t dev, u_int32 cmd, caddr_t arg, int mode, struct proc *p,
|
||||
struct scsi_device *device)
|
||||
{
|
||||
errval errcode;
|
||||
struct scsi_link *scsi_link = SCSI_LINK(device, GETUNIT(device, dev));
|
||||
|
||||
errcode = (device->dev_ioctl) ?
|
||||
(*device->dev_ioctl)(dev, cmd, arg, mode, scsi_link)
|
||||
: scsi_do_ioctl(dev, cmd, arg, mode, scsi_link);
|
||||
(*device->dev_ioctl)(dev, cmd, arg, mode, p, scsi_link)
|
||||
: scsi_do_ioctl(dev, cmd, arg, mode, p, scsi_link);
|
||||
|
||||
return errcode;
|
||||
}
|
||||
@ -172,7 +177,12 @@ scsi_strategy(struct buf *bp, struct scsi_device *device)
|
||||
SC_DEBUG(sc_link, SDEV_DB1, ("%s%ld: %d bytes @ blk%d\n",
|
||||
device->name, unit, bp->b_bcount, bp->b_blkno));
|
||||
|
||||
if (device->dev_strategy)
|
||||
if (bp->b_bcount == 0)
|
||||
{
|
||||
bp->b_resid = 0;
|
||||
biodone(bp);
|
||||
}
|
||||
else if (device->dev_strategy)
|
||||
{
|
||||
(*sc_link->adapter->scsi_minphys)(bp);
|
||||
(*device->dev_strategy)(bp, sc_link);
|
||||
|
@ -35,22 +35,27 @@
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $Id: scsi_ioctl.c,v 1.10 1995/01/19 12:41:36 dufault Exp $
|
||||
* $Id: scsi_driver.h,v 1.1 1995/03/01 22:24:42 dufault Exp $
|
||||
*
|
||||
*/
|
||||
#ifndef _SCSI__DRIVER_H_
|
||||
#define _SCSI__DRIVER_H_
|
||||
|
||||
#include <sys/conf.h>
|
||||
|
||||
struct kern_devconf;
|
||||
struct scsi_link;
|
||||
struct scsi_device;
|
||||
struct buf;
|
||||
struct proc;
|
||||
|
||||
int scsi_goaway __P((struct kern_devconf *, int));
|
||||
int scsi_device_attach __P((struct scsi_link *));
|
||||
errval scsi_open __P((dev_t, int, struct scsi_device *));
|
||||
errval scsi_close __P((dev_t, struct scsi_device *));
|
||||
errval scsi_ioctl __P((dev_t, u_int32, caddr_t, int, struct scsi_device *));
|
||||
int scsi_goaway __P((struct kern_devconf *, int));
|
||||
int scsi_device_attach __P((struct scsi_link *));
|
||||
|
||||
int scsi_open __P((dev_t, int, int, struct proc *, struct scsi_device *));
|
||||
int scsi_close __P((dev_t, int, int, struct proc *, struct scsi_device *));
|
||||
int scsi_ioctl __P((dev_t, u_int32, caddr_t, int, struct proc *,
|
||||
struct scsi_device *));
|
||||
void scsi_strategy __P((struct buf *, struct scsi_device *));
|
||||
void scsi_minphys __P((struct buf *, struct scsi_device *));
|
||||
|
||||
|
@ -38,7 +38,7 @@
|
||||
* SUCH DAMAGE.
|
||||
*End copyright
|
||||
*
|
||||
* $Id: scsi_ioctl.c,v 1.10 1995/01/19 12:41:36 dufault Exp $
|
||||
* $Id: scsi_ioctl.c,v 1.11 1995/03/01 22:24:42 dufault Exp $
|
||||
*
|
||||
*
|
||||
*/
|
||||
@ -243,7 +243,7 @@ void scsiminphys(struct buf *bp)
|
||||
* in the context of the calling process
|
||||
*/
|
||||
errval scsi_do_ioctl(dev_t dev, int cmd, caddr_t addr, int f,
|
||||
struct scsi_link *sc_link)
|
||||
struct proc *p, struct scsi_link *sc_link)
|
||||
{
|
||||
errval ret = 0;
|
||||
|
||||
|
@ -16,7 +16,7 @@
|
||||
*
|
||||
* New configuration setup: dufault@hda.com
|
||||
*
|
||||
* $Id: scsiconf.c,v 1.19 1995/02/14 06:18:06 phk Exp $
|
||||
* $Id: scsiconf.c,v 1.20 1995/03/01 22:24:43 dufault Exp $
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
@ -309,15 +309,15 @@ errval scsi_probe_bus(int bus, int targ, int lun);
|
||||
|
||||
/* XXX dufault@hda.com
|
||||
* This scsi_device doesn't have the scsi_data_size.
|
||||
* This is used during probe and used to be "probe_switch".
|
||||
* This is used during probe.
|
||||
*/
|
||||
struct scsi_device inval_switch =
|
||||
struct scsi_device probe_switch =
|
||||
{
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
"??",
|
||||
"probe",
|
||||
0,
|
||||
{0, 0},
|
||||
NULL,
|
||||
@ -470,7 +470,7 @@ scsi_init(void)
|
||||
/* Feel free to take this out when everyone is sure this config
|
||||
* code works well:
|
||||
*/
|
||||
#define CONFIGD() printf(" config'd at ")
|
||||
#define CONFIGD() printf(" is configured at ")
|
||||
|
||||
/* scsi_bus_conf: Figure out which bus this is. If it is wired in config
|
||||
* use that. Otherwise use the next free one.
|
||||
@ -519,7 +519,6 @@ scsi_assign_unit(struct scsi_link *sc_link)
|
||||
{
|
||||
int i;
|
||||
int found;
|
||||
printf("%s", sc_link->device->name);
|
||||
found = 0;
|
||||
for (i = 0; scsi_dinit[i].name; i++) {
|
||||
if ((strcmp(sc_link->device->name, scsi_dinit[i].name) == 0) &&
|
||||
@ -529,9 +528,12 @@ scsi_assign_unit(struct scsi_link *sc_link)
|
||||
(sc_link->lun == 0 && scsi_dinit[i].lun == SCCONF_UNSPEC)
|
||||
) &&
|
||||
sc_link->scsibus == scsi_dinit[i].cunit) {
|
||||
CONFIGD();
|
||||
sc_link->dev_unit = scsi_dinit[i].unit;
|
||||
found = 1;
|
||||
#ifdef CONFIGD
|
||||
printf("%s is configured at %d\n",
|
||||
sc_link->device->name, sc_link->dev_unit);
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -539,8 +541,6 @@ scsi_assign_unit(struct scsi_link *sc_link)
|
||||
if (!found)
|
||||
sc_link->dev_unit = sc_link->device->free_unit++;
|
||||
|
||||
printf("%d: ", sc_link->dev_unit);
|
||||
|
||||
return sc_link->dev_unit;
|
||||
}
|
||||
|
||||
@ -669,6 +669,7 @@ scsi_probe_bus(int bus, int targ, int lun)
|
||||
struct scsidevs *bestmatch = NULL;
|
||||
struct scsi_link *sc_link = NULL;
|
||||
boolean maybe_more;
|
||||
int type;
|
||||
|
||||
if ((bus < 0 ) || ( bus >= scbusses->nelem)) {
|
||||
return ENXIO;
|
||||
@ -717,11 +718,11 @@ scsi_probe_bus(int bus, int targ, int lun)
|
||||
}
|
||||
*sc_link = *sc_link_proto; /* struct copy */
|
||||
sc_link->opennings = 1;
|
||||
sc_link->device = &inval_switch;
|
||||
sc_link->device = &probe_switch;
|
||||
sc_link->target = targ;
|
||||
sc_link->lun = lun;
|
||||
sc_link->quirks = 0;
|
||||
bestmatch = scsi_probedev(sc_link, &maybe_more);
|
||||
bestmatch = scsi_probedev(sc_link, &maybe_more, &type);
|
||||
#ifdef NEW_SCSICONF
|
||||
if (bestmatch) {
|
||||
sc_link->quirks = bestmatch->quirks;
|
||||
@ -732,7 +733,7 @@ scsi_probe_bus(int bus, int targ, int lun)
|
||||
}
|
||||
#endif
|
||||
if (bestmatch) { /* FOUND */
|
||||
sc_link->device = scsi_device_lookup(bestmatch->type);
|
||||
sc_link->device = scsi_device_lookup(type);
|
||||
|
||||
(void)scsi_assign_unit(sc_link);
|
||||
|
||||
@ -777,9 +778,10 @@ scsi_link_get(bus, targ, lun)
|
||||
* entry.
|
||||
*/
|
||||
struct scsidevs *
|
||||
scsi_probedev(sc_link, maybe_more)
|
||||
scsi_probedev(sc_link, maybe_more, type_p)
|
||||
boolean *maybe_more;
|
||||
struct scsi_link *sc_link;
|
||||
int *type_p;
|
||||
{
|
||||
u_int8 unit = sc_link->adapter_unit;
|
||||
u_int8 target = sc_link->target;
|
||||
@ -916,35 +918,20 @@ scsi_probedev(sc_link, maybe_more)
|
||||
manu[8] = 0;
|
||||
model[16] = 0;
|
||||
version[4] = 0;
|
||||
printf("%s%d targ %d lun %d: type %ld(%s) %s SCSI%d\n"
|
||||
,scsi_adapter->name
|
||||
,unit
|
||||
,target
|
||||
,lu
|
||||
sc_print_addr(sc_link);
|
||||
printf("type %ld(%s) %s SCSI%d\n"
|
||||
,type
|
||||
,dtype
|
||||
,remov ? "removable" : "fixed"
|
||||
,inqbuf->version & SID_ANSII
|
||||
);
|
||||
printf("%s%d targ %d lun %d: <%s%s%s>\n"
|
||||
,scsi_adapter->name
|
||||
,unit
|
||||
,target
|
||||
,lu
|
||||
,manu
|
||||
,model
|
||||
,version
|
||||
);
|
||||
sc_print_addr(sc_link);
|
||||
printf("<%s%s%s>\n", manu, model, version );
|
||||
if (qtype[0]) {
|
||||
printf("%s%d targ %d lun %d: qualifier %ld(%s)\n"
|
||||
,scsi_adapter->name
|
||||
,unit
|
||||
,target
|
||||
,lu
|
||||
,qualifier
|
||||
,qtype
|
||||
);
|
||||
sc_print_addr(sc_link);
|
||||
printf("qualifier %ld(%s)\n" ,qualifier ,qtype);
|
||||
}
|
||||
|
||||
/*
|
||||
* Try make as good a match as possible with
|
||||
* available sub drivers
|
||||
@ -954,6 +941,15 @@ scsi_probedev(sc_link, maybe_more)
|
||||
if ((bestmatch) && (bestmatch->flags & SC_MORE_LUS)) {
|
||||
*maybe_more = 1;
|
||||
}
|
||||
|
||||
/* If the device is unknown then we should be trying to look up a
|
||||
* type driver based on the inquiry type.
|
||||
*/
|
||||
if (bestmatch == &unknowndev)
|
||||
*type_p = type;
|
||||
else
|
||||
*type_p = bestmatch->type;
|
||||
|
||||
return bestmatch;
|
||||
}
|
||||
|
||||
@ -1102,9 +1098,6 @@ scsi_selectdev(qualifier, type, remov, manu, model, rev)
|
||||
}
|
||||
#endif /* NEW_SCSICONF */
|
||||
if (bestmatch == (struct scsidevs *) 0) {
|
||||
/* XXX At this point we should default to a base type driver.
|
||||
*/
|
||||
printf("No explicit driver match. Attaching as unknown.\n");
|
||||
bestmatch = &unknowndev;
|
||||
}
|
||||
return (bestmatch);
|
||||
|
@ -14,7 +14,7 @@
|
||||
*
|
||||
* Ported to run under 386BSD by Julian Elischer (julian@tfs.com) Sept 1992
|
||||
*
|
||||
* $Id: scsiconf.h,v 1.17 1995/02/14 06:17:23 phk Exp $
|
||||
* $Id: scsiconf.h,v 1.18 1995/03/01 22:24:44 dufault Exp $
|
||||
*/
|
||||
#ifndef SCSI_SCSICONF_H
|
||||
#define SCSI_SCSICONF_H 1
|
||||
@ -148,6 +148,9 @@ struct scsi_data;
|
||||
|
||||
struct scsi_link; /* scsi_link refers to scsi_device and vice-versa */
|
||||
struct scsi_xfer;
|
||||
|
||||
struct proc;
|
||||
|
||||
/*
|
||||
* These entry points are called by the low-end drivers to get services from
|
||||
* whatever high-end drivers they are attached to. Each device type has one
|
||||
@ -172,17 +175,20 @@ struct scsi_device
|
||||
|
||||
/* 36*/ int32 link_flags; /* Flags OR'd into sc_link at attach time */
|
||||
/* 40*/ errval (*attach)(struct scsi_link *sc_link);
|
||||
/* 44*/ int (*open)(dev_t dev, int flags);
|
||||
/* 48*/ int sizeof_scsi_data;
|
||||
/* 52*/ int type; /* Type of device this supports */
|
||||
/* 56*/ int (*getunit)(dev_t dev);
|
||||
/* 60*/ dev_t (*setunit)(dev_t dev, int unit);
|
||||
/* 44*/ char *desc; /* Description of device */
|
||||
/* 48*/ int (*open)(dev_t dev, int flags, int fmt, struct proc *p);
|
||||
/* 52*/ int sizeof_scsi_data;
|
||||
/* 56*/ int type; /* Type of device this supports */
|
||||
/* 60*/ int (*getunit)(dev_t dev);
|
||||
/* 64*/ dev_t (*setunit)(dev_t dev, int unit);
|
||||
|
||||
/* 64*/ errval (*dev_open)(dev_t dev, int flags, struct scsi_link *sc_link);
|
||||
/* 68*/ errval (*dev_ioctl)(dev_t dev, int cmd, caddr_t arg, int mode,
|
||||
/* 68*/ int (*dev_open)(dev_t dev, int flags, int fmt, struct proc *p,
|
||||
struct scsi_link *sc_link);
|
||||
/* 72*/ errval (*dev_close)(dev_t dev, struct scsi_link *sc_link);
|
||||
/* 76*/ void (*dev_strategy)(struct buf *bp, struct scsi_link *sc_link);
|
||||
/* 72*/ int (*dev_ioctl)(dev_t dev, int cmd, caddr_t arg, int mode,
|
||||
struct proc *p, struct scsi_link *sc_link);
|
||||
/* 76*/ int (*dev_close)(dev_t dev, int flag, int fmt, struct proc *p,
|
||||
struct scsi_link *sc_link);
|
||||
/* 80*/ void (*dev_strategy)(struct buf *bp, struct scsi_link *sc_link);
|
||||
|
||||
/* Not initialized after this */
|
||||
|
||||
@ -212,17 +218,17 @@ void NAME##init(void) \
|
||||
{ \
|
||||
scsi_device_register(&NAME##_switch); \
|
||||
} \
|
||||
errval NAME##open(dev_t dev, int flags) \
|
||||
int NAME##open(dev_t dev, int flags, int fmt, struct proc *p) \
|
||||
{ \
|
||||
return scsi_open(dev, flags, &NAME##_switch); \
|
||||
return scsi_open(dev, flags, fmt, p, &NAME##_switch); \
|
||||
} \
|
||||
errval NAME##ioctl(dev_t dev, int cmd, caddr_t addr, int flag) \
|
||||
int NAME##ioctl(dev_t dev, int cmd, caddr_t addr, int flag, struct proc *p) \
|
||||
{ \
|
||||
return scsi_ioctl(dev, cmd, addr, flag, &NAME##_switch); \
|
||||
return scsi_ioctl(dev, cmd, addr, flag, p, &NAME##_switch); \
|
||||
} \
|
||||
errval NAME##close(dev_t dev) \
|
||||
int NAME##close(dev_t dev, int flag, int fmt, struct proc *p) \
|
||||
{ \
|
||||
return scsi_close(dev, &NAME##_switch); \
|
||||
return scsi_close(dev, flag, fmt, p, &NAME##_switch); \
|
||||
} \
|
||||
void NAME##minphys(struct buf *bp) \
|
||||
{ \
|
||||
@ -439,7 +445,8 @@ char * scsi_type_name(int type);
|
||||
void scsi_attachdevs __P((struct scsi_link *sc_link_proto));
|
||||
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_size( 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_change_def( struct scsi_link *sc_link, u_int32 flags);
|
||||
errval scsi_inquire( struct scsi_link *sc_link,
|
||||
@ -453,11 +460,12 @@ errval scsi_scsi_cmd( struct scsi_link *sc_link, struct scsi_generic *scsi_cmd,
|
||||
u_int32 datalen, u_int32 retries,
|
||||
u_int32 timeout, struct buf *bp,
|
||||
u_int32 flags);
|
||||
errval scsi_do_ioctl __P((dev_t dev,
|
||||
int cmd, caddr_t addr, int f, struct scsi_link *sc_link));
|
||||
int scsi_do_ioctl __P((dev_t dev, int cmd, caddr_t addr, int mode,
|
||||
struct proc *p, struct scsi_link *sc_link));
|
||||
|
||||
struct scsi_link *scsi_link_get __P((int bus, int targ, int lun));
|
||||
dev_t scsi_dev_lookup __P((int (*opener)(dev_t dev, int flags)));
|
||||
dev_t scsi_dev_lookup __P((int (*opener)(dev_t dev, int flags, int fmt,
|
||||
struct proc *p)));
|
||||
|
||||
int scsi_opened_ok __P((dev_t dev, int flag, int type, struct scsi_link *sc_link));
|
||||
|
||||
@ -469,6 +477,10 @@ void show_mem(unsigned char * , u_int32);
|
||||
void scsi_uto3b __P((u_int32 val, u_char *bytes));
|
||||
u_int32 scsi_3btou __P((u_char *bytes));
|
||||
int32 scsi_3btoi __P((u_char *bytes));
|
||||
void scsi_uto4b __P((u_int32 val, u_char *bytes));
|
||||
u_int32 scsi_4btou __P((u_char *bytes));
|
||||
void scsi_uto2b __P((u_int32 val, u_char *bytes));
|
||||
u_int32 scsi_2btou __P((u_char *bytes));
|
||||
|
||||
extern void sc_print_addr(struct scsi_link *);
|
||||
|
||||
@ -561,10 +573,6 @@ extern struct kern_devconf kdc_scbus0; /* XXX should go away */
|
||||
#define CDUNIT(DEV) SH3_UNIT(DEV)
|
||||
#define CDSETUNIT(DEV, U) SH3SETUNIT((DEV), (U))
|
||||
|
||||
#define SDUNITSHIFT 3
|
||||
#define SDUNIT(DEV) SH3_UNIT(DEV)
|
||||
#define SDSETUNIT(DEV, U) SH3SETUNIT((DEV), (U))
|
||||
|
||||
#define CHUNIT(DEV) SH4_UNIT(DEV)
|
||||
#define CHSETUNIT(DEV, U) SH4SETUNIT((DEV), (U))
|
||||
|
||||
|
@ -14,7 +14,7 @@
|
||||
*
|
||||
* Ported to run under 386BSD by Julian Elischer (julian@dialix.oz.au) Sept 1992
|
||||
*
|
||||
* $Id: sd.c,v 1.50 1995/01/31 11:41:46 dufault Exp $
|
||||
* $Id: sd.c,v 1.51 1995/03/01 22:24:45 dufault Exp $
|
||||
*/
|
||||
|
||||
#define SPLSD splbio
|
||||
@ -48,6 +48,10 @@ u_int32 sdstrats, sdqueues;
|
||||
#define SD_RETRIES 4
|
||||
#define MAXTRANSFER 8 /* 1 page at a time */
|
||||
|
||||
#define SDUNITSHIFT 3
|
||||
#define SDUNIT(DEV) SH3_UNIT(DEV)
|
||||
#define SDSETUNIT(DEV, U) SH3SETUNIT((DEV), (U))
|
||||
|
||||
#define MAKESDDEV(maj, unit, part) (makedev(maj,((unit<<SDUNITSHIFT)+part)))
|
||||
#define PARTITION(z) (minor(z) & 0x07)
|
||||
|
||||
@ -92,10 +96,12 @@ struct scsi_data {
|
||||
static int sdunit(dev_t dev) { return SDUNIT(dev); }
|
||||
static dev_t sdsetunit(dev_t dev, int unit) { return SDSETUNIT(dev, unit); }
|
||||
|
||||
errval sd_open(dev_t dev, int flags, struct scsi_link *sc_link);
|
||||
errval sd_open(dev_t dev, int flags, int fmt, struct proc *p,
|
||||
struct scsi_link *sc_link);
|
||||
errval sd_ioctl(dev_t dev, int cmd, caddr_t addr, int flag,
|
||||
struct scsi_link *sc_link);
|
||||
errval sd_close(dev_t dev, struct scsi_link *sc_link);
|
||||
struct proc *p, struct scsi_link *sc_link);
|
||||
errval sd_close(dev_t dev, int flag, int fmt, struct proc *p,
|
||||
struct scsi_link *sc_link);
|
||||
void sd_strategy(struct buf *bp, struct scsi_link *sc_link);
|
||||
|
||||
SCSI_DEVICE_ENTRIES(sd)
|
||||
@ -111,6 +117,7 @@ struct scsi_device sd_switch =
|
||||
{0, 0},
|
||||
0, /* Link flags */
|
||||
sdattach,
|
||||
"Direct-Access",
|
||||
sdopen,
|
||||
sizeof(struct scsi_data),
|
||||
T_DIRECT,
|
||||
@ -139,7 +146,6 @@ static struct kern_devconf kdc_sd_template = {
|
||||
&kdc_scbus0, /* XXX parent */
|
||||
0, /* parentdata */
|
||||
DC_UNKNOWN, /* not supported */
|
||||
"SCSI disk"
|
||||
};
|
||||
|
||||
static inline void
|
||||
@ -151,6 +157,7 @@ sd_registerdev(int unit)
|
||||
if(!kdc) return;
|
||||
*kdc = kdc_sd_template;
|
||||
kdc->kdc_unit = unit;
|
||||
kdc->kdc_description = sd_switch.desc;
|
||||
dev_attach(kdc);
|
||||
if(dk_ndrive < DK_NDRIVE) {
|
||||
sprintf(dk_names[dk_ndrive], "sd%d", unit);
|
||||
@ -218,7 +225,8 @@ sdattach(struct scsi_link *sc_link)
|
||||
* open the device. Make sure the partition info is a up-to-date as can be.
|
||||
*/
|
||||
errval
|
||||
sd_open(dev_t dev, int flags, struct scsi_link *sc_link)
|
||||
sd_open(dev_t dev, int flags, int fmt, struct proc *p,
|
||||
struct scsi_link *sc_link)
|
||||
{
|
||||
errval errcode = 0;
|
||||
u_int32 unit, part;
|
||||
@ -340,7 +348,8 @@ sd_open(dev_t dev, int flags, struct scsi_link *sc_link)
|
||||
* device. Convenient now but usually a pain.
|
||||
*/
|
||||
errval
|
||||
sd_close(dev_t dev, struct scsi_link *sc_link)
|
||||
sd_close(dev_t dev, int flag, int fmt, struct proc *p,
|
||||
struct scsi_link *sc_link)
|
||||
{
|
||||
unsigned char unit, part;
|
||||
struct scsi_data *sd;
|
||||
@ -586,7 +595,7 @@ sdstart(u_int32 unit)
|
||||
*/
|
||||
errval
|
||||
sd_ioctl(dev_t dev, int cmd, caddr_t addr, int flag,
|
||||
struct scsi_link *sc_link)
|
||||
struct proc *p, struct scsi_link *sc_link)
|
||||
{
|
||||
/* struct sd_cmd_buf *args; */
|
||||
errval error = 0;
|
||||
@ -693,7 +702,7 @@ struct scsi_link *sc_link)
|
||||
|
||||
default:
|
||||
if (part == RAWPART || SCSI_SUPER(dev) )
|
||||
error = scsi_do_ioctl(dev, cmd, addr, flag, sc_link);
|
||||
error = scsi_do_ioctl(dev, cmd, addr, flag, p, sc_link);
|
||||
else
|
||||
error = ENOTTY;
|
||||
break;
|
||||
@ -954,10 +963,7 @@ sdsize(dev_t dev)
|
||||
if ((sd->flags & SDINIT) == 0)
|
||||
return -1;
|
||||
if (sd == 0 || (sd->flags & SDHAVELABEL) == 0) {
|
||||
/* XXX: By rights sdopen should be called like:
|
||||
* sdopen(MAKESDDEV(major(dev), unit, RAWPART), FREAD, S_IFBLK, 0);
|
||||
*/
|
||||
val = sdopen(MAKESDDEV(major(dev), unit, RAWPART), FREAD);
|
||||
val = sdopen(MAKESDDEV(major(dev), unit, RAWPART), FREAD, S_IFBLK, 0);
|
||||
if (val != 0)
|
||||
return -1;
|
||||
}
|
||||
|
@ -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.27 1995/02/25 19:11:11 jkh Exp $
|
||||
* $Id: st.c,v 1.28 1995/03/01 22:24:46 dufault Exp $
|
||||
*/
|
||||
|
||||
/*
|
||||
@ -218,10 +218,12 @@ struct scsi_data {
|
||||
static int stunit(dev_t dev) { return STUNIT(dev); }
|
||||
static dev_t stsetunit(dev_t dev, int unit) { return STSETUNIT(dev, unit); }
|
||||
|
||||
errval st_open(dev_t dev, int flags, struct scsi_link *sc_link);
|
||||
errval st_open(dev_t dev, int flags, int fmt, struct proc *p,
|
||||
struct scsi_link *sc_link);
|
||||
errval st_ioctl(dev_t dev, int cmd, caddr_t addr, int flag,
|
||||
struct scsi_link *sc_link);
|
||||
errval st_close(dev_t dev, struct scsi_link *sc_link);
|
||||
struct proc *p, struct scsi_link *sc_link);
|
||||
errval st_close(dev_t dev, int flag, int fmt, struct proc *p,
|
||||
struct scsi_link *sc_link);
|
||||
void st_strategy(struct buf *bp, struct scsi_link *sc_link);
|
||||
|
||||
SCSI_DEVICE_ENTRIES(st)
|
||||
@ -237,6 +239,7 @@ struct scsi_device st_switch =
|
||||
{0, 0},
|
||||
0, /* Link flags */
|
||||
stattach,
|
||||
"Sequential-Access",
|
||||
stopen,
|
||||
sizeof(struct scsi_data),
|
||||
T_SEQUENTIAL,
|
||||
@ -287,7 +290,6 @@ static struct kern_devconf kdc_st_template = {
|
||||
&kdc_scbus0, /* XXX parent */
|
||||
0, /* parentdata */
|
||||
DC_UNKNOWN, /* not supported */
|
||||
"SCSI tape drive"
|
||||
};
|
||||
|
||||
static inline void
|
||||
@ -299,6 +301,7 @@ st_registerdev(int unit)
|
||||
if(!kdc) return;
|
||||
*kdc = kdc_st_template;
|
||||
kdc->kdc_unit = unit;
|
||||
kdc->kdc_description = st_switch.desc;
|
||||
dev_attach(kdc);
|
||||
}
|
||||
|
||||
@ -495,7 +498,8 @@ st_loadquirks(sc_link)
|
||||
* open the device.
|
||||
*/
|
||||
errval
|
||||
st_open(dev_t dev, int flags, struct scsi_link *sc_link)
|
||||
st_open(dev_t dev, int flags, int fmt, struct proc *p,
|
||||
struct scsi_link *sc_link)
|
||||
{
|
||||
u_int32 unit, mode, dsty;
|
||||
errval errno = 0;
|
||||
@ -580,7 +584,8 @@ st_open(dev_t dev, int flags, struct scsi_link *sc_link)
|
||||
* occurence of an open device
|
||||
*/
|
||||
errval
|
||||
st_close(dev_t dev, struct scsi_link *sc_link)
|
||||
st_close(dev_t dev, int flag, int fmt, struct proc *p,
|
||||
struct scsi_link *sc_link)
|
||||
{
|
||||
unsigned char unit, mode;
|
||||
struct scsi_data *st;
|
||||
@ -1104,7 +1109,7 @@ ststart(unit)
|
||||
*/
|
||||
errval
|
||||
st_ioctl(dev_t dev, int cmd, caddr_t arg, int flag,
|
||||
struct scsi_link *sc_link)
|
||||
struct proc *p, struct scsi_link *sc_link)
|
||||
{
|
||||
errval errcode = 0;
|
||||
unsigned char unit;
|
||||
@ -1227,7 +1232,7 @@ struct scsi_link *sc_link)
|
||||
break;
|
||||
default:
|
||||
if(IS_CTLMODE(dev))
|
||||
errcode = scsi_do_ioctl(dev, cmd, arg, flag, sc_link);
|
||||
errcode = scsi_do_ioctl(dev, cmd, arg, flag, p, sc_link);
|
||||
else
|
||||
errcode = ENOTTY;
|
||||
break;
|
||||
|
@ -44,7 +44,7 @@
|
||||
* SUCH DAMAGE.
|
||||
*End copyright
|
||||
*
|
||||
* $Id:$
|
||||
* $Id: su.c,v 1.3 1995/01/08 15:56:10 dufault Exp $
|
||||
*
|
||||
* Tabstops 4
|
||||
*/
|
||||
@ -58,39 +58,49 @@
|
||||
#include <sys/buf.h>
|
||||
#include <sys/systm.h>
|
||||
|
||||
/* bnxio, cnxio: non existent device entries (with ugly casts to quiet gcc).
|
||||
/* XXX: These are taken from, and perhaps belong in, conf.c
|
||||
*/
|
||||
#define nxopen (d_open_t *)enxio
|
||||
#define nxclose (d_close_t *)enxio
|
||||
#define nxread (d_rdwr_t *)enxio
|
||||
#define nxwrite nxread
|
||||
#define nxstrategy (d_strategy_t *)enxio
|
||||
#define nxioctl (d_ioctl_t *)enxio
|
||||
#define nxdump (d_dump_t *)enxio
|
||||
#define nxstop (d_stop_t *)enxio
|
||||
#define nxreset (d_reset_t *)enxio
|
||||
#define nxselect (d_select_t *)enxio
|
||||
#define nxmmap (d_mmap_t *)enxio
|
||||
#define nxdevtotty (d_ttycv_t *)nullop
|
||||
#define zerosize (d_psize_t *)0
|
||||
|
||||
/* bnxio, cnxio: non existent device entries
|
||||
*/
|
||||
static struct bdevsw bnxio = {
|
||||
(int (*) __P((dev_t dev, int oflags, int devtype,
|
||||
struct proc *p))) enxio,
|
||||
(int (*) __P((dev_t dev, int fflag, int devtype,
|
||||
struct proc *p))) enxio,
|
||||
(d_strategy_t *) enxio,
|
||||
(int (*) __P((dev_t dev, int cmd, caddr_t data,
|
||||
int fflag, struct proc *p))) enxio,
|
||||
(int (*) ()) enxio,
|
||||
(int (*) __P((dev_t dev))) 0,
|
||||
(int ) 0
|
||||
nxopen,
|
||||
nxclose,
|
||||
nxstrategy,
|
||||
nxioctl,
|
||||
nxdump,
|
||||
zerosize,
|
||||
0
|
||||
};
|
||||
|
||||
static struct cdevsw cnxio = {
|
||||
(int (*) __P((dev_t dev, int oflags, int devtype,
|
||||
struct proc *p))) enxio,
|
||||
(int (*) __P((dev_t dev, int fflag, int devtype,
|
||||
struct proc *))) enxio,
|
||||
(int (*) __P((dev_t dev, struct uio *uio, int ioflag))) enxio,
|
||||
(int (*) __P((dev_t dev, struct uio *uio, int ioflag))) enxio,
|
||||
(int (*) __P((dev_t dev, int cmd, caddr_t data,
|
||||
int fflag, struct proc *p))) enxio,
|
||||
(int (*) __P((struct tty *tp, int rw))) nullop,
|
||||
(int (*) __P((int uban))) enxio,
|
||||
(struct tty *) 0,
|
||||
(int (*) __P((dev_t dev, int which, struct proc *p))) enxio,
|
||||
(int (*) __P(())) enxio,
|
||||
(d_strategy_t *) enxio
|
||||
nxopen,
|
||||
nxclose,
|
||||
nxread,
|
||||
nxwrite,
|
||||
nxioctl,
|
||||
nxstop,
|
||||
nxreset,
|
||||
nxdevtotty,
|
||||
nxselect,
|
||||
nxmmap,
|
||||
nxstrategy
|
||||
};
|
||||
|
||||
/* getsws: Look up the base dev switch for a given new style
|
||||
/* getsws: Look up the base dev switch for a given "by minor number" style
|
||||
* device.
|
||||
*/
|
||||
static int
|
||||
|
@ -2,7 +2,10 @@
|
||||
* Driver for a device we can't identify.
|
||||
* by Julian Elischer (julian@tfs.com)
|
||||
*
|
||||
* $Id: uk.c,v 1.6 1995/01/08 13:38:38 dufault Exp $
|
||||
* $Id: uk.c,v 1.7 1995/03/01 22:24:47 dufault Exp $
|
||||
*
|
||||
* If you find that you are adding any code to this file look closely
|
||||
* at putting it in "scsi_driver.c" instead.
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
@ -21,7 +24,8 @@ struct scsi_device uk_switch =
|
||||
0,
|
||||
{0, 0},
|
||||
SDEV_ONCE_ONLY, /* Only one open allowed */
|
||||
ukattach,
|
||||
0,
|
||||
"Unknown",
|
||||
ukopen,
|
||||
0,
|
||||
T_UNKNOWN,
|
||||
@ -32,15 +36,3 @@ struct scsi_device uk_switch =
|
||||
0,
|
||||
0,
|
||||
};
|
||||
|
||||
/*
|
||||
* The routine called by the low level scsi routine when it discovers
|
||||
* a device suitable for this driver.
|
||||
*/
|
||||
errval
|
||||
ukattach(struct scsi_link *sc_link)
|
||||
{
|
||||
printf("unknown device\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
360
sys/scsi/worm.c
Normal file
360
sys/scsi/worm.c
Normal file
@ -0,0 +1,360 @@
|
||||
/*
|
||||
* worm: Write Once device driver
|
||||
*
|
||||
* Copyright (C) 1995, HD Associates, Inc.
|
||||
* PO Box 276
|
||||
* Pepperell, MA 01463
|
||||
* 508 433 5266
|
||||
* dufault@hda.com
|
||||
*
|
||||
* This code is contributed to the University of California at Berkeley:
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $Id:$
|
||||
*/
|
||||
|
||||
/* XXX This is PRELIMINARY.
|
||||
*
|
||||
* We need the "kern devconf" stuff, but I'm not
|
||||
* going to add it until it is done in a simple way that provides
|
||||
* base behavior in scsi_driver.c
|
||||
*
|
||||
* Until Bruce finishes the slice stuff there will be no partitions.
|
||||
* When it is finished I hope to hoist the partition code up into
|
||||
* "scsi_driver" and use common code for all devices.
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/buf.h>
|
||||
#include <scsi/scsi_all.h>
|
||||
#include <scsi/scsiconf.h>
|
||||
#include <scsi/scsi_disk.h>
|
||||
|
||||
struct scsi_data {
|
||||
struct buf *buf_queue; /* the queue of pending IO operations */
|
||||
|
||||
u_int32 n_blks; /* Number of blocks (0 for bogus) */
|
||||
u_int32 blk_size; /* Size of each blocks */
|
||||
};
|
||||
|
||||
void wormstart(u_int32 unit);
|
||||
|
||||
errval worm_open(dev_t dev, int flags, int fmt, struct proc *p,
|
||||
struct scsi_link *sc_link);
|
||||
errval worm_ioctl(dev_t dev, int cmd, caddr_t addr, int flag,
|
||||
struct proc *p, struct scsi_link *sc_link);
|
||||
errval worm_close(dev_t dev, int flag, int fmt, struct proc *p,
|
||||
struct scsi_link *sc_link);
|
||||
void worm_strategy(struct buf *bp, struct scsi_link *sc_link);
|
||||
|
||||
SCSI_DEVICE_ENTRIES(worm)
|
||||
|
||||
struct scsi_device worm_switch =
|
||||
{
|
||||
NULL,
|
||||
wormstart, /* we have a queue, and this is how we service it */
|
||||
NULL,
|
||||
NULL,
|
||||
"worm",
|
||||
0,
|
||||
{0, 0},
|
||||
SDEV_ONCE_ONLY, /* Only one open allowed */
|
||||
wormattach,
|
||||
"Write-Once",
|
||||
wormopen,
|
||||
sizeof(struct scsi_data),
|
||||
T_WORM,
|
||||
0,
|
||||
0,
|
||||
worm_open,
|
||||
0,
|
||||
worm_close,
|
||||
worm_strategy,
|
||||
};
|
||||
|
||||
static int worm_size(struct scsi_link *sc_link)
|
||||
{
|
||||
int ret;
|
||||
struct scsi_data *worm = sc_link->sd;
|
||||
|
||||
worm->n_blks = scsi_read_capacity(sc_link, &worm->blk_size,
|
||||
SCSI_NOSLEEP | SCSI_NOMASK);
|
||||
|
||||
if (worm->n_blks)
|
||||
{
|
||||
sc_link->flags |= SDEV_MEDIA_LOADED;
|
||||
ret = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
sc_link->flags &= ~SDEV_MEDIA_LOADED;
|
||||
ret = 0;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
errval
|
||||
wormattach(struct scsi_link *sc_link)
|
||||
{
|
||||
struct scsi_data *worm = sc_link->sd;
|
||||
|
||||
printf("- UNTESTED ");
|
||||
|
||||
if (worm_size(sc_link) == 0)
|
||||
printf("- can't get capacity.\n");
|
||||
else
|
||||
printf("with %ld %ld byte blocks.\n", worm->n_blks, worm->blk_size);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* wormstart looks to see if there is a buf waiting for the device
|
||||
* and that the device is not already busy. If both are true,
|
||||
* It dequeues the buf and creates a scsi command to perform the
|
||||
* transfer required. The transfer request will call scsi_done
|
||||
* on completion, which will in turn call this routine again
|
||||
* so that the next queued transfer is performed.
|
||||
* The bufs are queued by the strategy routine (wormstrategy)
|
||||
*
|
||||
* This routine is also called after other non-queued requests
|
||||
* have been made of the scsi driver, to ensure that the queue
|
||||
* continues to be drained.
|
||||
* wormstart() is called at splbio
|
||||
*
|
||||
* XXX It looks like we need a "scsistart" to hoist common code up
|
||||
* into. In particular, the removable media checking should be
|
||||
* handled in one place.
|
||||
*/
|
||||
void
|
||||
wormstart(unit)
|
||||
u_int32 unit;
|
||||
{
|
||||
struct scsi_link *sc_link = SCSI_LINK(&worm_switch, unit);
|
||||
struct scsi_data *worm = sc_link->sd;
|
||||
register struct buf *bp = 0;
|
||||
struct
|
||||
{
|
||||
u_char op_code;
|
||||
u_char byte2;
|
||||
u_char lba3; /* I don't want to worry about packing */
|
||||
u_char lba2;
|
||||
u_char lba1;
|
||||
u_char lba0;
|
||||
u_char reserved;
|
||||
u_char tl1;
|
||||
u_char tl0;
|
||||
u_char ctl;
|
||||
} cmd;
|
||||
|
||||
u_int32 flags;
|
||||
u_int32 lba; /* Logical block address */
|
||||
u_int32 tl; /* Transfer length */
|
||||
|
||||
SC_DEBUG(sc_link, SDEV_DB2, ("wormstart "));
|
||||
|
||||
/*
|
||||
* We should reject all queued entries if SDEV_MEDIA_LOADED is not true.
|
||||
*/
|
||||
if (!(sc_link->flags & SDEV_MEDIA_LOADED)) {
|
||||
goto badnews; /* no I/O.. media changed or something */
|
||||
}
|
||||
|
||||
/*
|
||||
* See if there is a buf to do and we are not already
|
||||
* doing one
|
||||
*/
|
||||
while (sc_link->opennings != 0) {
|
||||
|
||||
/* if a special awaits, let it proceed first */
|
||||
if (sc_link->flags & SDEV_WAITING) {
|
||||
sc_link->flags &= ~SDEV_WAITING;
|
||||
wakeup((caddr_t)sc_link);
|
||||
return;
|
||||
}
|
||||
if ((bp = worm->buf_queue) == NULL) {
|
||||
return; /* no work to bother with */
|
||||
}
|
||||
worm->buf_queue = bp->b_actf;
|
||||
|
||||
/*
|
||||
* Fill out the scsi command
|
||||
*/
|
||||
bzero(&cmd, sizeof(cmd));
|
||||
if ((bp->b_flags & B_READ) == B_WRITE) {
|
||||
cmd.op_code = WRITE_BIG;
|
||||
flags = SCSI_DATA_OUT;
|
||||
} else {
|
||||
cmd.op_code = READ_BIG;
|
||||
flags = SCSI_DATA_IN;
|
||||
}
|
||||
|
||||
|
||||
lba = bp->b_blkno / (worm->blk_size / DEV_BSIZE);
|
||||
tl = bp->b_bcount / worm->blk_size;
|
||||
|
||||
scsi_uto4b(lba, &cmd.lba3);
|
||||
scsi_uto2b(tl, &cmd.tl1);
|
||||
|
||||
/*
|
||||
* go ask the adapter to do all this for us
|
||||
*/
|
||||
if (scsi_scsi_cmd(sc_link,
|
||||
(struct scsi_generic *) &cmd,
|
||||
sizeof(cmd),
|
||||
(u_char *) bp->b_un.b_addr,
|
||||
bp->b_bcount,
|
||||
0, /* can't retry a read on a tape really */
|
||||
100000,
|
||||
bp,
|
||||
flags | SCSI_NOSLEEP) == SUCCESSFULLY_QUEUED) {
|
||||
} else {
|
||||
badnews:
|
||||
printf("worm%d: oops not queued\n", unit);
|
||||
bp->b_flags |= B_ERROR;
|
||||
bp->b_error = EIO;
|
||||
biodone(bp);
|
||||
}
|
||||
} /* go back and see if we can cram more work in.. */
|
||||
}
|
||||
|
||||
void
|
||||
worm_strategy(struct buf *bp, struct scsi_link *sc_link)
|
||||
{
|
||||
struct buf **dp;
|
||||
unsigned char unit;
|
||||
u_int32 opri;
|
||||
struct scsi_data *worm;
|
||||
|
||||
unit = STUNIT((bp->b_dev));
|
||||
worm = sc_link->sd;
|
||||
|
||||
/* XXX: Can't we move this check up to "scsi_strategy"?
|
||||
*/
|
||||
if (!(sc_link->flags & SDEV_MEDIA_LOADED) ||
|
||||
bp->b_blkno > worm->n_blks ||
|
||||
bp->b_bcount & (worm->blk_size - 1)) {
|
||||
bp->b_error = EIO;
|
||||
bp->b_flags |= B_ERROR;
|
||||
biodone(bp);
|
||||
return;
|
||||
}
|
||||
|
||||
opri = splbio();
|
||||
|
||||
/*
|
||||
* Use a bounce buffer if necessary
|
||||
* XXX: How can we move this up?
|
||||
*/
|
||||
#ifdef BOUNCE_BUFFERS
|
||||
if (sc_link->flags & SDEV_BOUNCE)
|
||||
vm_bounce_alloc(bp);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Place it in the queue of activities for this device
|
||||
* at the end.
|
||||
*/
|
||||
dp = &(worm->buf_queue);
|
||||
while (*dp) {
|
||||
dp = &((*dp)->b_actf);
|
||||
}
|
||||
*dp = bp;
|
||||
bp->b_actf = NULL;
|
||||
|
||||
wormstart(unit);
|
||||
|
||||
splx(opri);
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Open the device. XXX: I'm completely guessing at this sequence.
|
||||
*/
|
||||
int
|
||||
worm_open(dev_t dev, int flags, int fmt, struct proc *p,
|
||||
struct scsi_link *sc_link)
|
||||
{
|
||||
struct scsi_data *worm = sc_link->sd;
|
||||
|
||||
if (sc_link->flags & SDEV_OPEN)
|
||||
return EBUSY;
|
||||
|
||||
/*
|
||||
* Check that it is still responding and ok.
|
||||
* if the media has been changed this will result in a
|
||||
* "unit attention" error which the error code will
|
||||
* disregard because the SDEV_OPEN flag is not yet set
|
||||
*
|
||||
* XXX This should REALLY be hoisted up. As soon as Bruce
|
||||
* finishes that slice stuff. (Add a different flag,
|
||||
* and then do a "scsi_test_unit_ready" with the "ignore
|
||||
* unit attention" thing set. Then all this replicated
|
||||
* test unit ready code can be pulled up.
|
||||
*/
|
||||
scsi_test_unit_ready(sc_link, SCSI_SILENT);
|
||||
|
||||
/*
|
||||
* Next time actually take notice of error returns
|
||||
*/
|
||||
sc_link->flags |= SDEV_OPEN; /* unit attn errors are now errors */
|
||||
|
||||
if (scsi_test_unit_ready(sc_link, SCSI_SILENT) != 0) {
|
||||
SC_DEBUG(sc_link, SDEV_DB3, ("not ready\n"));
|
||||
sc_link->flags &= ~SDEV_OPEN;
|
||||
return ENXIO;
|
||||
}
|
||||
|
||||
scsi_start_unit(sc_link, SCSI_SILENT);
|
||||
|
||||
scsi_prevent(sc_link, PR_PREVENT, SCSI_SILENT);
|
||||
|
||||
if (worm_size(sc_link) == 0) {
|
||||
scsi_stop_unit(sc_link, 0, SCSI_SILENT);
|
||||
scsi_prevent(sc_link, PR_ALLOW, SCSI_SILENT);
|
||||
sc_link->flags &= ~SDEV_OPEN;
|
||||
return ENXIO;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
worm_close(dev_t dev, int flag, int fmt, struct proc *p,
|
||||
struct scsi_link *sc_link)
|
||||
{
|
||||
scsi_stop_unit(sc_link, 0, SCSI_SILENT);
|
||||
scsi_prevent(sc_link, PR_ALLOW, SCSI_SILENT);
|
||||
sc_link->flags &= ~SDEV_OPEN;
|
||||
|
||||
return 0;
|
||||
}
|
Loading…
Reference in New Issue
Block a user