diff options
-rw-r--r-- | sys/scsi/cd.c | 34 | ||||
-rw-r--r-- | sys/scsi/ch.c | 40 | ||||
-rw-r--r-- | sys/scsi/pt.c | 214 | ||||
-rw-r--r-- | sys/scsi/scsi_base.c | 63 | ||||
-rw-r--r-- | sys/scsi/scsi_driver.c | 36 | ||||
-rw-r--r-- | sys/scsi/scsi_driver.h | 17 | ||||
-rw-r--r-- | sys/scsi/scsi_ioctl.c | 4 | ||||
-rw-r--r-- | sys/scsi/scsiconf.c | 69 | ||||
-rw-r--r-- | sys/scsi/scsiconf.h | 58 | ||||
-rw-r--r-- | sys/scsi/sd.c | 32 | ||||
-rw-r--r-- | sys/scsi/st.c | 23 | ||||
-rw-r--r-- | sys/scsi/su.c | 64 | ||||
-rw-r--r-- | sys/scsi/uk.c | 20 | ||||
-rw-r--r-- | sys/scsi/worm.c | 360 |
14 files changed, 835 insertions, 199 deletions
diff --git a/sys/scsi/cd.c b/sys/scsi/cd.c index d052203..76ce80e 100644 --- a/sys/scsi/cd.c +++ b/sys/scsi/cd.c @@ -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; @@ -370,12 +375,6 @@ cd_strategy(struct buf *bp, struct scsi_link *sc_link) 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 */ if (PARTITION(bp->b_dev) != RAW_PART) { @@ -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; diff --git a/sys/scsi/ch.c b/sys/scsi/ch.c index 1c19f5e..73ebc95 100644 --- a/sys/scsi/ch.c +++ b/sys/scsi/ch.c @@ -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; @@ -169,12 +168,6 @@ ch_open(dev_t dev, int flags, struct scsi_link *sc_link) return EBUSY; } /* - * Make sure the device has been initialised - */ - if (!cd->initialized) - return (ENXIO); - - /* * Catch any unit attention errors. */ scsi_test_unit_ready(sc_link, SCSI_SILENT); @@ -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); } diff --git a/sys/scsi/pt.c b/sys/scsi/pt.c new file mode 100644 index 0000000..e606b8e --- /dev/null +++ b/sys/scsi/pt.c @@ -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; +} diff --git a/sys/scsi/scsi_base.c b/sys/scsi/scsi_base.c index 31fdbe6..a055b33 100644 --- a/sys/scsi/scsi_base.c +++ b/sys/scsi/scsi_base.c @@ -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. */ diff --git a/sys/scsi/scsi_driver.c b/sys/scsi/scsi_driver.c index dab2d5b..56c1acd 100644 --- a/sys/scsi/scsi_driver.c +++ b/sys/scsi/scsi_driver.c @@ -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); diff --git a/sys/scsi/scsi_driver.h b/sys/scsi/scsi_driver.h index dff132e..867b2f1 100644 --- a/sys/scsi/scsi_driver.h +++ b/sys/scsi/scsi_driver.h @@ -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 *)); -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_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 *)); diff --git a/sys/scsi/scsi_ioctl.c b/sys/scsi/scsi_ioctl.c index bca35ca..90dc134 100644 --- a/sys/scsi/scsi_ioctl.c +++ b/sys/scsi/scsi_ioctl.c @@ -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; diff --git a/sys/scsi/scsiconf.c b/sys/scsi/scsiconf.c index c65a774..9a998ba 100644 --- a/sys/scsi/scsiconf.c +++ b/sys/scsi/scsiconf.c @@ -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); diff --git a/sys/scsi/scsiconf.h b/sys/scsi/scsiconf.h index 50faf12..2c18e9c 100644 --- a/sys/scsi/scsiconf.h +++ b/sys/scsi/scsiconf.h @@ -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); - -/* 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, +/* 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); + +/* 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)) diff --git a/sys/scsi/sd.c b/sys/scsi/sd.c index 0a37774..5a61b15 100644 --- a/sys/scsi/sd.c +++ b/sys/scsi/sd.c @@ -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 @@ bad: * 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 @@ bad: */ 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; } diff --git a/sys/scsi/st.c b/sys/scsi/st.c index 5bb9cbc..19da5eb 100644 --- a/sys/scsi/st.c +++ b/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.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 @@ badnews: */ 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; diff --git a/sys/scsi/su.c b/sys/scsi/su.c index fffe45d..0211295 100644 --- a/sys/scsi/su.c +++ b/sys/scsi/su.c @@ -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 diff --git a/sys/scsi/uk.c b/sys/scsi/uk.c index 0f21110..d3c3506 100644 --- a/sys/scsi/uk.c +++ b/sys/scsi/uk.c @@ -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; -} diff --git a/sys/scsi/worm.c b/sys/scsi/worm.c new file mode 100644 index 0000000..78917b4 --- /dev/null +++ b/sys/scsi/worm.c @@ -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; +} |