diff --git a/sys/arch/hp300/dev/ac.c b/sys/arch/hp300/dev/ac.c index 19117133aa9a..29bb2a910cd4 100644 --- a/sys/arch/hp300/dev/ac.c +++ b/sys/arch/hp300/dev/ac.c @@ -1,6 +1,7 @@ -/* $NetBSD: ac.c,v 1.6 1996/10/13 03:14:05 christos Exp $ */ +/* $NetBSD: ac.c,v 1.7 1997/01/30 09:14:10 thorpej Exp $ */ /* + * Copyright (c) 1996, 1997 Jason R. Thorpe. All rights reserved. * Copyright (c) 1991 University of Utah. * Copyright (c) 1990, 1993 * The Regents of the University of California. All rights reserved. @@ -51,42 +52,34 @@ * never uses it. */ -#include "ac.h" -#if NAC > 0 - #include #include #include #include #include #include +#include -#include #include +#include + #include #include -extern int scsi_test_unit_rdy(); -extern int scsi_request_sense(); -extern int scsiustart(); -extern int scsigo(); -extern void scsifree(); -extern void scsireset(); -extern void scsi_delay(); -extern void scsi_str __P((char *, char *, size_t)); +int acmatch __P((struct device *, struct cfdata *, void *)); +void acattach __P((struct device *, struct device *, void *)); -extern int scsi_immed_command(); - -int acmatch(), acstart(), acgo(), acintr(); -void acattach(); - -struct driver acdriver = { - acmatch, acattach, "ac", acstart, acgo, acintr, +struct cfattach ac_ca = { + sizeof(struct ac_softc), acmatch, acattach }; -struct ac_softc ac_softc[NAC]; -static struct buf acbuf[NAC]; -static struct scsi_fmt_cdb accmd[NAC]; +struct cfdriver ac_cd = { + NULL, "ac", DV_DULL +}; + +void acstart __P((void *)); +void acgo __P((void *)); +void acintr __P((void *, int)); #ifdef DEBUG int ac_debug = 0x0000; @@ -95,108 +88,52 @@ int ac_debug = 0x0000; #endif int -acmatch(hd) - register struct hp_device *hd; +acmatch(parent, match, aux) + struct device *parent; + struct cfdata *match; + void *aux; { - int unit = hd->hp_unit; - register struct ac_softc *sc = &ac_softc[unit]; + struct oscsi_attach_args *osa = aux; - sc->sc_hd = hd; - sc->sc_punit = hd->hp_flags & 7; - if (acident(sc, hd, 0) < 0) + if (osa->osa_inqbuf->type != 8 || osa->osa_inqbuf->qual != 0x80 || + osa->osa_inqbuf->version != 2) return (0); return (1); } void -acattach(hd) - register struct hp_device *hd; +acattach(parent, self, aux) + struct device *parent, *self; + void *aux; { - int unit = hd->hp_unit; - register struct ac_softc *sc = &ac_softc[unit]; + struct ac_softc *sc = (struct ac_softc *)self; + struct oscsi_attach_args *osa = aux; - (void)acident(sc, hd, 1); /* XXX Ick. */ + printf("\n"); - sc->sc_dq.dq_softc = sc; - sc->sc_dq.dq_unit = unit; - sc->sc_dq.dq_ctlr = hd->hp_ctlr; - sc->sc_dq.dq_slave = hd->hp_slave; - sc->sc_dq.dq_driver = &acdriver; - sc->sc_bp = &acbuf[unit]; - sc->sc_cmd = &accmd[unit]; - sc->sc_flags = ACF_ALIVE; -} + sc->sc_target = osa->osa_target; + sc->sc_lun = osa->osa_lun; -acident(sc, hd, verbose) - register struct ac_softc *sc; - register struct hp_device *hd; - int verbose; -{ - int unit; - register int ctlr, slave; - int i, stat; - int tries = 5; - struct scsi_inquiry inqbuf; - char vendor[9], product[17], revision[5]; - static struct scsi_fmt_cdb inq = { - 6, - CMD_INQUIRY, 0, 0, 0, sizeof(inqbuf), 0 - }; + /* Initialize SCSI queue entry. */ + sc->sc_sq.sq_softc = sc; + sc->sc_sq.sq_target = sc->sc_target; + sc->sc_sq.sq_lun = sc->sc_lun; + sc->sc_sq.sq_start = acstart; + sc->sc_sq.sq_go = acgo; + sc->sc_sq.sq_intr = acintr; - ctlr = hd->hp_ctlr; - slave = hd->hp_slave; - unit = sc->sc_punit; - scsi_delay(-1); + sc->sc_bp = (struct buf *)malloc(sizeof(struct buf), + M_DEVBUF, M_NOWAIT); + sc->sc_cmd = (struct scsi_fmt_cdb *)malloc(sizeof(struct scsi_fmt_cdb), + M_DEVBUF, M_NOWAIT); - /* - * See if device is ready - */ - while ((i = scsi_test_unit_rdy(ctlr, slave, unit)) != 0) { - if (i == -1 || --tries < 0) - /* doesn't exist or not a CCS device */ - goto failed; - if (i == STS_CHECKCOND) { - u_char sensebuf[128]; - struct scsi_xsense *sp; - - scsi_request_sense(ctlr, slave, unit, - sensebuf, sizeof(sensebuf)); - sp = (struct scsi_xsense *) sensebuf; - if (sp->class == 7 && sp->key == 6) - /* drive doing an RTZ -- give it a while */ - DELAY(1000000); - } - DELAY(1000); + if (sc->sc_bp == NULL || sc->sc_cmd == NULL) { + printf("%s: memory allocation failed\n", sc->sc_dev.dv_xname); + return; } - /* - * Find out if it is an autochanger - */ - if (scsi_immed_command(ctlr, slave, unit, &inq, - (u_char *)&inqbuf, sizeof(inqbuf), B_READ)) - goto failed; - if (inqbuf.type != 8 || inqbuf.qual != 0x80 || inqbuf.version != 2) - goto failed; - - /* - * Get a usable id string - */ - bzero(vendor, sizeof(vendor)); - bzero(product, sizeof(product)); - bzero(revision, sizeof(revision)); - scsi_str(inqbuf.vendor_id, vendor, sizeof(inqbuf.vendor_id)); - scsi_str(inqbuf.product_id, product, sizeof(inqbuf.product_id)); - scsi_str(inqbuf.rev, revision, sizeof(inqbuf.rev)); - - if (verbose) - printf(": <%s, %s, %s>\n", vendor, product, revision); - - scsi_delay(0); - return(inqbuf.type); -failed: - scsi_delay(0); - return(-1); + sc->sc_flags = ACF_ALIVE; } /*ARGSUSED*/ @@ -206,13 +143,17 @@ acopen(dev, flag, mode, p) struct proc *p; { register int unit = minor(dev); - register struct ac_softc *sc = &ac_softc[unit]; + struct ac_softc *sc; int error = 0; - if (unit >= NAC || (sc->sc_flags & ACF_ALIVE) == 0) - return(ENXIO); + if (unit >= ac_cd.cd_ndevs || + (sc = ac_cd.cd_devs[unit]) == NULL || + (sc->sc_flags & ACF_ALIVE) == 0) + return (ENXIO); + if (sc->sc_flags & ACF_OPEN) - return(EBUSY); + return (EBUSY); + /* * Since acgeteinfo can block we mark the changer open now. */ @@ -221,7 +162,7 @@ acopen(dev, flag, mode, p) sc->sc_flags &= ~ACF_OPEN; return(EIO); } - return(0); + return (0); } /*ARGSUSED*/ @@ -230,9 +171,10 @@ acclose(dev, flag, mode, p) int flag, mode; struct proc *p; { - struct ac_softc *sc = &ac_softc[minor(dev)]; + struct ac_softc *sc = ac_cd.cd_devs[minor(dev)]; sc->sc_flags &= ~ACF_OPEN; + return (0); } #define ACRESLEN(ep) \ @@ -246,7 +188,7 @@ acioctl(dev, cmd, data, flag, p) int flag; struct proc *p; { - register struct ac_softc *sc = &ac_softc[minor(dev)]; + struct ac_softc *sc = ac_cd.cd_devs[minor(dev)]; char *dp; int dlen, error = 0; @@ -323,7 +265,7 @@ accommand(dev, command, bufp, buflen) int buflen; { int unit = minor(dev); - register struct ac_softc *sc = &ac_softc[unit]; + struct ac_softc *sc = ac_cd.cd_devs[unit]; register struct buf *bp = sc->sc_bp; register struct scsi_fmt_cdb *cmd = sc->sc_cmd; int error; @@ -379,38 +321,41 @@ accommand(dev, command, bufp, buflen) bp->b_resid = 0; bp->b_blkno = 0; bp->b_error = 0; - if (scsireq(&sc->sc_dq)) - acstart(unit); + if (scsireq(sc->sc_dev.dv_parent, &sc->sc_sq)) + acstart(sc); error = biowait(bp); sc->sc_flags &= ~ACF_ACTIVE; return (error); } -acstart(unit) - int unit; +void +acstart(arg) + void *arg; { + struct ac_softc *sc = arg; + #ifdef DEBUG if (ac_debug & ACD_FOLLOW) printf("acstart(unit=%x)\n", unit); #endif - if (scsiustart(ac_softc[unit].sc_hd->hp_ctlr)) - acgo(unit); + if (scsiustart(sc->sc_dev.dv_parent->dv_unit)) + acgo(arg); } -acgo(unit) - int unit; +void +acgo(arg) + void *arg; { - register struct ac_softc *sc = &ac_softc[unit]; + struct ac_softc *sc = arg; register struct buf *bp = sc->sc_bp; - struct hp_device *hp = sc->sc_hd; int stat; #ifdef DEBUG if (ac_debug & ACD_FOLLOW) printf("acgo(unit=%x): ", unit); #endif - stat = scsigo(hp->hp_ctlr, hp->hp_slave, sc->sc_punit, - bp, sc->sc_cmd, 0); + stat = scsigo(sc->sc_dev.dv_parent->dv_unit, sc->sc_target, + sc->sc_lun, bp, sc->sc_cmd, 0); #ifdef DEBUG if (ac_debug & ACD_FOLLOW) printf("scsigo returns %x\n", stat); @@ -419,10 +364,11 @@ acgo(unit) bp->b_error = EIO; bp->b_flags |= B_ERROR; (void) biodone(bp); - scsifree(&sc->sc_dq); + scsifree(sc->sc_dev.dv_parent, &sc->sc_sq); } } +void acintr(arg, stat) void *arg; int stat; @@ -431,7 +377,7 @@ acintr(arg, stat) register struct buf *bp = sc->sc_bp; u_char sensebuf[78]; struct scsi_xsense *sp; - int unit = sc->sc_hd->hp_unit; + int unit = sc->sc_dev.dv_unit; #ifdef DEBUG if (ac_debug & ACD_FOLLOW) @@ -442,27 +388,27 @@ acintr(arg, stat) bp->b_resid = 0; break; case STS_CHECKCOND: - scsi_request_sense(sc->sc_hd->hp_ctlr, sc->sc_hd->hp_slave, - sc->sc_punit, sensebuf, sizeof sensebuf); + scsi_request_sense(sc->sc_dev.dv_parent->dv_unit, + sc->sc_target, sc->sc_lun, sensebuf, sizeof sensebuf); sp = (struct scsi_xsense *)sensebuf; printf("%s: acintr sense key=%x, ac=%x, acq=%x\n", - sc->sc_hd->hp_xname, sp->key, sp->info4, sp->len); + sc->sc_dev.dv_xname, sp->key, sp->info4, sp->len); bp->b_flags |= B_ERROR; bp->b_error = EIO; break; default: - printf("%s: acintr unknown status 0x%x\n", sc->sc_hd->hp_xname, + printf("%s: acintr unknown status 0x%x\n", sc->sc_dev.dv_xname, stat); break; } (void) biodone(sc->sc_bp); - scsifree(&sc->sc_dq); + scsifree(sc->sc_dev.dv_parent, &sc->sc_sq); } acgeteinfo(dev) dev_t dev; { - register struct ac_softc *sc = &ac_softc[minor(dev)]; + struct ac_softc *sc = ac_cd.cd_devs[minor(dev)]; register char *bp; char msbuf[48]; int error; @@ -550,4 +496,3 @@ acconvert(sbuf, dbuf, ne) #endif } } -#endif diff --git a/sys/arch/hp300/dev/acvar.h b/sys/arch/hp300/dev/acvar.h index 8ed788828066..aac4401fd90e 100644 --- a/sys/arch/hp300/dev/acvar.h +++ b/sys/arch/hp300/dev/acvar.h @@ -1,4 +1,4 @@ -/* $NetBSD: acvar.h,v 1.2 1994/10/26 07:23:27 cgd Exp $ */ +/* $NetBSD: acvar.h,v 1.3 1997/01/30 09:14:11 thorpej Exp $ */ /* * Copyright (c) 1991 University of Utah. @@ -43,14 +43,15 @@ */ struct ac_softc { - struct hp_device *sc_hd; + struct device sc_dev; + int sc_target; + int sc_lun; int sc_flags; struct buf *sc_bp; struct scsi_fmt_cdb *sc_cmd; struct acinfo sc_einfo; - short sc_punit; short sc_picker; - struct devqueue sc_dq; + struct scsiqueue sc_sq; }; #define ACF_ALIVE 0x01 diff --git a/sys/arch/hp300/dev/ct.c b/sys/arch/hp300/dev/ct.c index 23197a1c6fcd..78fb444e5fb4 100644 --- a/sys/arch/hp300/dev/ct.c +++ b/sys/arch/hp300/dev/ct.c @@ -1,6 +1,7 @@ -/* $NetBSD: ct.c,v 1.18 1996/10/14 07:14:11 thorpej Exp $ */ +/* $NetBSD: ct.c,v 1.19 1997/01/30 09:14:12 thorpej Exp $ */ /* + * Copyright (c) 1996, 1997 Jason R. Thorpe. All rights reserved. * Copyright (c) 1982, 1990, 1993 * The Regents of the University of California. All rights reserved. * @@ -35,8 +36,6 @@ * @(#)ct.c 8.2 (Berkeley) 1/12/94 */ -#include "ct.h" -#if NCT > 0 /* * CS80 cartridge tape driver (9144, 88140, 9145) * @@ -57,21 +56,20 @@ #include #include #include +#include +#include + +#include -#include #include /* number of eof marks to remember */ #define EOFS 128 -int ctmatch(), ctstart(), ctgo(), ctintr(); -void ctattach(), ctstrategy(), ctdone(); -struct driver ctdriver = { - ctmatch, ctattach, "ct", ctstart, ctgo, ctintr, -}; - struct ct_softc { - struct hp_device *sc_hd; + struct device sc_dev; + int sc_slave; /* HP-IB slave ID */ + int sc_punit; /* physical unit */ struct ct_iocmd sc_ioc; struct ct_rscmd sc_rsc; struct ct_stat sc_stat; @@ -81,19 +79,20 @@ struct ct_softc { struct ct_ulcmd sc_ul; struct ct_wfmcmd sc_wfm; struct ct_clearcmd sc_clear; + struct buf sc_tab; struct buf *sc_bp; + struct buf sc_bufstore; /* XXX */ int sc_blkno; int sc_cmd; int sc_resid; char *sc_addr; int sc_flags; short sc_type; - short sc_punit; tpr_t sc_tpr; - struct devqueue sc_dq; + struct hpibqueue sc_hq; /* entry on hpib job queue */ int sc_eofp; int sc_eofs[EOFS]; -} ct_softc[NCT]; +}; /* flags */ #define CTF_OPEN 0x01 @@ -108,6 +107,35 @@ struct ct_softc { #define CTF_CANSTREAM 0x200 #define CTF_WRTTN 0x400 +int ctmatch __P((struct device *, struct cfdata *, void *)); +void ctattach __P((struct device *, struct device *, void *)); + +struct cfattach ct_ca = { + sizeof(struct ct_softc), ctmatch, ctattach +}; + +struct cfdriver ct_cd = { + NULL, "ct", DV_TAPE +}; + +int ctident __P((struct device *, struct ct_softc *, + struct hpibbus_attach_args *)); + +void ctreset __P((struct ct_softc *)); +void ctaddeof __P((struct ct_softc *)); +void ctustart __P((struct ct_softc *)); +void cteof __P((struct ct_softc *, struct buf *)); +void ctdone __P((struct ct_softc *, struct buf *)); + +void ctstart __P((void *)); +void ctgo __P((void *)); +void ctintr __P((void *)); + +void ctcommand __P((dev_t, int, int)); + +cdev_decl(ct); +bdev_decl(ct); + struct ctinfo { short hwid; short punit; @@ -121,9 +149,6 @@ struct ctinfo { }; int nctinfo = sizeof(ctinfo) / sizeof(ctinfo[0]); -struct buf cttab[NCT]; -struct buf ctbuf[NCT]; - #define CT_NOREW 4 #define CT_STREAM 8 #define UNIT(x) (minor(x) & 3) @@ -136,164 +161,184 @@ int ctdebug = 0; #endif int -ctmatch(hd) - register struct hp_device *hd; +ctmatch(parent, match, aux) + struct device *parent; + struct cfdata *match; + void *aux; { - register struct ct_softc *sc = &ct_softc[hd->hp_unit]; - register struct buf *bp; + struct hpibbus_attach_args *ha = aux; - for (bp = cttab; bp < &cttab[NCT]; bp++) - bp->b_actb = &bp->b_actf; - sc->sc_hd = hd; - sc->sc_punit = ctpunit(hd->hp_flags); - if (ctident(sc, hd, 0) < 0) - return (0); - - return (1); + return (ctident(parent, NULL, ha)); } void -ctattach(hd) - register struct hp_device *hd; +ctattach(parent, self, aux) + struct device *parent, *self; + void *aux; { - struct ct_softc *sc = &ct_softc[hd->hp_unit]; + struct ct_softc *sc = (struct ct_softc *)self; + struct hpibbus_attach_args *ha = aux; - (void)ctident(sc, hd, 1); /* XXX Ick. */ + if (ctident(parent, sc, ha) == 0) { + printf("\n%s: didn't respond to describe command!\n", + sc->sc_dev.dv_xname); + return; + } - ctreset(sc, hd); - sc->sc_dq.dq_softc = sc; - sc->sc_dq.dq_ctlr = hd->hp_ctlr; - sc->sc_dq.dq_unit = hd->hp_unit; - sc->sc_dq.dq_slave = hd->hp_slave; - sc->sc_dq.dq_driver = &ctdriver; + sc->sc_slave = ha->ha_slave; + sc->sc_punit = ha->ha_punit; + + sc->sc_tab.b_actb = &sc->sc_tab.b_actf; + + /* Initialize hpib job queue entry. */ + sc->sc_hq.hq_softc = sc; + sc->sc_hq.hq_slave = sc->sc_slave; + sc->sc_hq.hq_start = ctstart; + sc->sc_hq.hq_go = ctgo; + sc->sc_hq.hq_intr = ctintr; + + ctreset(sc); sc->sc_flags |= CTF_ALIVE; - - /* XXX Set device class. */ - hd->hp_dev.dv_class = DV_TAPE; } int -ctident(sc, hd, verbose) - register struct ct_softc *sc; - register struct hp_device *hd; - int verbose; +ctident(parent, sc, ha) + struct device *parent; + struct ct_softc *sc; + struct hpibbus_attach_args *ha; { struct ct_describe desc; u_char stat, cmd[3]; char name[7]; - int id, i; + int i, id, n, type, canstream; - /* - * Read device id and verify that: - * 1. It is a CS80 device - * 2. It is one of our recognized tape devices - * 3. It has the proper physical unit number - */ - id = hpibid(hd->hp_ctlr, hd->hp_slave); - if ((id & 0x200) == 0) - return(-1); - for (i = 0; i < nctinfo; i++) - if (id == ctinfo[i].hwid) + type = canstream = 0; + + /* Verify that we have a CS80 device. */ + if ((ha->ha_id & 0x200) == 0) + return (0); + + /* Is it one of the tapes we support? */ + for (id = 0; id < nctinfo; id++) + if (ha->ha_id == ctinfo[id].hwid) break; - if (i == nctinfo || sc->sc_punit != ctinfo[i].punit) - return(-1); - id = i; + if (id == nctinfo) + return (0); + + ha->ha_punit = ctinfo[id].punit; /* - * Collect device description. - * Right now we only need this to differentiate 7945 from 7946. - * Note that we always issue the describe command to unit 0. + * So far, so good. Get drive parameters. Note command + * is always issued to unit 0. */ cmd[0] = C_SUNIT(0); cmd[1] = C_SVOL(0); cmd[2] = C_DESC; - hpibsend(hd->hp_ctlr, hd->hp_slave, C_CMD, cmd, sizeof(cmd)); - hpibrecv(hd->hp_ctlr, hd->hp_slave, C_EXEC, &desc, 37); - hpibrecv(hd->hp_ctlr, hd->hp_slave, C_QSTAT, &stat, sizeof(stat)); + hpibsend(parent->dv_unit, ha->ha_slave, C_CMD, cmd, sizeof(cmd)); + hpibrecv(parent->dv_unit, ha->ha_slave, C_EXEC, &desc, 37); + hpibrecv(parent->dv_unit, ha->ha_slave, C_QSTAT, &stat, sizeof(stat)); + bzero(name, sizeof(name)); - if (!stat) { - register int n = desc.d_name; + if (stat == 0) { + n = desc.d_name; for (i = 5; i >= 0; i--) { name[i] = (n & 0xf) + '0'; n >>= 4; } } - switch (ctinfo[id].hwid) { + + switch (ha->ha_id) { case CT7946ID: if (bcmp(name, "079450", 6) == 0) - return(-1); /* not really a 7946 */ + return (0); /* not really a 7946 */ /* fall into... */ case CT9144ID: case CT9145ID: - sc->sc_type = CT9144; - sc->sc_flags |= CTF_CANSTREAM; + type = CT9144; + canstream = 1; break; case CT7912PID: case CT7914PID: - sc->sc_type = CT88140; + type = CT88140; break; } - if (verbose) + + if (sc != NULL) { + sc->sc_type = type; + sc->sc_flags = canstream ? CTF_CANSTREAM : 0; printf(": %s %stape\n", ctinfo[id].desc, - (sc->sc_flags & CTF_CANSTREAM) ? "streaming " : " "); - return(id); + canstream ? "streaming " : ""); + } + + return (1); } -ctreset(sc, hd) - register struct ct_softc *sc; - register struct hp_device *hd; +void +ctreset(sc) + struct ct_softc *sc; { + int ctlr, slave; u_char stat; + ctlr = sc->sc_dev.dv_parent->dv_unit; + slave = sc->sc_slave; + sc->sc_clear.unit = C_SUNIT(sc->sc_punit); sc->sc_clear.cmd = C_CLEAR; - hpibsend(hd->hp_ctlr, hd->hp_slave, C_TCMD, &sc->sc_clear, - sizeof(sc->sc_clear)); - hpibswait(hd->hp_ctlr, hd->hp_slave); - hpibrecv(hd->hp_ctlr, hd->hp_slave, C_QSTAT, &stat, sizeof(stat)); + hpibsend(ctlr, slave, C_TCMD, &sc->sc_clear, sizeof(sc->sc_clear)); + hpibswait(ctlr, slave); + hpibrecv(ctlr, slave, C_QSTAT, &stat, sizeof(stat)); + sc->sc_src.unit = C_SUNIT(CTCTLR); sc->sc_src.nop = C_NOP; sc->sc_src.cmd = C_SREL; sc->sc_src.param = C_REL; - hpibsend(hd->hp_ctlr, hd->hp_slave, C_CMD, &sc->sc_src, - sizeof(sc->sc_src)); - hpibswait(hd->hp_ctlr, hd->hp_slave); - hpibrecv(hd->hp_ctlr, hd->hp_slave, C_QSTAT, &stat, sizeof(stat)); + hpibsend(ctlr, slave, C_CMD, &sc->sc_src, sizeof(sc->sc_src)); + hpibswait(ctlr, slave); + hpibrecv(ctlr, slave, C_QSTAT, &stat, sizeof(stat)); + sc->sc_ssmc.unit = C_SUNIT(sc->sc_punit); sc->sc_ssmc.cmd = C_SSM; sc->sc_ssmc.refm = REF_MASK; sc->sc_ssmc.fefm = FEF_MASK; sc->sc_ssmc.aefm = AEF_MASK; sc->sc_ssmc.iefm = IEF_MASK; - hpibsend(hd->hp_ctlr, hd->hp_slave, C_CMD, &sc->sc_ssmc, - sizeof(sc->sc_ssmc)); - hpibswait(hd->hp_ctlr, hd->hp_slave); - hpibrecv(hd->hp_ctlr, hd->hp_slave, C_QSTAT, &stat, sizeof(stat)); + hpibsend(ctlr, slave, C_CMD, &sc->sc_ssmc, sizeof(sc->sc_ssmc)); + hpibswait(ctlr, slave); + hpibrecv(ctlr, slave, C_QSTAT, &stat, sizeof(stat)); + sc->sc_soptc.unit = C_SUNIT(sc->sc_punit); sc->sc_soptc.nop = C_NOP; sc->sc_soptc.cmd = C_SOPT; sc->sc_soptc.opt = C_SPAR; - hpibsend(hd->hp_ctlr, hd->hp_slave, C_CMD, &sc->sc_soptc, - sizeof(sc->sc_soptc)); - hpibswait(hd->hp_ctlr, hd->hp_slave); - hpibrecv(hd->hp_ctlr, hd->hp_slave, C_QSTAT, &stat, sizeof(stat)); + hpibsend(ctlr, slave, C_CMD, &sc->sc_soptc, sizeof(sc->sc_soptc)); + hpibswait(ctlr, slave); + hpibrecv(ctlr, slave, C_QSTAT, &stat, sizeof(stat)); } /*ARGSUSED*/ +int ctopen(dev, flag, type, p) dev_t dev; int flag, type; struct proc *p; { - register struct ct_softc *sc = &ct_softc[UNIT(dev)]; + struct ct_softc *sc; u_char stat; - int cc; + int cc, ctlr, slave; + + if (UNIT(dev) >= ct_cd.cd_ndevs || + (sc = ct_cd.cd_devs[UNIT(dev)]) == NULL || + (sc->sc_flags & CTF_ALIVE) == 0) + return (ENXIO); - if (UNIT(dev) >= NCT || (sc->sc_flags & CTF_ALIVE) == 0) - return(ENXIO); if (sc->sc_flags & CTF_OPEN) - return(EBUSY); + return (EBUSY); + + ctlr = sc->sc_dev.dv_parent->dv_unit; + slave = sc->sc_slave; + sc->sc_soptc.unit = C_SUNIT(sc->sc_punit); sc->sc_soptc.nop = C_NOP; sc->sc_soptc.cmd = C_SOPT; @@ -301,31 +346,34 @@ ctopen(dev, flag, type, p) sc->sc_soptc.opt = C_SPAR | C_IMRPT; else sc->sc_soptc.opt = C_SPAR; + /* * Check the return of hpibsend() and hpibswait(). * Drive could be loading/unloading a tape. If not checked, * driver hangs. */ - cc = hpibsend(sc->sc_hd->hp_ctlr, sc->sc_hd->hp_slave, - C_CMD, &sc->sc_soptc, sizeof(sc->sc_soptc)); + cc = hpibsend(ctlr, slave, C_CMD, &sc->sc_soptc, sizeof(sc->sc_soptc)); if (cc != sizeof(sc->sc_soptc)) - return(EBUSY); - hpibswait(sc->sc_hd->hp_ctlr, sc->sc_hd->hp_slave); - cc = hpibrecv(sc->sc_hd->hp_ctlr, sc->sc_hd->hp_slave, C_QSTAT, - &stat, sizeof(stat)); + return (EBUSY); + + hpibswait(ctlr, slave); + cc = hpibrecv(ctlr, slave, C_QSTAT, &stat, sizeof(stat)); if (cc != sizeof(stat)) return(EBUSY); + sc->sc_tpr = tprintf_open(p); sc->sc_flags |= CTF_OPEN; return(0); } /*ARGSUSED*/ -ctclose(dev, flag) +int +ctclose(dev, flag, fmt, p) dev_t dev; - int flag; + int flag, fmt; + struct proc *p; { - register struct ct_softc *sc = &ct_softc[UNIT(dev)]; + struct ct_softc *sc = ct_cd.cd_devs[UNIT(dev)]; if ((sc->sc_flags & (CTF_WRT|CTF_WRTTN)) == (CTF_WRT|CTF_WRTTN) && (sc->sc_flags & CTF_EOT) == 0 ) { /* XXX return error if EOT ?? */ @@ -338,7 +386,7 @@ ctclose(dev, flag) #ifdef DEBUG if(ctdebug & CT_BSF) printf("%s: ctclose backup eofs prt %d blk %d\n", - sc->sc_hd->hp_xname, sc->sc_eofp, + sc->sc_dev.dv_xname, sc->sc_eofp, sc->sc_eofs[sc->sc_eofp]); #endif } @@ -353,13 +401,14 @@ ctclose(dev, flag) return(0); /* XXX */ } +void ctcommand(dev, cmd, cnt) dev_t dev; int cmd; register int cnt; { - register struct ct_softc *sc = &ct_softc[UNIT(dev)]; - register struct buf *bp = &ctbuf[UNIT(dev)]; + struct ct_softc *sc = ct_cd.cd_devs[UNIT(dev)]; + register struct buf *bp = &sc->sc_bufstore; register struct buf *nbp = 0; if (cmd == MTBSF && sc->sc_eofp == EOFS - 1) { @@ -393,7 +442,7 @@ ctcommand(dev, cmd, cnt) #ifdef DEBUG if (ctdebug & CT_BSF) printf("%s: backup eof pos %d blk %d\n", - sc->sc_hd->hp_xname, sc->sc_eofp, + sc->sc_dev.dv_xname, sc->sc_eofp, sc->sc_eofs[sc->sc_eofp]); #endif } @@ -412,45 +461,51 @@ ctstrategy(bp) { register struct buf *dp; register int s, unit; + struct ct_softc *sc; unit = UNIT(bp->b_dev); - dp = &cttab[unit]; + sc = ct_cd.cd_devs[unit]; + + dp = &sc->sc_tab; bp->b_actf = NULL; s = splbio(); bp->b_actb = dp->b_actb; - *dp->b_actb = bp; + *(dp->b_actb) = bp; dp->b_actb = &bp->b_actf; if (dp->b_active == 0) { dp->b_active = 1; - ctustart(unit); + ctustart(sc); } splx(s); } -ctustart(unit) - register int unit; +void +ctustart(sc) + struct ct_softc *sc; { - register struct ct_softc *sc = &ct_softc[unit]; register struct buf *bp; - bp = cttab[unit].b_actf; + bp = sc->sc_tab.b_actf; sc->sc_addr = bp->b_un.b_addr; sc->sc_resid = bp->b_bcount; - if (hpibreq(&sc->sc_dq)) - ctstart(unit); + if (hpibreq(sc->sc_dev.dv_parent, &sc->sc_hq)) + ctstart(sc); } -ctstart(unit) - register int unit; +void +ctstart(arg) + void *arg; { - register struct ct_softc *sc = &ct_softc[unit]; - register struct buf *bp, *dp; - register int i; + struct ct_softc *sc = arg; + struct buf *bp, *dp; + int i, ctlr, slave; - bp = cttab[unit].b_actf; + ctlr = sc->sc_dev.dv_parent->dv_unit; + slave = sc->sc_slave; + + bp = sc->sc_tab.b_actf; if ((sc->sc_flags & CTF_CMD) && sc->sc_bp == bp) { switch(sc->sc_cmd) { - case MTFSF: bp->b_flags |= B_READ; goto mustio; @@ -462,8 +517,8 @@ ctstart(unit) sc->sc_blkno = 0; sc->sc_ul.unit = C_SUNIT(sc->sc_punit); sc->sc_ul.cmd = C_UNLOAD; - hpibsend(sc->sc_hd->hp_ctlr, sc->sc_hd->hp_slave, - C_CMD, &sc->sc_ul, sizeof(sc->sc_ul)); + hpibsend(ctlr, slave, C_CMD, &sc->sc_ul, + sizeof(sc->sc_ul)); break; case MTWEOF: @@ -471,9 +526,9 @@ ctstart(unit) sc->sc_flags |= CTF_WRT; sc->sc_wfm.unit = C_SUNIT(sc->sc_punit); sc->sc_wfm.cmd = C_WFM; - hpibsend(sc->sc_hd->hp_ctlr, sc->sc_hd->hp_slave, - C_CMD, &sc->sc_wfm, sizeof(sc->sc_wfm)); - ctaddeof(unit); + hpibsend(ctlr, slave, C_CMD, &sc->sc_wfm, + sizeof(sc->sc_wfm)); + ctaddeof(sc); break; case MTBSR: @@ -489,7 +544,7 @@ ctstart(unit) #ifdef DEBUG if(ctdebug & CT_BSF) printf("%s: clearing eofs\n", - sc->sc_hd->hp_xname); + sc->sc_dev.dv_xname); #endif for (i=0; isc_eofs[i] = 0; @@ -505,29 +560,30 @@ gotaddr: sc->sc_ioc.len = 0; sc->sc_ioc.nop3 = C_NOP; sc->sc_ioc.cmd = C_READ; - hpibsend(sc->sc_hd->hp_ctlr, sc->sc_hd->hp_slave, - C_CMD, &sc->sc_ioc, sizeof(sc->sc_ioc)); + hpibsend(ctlr, slave, C_CMD, &sc->sc_ioc, + sizeof(sc->sc_ioc)); break; } - } - else { + } else { mustio: if ((bp->b_flags & B_READ) && sc->sc_flags & (CTF_BEOF|CTF_EOT)) { #ifdef DEBUG if (ctdebug & CDB_FILES) - printf("ctstart: before flags %x\n", sc->sc_flags); + printf("ctstart: before flags %x\n", + sc->sc_flags); #endif if (sc->sc_flags & CTF_BEOF) { sc->sc_flags &= ~CTF_BEOF; sc->sc_flags |= CTF_AEOF; #ifdef DEBUG if (ctdebug & CDB_FILES) - printf("ctstart: after flags %x\n", sc->sc_flags); + printf("ctstart: after flags %x\n", + sc->sc_flags); #endif } bp->b_resid = bp->b_bcount; - ctdone(unit, bp); + ctdone(sc, bp); return; } sc->sc_flags |= CTF_IO; @@ -545,28 +601,29 @@ mustio: sc->sc_ioc.cmd = C_WRITE; sc->sc_flags |= (CTF_WRT | CTF_WRTTN); } - hpibsend(sc->sc_hd->hp_ctlr, sc->sc_hd->hp_slave, C_CMD, - &sc->sc_ioc, sizeof(sc->sc_ioc)); + hpibsend(ctlr, slave, C_CMD, &sc->sc_ioc, sizeof(sc->sc_ioc)); } - hpibawait(sc->sc_hd->hp_ctlr); + hpibawait(ctlr); } -ctgo(unit) - register int unit; +void +ctgo(arg) + void *arg; { - register struct ct_softc *sc = &ct_softc[unit]; + struct ct_softc *sc = arg; register struct buf *bp; int rw; - bp = cttab[unit].b_actf; + bp = sc->sc_tab.b_actf; rw = bp->b_flags & B_READ; - hpibgo(sc->sc_hd->hp_ctlr, sc->sc_hd->hp_slave, C_EXEC, - sc->sc_addr, sc->sc_resid, rw, rw != 0); + hpibgo(sc->sc_dev.dv_parent->dv_unit, sc->sc_slave, C_EXEC, + sc->sc_addr, sc->sc_resid, rw, rw != 0); } /* * Hideous grue to handle EOF/EOT (mostly for reads) */ +void cteof(sc, bp) register struct ct_softc *sc; register struct buf *bp; @@ -639,35 +696,40 @@ cteof(sc, bp) #endif } -int +/* ARGSUSED */ +void ctintr(arg) void *arg; { register struct ct_softc *sc = arg; - register struct buf *bp, *dp; + register struct buf *bp; u_char stat; - int unit = sc->sc_hd->hp_unit; + int ctlr, slave, unit; - bp = cttab[unit].b_actf; + ctlr = sc->sc_dev.dv_parent->dv_unit; + slave = sc->sc_slave; + unit = sc->sc_dev.dv_unit; + + bp = sc->sc_tab.b_actf; if (bp == NULL) { - printf("%s: bp == NULL\n", sc->sc_hd->hp_xname); + printf("%s: bp == NULL\n", sc->sc_dev.dv_xname); return; } if (sc->sc_flags & CTF_IO) { sc->sc_flags &= ~CTF_IO; - if (hpibustart(sc->sc_hd->hp_ctlr)) - ctgo(unit); + if (hpibustart(ctlr)) + ctgo(sc); return; } if ((sc->sc_flags & CTF_STATWAIT) == 0) { - if (hpibpptest(sc->sc_hd->hp_ctlr, sc->sc_hd->hp_slave) == 0) { + if (hpibpptest(ctlr, slave) == 0) { sc->sc_flags |= CTF_STATWAIT; - hpibawait(sc->sc_hd->hp_ctlr); + hpibawait(ctlr); return; } } else sc->sc_flags &= ~CTF_STATWAIT; - hpibrecv(sc->sc_hd->hp_ctlr, sc->sc_hd->hp_slave, C_QSTAT, &stat, 1); + hpibrecv(ctlr, slave, C_QSTAT, &stat, 1); #ifdef DEBUG if (ctdebug & CDB_FILES) printf("ctintr: before flags %x\n", sc->sc_flags); @@ -675,12 +737,10 @@ ctintr(arg) if (stat) { sc->sc_rsc.unit = C_SUNIT(sc->sc_punit); sc->sc_rsc.cmd = C_STATUS; - hpibsend(sc->sc_hd->hp_ctlr, sc->sc_hd->hp_slave, C_CMD, - &sc->sc_rsc, sizeof(sc->sc_rsc)); - hpibrecv(sc->sc_hd->hp_ctlr, sc->sc_hd->hp_slave, C_EXEC, - &sc->sc_stat, sizeof(sc->sc_stat)); - hpibrecv(sc->sc_hd->hp_ctlr, sc->sc_hd->hp_slave, C_QSTAT, - &stat, 1); + hpibsend(ctlr, slave, C_CMD, &sc->sc_rsc, sizeof(sc->sc_rsc)); + hpibrecv(ctlr, slave, C_EXEC, &sc->sc_stat, + sizeof(sc->sc_stat)); + hpibrecv(ctlr, slave, C_QSTAT, &stat, 1); #ifdef DEBUG if (ctdebug & CDB_FILES) printf("ctintr: return stat 0x%x, A%x F%x blk %d\n", @@ -690,34 +750,34 @@ ctintr(arg) if (stat == 0) { if (sc->sc_stat.c_aef & (AEF_EOF | AEF_EOV)) { cteof(sc, bp); - ctaddeof(unit); + ctaddeof(sc); goto done; } if (sc->sc_stat.c_fef & FEF_PF) { - ctreset(sc, sc->sc_hd); - ctstart(unit); + ctreset(sc); + ctstart(sc); return; } if (sc->sc_stat.c_fef & FEF_REXMT) { - ctstart(unit); + ctstart(sc); return; } if (sc->sc_stat.c_aef & 0x5800) { if (sc->sc_stat.c_aef & 0x4000) tprintf(sc->sc_tpr, "%s: uninitialized media\n", - sc->sc_hd->hp_xname); + sc->sc_dev.dv_xname); if (sc->sc_stat.c_aef & 0x1000) tprintf(sc->sc_tpr, "%s: not ready\n", - sc->sc_hd->hp_xname); + sc->sc_dev.dv_xname); if (sc->sc_stat.c_aef & 0x0800) tprintf(sc->sc_tpr, "%s: write protect\n", - sc->sc_hd->hp_xname); + sc->sc_dev.dv_xname); } else { printf("%s err: v%d u%d ru%d bn%d, ", - sc->sc_hd->hp_xname, + sc->sc_dev.dv_xname, (sc->sc_stat.c_vu>>4)&0xF, sc->sc_stat.c_vu&0xF, sc->sc_stat.c_pend, @@ -730,7 +790,7 @@ ctintr(arg) } } else printf("%s: request status failed\n", - sc->sc_hd->hp_xname); + sc->sc_dev.dv_xname); bp->b_flags |= B_ERROR; bp->b_error = EIO; goto done; @@ -741,7 +801,7 @@ ctintr(arg) case MTFSF: sc->sc_flags &= ~(CTF_BEOF|CTF_AEOF); sc->sc_blkno += CTBTOK(sc->sc_resid); - ctstart(unit); + ctstart(sc); return; case MTBSF: sc->sc_flags &= ~(CTF_AEOF|CTF_BEOF|CTF_EOT); @@ -778,29 +838,28 @@ done: if (ctdebug & CDB_FILES) printf("ctintr: after flags %x\n", sc->sc_flags); #endif - ctdone(unit, bp); + ctdone(sc, bp); } void -ctdone(unit, bp) - int unit; +ctdone(sc, bp) + struct ct_softc *sc; register struct buf *bp; { - register struct ct_softc *sc = &ct_softc[unit]; register struct buf *dp; - if (dp = bp->b_actf) + if ((dp = bp->b_actf) != NULL) dp->b_actb = bp->b_actb; else - cttab[unit].b_actb = bp->b_actb; + sc->sc_tab.b_actb = bp->b_actb; *bp->b_actb = dp; biodone(bp); - hpibfree(&sc->sc_dq); - if (cttab[unit].b_actf == NULL) { - cttab[unit].b_active = 0; + hpibfree(sc->sc_dev.dv_parent, &sc->sc_hq); + if (sc->sc_tab.b_actf == NULL) { + sc->sc_tab.b_active = 0; return; } - ctustart(unit); + ctustart(sc); } int @@ -823,9 +882,11 @@ ctwrite(dev, uio, flags) } /*ARGSUSED*/ +int ctioctl(dev, cmd, data, flag, p) dev_t dev; - int cmd, flag; + u_long cmd; + int flag; caddr_t data; struct proc *p; { @@ -866,18 +927,23 @@ ctioctl(dev, cmd, data, flag, p) return(0); } -/*ARGSUSED*/ -ctdump(dev) +/* ARGSUSED */ +int +ctdump(dev, blkno, va, size) dev_t dev; + daddr_t blkno; + caddr_t va; + size_t size; { - return(ENXIO); + + return (ENODEV); } -ctaddeof(unit) - int unit; +void +ctaddeof(sc) + struct ct_softc *sc; { - register struct ct_softc *sc = &ct_softc[unit]; - + if (sc->sc_eofp == EOFS - 1) sc->sc_eofs[EOFS - 1]++; else { @@ -891,8 +957,7 @@ ctaddeof(unit) #ifdef DEBUG if (ctdebug & CT_BSF) printf("%s: add eof pos %d blk %d\n", - sc->sc_hd->hp_xname, sc->sc_eofp, + sc->sc_dev.dv_xname, sc->sc_eofp, sc->sc_eofs[sc->sc_eofp]); #endif } -#endif diff --git a/sys/arch/hp300/dev/mt.c b/sys/arch/hp300/dev/mt.c index 2c2a3014d4f7..29cb4625a769 100644 --- a/sys/arch/hp300/dev/mt.c +++ b/sys/arch/hp300/dev/mt.c @@ -1,6 +1,7 @@ -/* $NetBSD: mt.c,v 1.6 1996/10/14 07:14:18 thorpej Exp $ */ +/* $NetBSD: mt.c,v 1.7 1997/01/30 09:14:14 thorpej Exp $ */ /* + * Copyright (c) 1996, 1997 Jason R. Thorpe. All rights reserved. * Copyright (c) 1992, The University of Utah and * the Computer Systems Laboratory at the University of Utah (CSL). * All rights reserved. @@ -29,8 +30,6 @@ * Modified for 4.4BSD by Mark Davies and Andrew Vignaux, Department of * Computer Science, Victoria University of Wellington */ -#include "mt.h" -#if NMT > 0 #include #include @@ -44,11 +43,12 @@ #include #include #include +#include +#include -#include #include -#include +#include struct mtinfo { u_short hwid; @@ -62,9 +62,9 @@ struct mtinfo { int nmtinfo = sizeof(mtinfo) / sizeof(mtinfo[0]); struct mt_softc { - struct hp_device *sc_hd; - short sc_hpibno; /* logical HPIB this slave it attached to */ - short sc_slave; /* HPIB slave address (0-6) */ + struct device sc_dev; + int sc_hpibno; /* logical HPIB this slave it attached to */ + int sc_slave; /* HPIB slave address (0-6) */ short sc_flags; /* see below */ u_char sc_lastdsj; /* place for DSJ in mtreaddsj() */ u_char sc_lastecmd; /* place for End Command in mtreaddsj() */ @@ -73,11 +73,11 @@ struct mt_softc { struct mt_stat sc_stat;/* status bytes last read from device */ short sc_density; /* current density of tape (mtio.h format) */ short sc_type; /* tape drive model (hardware IDs) */ - struct devqueue sc_dq; /* HPIB device queue member */ + struct hpibqueue sc_hq; /* HPIB device queue member */ tpr_t sc_ttyp; -} mt_softc[NMT]; -struct buf mttab[NMT]; -struct buf mtbuf[NMT]; + struct buf sc_tab; /* buf queue */ + struct buf sc_bufstore; /* XXX buffer storage */ +}; #ifdef DEBUG int mtdebug = 0; @@ -91,67 +91,91 @@ int mtdebug = 0; #define B_CMD B_XXX /* command buf instead of data */ #define b_cmd b_blkno /* blkno holds cmd when B_CMD */ -int mtmatch(), mtintr(); -void mtattach(), mtustart(), mtstart(), mtgo(), mtstrategy(); -struct driver mtdriver = { - mtmatch, mtattach, "mt", (int (*)()) mtstart, (int (*)()) mtgo, mtintr, +int mtmatch __P((struct device *, struct cfdata *, void *)); +void mtattach __P((struct device *, struct device *, void *)); + +struct cfattach mt_ca = { + sizeof(struct mt_softc), mtmatch, mtattach }; +struct cfdriver mt_cd = { + NULL, "mt", DV_TAPE +}; + +int mtident __P((struct mt_softc *, struct hpibbus_attach_args *)); +void mtustart __P((struct mt_softc *)); +int mtreaddsj __P((struct mt_softc *, int)); +int mtcommand __P((dev_t, int, int)); +void spl_mtintr __P((void *)); +void spl_mtstart __P((void *)); + +void mtstart __P((void *)); +void mtgo __P((void *)); +void mtintr __P((void *)); + +bdev_decl(mt); +cdev_decl(mt); + int -mtmatch(hd) - register struct hp_device *hd; +mtmatch(parent, match, aux) + struct device *parent; + struct cfdata *match; + void *aux; { - register int unit; - register int hpibno = hd->hp_ctlr; - register int slave = hd->hp_slave; - register struct mt_softc *sc = &mt_softc[hd->hp_unit]; - register int id; - register struct buf *bp; + struct hpibbus_attach_args *ha = aux; - sc->sc_hd = hd; - - for (bp = mttab; bp < &mttab[NMT]; bp++) - bp->b_actb = &bp->b_actf; - unit = hpibid(hpibno, slave); - for (id = 0; id < nmtinfo; id++) - if (unit == mtinfo[id].hwid) - return (1); - return (0); /* not a known HP magtape */ + return (mtident(NULL, ha)); } void -mtattach(hd) - register struct hp_device *hd; +mtattach(parent, self, aux) + struct device *parent, *self; + void *aux; { - register int unit; - register int hpibno = hd->hp_ctlr; - register int slave = hd->hp_slave; - register struct mt_softc *sc; - register int id; - register struct buf *bp; + struct mt_softc *sc = (struct mt_softc *)self; + struct hpibbus_attach_args *ha = aux; + int unit, hpibno, slave; - /* XXX Ick. */ - unit = hpibid(hpibno, slave); - for (id = 0; id < nmtinfo; id++) - if (unit == mtinfo[id].hwid) - break; + if (mtident(sc, ha) == 0) { + printf("\n%s: impossible!\n", sc->sc_dev.dv_xname); + return; + } - unit = hd->hp_unit; - sc = &mt_softc[unit]; - sc->sc_type = mtinfo[id].hwid; - printf(": %s tape\n", mtinfo[id].desc); + unit = self->dv_unit; + hpibno = parent->dv_unit; + slave = ha->ha_slave; + + sc->sc_tab.b_actb = &sc->sc_tab.b_actf; sc->sc_hpibno = hpibno; sc->sc_slave = slave; sc->sc_flags = MTF_EXISTS; - sc->sc_dq.dq_softc = sc; - sc->sc_dq.dq_ctlr = hpibno; - sc->sc_dq.dq_unit = unit; - sc->sc_dq.dq_slave = slave; - sc->sc_dq.dq_driver = &mtdriver; - /* XXX Set device class. */ - hd->hp_dev.dv_class = DV_TAPE; + /* Initialize hpib job queue entry. */ + sc->sc_hq.hq_softc = sc; + sc->sc_hq.hq_slave = sc->sc_slave; + sc->sc_hq.hq_start = mtstart; + sc->sc_hq.hq_go = mtgo; + sc->sc_hq.hq_intr = mtintr; +} + +int +mtident(sc, ha) + struct mt_softc *sc; + struct hpibbus_attach_args *ha; +{ + int i; + + for (i = 0; i < nmtinfo; i++) { + if (ha->ha_id == mtinfo[i].hwid) { + if (sc != NULL) { + sc->sc_type = mtinfo[i].hwid; + printf(": %s tape\n", mtinfo[i].desc); + } + return (1); + } + } + return (0); } /* @@ -160,21 +184,22 @@ mtattach(hd) * performed, unless "ecmd" is zero. Returns DSJ value, -1 on failure * and -2 on "temporary" failure. */ -mtreaddsj(unit, ecmd) - register int unit; +int +mtreaddsj(sc, ecmd) + struct mt_softc *sc; int ecmd; { - register struct mt_softc *sc = &mt_softc[unit]; int retval; if (sc->sc_flags & MTF_STATTIMEO) goto getstats; retval = hpibrecv(sc->sc_hpibno, - (sc->sc_flags & MTF_DSJTIMEO) ? -1 : sc->sc_slave, - MTT_DSJ, &(sc->sc_lastdsj), 1); + (sc->sc_flags & MTF_DSJTIMEO) ? -1 : sc->sc_slave, + MTT_DSJ, &(sc->sc_lastdsj), 1); sc->sc_flags &= ~MTF_DSJTIMEO; if (retval != 1) { - dlog(LOG_DEBUG, "mt%d can't hpibrecv DSJ\n", unit); + dlog(LOG_DEBUG, "%s can't hpibrecv DSJ", + sc->sc_dev.dv_xname); if (sc->sc_recvtimeo == 0) sc->sc_recvtimeo = hz; if (--sc->sc_recvtimeo == 0) @@ -185,7 +210,8 @@ mtreaddsj(unit, ecmd) } sc->sc_recvtimeo = 0; sc->sc_statindex = 0; - dlog(LOG_DEBUG, "mt%d readdsj: 0x%x\n", unit, sc->sc_lastdsj); + dlog(LOG_DEBUG, "%s readdsj: 0x%x", sc->sc_dev.dv_xname, + sc->sc_lastdsj); sc->sc_lastecmd = ecmd; switch (sc->sc_lastdsj) { case 0: @@ -199,14 +225,15 @@ mtreaddsj(unit, ecmd) break; default: - log(LOG_ERR, "mt%d readdsj: DSJ 0x%x\n", unit, sc->sc_lastdsj); + log(LOG_ERR, "%s readdsj: DSJ 0x%x\n", sc->sc_dev.dv_xname, + sc->sc_lastdsj); return (-1); } getstats: retval = hpibrecv(sc->sc_hpibno, - (sc->sc_flags & MTF_STATCONT) ? -1 : sc->sc_slave, - MTT_STAT, ((char *)&(sc->sc_stat)) + sc->sc_statindex, - sizeof(sc->sc_stat) - sc->sc_statindex); + (sc->sc_flags & MTF_STATCONT) ? -1 : sc->sc_slave, + MTT_STAT, ((char *)&(sc->sc_stat)) + sc->sc_statindex, + sizeof(sc->sc_stat) - sc->sc_statindex); sc->sc_flags &= ~(MTF_STATTIMEO | MTF_STATCONT); if (retval != sizeof(sc->sc_stat) - sc->sc_statindex) { if (sc->sc_recvtimeo == 0) @@ -219,33 +246,40 @@ mtreaddsj(unit, ecmd) sc->sc_flags |= MTF_STATTIMEO; return (-2); } - log(LOG_ERR, "mt%d readdsj: can't read status\n", unit); + log(LOG_ERR, "%s readdsj: can't read status", + sc->sc_dev.dv_xname); return (-1); } sc->sc_recvtimeo = 0; sc->sc_statindex = 0; - dlog(LOG_DEBUG, "mt%d readdsj: status is %x %x %x %x %x %x\n", unit, - sc->sc_stat1, sc->sc_stat2, sc->sc_stat3, - sc->sc_stat4, sc->sc_stat5, sc->sc_stat6); + dlog(LOG_DEBUG, "%s readdsj: status is %x %x %x %x %x %x", + sc->sc_dev.dv_xname, + sc->sc_stat1, sc->sc_stat2, sc->sc_stat3, + sc->sc_stat4, sc->sc_stat5, sc->sc_stat6); if (sc->sc_lastecmd) (void) hpibsend(sc->sc_hpibno, sc->sc_slave, - MTL_ECMD, &(sc->sc_lastecmd), 1); + MTL_ECMD, &(sc->sc_lastecmd), 1); return ((int) sc->sc_lastdsj); } +int mtopen(dev, flag, mode, p) dev_t dev; int flag, mode; struct proc *p; { register int unit = UNIT(dev); - register struct mt_softc *sc = &mt_softc[unit]; + struct mt_softc *sc; register int req_den; int error; - dlog(LOG_DEBUG, "mt%d open: flags 0x%x\n", unit, sc->sc_flags); - if (unit >= NMT || (sc->sc_flags & MTF_EXISTS) == 0) + if (unit >= mt_cd.cd_ndevs || + (sc = mt_cd.cd_devs[unit]) == NULL || + (sc->sc_flags & MTF_EXISTS) == 0) return (ENXIO); + + dlog(LOG_DEBUG, "%s open: flags 0x%x", sc->sc_dev.dv_xname, + sc->sc_flags); if (sc->sc_flags & MTF_OPEN) return (EBUSY); sc->sc_flags |= MTF_OPEN; @@ -262,7 +296,8 @@ mtopen(dev, flag, mode, p) goto errout; if (!(sc->sc_flags & MTF_REW)) break; - if (tsleep((caddr_t) &lbolt, PCATCH | (PZERO + 1), "mt", 0) != 0) { + if (tsleep((caddr_t) &lbolt, PCATCH | (PZERO + 1), + "mt", 0) != 0) { error = EINTR; goto errout; } @@ -272,7 +307,7 @@ mtopen(dev, flag, mode, p) goto errout; } if (!(sc->sc_stat1 & SR1_ONLINE)) { - uprintf("%s: not online\n", sc->sc_hd->hp_xname); + uprintf("%s: not online\n", sc->sc_dev.dv_xname); error = EIO; goto errout; } @@ -310,7 +345,7 @@ mtopen(dev, flag, mode, p) if (!(sc->sc_stat1 & SR1_BOT)) { if (sc->sc_density != req_den) { uprintf("%s: can't change density mid-tape\n", - sc->sc_hd->hp_xname); + sc->sc_dev.dv_xname); error = EIO; goto errout; } @@ -333,11 +368,13 @@ errout: return (error); } -mtclose(dev, flag) +int +mtclose(dev, flag, fmt, p) dev_t dev; - int flag; + int flag, fmt; + struct proc *p; { - register struct mt_softc *sc = &mt_softc[UNIT(dev)]; + struct mt_softc *sc = mt_cd.cd_devs[UNIT(dev)]; if (sc->sc_flags & MTF_WRT) { (void) mtcommand(dev, MTWEOF, 2); @@ -350,12 +387,14 @@ mtclose(dev, flag) return (0); } +int mtcommand(dev, cmd, cnt) dev_t dev; int cmd; int cnt; { - register struct buf *bp = &mtbuf[UNIT(dev)]; + struct mt_softc *sc = mt_cd.cd_devs[UNIT(dev)]; + struct buf *bp = &sc->sc_bufstore; int error = 0; #if 1 @@ -394,15 +433,15 @@ mtstrategy(bp) register int s; unit = UNIT(bp->b_dev); - sc = &mt_softc[unit]; - dlog(LOG_DEBUG, "mt%d strategy\n", unit); + sc = mt_cd.cd_devs[unit]; + dlog(LOG_DEBUG, "%s strategy", sc->sc_dev.dv_xname); if ((bp->b_flags & (B_CMD | B_READ)) == 0) { #define WRITE_BITS_IGNORED 8 #if 0 if (bp->b_bcount & ((1 << WRITE_BITS_IGNORED) - 1)) { tprintf(sc->sc_ttyp, "%s: write record must be multiple of %d\n", - sc->sc_hd->hp_xname, 1 << WRITE_BITS_IGNORED); + sc->sc_dev.dv_xname, 1 << WRITE_BITS_IGNORED); goto error; } #endif @@ -422,7 +461,7 @@ mtstrategy(bp) if (bp->b_bcount > s) { tprintf(sc->sc_ttyp, "%s: write record (%d) too big: limit (%d)\n", - sc->sc_hd->hp_xname, bp->b_bcount, s); + sc->sc_dev.dv_xname, bp->b_bcount, s); error: bp->b_flags |= B_ERROR; bp->b_error = EIO; @@ -430,7 +469,7 @@ mtstrategy(bp) return; } } - dp = &mttab[unit]; + dp = &sc->sc_tab; bp->b_actf = NULL; s = splbio(); bp->b_actb = dp->b_actb; @@ -438,24 +477,21 @@ mtstrategy(bp) dp->b_actb = &bp->b_actf; if (dp->b_active == 0) { dp->b_active = 1; - mtustart(unit); + mtustart(sc); } splx(s); } void -mtustart(unit) - register int unit; +mtustart(sc) + struct mt_softc *sc; { - dlog(LOG_DEBUG, "mt%d ustart\n", unit); - if (hpibreq(&(mt_softc[unit].sc_dq))) - mtstart(unit); + dlog(LOG_DEBUG, "%s ustart", sc->sc_dev.dv_xname); + if (hpibreq(sc->sc_dev.dv_parent, &sc->sc_hq)) + mtstart(sc); } -#define hpibppclear(unit) \ - { hpib_softc[unit].sc_flags &= ~HPIBF_PPOLL; } - void spl_mtintr(arg) void *arg; @@ -469,27 +505,27 @@ spl_mtintr(arg) } void -spl_mtstart(unit) - int unit; +spl_mtstart(arg) + void *arg; { int s = splbio(); - mtstart(unit); + mtstart(arg); (void) splx(s); } void -mtstart(unit) - register int unit; +mtstart(arg) + void *arg; { - register struct mt_softc *sc = &mt_softc[unit]; + struct mt_softc *sc = arg; register struct buf *bp, *dp; short cmdcount = 1; u_char cmdbuf[2]; - dlog(LOG_DEBUG, "mt%d start\n", unit); + dlog(LOG_DEBUG, "%s start", sc->sc_dev.dv_xname); sc->sc_flags &= ~MTF_WRT; - bp = mttab[unit].b_actf; + bp = sc->sc_tab.b_actf; if ((sc->sc_flags & MTF_ALIVE) == 0 && ((bp->b_flags & B_CMD) == 0 || bp->b_cmd != MTRESET)) goto fatalerror; @@ -497,7 +533,7 @@ mtstart(unit) if (sc->sc_flags & MTF_REW) { if (!hpibpptest(sc->sc_hpibno, sc->sc_slave)) goto stillrew; - switch (mtreaddsj(unit, MTE_DSJ_FORCE|MTE_COMPLETE|MTE_IDLE)) { + switch (mtreaddsj(sc, MTE_DSJ_FORCE|MTE_COMPLETE|MTE_IDLE)) { case 0: case 1: stillrew: @@ -513,7 +549,7 @@ mtstart(unit) * but not otherwise. */ if (sc->sc_flags & (MTF_DSJTIMEO | MTF_STATTIMEO)) { - timeout(spl_mtstart, (void *)unit, hz >> 5); + timeout(spl_mtstart, sc, hz >> 5); return; } case 2: @@ -584,8 +620,8 @@ mtstart(unit) * NOP is supposed to set status bits. * Force readdsj to do it. */ - switch (mtreaddsj(unit, - MTE_DSJ_FORCE | MTE_COMPLETE | MTE_IDLE)) { + switch (mtreaddsj(sc, + MTE_DSJ_FORCE | MTE_COMPLETE | MTE_IDLE)) { default: goto done; @@ -599,7 +635,7 @@ mtstart(unit) break; case -2: - timeout(spl_mtstart, (void *)unit, hz >> 5); + timeout(spl_mtstart, sc, hz >> 5); return; } @@ -610,10 +646,11 @@ mtstart(unit) * 3) interrupt will read DSJ (and END COMPLETE-IDLE) */ if (hpibsend(sc->sc_hpibno, sc->sc_slave, -2, NULL, 0)){ - log(LOG_ERR, "mt%d can't reset\n", unit); + log(LOG_ERR, "%s can't reset", + sc->sc_dev.dv_xname); goto fatalerror; } - timeout(spl_mtintr, (void *)sc, 4 * hz); + timeout(spl_mtintr, sc, 4 * hz); hpibawait(sc->sc_hpibno, sc->sc_slave); return; @@ -671,13 +708,13 @@ done: if (dp = bp->b_actf) dp->b_actb = bp->b_actb; else - mttab[unit].b_actb = bp->b_actb; + sc->sc_tab.b_actb = bp->b_actb; *bp->b_actb = dp; - hpibfree(&(sc->sc_dq)); + hpibfree(sc->sc_dev.dv_parent, &sc->sc_hq); if ((bp = dp) == NULL) - mttab[unit].b_active = 0; + sc->sc_tab.b_active = 0; else - mtustart(unit); + mtustart(sc); } /* @@ -686,36 +723,37 @@ done: * -- ajv@comp.vuw.ac.nz */ void -mtgo(unit) - register int unit; +mtgo(arg) + void *arg; { - register struct mt_softc *sc = &mt_softc[unit]; - register struct buf *bp; + struct mt_softc *sc = arg; + struct buf *bp; int rw; - dlog(LOG_DEBUG, "mt%d go\n", unit); - bp = mttab[unit].b_actf; + dlog(LOG_DEBUG, "%s go", sc->sc_dev.dv_xname); + bp = sc->sc_tab.b_actf; rw = bp->b_flags & B_READ; hpibgo(sc->sc_hpibno, sc->sc_slave, rw ? MTT_READ : MTL_WRITE, - bp->b_un.b_addr, bp->b_bcount, rw, rw != 0); + bp->b_un.b_addr, bp->b_bcount, rw, rw != 0); } -int +void mtintr(arg) void *arg; { - register struct mt_softc *sc = arg; - register struct buf *bp, *dp; - register int i; - int unit = sc->sc_hd->hp_unit; - u_char cmdbuf[4]; + struct mt_softc *sc = arg; + struct buf *bp, *dp; + int i; + u_char cmdbuf[4]; - bp = mttab[unit].b_actf; + bp = sc->sc_tab.b_actf; if (bp == NULL) { - log(LOG_ERR, "mt%d intr: bp == NULL\n", unit); + log(LOG_ERR, "%s intr: bp == NULL", sc->sc_dev.dv_xname); return; } - dlog(LOG_DEBUG, "mt%d intr\n", unit); + + dlog(LOG_DEBUG, "%s intr", sc->sc_dev.dv_xname); + /* * Some operation completed. Read status bytes and report errors. * Clear EOF flags here `cause they're set once on specific conditions @@ -729,7 +767,7 @@ mtintr(arg) cmdbuf[0] = MTE_STOP; (void) hpibsend(sc->sc_hpibno, sc->sc_slave, MTL_ECMD,cmdbuf,1); } - switch (mtreaddsj(unit, 0)) { + switch (mtreaddsj(sc, 0)) { case 0: break; @@ -751,24 +789,25 @@ mtintr(arg) * to the request for DSJ. It's probably just "busy" figuring * it out and will know in a little bit... */ - timeout(spl_mtintr, (void *)sc, hz >> 5); + timeout(spl_mtintr, sc, hz >> 5); return; default: - log(LOG_ERR, "mt%d intr: can't get drive stat\n", unit); + log(LOG_ERR, "%s intr: can't get drive stat", + sc->sc_dev.dv_xname); goto error; } if (sc->sc_stat1 & (SR1_ERR | SR1_REJECT)) { i = sc->sc_stat4 & SR4_ERCLMASK; - log(LOG_ERR, "%s: %s error, retry %d, SR2/3 %x/%x, code %d\n", - sc->sc_hd->hp_xname, i == SR4_DEVICE ? "device" : + log(LOG_ERR, "%s: %s error, retry %d, SR2/3 %x/%x, code %d", + sc->sc_dev.dv_xname, i == SR4_DEVICE ? "device" : (i == SR4_PROTOCOL ? "protocol" : (i == SR4_SELFTEST ? "selftest" : "unknown")), sc->sc_stat4 & SR4_RETRYMASK, sc->sc_stat2, sc->sc_stat3, sc->sc_stat5); if ((bp->b_flags & B_CMD) && bp->b_cmd == MTRESET) - untimeout(spl_mtintr, (void *)sc); + untimeout(spl_mtintr, sc); if (sc->sc_stat3 & SR3_POWERUP) sc->sc_flags &= MTF_OPEN | MTF_EXISTS; goto error; @@ -778,7 +817,7 @@ mtintr(arg) */ if (sc->sc_stat1 & SR1_SOFTERR) { log(LOG_WARNING, "%s: soft error, retry %d\n", - sc->sc_hd->hp_xname, sc->sc_stat4 & SR4_RETRYMASK); + sc->sc_dev.dv_xname, sc->sc_stat4 & SR4_RETRYMASK); sc->sc_stat1 &= ~SR1_SOFTERR; } /* @@ -788,7 +827,7 @@ mtintr(arg) if (sc->sc_flags & MTF_IO) { sc->sc_flags &= ~MTF_IO; if (hpibustart(sc->sc_hpibno)) - mtgo(unit); + mtgo(sc); return; } /* @@ -820,7 +859,7 @@ mtintr(arg) sc->sc_flags |= MTF_HITBOF; } if (bp->b_cmd == MTRESET) { - untimeout(spl_mtintr, (void *)sc); + untimeout(spl_mtintr, sc); sc->sc_flags |= MTF_ALIVE; } } else { @@ -834,12 +873,12 @@ mtintr(arg) if (i == 0) sc->sc_flags |= MTF_HITEOF; bp->b_resid = bp->b_bcount - i; - dlog(LOG_DEBUG, "mt%d intr: bcount %d, resid %d\n", - unit, bp->b_bcount, bp->b_resid); + dlog(LOG_DEBUG, "%s intr: bcount %d, resid %d", + sc->sc_dev.dv_xname, bp->b_bcount, bp->b_resid); } else { tprintf(sc->sc_ttyp, "%s: record (%d) larger than wanted (%d)\n", - sc->sc_hd->hp_xname, i, bp->b_bcount); + sc->sc_dev.dv_xname, i, bp->b_bcount); error: sc->sc_flags &= ~MTF_IO; bp->b_error = EIO; @@ -857,38 +896,50 @@ mtintr(arg) if (dp = bp->b_actf) dp->b_actb = bp->b_actb; else - mttab[unit].b_actb = bp->b_actb; + sc->sc_tab.b_actb = bp->b_actb; *bp->b_actb = dp; - hpibfree(&(sc->sc_dq)); + hpibfree(sc->sc_dev.dv_parent, &sc->sc_hq); #if 0 - if (bp /*mttab[unit].b_actf*/ == NULL) + if (bp /*sc->sc_tab.b_actf*/ == NULL) #else - if (mttab[unit].b_actf == NULL) + if (sc->sc_tab.b_actf == NULL) #endif - mttab[unit].b_active = 0; + sc->sc_tab.b_active = 0; else - mtustart(unit); + mtustart(sc); } -mtread(dev, uio) +int +mtread(dev, uio, flags) dev_t dev; struct uio *uio; + int flags; { - return(physio(mtstrategy, &mtbuf[UNIT(dev)], dev, B_READ, minphys, uio)); + struct mt_softc *sc = mt_cd.cd_devs[UNIT(dev)]; + + return(physio(mtstrategy, &sc->sc_bufstore, + dev, B_READ, minphys, uio)); } -mtwrite(dev, uio) +int +mtwrite(dev, uio, flags) dev_t dev; struct uio *uio; + int flags; { - return(physio(mtstrategy, &mtbuf[UNIT(dev)], dev, B_WRITE, minphys, uio)); + struct mt_softc *sc = mt_cd.cd_devs[UNIT(dev)]; + + return(physio(mtstrategy, &sc->sc_bufstore, + dev, B_WRITE, minphys, uio)); } -mtioctl(dev, cmd, data, flag) +int +mtioctl(dev, cmd, data, flag, p) dev_t dev; u_long cmd; caddr_t data; int flag; + struct proc *p; { register struct mtop *op; int cnt; @@ -926,10 +977,12 @@ mtioctl(dev, cmd, data, flag) } /*ARGSUSED*/ -mtdump(dev) +int +mtdump(dev, blkno, va, size) dev_t dev; + daddr_t blkno; + caddr_t va; + size_t size; { - return(ENXIO); + return (ENODEV); } - -#endif /* NMT > 0 */ diff --git a/sys/arch/hp300/dev/ppi.c b/sys/arch/hp300/dev/ppi.c index 00076b1df01c..e8973ef43742 100644 --- a/sys/arch/hp300/dev/ppi.c +++ b/sys/arch/hp300/dev/ppi.c @@ -1,6 +1,7 @@ -/* $NetBSD: ppi.c,v 1.10 1996/10/13 03:14:20 christos Exp $ */ +/* $NetBSD: ppi.c,v 1.11 1997/01/30 09:14:16 thorpej Exp $ */ /* + * Copyright (c) 1996, 1997 Jason R. Thorpe. All rights reserved. * Copyright (c) 1982, 1990, 1993 * The Regents of the University of California. All rights reserved. * @@ -39,34 +40,29 @@ * Printer/Plotter HPIB interface */ -#include "ppi.h" -#if NPPI > 0 - #include #include #include #include #include +#include +#include + +#include -#include #include -int ppimatch(), ppistart(); -void ppiattach(), ppitimo(); -struct driver ppidriver = { - ppimatch, ppiattach, "ppi", ppistart, -}; - struct ppi_softc { + struct device sc_dev; int sc_flags; - struct devqueue sc_dq; - struct hp_device *sc_hd; + struct hpibqueue sc_hq; /* HP-IB job queue entry */ struct ppiparam sc_param; #define sc_burst sc_param.burst #define sc_timo sc_param.timo #define sc_delay sc_param.delay int sc_sec; -} ppi_softc[NPPI]; + int sc_slave; /* HP-IB slave address */ +}; /* sc_flags values */ #define PPIF_ALIVE 0x01 @@ -75,6 +71,28 @@ struct ppi_softc { #define PPIF_TIMO 0x08 #define PPIF_DELAY 0x10 +int ppimatch __P((struct device *, struct cfdata *, void *)); +void ppiattach __P((struct device *, struct device *, void *)); + +struct cfattach ppi_ca = { + sizeof(struct ppi_softc), ppimatch, ppiattach +}; + +struct cfdriver ppi_cd = { + NULL, "ppi", DV_DULL +}; + +void ppistart __P((void *)); +void ppinoop __P((void *)); + +void ppitimo __P((void *)); +int ppirw __P((dev_t, struct uio *)); +int ppihztoms __P((int)); +int ppimstohz __P((int)); + +bdev_decl(ppi); +cdev_decl(ppi); + #define UNIT(x) minor(x) #ifdef DEBUG @@ -85,57 +103,82 @@ int ppidebug = 0x80; #endif int -ppimatch(hd) - register struct hp_device *hd; +ppimatch(parent, match, aux) + struct device *parent; + struct cfdata *match; + void *aux; { - register struct ppi_softc *sc = &ppi_softc[hd->hp_unit]; + struct hpibbus_attach_args *ha = aux; -#ifdef DEBUG - if ((ppidebug & PDB_NOCHECK) == 0) -#endif /* - * XXX: the printer/plotter doesn't seem to really return - * an ID but this will at least prevent us from mistaking - * a cs80 disk or tape for a ppi device. + * The printer/plotter doesn't return an ID tag. + * The check below prevents us from matching a CS80 + * device by mistake. */ - if (hpibid(hd->hp_ctlr, hd->hp_slave) & 0x200) + if (ha->ha_id & 0x200) + return (0); + + /* + * To prevent matching all unused slots on the bus, we + * don't allow wildcarded locators. + */ + if (match->hpibbuscf_slave == HPIBBUS_SLAVE_UNK || + match->hpibbuscf_punit == HPIBBUS_PUNIT_UNK) return (0); - sc->sc_hd = hd; return (1); } void -ppiattach(hd) - register struct hp_device *hd; +ppiattach(parent, self, aux) + struct device *parent, *self; + void *aux; { - struct ppi_softc *sc = &ppi_softc[hd->hp_unit]; + struct ppi_softc *sc = (struct ppi_softc *)self; + struct hpibbus_attach_args *ha = aux; printf("\n"); + sc->sc_slave = ha->ha_slave; + + /* Initialize the hpib queue entry. */ + sc->sc_hq.hq_softc = sc; + sc->sc_hq.hq_slave = sc->sc_slave; + sc->sc_hq.hq_start = ppistart; + sc->sc_hq.hq_go = ppinoop; + sc->sc_hq.hq_intr = ppinoop; + sc->sc_flags = PPIF_ALIVE; - sc->sc_dq.dq_softc = sc; - sc->sc_dq.dq_ctlr = hd->hp_ctlr; - sc->sc_dq.dq_unit = hd->hp_unit; - sc->sc_dq.dq_slave = hd->hp_slave; - sc->sc_dq.dq_driver = &ppidriver; } -ppiopen(dev, flags) +void +ppinoop(arg) + void *arg; +{ + /* Noop! */ +} + +int +ppiopen(dev, flags, fmt, p) dev_t dev; + int flags, fmt; + struct proc *p; { register int unit = UNIT(dev); - register struct ppi_softc *sc = &ppi_softc[unit]; + struct ppi_softc *sc; + + if (unit >= ppi_cd.cd_ndevs || + (sc = ppi_cd.cd_devs[unit]) == NULL || + (sc->sc_flags & PPIF_ALIVE) == 0) + return (ENXIO); - if (unit >= NPPI || (sc->sc_flags & PPIF_ALIVE) == 0) - return(ENXIO); #ifdef DEBUG if (ppidebug & PDB_FOLLOW) printf("ppiopen(%x, %x): flags %x\n", dev, flags, sc->sc_flags); #endif if (sc->sc_flags & PPIF_OPEN) - return(EBUSY); + return (EBUSY); sc->sc_flags |= PPIF_OPEN; sc->sc_burst = PPI_BURST; sc->sc_timo = ppimstohz(PPI_TIMO); @@ -144,11 +187,14 @@ ppiopen(dev, flags) return(0); } -ppiclose(dev, flags) +int +ppiclose(dev, flags, fmt, p) dev_t dev; + int flags, fmt; + struct proc *p; { register int unit = UNIT(dev); - register struct ppi_softc *sc = &ppi_softc[unit]; + struct ppi_softc *sc = ppi_cd.cd_devs[unit]; #ifdef DEBUG if (ppidebug & PDB_FOLLOW) @@ -159,33 +205,39 @@ ppiclose(dev, flags) return(0); } -ppistart(unit) - int unit; +void +ppistart(arg) + void *arg; { + struct ppi_softc *sc = arg; + #ifdef DEBUG if (ppidebug & PDB_FOLLOW) printf("ppistart(%x)\n", unit); #endif - ppi_softc[unit].sc_flags &= ~PPIF_DELAY; - wakeup(&ppi_softc[unit]); - return (0); + sc->sc_flags &= ~PPIF_DELAY; + wakeup(sc); } void -ppitimo(unit) - int unit; +ppitimo(arg) + void *arg; { + struct ppi_softc *sc = arg; + #ifdef DEBUG if (ppidebug & PDB_FOLLOW) - printf("ppitimo(%x)\n", unit); + printf("ppitimo(%x)\n", sc->sc_dev.dv_unit); #endif - ppi_softc[unit].sc_flags &= ~(PPIF_UIO|PPIF_TIMO); - wakeup(&ppi_softc[unit]); + sc->sc_flags &= ~(PPIF_UIO|PPIF_TIMO); + wakeup(sc); } -ppiread(dev, uio) +int +ppiread(dev, uio, flags) dev_t dev; struct uio *uio; + int flags; { #ifdef DEBUG @@ -195,9 +247,11 @@ ppiread(dev, uio) return (ppirw(dev, uio)); } -ppiwrite(dev, uio) +int +ppiwrite(dev, uio, flags) dev_t dev; struct uio *uio; + int flags; { #ifdef DEBUG @@ -207,21 +261,25 @@ ppiwrite(dev, uio) return (ppirw(dev, uio)); } +int ppirw(dev, uio) dev_t dev; register struct uio *uio; { int unit = UNIT(dev); - register struct ppi_softc *sc = &ppi_softc[unit]; + struct ppi_softc *sc = ppi_cd.cd_devs[unit]; register int s, len, cnt; register char *cp; int error = 0, gotdata = 0; - int buflen; + int buflen, ctlr, slave; char *buf; if (uio->uio_resid == 0) return(0); + ctlr = sc->sc_dev.dv_parent->dv_unit; + slave = sc->sc_slave; + #ifdef DEBUG if (ppidebug & (PDB_FOLLOW|PDB_IO)) printf("ppirw(%x, %x, %c): burst %d, timo %d, resid %x\n", @@ -233,7 +291,7 @@ ppirw(dev, uio) sc->sc_flags |= PPIF_UIO; if (sc->sc_timo > 0) { sc->sc_flags |= PPIF_TIMO; - timeout(ppitimo, (void *)unit, sc->sc_timo); + timeout(ppitimo, sc, sc->sc_timo); } while (uio->uio_resid > 0) { len = min(buflen, uio->uio_resid); @@ -245,7 +303,8 @@ ppirw(dev, uio) } again: s = splbio(); - if ((sc->sc_flags & PPIF_UIO) && hpibreq(&sc->sc_dq) == 0) + if ((sc->sc_flags & PPIF_UIO) && + hpibreq(sc->sc_dev.dv_parent, &sc->sc_hq) == 0) sleep(sc, PRIBIO+1); /* * Check if we timed out during sleep or uiomove @@ -258,7 +317,7 @@ again: sc->sc_flags); #endif if (sc->sc_flags & PPIF_TIMO) { - untimeout(ppitimo, (void *)unit); + untimeout(ppitimo, sc); sc->sc_flags &= ~PPIF_TIMO; } splx(s); @@ -269,19 +328,16 @@ again: * Perform the operation */ if (uio->uio_rw == UIO_WRITE) - cnt = hpibsend(sc->sc_hd->hp_ctlr, sc->sc_hd->hp_slave, - sc->sc_sec, cp, len); + cnt = hpibsend(ctlr, slave, sc->sc_sec, cp, len); else - cnt = hpibrecv(sc->sc_hd->hp_ctlr, sc->sc_hd->hp_slave, - sc->sc_sec, cp, len); + cnt = hpibrecv(ctlr, slave, sc->sc_sec, cp, len); s = splbio(); - hpibfree(&sc->sc_dq); + hpibfree(sc->sc_dev.dv_parent, &sc->sc_hq); #ifdef DEBUG if (ppidebug & PDB_IO) printf("ppirw: %s(%d, %d, %x, %x, %d) -> %d\n", uio->uio_rw == UIO_READ ? "recv" : "send", - sc->sc_hd->hp_ctlr, sc->sc_hd->hp_slave, - sc->sc_sec, cp, len, cnt); + ctlr, slave, sc->sc_sec, cp, len, cnt); #endif splx(s); if (uio->uio_rw == UIO_READ) { @@ -315,8 +371,7 @@ again: */ if (sc->sc_delay > 0) { sc->sc_flags |= PPIF_DELAY; - timeout((void (*)__P((void *)))ppistart, (void *)unit, - sc->sc_delay); + timeout(ppistart, sc, sc->sc_delay); error = tsleep(sc, PCATCH|PZERO+1, "hpib", 0); if (error) { splx(s); @@ -337,11 +392,11 @@ again: } s = splsoftclock(); if (sc->sc_flags & PPIF_TIMO) { - untimeout(ppitimo, (void *)unit); + untimeout(ppitimo, sc); sc->sc_flags &= ~PPIF_TIMO; } if (sc->sc_flags & PPIF_DELAY) { - untimeout((void (*)__P((void *)))ppistart, (void *)unit); + untimeout(ppistart, sc); sc->sc_flags &= ~PPIF_DELAY; } splx(s); @@ -364,14 +419,15 @@ again: return (error); } +int ppiioctl(dev, cmd, data, flag, p) dev_t dev; - int cmd; + u_long cmd; caddr_t data; int flag; struct proc *p; { - struct ppi_softc *sc = &ppi_softc[UNIT(dev)]; + struct ppi_softc *sc = ppi_cd.cd_devs[UNIT(dev)]; struct ppiparam *pp, *upp; int error = 0; @@ -402,6 +458,7 @@ ppiioctl(dev, cmd, data, flag, p) return (error); } +int ppihztoms(h) int h; { @@ -413,6 +470,7 @@ ppihztoms(h) return(m); } +int ppimstohz(m) int m; { @@ -426,4 +484,3 @@ ppimstohz(m) } return(h); } -#endif diff --git a/sys/arch/hp300/dev/rd.c b/sys/arch/hp300/dev/rd.c index 96c84a237eb8..d85ce9553a2b 100644 --- a/sys/arch/hp300/dev/rd.c +++ b/sys/arch/hp300/dev/rd.c @@ -1,6 +1,7 @@ -/* $NetBSD: rd.c,v 1.26 1997/01/07 09:29:32 thorpej Exp $ */ +/* $NetBSD: rd.c,v 1.27 1997/01/30 09:14:17 thorpej Exp $ */ /* + * Copyright (c) 1996, 1997 Jason R. Thorpe. All rights reserved. * Copyright (c) 1988 University of Utah. * Copyright (c) 1982, 1990, 1993 * The Regents of the University of California. All rights reserved. @@ -45,8 +46,6 @@ /* * CS80/SS80 disk driver */ -#include "rd.h" -#if NRD > 0 #include #include @@ -56,10 +55,14 @@ #include #include #include +#include +#include + +#include -#include #include #include + #ifdef USELEDS #include #endif @@ -69,14 +72,32 @@ #include #include -int rdmatch(), rdstart(), rdgo(), rdintr(); -void rdattach(), rdstrategy(); -struct driver rddriver = { - rdmatch, rdattach, "rd", rdstart, rdgo, rdintr, +int rdmatch __P((struct device *, struct cfdata *, void *)); +void rdattach __P((struct device *, struct device *, void *)); + +struct cfattach rd_ca = { + sizeof(struct rd_softc), rdmatch, rdattach }; -struct rd_softc rd_softc[NRD]; -struct buf rdtab[NRD]; +struct cfdriver rd_cd = { + NULL, "rd", DV_DISK +}; + +int rdident __P((struct device *, struct rd_softc *, + struct hpibbus_attach_args *)); +void rdreset __P((struct rd_softc *)); +void rdustart __P((struct rd_softc *)); +int rdgetinfo __P((dev_t)); +void rdrestart __P((void *)); +struct buf *rdfinish __P((struct rd_softc *, struct buf *)); + +void rdstart __P((void *)); +void rdintr __P((void *)); +void rdgo __P((void *)); + +bdev_decl(rd); +cdev_decl(rd); + int rderrthresh = RDRETRY-1; /* when to start reporting errors */ #ifdef DEBUG @@ -147,7 +168,6 @@ char *err_info[] = { 0, 0 }; -struct rdstats rdstats[NRD]; int rddebug = 0x80; #define RDB_FOLLOW 0x01 #define RDB_STATUS 0x02 @@ -222,144 +242,151 @@ struct rdidentinfo rdidentinfo[] = { int numrdidentinfo = sizeof(rdidentinfo) / sizeof(rdidentinfo[0]); int -rdmatch(hd) - register struct hp_device *hd; +rdmatch(parent, match, aux) + struct device *parent; + struct cfdata *match; + void *aux; { - register struct rd_softc *rs = &rd_softc[hd->hp_unit]; - - rs->sc_hd = hd; - rs->sc_punit = rdpunit(hd->hp_flags); - rs->sc_type = rdident(rs, hd, 0); - if (rs->sc_type < 0) { - /* - * XXX Some ancient drives may be slow to respond, so - * probe them again. - */ - DELAY(10000); - rs->sc_type = rdident(rs, hd, 0); - if (rs->sc_type < 0) - return (0); - } - - /* XXX set up the external name */ - bzero(rs->sc_xname, sizeof(rs->sc_xname)); - sprintf(rs->sc_xname, "rd%d", hd->hp_unit); + struct hpibbus_attach_args *ha = aux; /* - * Initialize and attach the disk structure. + * Set punit if operator specified one in the kernel + * configuration file. */ - bzero(&rs->sc_dkdev, sizeof(rs->sc_dkdev)); - rs->sc_dkdev.dk_name = rs->sc_xname; - disk_attach(&rs->sc_dkdev); + if (match->hpibbuscf_punit != HPIBBUS_PUNIT_UNK && + match->hpibbuscf_punit < HPIB_NPUNITS) + ha->ha_punit = match->hpibbuscf_punit; + if (rdident(parent, NULL, ha) == 0) { + /* + * XXX Some aging HP-IB drives are slow to + * XXX respond; give them a chance to catch + * XXX up and probe them again. + */ + delay(10000); + ha->ha_id = hpibid(parent->dv_unit, ha->ha_slave); + return (rdident(parent, NULL, ha)); + } return (1); } void -rdattach(hd) - register struct hp_device *hd; +rdattach(parent, self, aux) + struct device *parent, *self; + void *aux; { - register struct rd_softc *rs = &rd_softc[hd->hp_unit]; + struct rd_softc *sc = (struct rd_softc *)self; + struct hpibbus_attach_args *ha = aux; - (void)rdident(rs, hd, 1); /* XXX Ick. */ + if (rdident(parent, sc, ha) == 0) { + printf("\n%s: didn't respond to describe command!\n", + sc->sc_dev.dv_xname); + return; + } - rs->sc_dq.dq_softc = rs; - rs->sc_dq.dq_ctlr = hd->hp_ctlr; - rs->sc_dq.dq_unit = hd->hp_unit; - rs->sc_dq.dq_slave = hd->hp_slave; - rs->sc_dq.dq_driver = &rddriver; - rs->sc_flags = RDF_ALIVE; + /* + * Initialize and attach the disk structure. + */ + bzero(&sc->sc_dkdev, sizeof(sc->sc_dkdev)); + sc->sc_dkdev.dk_name = sc->sc_dev.dv_xname; + disk_attach(&sc->sc_dkdev); + + sc->sc_slave = ha->ha_slave; + sc->sc_punit = ha->ha_punit; + + /* Initialize the hpib job queue entry */ + sc->sc_hq.hq_softc = sc; + sc->sc_hq.hq_slave = sc->sc_slave; + sc->sc_hq.hq_start = rdstart; + sc->sc_hq.hq_go = rdgo; + sc->sc_hq.hq_intr = rdintr; + + sc->sc_flags = RDF_ALIVE; #ifdef DEBUG /* always report errors */ if (rddebug & RDB_ERROR) rderrthresh = 0; #endif - - /* XXX Set device class. */ - hd->hp_dev.dv_class = DV_DISK; } int -rdident(rs, hd, verbose) - struct rd_softc *rs; - struct hp_device *hd; - int verbose; +rdident(parent, sc, ha) + struct device *parent; + struct rd_softc *sc; + struct hpibbus_attach_args *ha; { - struct rd_describe *desc = &rs->sc_rddesc; + struct rd_softc rsc; + struct rd_describe *desc = sc != NULL ? &sc->sc_rddesc : NULL; u_char stat, cmd[3]; - int unit, lunit; char name[7]; - register int ctlr, slave, id, i; + int i, id, n, ctlr, slave; - ctlr = hd->hp_ctlr; - slave = hd->hp_slave; - unit = rs->sc_punit; - lunit = hd->hp_unit; + ctlr = parent->dv_unit; + slave = ha->ha_slave; - /* - * Grab device id and make sure: - * 1. It is a CS80 device. - * 2. It is one of the types we support. - * 3. If it is a 7946, we are accessing the disk unit (0) - */ - id = hpibid(ctlr, slave); -#ifdef DEBUG - if (rddebug & RDB_IDENT) - printf("hpibid(%d, %d) -> %x\n", ctlr, slave, id); -#endif - if ((id & 0x200) == 0) - return(-1); - for (i = 0; i < numrdidentinfo; i++) - if (id == rdidentinfo[i].ri_hwid) + /* Verify that we have a CS80 device. */ + if ((ha->ha_id & 0x200) == 0) + return (0); + + /* Is it one of the disks we support? */ + for (id = 0; id < numrdidentinfo; id++) + if (ha->ha_id == rdidentinfo[id].ri_hwid) break; - if (i == numrdidentinfo || unit > rdidentinfo[i].ri_maxunum) - return(-1); - id = i; + if (id == numrdidentinfo || ha->ha_punit > rdidentinfo[id].ri_maxunum) + return (0); /* - * Reset drive and collect device description. - * Don't really use the description info right now but - * might come in handy in the future (for disk labels). + * If we're just probing for the device, that's all the + * work we need to do. */ - rdreset(rs, hd); - cmd[0] = C_SUNIT(unit); + if (sc == NULL) + return (1); + + /* + * Reset device and collect description + */ + rdreset(sc); + cmd[0] = C_SUNIT(ha->ha_punit); cmd[1] = C_SVOL(0); cmd[2] = C_DESC; hpibsend(ctlr, slave, C_CMD, cmd, sizeof(cmd)); hpibrecv(ctlr, slave, C_EXEC, desc, 37); hpibrecv(ctlr, slave, C_QSTAT, &stat, sizeof(stat)); - bzero(name, sizeof(name)); - if (!stat) { - register int n = desc->d_name; + bzero(name, sizeof(name)); + if (stat == 0) { + n = desc->d_name; for (i = 5; i >= 0; i--) { name[i] = (n & 0xf) + '0'; n >>= 4; } } + #ifdef DEBUG if (rddebug & RDB_IDENT) { - printf("rd%d: name: %x ('%s')\n", - lunit, desc->d_name, name); + printf("\n%s: name: %x ('%s')\n", + sc->sc_dev.dv_xname, desc->d_name, name); printf(" iuw %x, maxxfr %d, ctype %d\n", - desc->d_iuw, desc->d_cmaxxfr, desc->d_ctype); + desc->d_iuw, desc->d_cmaxxfr, desc->d_ctype); printf(" utype %d, bps %d, blkbuf %d, burst %d, blktime %d\n", - desc->d_utype, desc->d_sectsize, - desc->d_blkbuf, desc->d_burstsize, desc->d_blocktime); + desc->d_utype, desc->d_sectsize, + desc->d_blkbuf, desc->d_burstsize, desc->d_blocktime); printf(" avxfr %d, ort %d, atp %d, maxint %d, fv %x, rv %x\n", - desc->d_uavexfr, desc->d_retry, desc->d_access, - desc->d_maxint, desc->d_fvbyte, desc->d_rvbyte); + desc->d_uavexfr, desc->d_retry, desc->d_access, + desc->d_maxint, desc->d_fvbyte, desc->d_rvbyte); printf(" maxcyl/head/sect %d/%d/%d, maxvsect %d, inter %d\n", - desc->d_maxcyl, desc->d_maxhead, desc->d_maxsect, - desc->d_maxvsectl, desc->d_interleave); + desc->d_maxcyl, desc->d_maxhead, desc->d_maxsect, + desc->d_maxvsectl, desc->d_interleave); + printf("%s", sc->sc_dev.dv_xname); } #endif + /* * Take care of a couple of anomolies: * 1. 7945A and 7946A both return same HW id * 2. 9122S and 9134D both return same HW id * 3. 9122D and 9134L both return same HW id */ - switch (rdidentinfo[id].ri_hwid) { + switch (ha->ha_id) { case RD7946AID: if (bcmp(name, "079450", 6) == 0) id = RD7945A; @@ -381,53 +408,56 @@ rdident(rs, hd, verbose) id = RD9134D; break; } + + sc->sc_type = id; + /* * XXX We use DEV_BSIZE instead of the sector size value pulled - * off the driver because all of this code assumes 512 byte - * blocks. ICK! + * XXX off the driver because all of this code assumes 512 byte + * XXX blocks. ICK! */ - if (verbose) { - printf(": %s\n", rdidentinfo[id].ri_desc); - printf("%s: %d cylinders, %d heads, %d blocks, %d bytes/block\n", - rs->sc_hd->hp_xname, rdidentinfo[id].ri_ncyl, - rdidentinfo[id].ri_ntpc, rdidentinfo[id].ri_nblocks, - DEV_BSIZE); - } - return(id); + printf(": %s\n", rdidentinfo[id].ri_desc); + printf("%s: %d cylinders, %d heads, %d blocks, %d bytes/block\n", + sc->sc_dev.dv_xname, rdidentinfo[id].ri_ncyl, + rdidentinfo[id].ri_ntpc, rdidentinfo[id].ri_nblocks, + DEV_BSIZE); + + return (1); } -rdreset(rs, hd) +void +rdreset(rs) register struct rd_softc *rs; - register struct hp_device *hd; { + int ctlr = rs->sc_dev.dv_parent->dv_unit; + int slave = rs->sc_slave; u_char stat; rs->sc_clear.c_unit = C_SUNIT(rs->sc_punit); rs->sc_clear.c_cmd = C_CLEAR; - hpibsend(hd->hp_ctlr, hd->hp_slave, C_TCMD, &rs->sc_clear, - sizeof(rs->sc_clear)); - hpibswait(hd->hp_ctlr, hd->hp_slave); - hpibrecv(hd->hp_ctlr, hd->hp_slave, C_QSTAT, &stat, sizeof(stat)); + hpibsend(ctlr, slave, C_TCMD, &rs->sc_clear, sizeof(rs->sc_clear)); + hpibswait(ctlr, slave); + hpibrecv(ctlr, slave, C_QSTAT, &stat, sizeof(stat)); + rs->sc_src.c_unit = C_SUNIT(RDCTLR); rs->sc_src.c_nop = C_NOP; rs->sc_src.c_cmd = C_SREL; rs->sc_src.c_param = C_REL; - hpibsend(hd->hp_ctlr, hd->hp_slave, C_CMD, &rs->sc_src, - sizeof(rs->sc_src)); - hpibswait(hd->hp_ctlr, hd->hp_slave); - hpibrecv(hd->hp_ctlr, hd->hp_slave, C_QSTAT, &stat, sizeof(stat)); + hpibsend(ctlr, slave, C_CMD, &rs->sc_src, sizeof(rs->sc_src)); + hpibswait(ctlr, slave); + hpibrecv(ctlr, slave, C_QSTAT, &stat, sizeof(stat)); + rs->sc_ssmc.c_unit = C_SUNIT(rs->sc_punit); rs->sc_ssmc.c_cmd = C_SSM; rs->sc_ssmc.c_refm = REF_MASK; rs->sc_ssmc.c_fefm = FEF_MASK; rs->sc_ssmc.c_aefm = AEF_MASK; rs->sc_ssmc.c_iefm = IEF_MASK; - hpibsend(hd->hp_ctlr, hd->hp_slave, C_CMD, &rs->sc_ssmc, - sizeof(rs->sc_ssmc)); - hpibswait(hd->hp_ctlr, hd->hp_slave); - hpibrecv(hd->hp_ctlr, hd->hp_slave, C_QSTAT, &stat, sizeof(stat)); + hpibsend(ctlr, slave, C_CMD, &rs->sc_ssmc, sizeof(rs->sc_ssmc)); + hpibswait(ctlr, slave); + hpibrecv(ctlr, slave, C_QSTAT, &stat, sizeof(stat)); #ifdef DEBUG - rdstats[hd->hp_unit].rdresets++; + rs->sc_stats.rdresets++; #endif } @@ -439,7 +469,7 @@ rdgetinfo(dev) dev_t dev; { int unit = rdunit(dev); - register struct rd_softc *rs = &rd_softc[unit]; + struct rd_softc *rs = rd_cd.cd_devs[unit]; register struct disklabel *lp = rs->sc_dkdev.dk_label; register struct partition *pi; char *msg, *readdisklabel(); @@ -467,7 +497,7 @@ rdgetinfo(dev) return(0); pi = lp->d_partitions; - printf("%s: WARNING: %s, ", rs->sc_hd->hp_xname, msg); + printf("%s: WARNING: %s, ", rs->sc_dev.dv_xname, msg); #ifdef COMPAT_NOLABEL printf("using old default partitioning\n"); rdmakedisklabel(unit, lp); @@ -488,11 +518,13 @@ rdopen(dev, flags, mode, p) struct proc *p; { register int unit = rdunit(dev); - register struct rd_softc *rs = &rd_softc[unit]; + register struct rd_softc *rs; int error, mask, part; - if (unit >= NRD || (rs->sc_flags & RDF_ALIVE) == 0) - return(ENXIO); + if (unit >= rd_cd.cd_ndevs || + (rs = rd_cd.cd_devs[unit]) == NULL || + (rs->sc_flags & RDF_ALIVE) == 0) + return (ENXIO); /* * Wait for any pending opens/closes to complete @@ -545,7 +577,7 @@ rdclose(dev, flag, mode, p) struct proc *p; { int unit = rdunit(dev); - register struct rd_softc *rs = &rd_softc[unit]; + struct rd_softc *rs = rd_cd.cd_devs[unit]; register struct disk *dk = &rs->sc_dkdev; int mask, s; @@ -565,9 +597,9 @@ rdclose(dev, flag, mode, p) if (dk->dk_openmask == 0) { rs->sc_flags |= RDF_CLOSING; s = splbio(); - while (rdtab[unit].b_active) { + while (rs->sc_tab.b_active) { rs->sc_flags |= RDF_WANTED; - sleep((caddr_t)&rdtab[unit], PRIBIO); + sleep((caddr_t)&rs->sc_tab, PRIBIO); } splx(s); rs->sc_flags &= ~(RDF_CLOSING|RDF_WLABEL); @@ -581,8 +613,8 @@ rdstrategy(bp) register struct buf *bp; { int unit = rdunit(bp->b_dev); - register struct rd_softc *rs = &rd_softc[unit]; - register struct buf *dp = &rdtab[unit]; + struct rd_softc *rs = rd_cd.cd_devs[unit]; + register struct buf *dp = &rs->sc_tab; register struct partition *pinfo; register daddr_t bn; register int sz, s; @@ -636,7 +668,7 @@ rdstrategy(bp) disksort(dp, bp); if (dp->b_active == 0) { dp->b_active = 1; - rdustart(unit); + rdustart(rs); } splx(s); return; @@ -654,58 +686,60 @@ rdrestart(arg) void *arg; { int s = splbio(); - rdustart((int)arg); + rdustart((struct rd_softc *)arg); splx(s); } -rdustart(unit) - register int unit; +void +rdustart(rs) + struct rd_softc *rs; { register struct buf *bp; - register struct rd_softc *rs = &rd_softc[unit]; - bp = rdtab[unit].b_actf; + bp = rs->sc_tab.b_actf; rs->sc_addr = bp->b_un.b_addr; rs->sc_resid = bp->b_bcount; - if (hpibreq(&rs->sc_dq)) - rdstart(unit); + if (hpibreq(rs->sc_dev.dv_parent, &rs->sc_hq)) + rdstart(rs); } struct buf * -rdfinish(unit, rs, bp) - int unit; +rdfinish(rs, bp) register struct rd_softc *rs; register struct buf *bp; { - register struct buf *dp = &rdtab[unit]; + register struct buf *dp = &rs->sc_tab; dp->b_errcnt = 0; dp->b_actf = bp->b_actf; bp->b_resid = 0; biodone(bp); - hpibfree(&rs->sc_dq); + hpibfree(rs->sc_dev.dv_parent, &rs->sc_hq); if (dp->b_actf) - return(dp->b_actf); + return (dp->b_actf); dp->b_active = 0; if (rs->sc_flags & RDF_WANTED) { rs->sc_flags &= ~RDF_WANTED; wakeup((caddr_t)dp); } - return(NULL); + return (NULL); } -rdstart(unit) - register int unit; +void +rdstart(arg) + void *arg; { - register struct rd_softc *rs = &rd_softc[unit]; - register struct buf *bp = rdtab[unit].b_actf; - register struct hp_device *hp = rs->sc_hd; - register int part; + struct rd_softc *rs = arg; + register struct buf *bp = rs->sc_tab.b_actf; + register int part, ctlr, slave; + + ctlr = rs->sc_dev.dv_parent->dv_unit; + slave = rs->sc_slave; again: #ifdef DEBUG if (rddebug & RDB_FOLLOW) - printf("rdstart(%d): bp %x, %c\n", unit, bp, + printf("rdstart(%s): bp %x, %c\n", sc->sc_dev.dv_xname, bp, (bp->b_flags & B_READ) ? 'R' : 'W'); #endif part = rdpart(bp->b_dev); @@ -722,10 +756,10 @@ again: #ifdef DEBUG if (rddebug & RDB_IO) printf("rdstart: hpibsend(%x, %x, %x, %x, %x)\n", - hp->hp_ctlr, hp->hp_slave, C_CMD, + ctlr, slave, C_CMD, &rs->sc_ioc.c_unit, sizeof(rs->sc_ioc)-2); #endif - if (hpibsend(hp->hp_ctlr, hp->hp_slave, C_CMD, &rs->sc_ioc.c_unit, + if (hpibsend(ctlr, slave, C_CMD, &rs->sc_ioc.c_unit, sizeof(rs->sc_ioc)-2) == sizeof(rs->sc_ioc)-2) { /* Instrumentation. */ @@ -734,9 +768,9 @@ again: #ifdef DEBUG if (rddebug & RDB_IO) - printf("rdstart: hpibawait(%x)\n", hp->hp_ctlr); + printf("rdstart: hpibawait(%x)\n", ctlr); #endif - hpibawait(hp->hp_ctlr); + hpibawait(ctlr); return; } /* @@ -748,35 +782,38 @@ again: #ifdef DEBUG if (rddebug & RDB_ERROR) printf("%s: rdstart: cmd %x adr %d blk %d len %d ecnt %d\n", - rs->sc_hd->hp_xname, rs->sc_ioc.c_cmd, rs->sc_ioc.c_addr, - bp->b_blkno, rs->sc_resid, rdtab[unit].b_errcnt); - rdstats[unit].rdretries++; + rs->sc_dev.dv_xname, rs->sc_ioc.c_cmd, rs->sc_ioc.c_addr, + bp->b_blkno, rs->sc_resid, rs->sc_tab.b_errcnt); + rs->sc_stats.rdretries++; #endif rs->sc_flags &= ~RDF_SEEK; - rdreset(rs, hp); - if (rdtab[unit].b_errcnt++ < RDRETRY) + rdreset(rs); + if (rs->sc_tab.b_errcnt++ < RDRETRY) goto again; printf("%s: rdstart err: cmd 0x%x sect %d blk %d len %d\n", - rs->sc_hd->hp_xname, rs->sc_ioc.c_cmd, rs->sc_ioc.c_addr, + rs->sc_dev.dv_xname, rs->sc_ioc.c_cmd, rs->sc_ioc.c_addr, bp->b_blkno, rs->sc_resid); bp->b_flags |= B_ERROR; bp->b_error = EIO; - bp = rdfinish(unit, rs, bp); + bp = rdfinish(rs, bp); if (bp) { rs->sc_addr = bp->b_un.b_addr; rs->sc_resid = bp->b_bcount; - if (hpibreq(&rs->sc_dq)) + if (hpibreq(rs->sc_dev.dv_parent, &rs->sc_hq)) goto again; } } -rdgo(unit) - register int unit; +void +rdgo(arg) + void *arg; { - register struct rd_softc *rs = &rd_softc[unit]; - register struct hp_device *hp = rs->sc_hd; - struct buf *bp = rdtab[unit].b_actf; - int rw; + struct rd_softc *rs = arg; + struct buf *bp = rs->sc_tab.b_actf; + int rw, ctlr, slave; + + ctlr = rs->sc_dev.dv_parent->dv_unit; + slave = rs->sc_slave; rw = bp->b_flags & B_READ; @@ -787,26 +824,29 @@ rdgo(unit) if (inledcontrol == 0) ledcontrol(0, 0, LED_DISK); #endif - hpibgo(hp->hp_ctlr, hp->hp_slave, C_EXEC, - rs->sc_addr, rs->sc_resid, rw, rw != 0); + hpibgo(ctlr, slave, C_EXEC, rs->sc_addr, rs->sc_resid, rw, rw != 0); } +/* ARGSUSED */ +void rdintr(arg) void *arg; { register struct rd_softc *rs = arg; - int unit = rs->sc_hd->hp_unit; - register struct buf *bp = rdtab[unit].b_actf; - register struct hp_device *hp = rs->sc_hd; + int unit = rs->sc_dev.dv_unit; + register struct buf *bp = rs->sc_tab.b_actf; u_char stat = 13; /* in case hpibrecv fails */ - int rv, restart; - + int rv, restart, ctlr, slave; + + ctlr = rs->sc_dev.dv_parent->dv_unit; + slave = rs->sc_slave; + #ifdef DEBUG if (rddebug & RDB_FOLLOW) printf("rdintr(%d): bp %x, %c, flags %x\n", unit, bp, (bp->b_flags & B_READ) ? 'R' : 'W', rs->sc_flags); if (bp == NULL) { - printf("%s: bp == NULL\n", rs->sc_hd->hp_xname); + printf("%s: bp == NULL\n", rs->sc_dev.dv_xname); return; } #endif @@ -814,28 +854,28 @@ rdintr(arg) if (rs->sc_flags & RDF_SEEK) { rs->sc_flags &= ~RDF_SEEK; - if (hpibustart(hp->hp_ctlr)) - rdgo(unit); + if (hpibustart(ctlr)) + rdgo(rs); return; } if ((rs->sc_flags & RDF_SWAIT) == 0) { #ifdef DEBUG - rdstats[unit].rdpolltries++; + rs->sc_stats.rdpolltries++; #endif - if (hpibpptest(hp->hp_ctlr, hp->hp_slave) == 0) { + if (hpibpptest(ctlr, slave) == 0) { #ifdef DEBUG - rdstats[unit].rdpollwaits++; + rs->sc_stats.rdpollwaits++; #endif /* Instrumentation. */ disk_busy(&rs->sc_dkdev); rs->sc_flags |= RDF_SWAIT; - hpibawait(hp->hp_ctlr); + hpibawait(ctlr); return; } } else rs->sc_flags &= ~RDF_SWAIT; - rv = hpibrecv(hp->hp_ctlr, hp->hp_slave, C_QSTAT, &stat, 1); + rv = hpibrecv(ctlr, slave, C_QSTAT, &stat, 1); if (rv != 1 || stat) { #ifdef DEBUG if (rddebug & RDB_ERROR) @@ -843,20 +883,21 @@ rdintr(arg) #endif restart = rderror(unit); #ifdef DEBUG - rdstats[unit].rdretries++; + rs->sc_stats.rdretries++; #endif - if (rdtab[unit].b_errcnt++ < RDRETRY) { + if (rs->sc_tab.b_errcnt++ < RDRETRY) { if (restart) - rdstart(unit); + rdstart(rs); return; } bp->b_flags |= B_ERROR; bp->b_error = EIO; } - if (rdfinish(unit, rs, bp)) - rdustart(unit); + if (rdfinish(rs, bp)) + rdustart(rs); } +int rdstatus(rs) register struct rd_softc *rs; { @@ -864,8 +905,8 @@ rdstatus(rs) u_char stat; int rv; - c = rs->sc_hd->hp_ctlr; - s = rs->sc_hd->hp_slave; + c = rs->sc_dev.dv_parent->dv_unit; + s = rs->sc_slave; rs->sc_rsc.c_unit = C_SUNIT(rs->sc_punit); rs->sc_rsc.c_sram = C_SRAM; rs->sc_rsc.c_ram = C_RAM; @@ -906,26 +947,27 @@ rdstatus(rs) * Returns 1 if request should be restarted, * 0 if we should just quietly give up. */ +int rderror(unit) int unit; { - struct rd_softc *rs = &rd_softc[unit]; + struct rd_softc *rs = rd_cd.cd_devs[unit]; register struct rd_stat *sp; struct buf *bp; daddr_t hwbn, pbn; if (rdstatus(rs)) { #ifdef DEBUG - printf("%s: couldn't get status\n", rs->sc_hd->hp_xname); + printf("%s: couldn't get status\n", rs->sc_dev.dv_xname); #endif - rdreset(rs, rs->sc_hd); + rdreset(rs); return(1); } sp = &rs->sc_stat; if (sp->c_fef & FEF_REXMT) return(1); if (sp->c_fef & FEF_PF) { - rdreset(rs, rs->sc_hd); + rdreset(rs); return(1); } /* @@ -937,14 +979,14 @@ rderror(unit) */ if (sp->c_fef & FEF_IMR) { extern int hz; - int rdtimo = RDWAITC << rdtab[unit].b_errcnt; + int rdtimo = RDWAITC << rs->sc_tab.b_errcnt; #ifdef DEBUG printf("%s: internal maintenance, %d second timeout\n", - rs->sc_hd->hp_xname, rdtimo); - rdstats[unit].rdtimeouts++; + rs->sc_dev.dv_xname, rdtimo); + rs->sc_stats.rdtimeouts++; #endif - hpibfree(&rs->sc_dq); - timeout(rdrestart, (void *)unit, rdtimo * hz); + hpibfree(rs->sc_dev.dv_parent, &rs->sc_hq); + timeout(rdrestart, rs, rdtimo * hz); return(0); } /* @@ -952,7 +994,7 @@ rderror(unit) * threshhold. By default, this will only report after the * retry limit has been exceeded. */ - if (rdtab[unit].b_errcnt < rderrthresh) + if (rs->sc_tab.b_errcnt < rderrthresh) return(1); /* @@ -960,7 +1002,7 @@ rderror(unit) * Note that not all errors report a block number, in that case * we just use b_blkno. */ - bp = rdtab[unit].b_actf; + bp = rs->sc_tab.b_actf; pbn = rs->sc_dkdev.dk_label->d_partitions[rdpart(bp->b_dev)].p_offset; if ((sp->c_fef & FEF_CU) || (sp->c_fef & FEF_DR) || (sp->c_ief & IEF_RRMASK)) { @@ -976,14 +1018,14 @@ rderror(unit) * out b_blkno which is just the beginning block number * of the transfer, not necessary where the error occured. */ - printf("rd%d%c: hard error sn%d\n", - rdunit(bp->b_dev), 'a'+rdpart(bp->b_dev), pbn); + printf("%s%c: hard error sn%d\n", rs->sc_dev.dv_xname, + 'a'+rdpart(bp->b_dev), pbn); /* * Now report the status as returned by the hardware with * attempt at interpretation (unless debugging). */ - printf("rd%d %s error:", - unit, (bp->b_flags & B_READ) ? "read" : "write"); + printf("%s %s error:", rs->sc_dev.dv_xname, + (bp->b_flags & B_READ) ? "read" : "write"); #ifdef DEBUG if (rddebug & RDB_ERROR) { /* status info */ @@ -1041,13 +1083,13 @@ rdwrite(dev, uio, flags) int rdioctl(dev, cmd, data, flag, p) dev_t dev; - int cmd; + u_long cmd; caddr_t data; int flag; struct proc *p; { int unit = rdunit(dev); - register struct rd_softc *sc = &rd_softc[unit]; + struct rd_softc *sc = rd_cd.cd_devs[unit]; register struct disklabel *lp = sc->sc_dkdev.dk_label; int error, flags; @@ -1103,11 +1145,13 @@ rdsize(dev) dev_t dev; { register int unit = rdunit(dev); - register struct rd_softc *rs = &rd_softc[unit]; + struct rd_softc *rs; int psize, didopen = 0; - if (unit >= NRD || (rs->sc_flags & RDF_ALIVE) == 0) - return(-1); + if (unit >= rd_cd.cd_ndevs || + (rs = rd_cd.cd_devs[unit]) == NULL || + (rs->sc_flags & RDF_ALIVE) == 0) + return (-1); /* * We get called very early on (via swapconf) @@ -1163,8 +1207,8 @@ rddump(dev, blkno, va, size) int totwrt; /* total number of sectors left to write */ int nwrt; /* current number of sectors to write */ int unit, part; + int ctlr, slave; struct rd_softc *rs; - struct hp_device *hp; struct disklabel *lp; char stat; @@ -1178,12 +1222,13 @@ rddump(dev, blkno, va, size) part = rdpart(dev); /* Make sure dump device is ok. */ - if (unit >= NRD) + if (unit >= rd_cd.cd_ndevs || + (rs = rd_cd.cd_devs[unit]) == NULL || + (rs->sc_flags & RDF_ALIVE) == 0) return (ENXIO); - rs = &rd_softc[unit]; - if ((rs->sc_flags & RDF_ALIVE) == 0) - return (ENXIO); - hp = rs->sc_hd; + + ctlr = rs->sc_dev.dv_parent->dv_unit; + slave = rs->sc_slave; /* * Convert to disk sectors. Request must be a multiple of size. @@ -1220,23 +1265,22 @@ rddump(dev, blkno, va, size) rs->sc_ioc.c_slen = C_SLEN; rs->sc_ioc.c_len = nwrt * sectorsize; rs->sc_ioc.c_cmd = C_WRITE; - hpibsend(hp->hp_ctlr, hp->hp_slave, C_CMD, - &rs->sc_ioc.c_unit, sizeof(rs->sc_ioc)-2); - if (hpibswait(hp->hp_ctlr, hp->hp_slave)) + hpibsend(ctlr, slave, C_CMD, &rs->sc_ioc.c_unit, + sizeof(rs->sc_ioc)-2); + if (hpibswait(ctlr, slave)) return (EIO); /* * Send the data. */ - hpibsend(hp->hp_ctlr, hp->hp_slave, C_EXEC, va, - nwrt * sectorsize); - (void) hpibswait(hp->hp_ctlr, hp->hp_slave); - hpibrecv(hp->hp_ctlr, hp->hp_slave, C_QSTAT, &stat, 1); + hpibsend(ctlr, slave, C_EXEC, va, nwrt * sectorsize); + (void) hpibswait(ctlr, slave); + hpibrecv(ctlr, slave, C_QSTAT, &stat, 1); if (stat) return (EIO); #else /* RD_DUMP_NOT_TRUSTED */ /* Let's just talk about this first... */ - printf("%s: dump addr %p, blk %d\n", hp->hp_xname, + printf("%s: dump addr %p, blk %d\n", sc->sc_dev.dv_xname, va, blkno); delay(500 * 1000); /* half a second */ #endif /* RD_DUMP_NOT_TRUSTED */ @@ -1249,4 +1293,3 @@ rddump(dev, blkno, va, size) rddoingadump = 0; return (0); } -#endif diff --git a/sys/arch/hp300/dev/rd_compat.c b/sys/arch/hp300/dev/rd_compat.c index 4adea53bcbdf..6cebe9ff8956 100644 --- a/sys/arch/hp300/dev/rd_compat.c +++ b/sys/arch/hp300/dev/rd_compat.c @@ -1,4 +1,4 @@ -/* $NetBSD: rd_compat.c,v 1.5 1996/01/07 22:02:14 thorpej Exp $ */ +/* $NetBSD: rd_compat.c,v 1.6 1997/01/30 09:14:18 thorpej Exp $ */ /* * Copyright (c) 1988 University of Utah. @@ -45,13 +45,15 @@ /* * Compatibility for CS80 disks without disklabels. */ -#include "rd.h" -#if NRD > 0 #include #include #include -#include +#include +#include /* XXX */ + +#include + #include #include @@ -257,7 +259,8 @@ rdmakedisklabel(unit, lp) int unit; struct disklabel *lp; { - register struct rd_softc *rs = &rd_softc[unit]; + extern struct cfdriver rd_cd; + register struct rd_softc *rs = rd_cd.cd_devs[unit]; register struct rdcompatinfo *ci = &rdcompatinfo[rs->sc_type]; struct rdidentinfo *ri = &rdidentinfo[rs->sc_type]; register struct partition *pi; @@ -287,4 +290,3 @@ rdmakedisklabel(unit, lp) pi++; } } -#endif diff --git a/sys/arch/hp300/dev/rdvar.h b/sys/arch/hp300/dev/rdvar.h index f1b7727cb6c6..275b03ad12be 100644 --- a/sys/arch/hp300/dev/rdvar.h +++ b/sys/arch/hp300/dev/rdvar.h @@ -1,4 +1,4 @@ -/* $NetBSD: rdvar.h,v 1.5 1996/06/06 16:17:42 thorpej Exp $ */ +/* $NetBSD: rdvar.h,v 1.6 1997/01/30 09:14:19 thorpej Exp $ */ /* * Copyright (c) 1988 University of Utah. @@ -52,23 +52,33 @@ struct rdidentinfo { int ri_nblocks; /* DEV_BSIZE blocks on disk */ }; +struct rdstats { + long rdretries; + long rdresets; + long rdtimeouts; + long rdpolltries; + long rdpollwaits; +}; + struct rd_softc { - struct hp_device *sc_hd; + struct device sc_dev; struct disk sc_dkdev; - char sc_xname[8]; + int sc_slave; /* HP-IB slave */ + int sc_punit; /* physical unit on slave */ int sc_flags; short sc_type; - short sc_punit; char *sc_addr; int sc_resid; struct rd_describe sc_rddesc; - struct devqueue sc_dq; + struct hpibqueue sc_hq; /* hpib job queue entry */ struct rd_iocmd sc_ioc; struct rd_rscmd sc_rsc; struct rd_stat sc_stat; struct rd_ssmcmd sc_ssmc; struct rd_srcmd sc_src; struct rd_clearcmd sc_clear; + struct buf sc_tab; /* buffer queue */ + struct rdstats sc_stats; }; /* sc_flags values */ @@ -80,14 +90,6 @@ struct rd_softc { #define RDF_WANTED 0x20 #define RDF_WLABEL 0x40 -struct rdstats { - long rdretries; - long rdresets; - long rdtimeouts; - long rdpolltries; - long rdpollwaits; -}; - #define rdunit(x) (minor(x) >> 3) #define rdpart(x) (minor(x) & 0x7) #define rdpunit(x) ((x) & 7) @@ -100,5 +102,4 @@ struct rdstats { #ifdef _KERNEL extern struct rdidentinfo rdidentinfo[]; -extern struct rd_softc rd_softc[]; #endif diff --git a/sys/arch/hp300/dev/sd.c b/sys/arch/hp300/dev/sd.c index 5b719a06a3d9..6ea2b460dc66 100644 --- a/sys/arch/hp300/dev/sd.c +++ b/sys/arch/hp300/dev/sd.c @@ -1,6 +1,7 @@ -/* $NetBSD: sd.c,v 1.28 1997/01/07 09:29:30 thorpej Exp $ */ +/* $NetBSD: sd.c,v 1.29 1997/01/30 09:14:20 thorpej Exp $ */ /* + * Copyright (c) 1996, 1997 Jason R. Thorpe. All rights reserved. * Copyright (c) 1990, 1993 * The Regents of the University of California. All rights reserved. * @@ -41,8 +42,6 @@ /* * SCSI CCS (Command Command Set) disk driver. */ -#include "sd.h" -#if NSD > 0 #include #include @@ -54,10 +53,13 @@ #include #include #include +#include -#include #include +#include + #include + #ifdef USELEDS #include #endif @@ -67,32 +69,33 @@ #include #include -extern int scsi_test_unit_rdy(); -extern int scsi_request_sense(); -extern int scsi_inquiry(); -extern int scsi_read_capacity(); -extern int scsi_tt_write(); -extern int scsireq(); -extern int scsiustart(); -extern int scsigo(); -extern void scsifree(); -extern void scsireset(); -extern void scsi_delay(); -extern void scsi_str __P((char *, char *, size_t)); - extern void disksort(); extern void biodone(); extern int physio(); extern void TBIS(); -int sdmatch(); -void sdattach(), sdstrategy(), sdstart(), sdustart(), sdgo(), sdintr(); +int sdmatch __P((struct device *, struct cfdata *, void *)); +void sdattach __P((struct device *, struct device *, void *)); -struct driver sddriver = { - sdmatch, sdattach, "sd", (int (*)())sdstart, - (int (*)())sdgo, (int (*)())sdintr, +struct cfattach sd_ca = { + sizeof(struct sd_softc), sdmatch, sdattach }; +struct cfdriver sd_cd = { + NULL, "sd", DV_DISK +}; + +void sdstrategy __P((struct buf *)); +void sdustart __P((int)); + +void sdstart __P((void *)); +void sdgo __P((void *)); +void sdintr __P((void *, int)); + +int sdgetcapacity __P((struct sd_softc *, dev_t)); + +static void sdgetgeom __P((struct sd_softc *)); + #ifdef DEBUG int sddebug = 1; #define SDB_ERROR 0x01 @@ -100,12 +103,6 @@ int sddebug = 1; #define SDB_CAPACITY 0x04 #endif -struct sd_softc sd_softc[NSD]; -struct sdstats sdstats[NSD]; -struct buf sdtab[NSD]; -struct scsi_fmt_cdb sdcmd[NSD]; -struct scsi_fmt_sense sdsense[NSD]; - static struct scsi_fmt_cdb sd_read_cmd = { 10, CMD_READ_EXT }; static struct scsi_fmt_cdb sd_write_cmd = { 10, CMD_WRITE_EXT }; @@ -134,19 +131,12 @@ static char legal_cmds[256] = { /*f0*/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }; -static struct scsi_inquiry inqbuf; -static struct scsi_fmt_cdb inq = { - 6, - CMD_INQUIRY, 0, 0, 0, sizeof(inqbuf), 0 -}; - /* * Perform a mode-sense on page 0x04 (rigid geometry). */ static void -sdgetgeom(sc, hd) +sdgetgeom(sc) struct sd_softc *sc; - struct hp_device *hd; { struct scsi_mode_sense_geom { struct scsi_modesense_hdr header; @@ -158,225 +148,119 @@ sdgetgeom(sc, hd) }; int ctlr, slave, unit; - ctlr = hd->hp_ctlr; - slave = hd->hp_slave; - unit = sc->sc_punit; + ctlr = sc->sc_dev.dv_parent->dv_unit; + slave = sc->sc_target; + unit = sc->sc_lun; + scsi_delay(-1); /* XXX */ (void)scsi_immed_command(ctlr, slave, unit, &modesense_geom, (u_char *)&sensebuf, sizeof(sensebuf), B_READ); + scsi_delay(0); /* XXX */ sc->sc_heads = sensebuf.geom.heads; sc->sc_cyls = (sensebuf.geom.cyl_ub << 16) | (sensebuf.geom.cyl_mb << 8) | sensebuf.geom.cyl_lb; } -static int -sdident(sc, hd, verbose) - struct sd_softc *sc; - struct hp_device *hd; - int verbose; +int +sdmatch(parent, match, aux) + struct device *parent; + struct cfdata *match; + void *aux; { - int unit; - register int ctlr, slave; - register int i; - register int tries = 10; - char vendor[9], product[17], revision[5]; - int isrm = 0; + struct oscsi_attach_args *osa = aux; - ctlr = hd->hp_ctlr; - slave = hd->hp_slave; - unit = sc->sc_punit; - scsi_delay(-1); - - /* - * See if unit exists and is a disk then read block size & nblocks. - */ - while ((i = scsi_test_unit_rdy(ctlr, slave, unit)) != 0) { - if (i == -1 || --tries < 0) { - if (isrm) - break; - /* doesn't exist or not a CCS device */ - goto failed; - } - if (i == STS_CHECKCOND) { - u_char sensebuf[128]; - struct scsi_xsense *sp = (struct scsi_xsense *)sensebuf; - - scsi_request_sense(ctlr, slave, unit, sensebuf, - sizeof(sensebuf)); - if (sp->class == 7) - switch (sp->key) { - /* - * Not ready -- might be removable media - * device with no media. Assume as much, - * if it really isn't, the inquiry commmand - * below will fail. - */ - case 2: - isrm = 1; - break; - /* drive doing an RTZ -- give it a while */ - case 6: - DELAY(1000000); - break; - default: - break; - } - } - DELAY(1000); - } - /* - * Find out about device - */ - if (scsi_immed_command(ctlr, slave, unit, &inq, - (u_char *)&inqbuf, sizeof(inqbuf), B_READ)) - goto failed; - switch (inqbuf.type) { + switch (osa->osa_inqbuf->type) { case 0: /* disk */ case 4: /* WORM */ case 5: /* CD-ROM */ case 7: /* Magneto-optical */ break; default: /* not a disk */ - goto failed; + return 0; } - /* - * Get a usable id string - */ - bzero(vendor, sizeof(vendor)); - bzero(product, sizeof(product)); - bzero(revision, sizeof(revision)); - switch (inqbuf.version) { - case 1: - case 2: - scsi_str(inqbuf.vendor_id, vendor, sizeof(inqbuf.vendor_id)); - scsi_str(inqbuf.product_id, product, - sizeof(inqbuf.product_id)); - scsi_str(inqbuf.rev, revision, sizeof(inqbuf.rev)); - break; - default: - bcopy("UNKNOWN", vendor, 8); - bcopy("DRIVE TYPE", product, 11); - } - if (inqbuf.qual & 0x80) - sc->sc_flags |= SDF_RMEDIA; - - if (sdgetcapacity(sc, hd, NODEV) < 0) - goto failed; - - switch (inqbuf.version) { - case 1: - case 2: - if (verbose) { - printf(": <%s, %s, %s>", vendor, product, revision); - if (inqbuf.version == 2) - printf(" (SCSI-2)"); - } - break; - default: - if (verbose) - printf(": type 0x%x, qual 0x%x, ver %d", - inqbuf.type, inqbuf.qual, inqbuf.version); - break; - } - if (verbose) - printf("\n"); - - if (verbose) { - /* - * Print out some additional information. - */ - printf("%s: ", hd->hp_xname); - switch (inqbuf.type) { - case 4: - printf("WORM, "); - break; - - case 5: - printf("CD-ROM, "); - break; - - case 7: - printf("Magneto-optical, "); - break; - - default: - printf("%d cylinders, %d heads, ", - sc->sc_cyls, sc->sc_heads); - } - - if (sc->sc_blks) - printf("%d blocks, %d bytes/block\n", - sc->sc_blks >> sc->sc_bshift, sc->sc_blksize); - else - printf("drive empty\n"); - } - - scsi_delay(0); - return(inqbuf.type); -failed: - scsi_delay(0); - return(-1); -} - -int -sdmatch(hd) - register struct hp_device *hd; -{ - register struct sd_softc *sc = &sd_softc[hd->hp_unit]; - - /* XXX set up external name */ - bzero(sc->sc_xname, sizeof(sc->sc_xname)); - sprintf(sc->sc_xname, "sd%d", hd->hp_unit); - - /* Initialize the disk structure. */ - bzero(&sc->sc_dkdev, sizeof(sc->sc_dkdev)); - sc->sc_dkdev.dk_name = sc->sc_xname; - - sc->sc_hd = hd; - sc->sc_flags = 0; - /* - * XXX formerly 0 meant unused but now pid 0 can legitimately - * use this interface (sdgetcapacity). - */ - sc->sc_format_pid = -1; - sc->sc_punit = sdpunit(hd->hp_flags); - sc->sc_type = sdident(sc, hd, 0); - if (sc->sc_type < 0) - return (0); return (1); } void -sdattach(hd) - register struct hp_device *hd; +sdattach(parent, self, aux) + struct device *parent, *self; + void *aux; { - struct sd_softc *sc = &sd_softc[hd->hp_unit]; + struct sd_softc *sc = (struct sd_softc *)self; + struct oscsi_attach_args *osa = aux; - (void)sdident(sc, hd, 1); /* XXX Ick. */ + /* + * XXX formerly 0 meant unused but now pid 0 can legitimately + * use this interface (sdgetcapacity). + */ + sc->sc_format_pid = -1; + sc->sc_flags = 0; - sc->sc_dq.dq_softc = sc; - sc->sc_dq.dq_ctlr = hd->hp_ctlr; - sc->sc_dq.dq_unit = hd->hp_unit; - sc->sc_dq.dq_slave = hd->hp_slave; - sc->sc_dq.dq_driver = &sddriver; + sc->sc_target = osa->osa_target; + sc->sc_lun = osa->osa_lun; + sc->sc_type = osa->osa_inqbuf->type; + + if (osa->osa_inqbuf->qual & 0x80) + sc->sc_flags |= SDF_RMEDIA; + + printf("\n"); + + /* Initialize the SCSI queue entry. */ + sc->sc_sq.sq_softc = sc; + sc->sc_sq.sq_target = sc->sc_target; + sc->sc_sq.sq_lun = sc->sc_lun; + sc->sc_sq.sq_start = sdstart; + sc->sc_sq.sq_go = sdgo; + sc->sc_sq.sq_intr = sdintr; + + if (sdgetcapacity(sc, NODEV) < 0) { + printf("%s: getcapacity failed!\n", sc->sc_dev.dv_xname); + return; + } + + /* + * Print out some additional information. + */ + printf("%s: ", sc->sc_dev.dv_xname); + switch (sc->sc_type) { + case 4: + printf("WORM, "); + break; + + case 5: + printf("CD-ROM, "); + break; + + case 7: + printf("Magneto-optical, "); + break; + + default: + printf("%d cylinders, %d heads, ", + sc->sc_cyls, sc->sc_heads); + } + if (sc->sc_blks) + printf("%d blocks, %d bytes/block\n", + sc->sc_blks >> sc->sc_bshift, sc->sc_blksize); + else + printf("drive empty\n"); + + /* Initialize the disk structure. */ + sc->sc_dkdev.dk_name = sc->sc_dev.dv_xname; /* Attach the disk. */ disk_attach(&sc->sc_dkdev); sc->sc_flags |= SDF_ALIVE; - - /* XXX Set device class. */ - hd->hp_dev.dv_class = DV_DISK; } void -sdreset(sc, hd) +sdreset(sc) register struct sd_softc *sc; - register struct hp_device *hd; { - sdstats[hd->hp_unit].sdresets++; + sc->sc_stats.sdresets++; } /* @@ -385,9 +269,8 @@ sdreset(sc, hd) * due to missing media. */ int -sdgetcapacity(sc, hd, dev) +sdgetcapacity(sc, dev) struct sd_softc *sc; - struct hp_device *hd; dev_t dev; { static struct scsi_fmt_cdb cap = { @@ -406,8 +289,11 @@ sdgetcapacity(sc, hd, dev) capbuf = malloc(capbufsize, M_DEVBUF, M_WAITOK); if (dev == NODEV) { - i = scsi_immed_command(hd->hp_ctlr, hd->hp_slave, sc->sc_punit, - &cap, capbuf, capbufsize, B_READ); + scsi_delay(-1); /* XXX */ + i = scsi_immed_command(sc->sc_dev.dv_parent->dv_unit, + sc->sc_target, sc->sc_lun, &cap, capbuf, + capbufsize, B_READ); + scsi_delay(0); /* XXX */ } else { struct buf *bp; @@ -418,13 +304,13 @@ sdgetcapacity(sc, hd, dev) panic("sdgetcapacity"); bp = malloc(sizeof *bp, M_DEVBUF, M_WAITOK); sc->sc_format_pid = curproc->p_pid; - bcopy((caddr_t)&cap, (caddr_t)&sdcmd[hd->hp_unit], sizeof cap); + bcopy(&cap, &sc->sc_cmdstore, sizeof cap); bp->b_dev = dev; bp->b_flags = B_READ | B_BUSY; bp->b_un.b_addr = (caddr_t)capbuf; bp->b_bcount = capbufsize; sdstrategy(bp); - i = biowait(bp) ? sdsense[hd->hp_unit].status : 0; + i = biowait(bp) ? sc->sc_sensestore.status : 0; free(bp, M_DEVBUF); sc->sc_format_pid = -1; } @@ -433,7 +319,7 @@ sdgetcapacity(sc, hd, dev) #ifdef DEBUG if (sddebug & SDB_CAPACITY) printf("%s: read_capacity returns %d\n", - hd->hp_xname, i); + sc->sc_dev.dv_xname, i); #endif free(capbuf, M_DEVBUF); return (-1); @@ -447,7 +333,7 @@ sdgetcapacity(sc, hd, dev) #ifdef DEBUG if (sddebug & SDB_CAPACITY) printf("%s: removable media not present\n", - hd->hp_xname); + sc->sc_dev.dv_xname); #endif free(capbuf, M_DEVBUF); return (1); @@ -463,7 +349,7 @@ sdgetcapacity(sc, hd, dev) if (sc->sc_blksize != DEV_BSIZE) { if (sc->sc_blksize < DEV_BSIZE) { printf("%s: need at least %d byte blocks - %s\n", - hd->hp_xname, DEV_BSIZE, "drive ignored"); + sc->sc_dev.dv_xname, DEV_BSIZE, "drive ignored"); return (-1); } for (i = sc->sc_blksize; i > DEV_BSIZE; i >>= 1) @@ -472,10 +358,11 @@ sdgetcapacity(sc, hd, dev) } #ifdef DEBUG if (sddebug & SDB_CAPACITY) - printf("%s: blks=%d, blksize=%d, bshift=%d\n", hd->hp_xname, - sc->sc_blks, sc->sc_blksize, sc->sc_bshift); + printf("%s: blks=%d, blksize=%d, bshift=%d\n", + sc->sc_dev.dv_xname, sc->sc_blks, sc->sc_blksize, + sc->sc_bshift); #endif - sdgetgeom(sc, hd); + sdgetgeom(sc); return (0); } @@ -487,7 +374,7 @@ sdgetinfo(dev) dev_t dev; { int unit = sdunit(dev); - register struct sd_softc *sc = &sd_softc[unit]; + struct sd_softc *sc = sd_cd.cd_devs[unit]; register struct disklabel *lp = sc->sc_dkdev.dk_label; register struct partition *pi; char *msg, *readdisklabel(); @@ -510,7 +397,7 @@ sdgetinfo(dev) * now. */ if ((sc->sc_flags & SDF_RMEDIA) || sc->sc_blks == 0) { - switch (sdgetcapacity(sc, sc->sc_hd, dev)) { + switch (sdgetcapacity(sc, dev)) { case 0: break; case -1: @@ -558,7 +445,7 @@ sdgetinfo(dev) } pi = lp->d_partitions; - printf("%s: WARNING: %s, ", sc->sc_hd->hp_xname, msg); + printf("%s: WARNING: %s, ", sc->sc_dev.dv_xname, msg); #ifdef COMPAT_NOLABEL if (usedefault) { printf("using old default partitioning\n"); @@ -581,11 +468,13 @@ sdopen(dev, flags, mode, p) struct proc *p; { register int unit = sdunit(dev); - register struct sd_softc *sc = &sd_softc[unit]; + struct sd_softc *sc; int error, mask, part; - if (unit >= NSD || (sc->sc_flags & SDF_ALIVE) == 0) - return(ENXIO); + if (unit >= sd_cd.cd_ndevs || + (sc = sd_cd.cd_devs[unit]) == NULL || + (sc->sc_flags & SDF_ALIVE) == 0) + return (ENXIO); /* * Wait for any pending opens/closes to complete @@ -638,7 +527,7 @@ sdclose(dev, flag, mode, p) struct proc *p; { int unit = sdunit(dev); - register struct sd_softc *sc = &sd_softc[unit]; + struct sd_softc *sc = sd_cd.cd_devs[unit]; register struct disk *dk = &sc->sc_dkdev; int mask, s; @@ -658,9 +547,9 @@ sdclose(dev, flag, mode, p) if (dk->dk_openmask == 0) { sc->sc_flags |= SDF_CLOSING; s = splbio(); - while (sdtab[unit].b_active) { + while (sc->sc_tab.b_active) { sc->sc_flags |= SDF_WANTED; - sleep((caddr_t)&sdtab[unit], PRIBIO); + sleep((caddr_t)&sc->sc_tab, PRIBIO); } splx(s); sc->sc_flags &= ~(SDF_CLOSING|SDF_WLABEL|SDF_ERROR); @@ -684,6 +573,7 @@ sdlblkstrat(bp, bsize) register struct buf *bp; register int bsize; { + struct sd_softc *sc = sd_cd.cd_devs[sdunit(bp->b_dev)]; register struct buf *cbp = (struct buf *)malloc(sizeof(struct buf), M_DEVBUF, M_WAITOK); caddr_t cbuf = (caddr_t)malloc(bsize, M_DEVBUF, M_WAITOK); @@ -707,7 +597,7 @@ sdlblkstrat(bp, bsize) register int count; if (boff || resid < bsize) { - sdstats[sdunit(bp->b_dev)].sdpartials++; + sc->sc_stats.sdpartials++; count = min(resid, bsize - boff); cbp->b_flags = B_BUSY | B_PHYS | B_READ; cbp->b_blkno = bn - btodb(boff); @@ -773,8 +663,8 @@ sdstrategy(bp) register struct buf *bp; { int unit = sdunit(bp->b_dev); - register struct sd_softc *sc = &sd_softc[unit]; - register struct buf *dp = &sdtab[unit]; + struct sd_softc *sc = sd_cd.cd_devs[unit]; + register struct buf *dp = &sc->sc_tab; register struct partition *pinfo; register daddr_t bn; register int sz, s; @@ -857,8 +747,10 @@ void sdustart(unit) register int unit; { - if (scsireq(&sd_softc[unit].sc_dq)) - sdstart(unit); + struct sd_softc *sc = sd_cd.cd_devs[unit]; + + if (scsireq(sc->sc_dev.dv_parent, &sc->sc_sq)) + sdstart(sc); } /* @@ -868,22 +760,21 @@ sdustart(unit) * >0 if a fatal error */ static int -sderror(unit, sc, hp, stat) - int unit, stat; - register struct sd_softc *sc; - register struct hp_device *hp; +sderror(sc, stat) + struct sd_softc *sc; + int stat; { int cond = 1; - sdsense[unit].status = stat; + sc->sc_sensestore.status = stat; if (stat & STS_CHECKCOND) { struct scsi_xsense *sp; - scsi_request_sense(hp->hp_ctlr, hp->hp_slave, - sc->sc_punit, sdsense[unit].sense, - sizeof(sdsense[unit].sense)); - sp = (struct scsi_xsense *)sdsense[unit].sense; - printf("%s: scsi sense class %d, code %d", hp->hp_xname, + scsi_request_sense(sc->sc_dev.dv_parent->dv_unit, + sc->sc_target, sc->sc_lun, sc->sc_sensestore.sense, + sizeof(sc->sc_sensestore.sense)); + sp = (struct scsi_xsense *)(sc->sc_sensestore.sense); + printf("%s: scsi sense class %d, code %d", sc->sc_dev.dv_xname, sp->class, sp->code); if (sp->class == 7) { printf(", key %d", sp->key); @@ -923,20 +814,19 @@ sderror(unit, sc, hp, stat) } static void -sdfinish(unit, sc, bp) - int unit; - register struct sd_softc *sc; - register struct buf *bp; +sdfinish(sc, bp) + struct sd_softc *sc; + struct buf *bp; { - register struct buf *dp = &sdtab[unit]; + register struct buf *dp = &sc->sc_tab; dp->b_errcnt = 0; dp->b_actf = bp->b_actf; bp->b_resid = 0; biodone(bp); - scsifree(&sc->sc_dq); + scsifree(sc->sc_dev.dv_parent, &sc->sc_sq); if (dp->b_actf) - sdustart(unit); + sdustart(sc->sc_dev.dv_unit); else { dp->b_active = 0; if (sc->sc_flags & SDF_WANTED) { @@ -947,54 +837,52 @@ sdfinish(unit, sc, bp) } void -sdstart(unit) - register int unit; +sdstart(arg) + void *arg; { - register struct sd_softc *sc = &sd_softc[unit]; - register struct hp_device *hp = sc->sc_hd; + struct sd_softc *sc = arg; /* * we have the SCSI bus -- in format mode, we may or may not need dma * so check now. */ - if (sc->sc_format_pid >= 0 && legal_cmds[sdcmd[unit].cdb[0]] > 0) { - register struct buf *bp = sdtab[unit].b_actf; + if (sc->sc_format_pid >= 0 && legal_cmds[sc->sc_cmdstore.cdb[0]] > 0) { + register struct buf *bp = sc->sc_tab.b_actf; register int sts; - sdtab[unit].b_errcnt = 0; + sc->sc_tab.b_errcnt = 0; while (1) { - sts = scsi_immed_command(hp->hp_ctlr, hp->hp_slave, - sc->sc_punit, &sdcmd[unit], - bp->b_un.b_addr, bp->b_bcount, - bp->b_flags & B_READ); - sdsense[unit].status = sts; + sts = scsi_immed_command(sc->sc_dev.dv_parent->dv_unit, + sc->sc_target, sc->sc_lun, &sc->sc_cmdstore, + bp->b_un.b_addr, bp->b_bcount, + bp->b_flags & B_READ); + sc->sc_sensestore.status = sts; if ((sts & 0xfe) == 0 || - (sts = sderror(unit, sc, hp, sts)) == 0) + (sts = sderror(sc, sts)) == 0) break; - if (sts > 0 || sdtab[unit].b_errcnt++ >= SDRETRY) { + if (sts > 0 || sc->sc_tab.b_errcnt++ >= SDRETRY) { bp->b_flags |= B_ERROR; bp->b_error = EIO; break; } } - sdfinish(unit, sc, bp); + sdfinish(sc, bp); - } else if (scsiustart(hp->hp_ctlr)) - sdgo(unit); + } else if (scsiustart(sc->sc_dev.dv_parent->dv_unit)) + sdgo(sc); } void -sdgo(unit) - register int unit; +sdgo(arg) + void *arg; { - register struct sd_softc *sc = &sd_softc[unit]; - register struct hp_device *hp = sc->sc_hd; - register struct buf *bp = sdtab[unit].b_actf; + struct sd_softc *sc = arg; + register struct buf *bp = sc->sc_tab.b_actf; register int pad; register struct scsi_fmt_cdb *cmd; if (sc->sc_format_pid >= 0) { - cmd = &sdcmd[unit]; + cmd = &sc->sc_cmdstore; pad = 0; } else { /* @@ -1003,7 +891,7 @@ sdgo(unit) if (sc->sc_flags & SDF_ERROR) { bp->b_flags |= B_ERROR; bp->b_error = EIO; - sdfinish(unit, sc, bp); + sdfinish(sc, bp); return; } cmd = bp->b_flags & B_READ? &sd_read_cmd : &sd_write_cmd; @@ -1014,15 +902,15 @@ sdgo(unit) #ifdef DEBUG if (pad) printf("%s: partial block xfer -- %x bytes\n", - sc->sc_hd->hp_xname, bp->b_bcount); + sc->sc_dev.dv_xname, bp->b_bcount); #endif - sdstats[unit].sdtransfers++; + sc->sc_stats.sdtransfers++; } #ifdef USELEDS if (inledcontrol == 0) ledcontrol(0, 0, LED_DISK); #endif - if (scsigo(hp->hp_ctlr, hp->hp_slave, sc->sc_punit, + if (scsigo(sc->sc_dev.dv_parent->dv_unit, sc->sc_target, sc->sc_lun, bp, cmd, pad) == 0) { /* Instrumentation. */ disk_busy(&sc->sc_dkdev); @@ -1032,14 +920,14 @@ sdgo(unit) #ifdef DEBUG if (sddebug & SDB_ERROR) printf("%s: sdstart: %s adr %d blk %d len %d ecnt %d\n", - sc->sc_hd->hp_xname, + sc->sc_dev.dv_xname, bp->b_flags & B_READ? "read" : "write", bp->b_un.b_addr, bp->b_cylin, bp->b_bcount, - sdtab[unit].b_errcnt); + sc->sc_tab.b_errcnt); #endif bp->b_flags |= B_ERROR; bp->b_error = EIO; - sdfinish(unit, sc, bp); + sdfinish(sc, bp); } void @@ -1048,13 +936,12 @@ sdintr(arg, stat) int stat; { register struct sd_softc *sc = arg; - int unit = sc->sc_hd->hp_unit; - register struct buf *bp = sdtab[unit].b_actf; - register struct hp_device *hp = sc->sc_hd; + int unit = sc->sc_dev.dv_unit; + register struct buf *bp = sc->sc_tab.b_actf; int cond; if (bp == NULL) { - printf("%s: bp == NULL\n", sc->sc_hd->hp_xname); + printf("%s: bp == NULL\n", sc->sc_dev.dv_xname); return; } @@ -1064,25 +951,25 @@ sdintr(arg, stat) #ifdef DEBUG if (sddebug & SDB_ERROR) printf("%s: sdintr: bad scsi status 0x%x\n", - sc->sc_hd->hp_xname, stat); + sc->sc_dev.dv_xname, stat); #endif - cond = sderror(unit, sc, hp, stat); + cond = sderror(sc, stat); if (cond) { - if (cond < 0 && sdtab[unit].b_errcnt++ < SDRETRY) { + if (cond < 0 && sc->sc_tab.b_errcnt++ < SDRETRY) { #ifdef DEBUG if (sddebug & SDB_ERROR) printf("%s: retry #%d\n", - sc->sc_hd->hp_xname, - sdtab[unit].b_errcnt); + sc->sc_dev.dv_xname, + sc->sc_tab.b_errcnt); #endif - sdstart(unit); + sdstart(sc); return; } bp->b_flags |= B_ERROR; bp->b_error = EIO; } } - sdfinish(unit, sc, bp); + sdfinish(sc, bp); } int @@ -1092,9 +979,10 @@ sdread(dev, uio, flags) int flags; { register int unit = sdunit(dev); + struct sd_softc *sc = sd_cd.cd_devs[unit]; register int pid; - if ((pid = sd_softc[unit].sc_format_pid) >= 0 && + if ((pid = sc->sc_format_pid) >= 0 && pid != uio->uio_procp->p_pid) return (EPERM); @@ -1108,9 +996,10 @@ sdwrite(dev, uio, flags) int flags; { register int unit = sdunit(dev); + struct sd_softc *sc = sd_cd.cd_devs[unit]; register int pid; - if ((pid = sd_softc[unit].sc_format_pid) >= 0 && + if ((pid = sc->sc_format_pid) >= 0 && pid != uio->uio_procp->p_pid) return (EPERM); @@ -1126,7 +1015,7 @@ sdioctl(dev, cmd, data, flag, p) struct proc *p; { int unit = sdunit(dev); - register struct sd_softc *sc = &sd_softc[unit]; + struct sd_softc *sc = sd_cd.cd_devs[unit]; register struct disklabel *lp = sc->sc_dkdev.dk_label; int error, flags; @@ -1205,7 +1094,7 @@ sdioctl(dev, cmd, data, flag, p) return (EPERM); if (legal_cmds[((struct scsi_fmt_cdb *)data)->cdb[0]] == 0) return (EINVAL); - bcopy(data, (caddr_t)&sdcmd[unit], sizeof(sdcmd[0])); + bcopy(data, &sc->sc_cmdstore, sizeof(struct scsi_fmt_cdb)); return (0); case SDIOCSENSE: @@ -1213,7 +1102,7 @@ sdioctl(dev, cmd, data, flag, p) * return the SCSI sense data saved after the last * operation that completed with "check condition" status. */ - bcopy((caddr_t)&sdsense[unit], data, sizeof(sdsense[0])); + bcopy(&sc->sc_sensestore, data, sizeof(sc->sc_sensestore)); return (0); } @@ -1225,11 +1114,13 @@ sdsize(dev) dev_t dev; { register int unit = sdunit(dev); - register struct sd_softc *sc = &sd_softc[unit]; + struct sd_softc *sc = sd_cd.cd_devs[unit]; int psize, didopen = 0; - if (unit >= NSD || (sc->sc_flags & SDF_ALIVE) == 0) - return(-1); + if (unit >= sd_cd.cd_ndevs || + (sc = sd_cd.cd_devs[unit]) == NULL || + (sc->sc_flags & SDF_ALIVE) == 0) + return (-1); /* * We get called very early on (via swapconf) @@ -1266,7 +1157,6 @@ sddump(dev, blkno, va, size) int nwrt; /* current number of sectors to write */ int unit, part; struct sd_softc *sc; - struct hp_device *hp; struct disklabel *lp; daddr_t baddr; char stat; @@ -1281,12 +1171,10 @@ sddump(dev, blkno, va, size) part = sdpart(dev); /* Make sure device is ok. */ - if (unit >= NSD) + if (unit >= sd_cd.cd_ndevs || + (sc = sd_cd.cd_devs[unit]) == NULL || + (sc->sc_flags & SDF_ALIVE) == 0) return (ENXIO); - sc = &sd_softc[unit]; - if ((sc->sc_flags & SDF_ALIVE) == 0) - return (ENXIO); - hp = sc->sc_hd; /* * Convert to disk sectors. Request must be a multiple of size. @@ -1315,15 +1203,16 @@ sddump(dev, blkno, va, size) * Send the data. Note the `0' argument for bshift; * we've done the necessary conversion above. */ - stat = scsi_tt_write(hp->hp_ctlr, hp->hp_slave, sc->sc_punit, - va, nwrt * sectorsize, blkno, 0); + stat = scsi_tt_write(sc->sc_dev.dv_parent->dv_unit, + sc->sc_target, sc->sc_lun, va, nwrt * sectorsize, + blkno, 0); if (stat) { printf("\nsddump: scsi write error 0x%x\n", stat); return (EIO); } #else /* SD_DUMP_NOT_TRUSTED */ /* Lets just talk about it first. */ - printf("%s: dump addr %p, blk %d\n", hp->hp_xname, + printf("%s: dump addr %p, blk %d\n", sc->sc_dev.dv_xname, va, blkno); delay(500 * 1000); /* half a second */ #endif /* SD_DUMP_NOT_TRUSTED */ @@ -1336,4 +1225,3 @@ sddump(dev, blkno, va, size) sddoingadump = 0; return (0); } -#endif diff --git a/sys/arch/hp300/dev/sd_compat.c b/sys/arch/hp300/dev/sd_compat.c index 60e25a63b810..8eee76e206c8 100644 --- a/sys/arch/hp300/dev/sd_compat.c +++ b/sys/arch/hp300/dev/sd_compat.c @@ -1,4 +1,4 @@ -/* $NetBSD: sd_compat.c,v 1.4 1996/01/07 22:02:20 thorpej Exp $ */ +/* $NetBSD: sd_compat.c,v 1.5 1997/01/30 09:14:21 thorpej Exp $ */ /* * Copyright (c) 1990, 1993 @@ -41,13 +41,15 @@ /* * Compatibility for SCSI disks without labels. */ -#include "sd.h" -#if NSD > 0 #include #include #include -#include +#include +#include /* XXX */ + +#include /* XXX */ +#include #include /* @@ -76,13 +78,12 @@ struct partition sddefaultpart[] = { }; int sdnumdefaultpart = sizeof(sddefaultpart)/sizeof(sddefaultpart[0]); -extern struct sd_softc sd_softc[]; - sdmakedisklabel(unit, lp) int unit; register struct disklabel *lp; { - register struct sd_softc *sc = &sd_softc[unit]; + extern struct cfdriver sd_cd; + struct sd_softc *sc = sd_cd.cd_devs[unit]; register struct partition *pi, *dpi; register int dcount; @@ -123,4 +124,3 @@ sdmakedisklabel(unit, lp) pi[5].p_offset = pi[5].p_size = 0; } } -#endif diff --git a/sys/arch/hp300/dev/sdvar.h b/sys/arch/hp300/dev/sdvar.h index ada34c16a6ce..20a328e12a4c 100644 --- a/sys/arch/hp300/dev/sdvar.h +++ b/sys/arch/hp300/dev/sdvar.h @@ -1,4 +1,4 @@ -/* $NetBSD: sdvar.h,v 1.5 1996/06/06 16:17:45 thorpej Exp $ */ +/* $NetBSD: sdvar.h,v 1.6 1997/01/30 09:14:22 thorpej Exp $ */ /* * Copyright (c) 1990, 1993 @@ -38,20 +38,30 @@ * @(#)sdvar.h 8.1 (Berkeley) 6/10/93 */ +struct sdstats { + long sdresets; + long sdtransfers; + long sdpartials; +}; + struct sd_softc { - struct hp_device *sc_hd; + struct device sc_dev; struct disk sc_dkdev; - char sc_xname[8]; - struct devqueue sc_dq; + struct scsiqueue sc_sq; int sc_format_pid; /* process using "format" mode */ short sc_flags; short sc_type; /* drive type */ - short sc_punit; /* physical unit (scsi lun) */ + int sc_target; /* SCSI target */ + int sc_lun; /* SCSI lun */ u_short sc_bshift; /* convert device blocks to DEV_BSIZE blks */ u_int sc_blks; /* number of blocks on device */ int sc_blksize; /* device block size in bytes */ u_int sc_heads; /* number of heads (tracks) */ u_int sc_cyls; /* number of cylinders */ + struct buf sc_tab; /* buffer queue */ + struct sdstats sc_stats; /* debugging stats */ + struct scsi_fmt_cdb sc_cmdstore; + struct scsi_fmt_sense sc_sensestore; }; /* sc_flags values */ @@ -63,12 +73,6 @@ struct sd_softc { #define SDF_RMEDIA 0x20 #define SDF_ERROR 0x40 -struct sdstats { - long sdresets; - long sdtransfers; - long sdpartials; -}; - #define sdunit(x) (minor(x) >> 3) #define sdpart(x) (minor(x) & 0x7) #define sdpunit(x) ((x) & 7) diff --git a/sys/arch/hp300/dev/st.c b/sys/arch/hp300/dev/st.c index 845ae11f8d86..b3bab0ed17ad 100644 --- a/sys/arch/hp300/dev/st.c +++ b/sys/arch/hp300/dev/st.c @@ -1,6 +1,7 @@ -/* $NetBSD: st.c,v 1.18 1996/10/14 07:14:21 thorpej Exp $ */ +/* $NetBSD: st.c,v 1.19 1997/01/30 09:14:23 thorpej Exp $ */ /* + * Copyright (c) 1996, 1997 Jason R. Thorpe. All rights reserved. * Copyright (c) 1990 University of Utah. * Copyright (c) 1990, 1993 * The Regents of the University of California. All rights reserved. @@ -74,9 +75,6 @@ * support for the block device not implemented */ -#include "st.h" -#if NST > 0 - #include #include #include @@ -87,32 +85,21 @@ #include #include #include +#include -#include #include +#include + #include -extern int scsi_test_unit_rdy(); -extern int scsi_request_sense(); -extern int scsiustart(); -extern int scsigo(); -extern void scsifree(); -extern void scsireset(); -extern void scsi_delay(); -extern int scsi_tt_oddio(); -extern void scsi_str __P((char *, char *, size_t)); - -extern int scsi_immed_command(); - -int stmatch(), ststart(), stgo(), stintr(); -void stattach(); -struct driver stdriver = { - stmatch, stattach, "st", ststart, stgo, stintr, +struct st_xsense { + struct scsi_xsense sc_xsense; /* data from sense */ + struct exb_xsense exb_xsense; /* additional info from exabyte */ }; struct st_softc { - struct hp_device *sc_hd; - struct devqueue sc_dq; + struct device sc_dev; + struct scsiqueue sc_sq; long sc_blkno; /* (possible block device support?) */ long sc_resid; /* (possible block device support?) */ int sc_flags; @@ -120,14 +107,19 @@ struct st_softc { int sc_filepos; /* file position on tape */ long sc_numblks; /* number of blocks on tape */ short sc_type; /* ansi scsi type */ - short sc_punit; /* physical unit (scsi lun) */ + int sc_target; + int sc_lun; short sc_tapeid; /* tape drive id */ char sc_datalen[32]; /* additional data length on some commands */ short sc_tticntdwn; /* interrupts between TTi display updates */ tpr_t sc_ctty; struct buf *sc_bp; u_char sc_cmd; -} st_softc[NST]; + struct st_xsense sc_sense; + struct scsi_fmt_cdb sc_cmdstore; + struct buf sc_tab; /* buffer queue */ + struct buf sc_bufstore; /* XXX buffer storage */ +}; /* softc flags */ #define STF_ALIVE 0x0001 @@ -138,25 +130,26 @@ struct st_softc { #define STF_LEOT 0x0020 #define STF_MOVED 0x0040 -struct st_mode st_mode[NST]; +int stmatch __P((struct device *, struct cfdata *, void *)); +void stattach __P((struct device *, struct device *, void *)); -/* - * Maybe this should not be global, but gives chance to get - * tape remaining, Rewrites/ECC, etc outside the driver - */ -static struct st_xsense { - struct scsi_xsense sc_xsense; /* data from sense */ - struct exb_xsense exb_xsense; /* additional info from exabyte */ -} st_xsense[NST]; +struct cfattach st_ca = { + sizeof(struct st_softc), stmatch, stattach +}; -static struct scsi_fmt_cdb stcmd[NST]; +struct cfdriver st_cd = { + NULL, "st", DV_TAPE +}; + +void stustart __P((int)); + +void ststart __P((void *)); +void stgo __P((void *)); +void stintr __P((void *, int)); static struct scsi_fmt_cdb st_read_cmd = { 6, CMD_READ }; static struct scsi_fmt_cdb st_write_cmd = { 6, CMD_WRITE }; -struct buf sttab[NST]; -struct buf stbuf[NST]; - #define UNIT(x) (minor(x) & 3) #define stpunit(x) ((x) & 7) @@ -225,84 +218,18 @@ int st_extti = 0x01; /* bitmask of unit numbers, do extra */ #endif int -stmatch(hd) - register struct hp_device *hd; +stmatch(parent, match, aux) + struct device *parent; + struct cfdata *match; + void *aux; { - register struct st_softc *sc = &st_softc[hd->hp_unit]; - register struct buf *bp; + struct oscsi_attach_args *osa = aux; - for (bp = sttab; bp < &sttab[NST]; bp++) - bp->b_actb = &bp->b_actf; - sc->sc_hd = hd; - sc->sc_punit = stpunit(hd->hp_flags); - sc->sc_type = stident(sc, hd, 0); - if (sc->sc_type < 0) - return (0); - - return (1); -} - -void -stattach(hd) - register struct hp_device *hd; -{ - struct st_softc *sc = &st_softc[hd->hp_unit]; - - (void)stident(sc, hd, 1); /* XXX Ick. */ - - sc->sc_dq.dq_softc = sc; - sc->sc_dq.dq_ctlr = hd->hp_ctlr; - sc->sc_dq.dq_unit = hd->hp_unit; - sc->sc_dq.dq_slave = hd->hp_slave; - sc->sc_dq.dq_driver = &stdriver; - sc->sc_blkno = 0; - sc->sc_flags = STF_ALIVE; - - /* XXX Set device class. */ - hd->hp_dev.dv_class = DV_TAPE; -} - -int -stident(sc, hd, verbose) - register struct st_softc *sc; - register struct hp_device *hd; - int verbose; -{ - int unit; - int ctlr, slave; - int i, stat, inqlen; - char vendor[9], product[17], revision[5]; - static int havest = 0; - struct st_inquiry { - struct scsi_inquiry inqbuf; - struct exb_inquiry exb_inquiry; - } st_inqbuf; - static struct scsi_fmt_cdb st_inq = { - 6, - CMD_INQUIRY, 0, 0, 0, sizeof(st_inqbuf), 0 - }; - - ctlr = hd->hp_ctlr; - slave = hd->hp_slave; - unit = sc->sc_punit; - scsi_delay(-1); - - inqlen = 0x05; /* min */ - st_inq.cdb[4] = 0x05; - stat = scsi_immed_command(ctlr, slave, unit, &st_inq, - (u_char *)&st_inqbuf, inqlen, B_READ); - /* do twice as first command on some scsi tapes always fails */ - stat = scsi_immed_command(ctlr, slave, unit, &st_inq, - (u_char *)&st_inqbuf, inqlen, B_READ); - if (stat == -1) - goto failed; - - if ((st_inqbuf.inqbuf.type != 0x01 || /* sequential access device */ - st_inqbuf.inqbuf.qual != 0x80 || /* removable media */ - (st_inqbuf.inqbuf.version != 0x01 && /* current ANSI SCSI spec */ - st_inqbuf.inqbuf.version != 0x02)) /* 0x02 is for HP DAT */ - && - (st_inqbuf.inqbuf.type != 0x01 || /* M4 ??! */ + if ((osa->osa_inqbuf->type != 0x01 || /* sequential access device */ + osa->osa_inqbuf->qual != 0x80 || /* removable media */ + (osa->osa_inqbuf->version != 0x01 && + osa->osa_inqbuf->version != 0x02)) && + (osa->osa_inqbuf->type != 0x01 || /* M4 ??! */ /* * the M4 is a little too smart (ass?) for its own good: * qual codes: @@ -310,38 +237,48 @@ stident(sc, hd, verbose) * 0xf8: online and at 6250bpi * 0xf9: online and at 1600bpi */ - st_inqbuf.inqbuf.version != 0x09)) /* M4 tape */ -{ -printf("st: wrong specs: type %x qual %x version %d\n", st_inqbuf.inqbuf.type, -st_inqbuf.inqbuf.qual, st_inqbuf.inqbuf.version); - goto failed; + osa->osa_inqbuf->version != 0x09)) /* M4 tape */ + return (0); + + return (1); } - /* now get additonal info */ - inqlen = 0x05 + st_inqbuf.inqbuf.len; - st_inq.cdb[4] = inqlen; - bzero(&st_inqbuf, sizeof(st_inqbuf)); - stat = scsi_immed_command(ctlr, slave, unit, &st_inq, - (u_char *)&st_inqbuf, inqlen, B_READ); +void +stattach(parent, self, aux) + struct device *parent, *self; + void *aux; +{ + struct st_softc *sc = (struct st_softc *)self; + struct oscsi_attach_args *osa = aux; + char vendor[9], product[17], revision[5]; + int stat; + static int havest = 0; + + printf("\n"); + + sc->sc_tab.b_actb = &sc->sc_tab.b_actf; bzero(vendor, sizeof(vendor)); bzero(product, sizeof(product)); bzero(revision, sizeof(revision)); - if (st_inqbuf.inqbuf.len >= 28) { - scsi_str(st_inqbuf.inqbuf.vendor_id, vendor, - sizeof(st_inqbuf.inqbuf.vendor_id)); - scsi_str(st_inqbuf.inqbuf.product_id, product, - sizeof(st_inqbuf.inqbuf.product_id)); - scsi_str(st_inqbuf.inqbuf.rev, revision, - sizeof(st_inqbuf.inqbuf.rev)); - if (verbose) - printf(": <%s, %s, %s>\n", vendor, product, revision); - } - if (stat == 0xff) { - printf("st%d: Can't handle this tape drive\n", hd->hp_unit); - goto failed; - } + scsi_str(osa->osa_inqbuf->vendor_id, vendor, + sizeof(osa->osa_inqbuf->vendor_id)); + scsi_str(osa->osa_inqbuf->product_id, product, + sizeof(osa->osa_inqbuf->product_id)); + scsi_str(osa->osa_inqbuf->rev, revision, + sizeof(osa->osa_inqbuf->rev)); + + sc->sc_target = osa->osa_target; + sc->sc_lun = osa->osa_lun; + + /* Initialize SCSI queue entry. */ + sc->sc_sq.sq_softc = sc; + sc->sc_sq.sq_target = sc->sc_target; + sc->sc_sq.sq_lun = sc->sc_lun; + sc->sc_sq.sq_start = ststart; + sc->sc_sq.sq_go = stgo; + sc->sc_sq.sq_intr = stintr; if (bcmp("EXB-8200", product, 8) == 0) { sc->sc_tapeid = MT_ISEXABYTE; @@ -365,7 +302,8 @@ st_inqbuf.inqbuf.qual, st_inqbuf.inqbuf.version); sc->sc_datalen[CMD_MODE_SENSE] = 12; } else if (bcmp("HP35450A", product, 8) == 0) { /* XXX "extra" stat makes the HP drive happy at boot time */ - stat = scsi_test_unit_rdy(ctlr, slave, unit); + stat = scsi_test_unit_rdy(sc->sc_dev.dv_parent->dv_unit, + sc->sc_target, sc->sc_lun); sc->sc_tapeid = MT_ISHPDAT; sc->sc_datalen[CMD_REQUEST_SENSE] = 14; sc->sc_datalen[CMD_INQUIRY] = 36; @@ -379,9 +317,8 @@ st_inqbuf.inqbuf.qual, st_inqbuf.inqbuf.version); sc->sc_datalen[CMD_MODE_SELECT] = 12; sc->sc_datalen[CMD_MODE_SENSE] = 12; } else { - if (verbose) - printf("%s: Unsupported tape device, faking it\n", - sc->sc_hd->hp_xname); + printf("%s: Unsupported tape device, faking it\n", + sc->sc_dev.dv_xname); sc->sc_tapeid = MT_ISAR; sc->sc_datalen[CMD_REQUEST_SENSE] = 8; sc->sc_datalen[CMD_INQUIRY] = 5; @@ -392,18 +329,18 @@ st_inqbuf.inqbuf.qual, st_inqbuf.inqbuf.version); sc->sc_filepos = 0; /* load xsense */ - stxsense(ctlr, slave, unit, sc); - + scsi_delay(-1); + stxsense(sc->sc_dev.dv_parent->dv_unit, sc->sc_target, sc->sc_lun, sc); scsi_delay(0); + /* XXX if we have a tape, we must up the delays in the HA driver */ if (!havest) { havest = 1; scsi_delay(20000); } - return(st_inqbuf.inqbuf.type); -failed: - scsi_delay(0); - return(-1); + + sc->sc_blkno = 0; + sc->sc_flags = STF_ALIVE; } stopen(dev, flag, type, p) @@ -411,7 +348,7 @@ stopen(dev, flag, type, p) int flag, type; struct proc *p; { - register struct st_softc *sc = &st_softc[UNIT(dev)]; + register struct st_softc *sc; register struct st_xsense *xsense; register int count; register int stat; @@ -429,15 +366,18 @@ stopen(dev, flag, type, p) CMD_MODE_SENSE, 0, 0, 0, sizeof(mode), 0 }; - ctlr = sc->sc_dq.dq_ctlr; - slave = sc->sc_dq.dq_slave; - unit = sc->sc_punit; - xsense = &st_xsense[UNIT(dev)]; + if (UNIT(dev) > st_cd.cd_ndevs || + (sc = st_cd.cd_devs[UNIT(dev)]) == NULL || + (sc->sc_flags & STF_ALIVE) == 0) + return (ENXIO); - if (UNIT(dev) > NST || (sc->sc_flags & STF_ALIVE) == 0) - return(ENXIO); if (sc->sc_flags & STF_OPEN) - return(EBUSY); + return (EBUSY); + + ctlr = sc->sc_dev.dv_parent->dv_unit; + slave = sc->sc_target; + unit = sc->sc_lun; + xsense = &sc->sc_sense; /* * Be prepared to print error messages @@ -568,7 +508,7 @@ retryselect: #endif if (stat == STS_CHECKCOND) { stxsense(ctlr, slave, unit, sc); - prtkey(UNIT(dev), sc); + prtkey(sc); } if (stat) return(EIO); @@ -612,7 +552,7 @@ retryselect: xsense->exb_xsense.tnp) uprintf("cartridge unloading\n"); else - prtkey(UNIT(dev), sc); + prtkey(sc); break; case MT_ISMFOUR: case MT_ISAR: @@ -621,7 +561,7 @@ retryselect: if (stat == STS_CHECKCOND) { stxsense(ctlr, slave, unit, sc); if (xsense->sc_xsense.key) - prtkey(UNIT(dev), sc); + prtkey(sc); } else { sc->sc_filepos = 0; /* new tape */ stat = 0; @@ -635,12 +575,12 @@ retryselect: if (stat == STS_CHECKCOND) { stxsense(ctlr, slave, unit, sc); if (xsense->sc_xsense.key) - prtkey(UNIT(dev), sc); + prtkey(sc); } break; default: - uprintf("%s: not ready\n", sc->sc_hd->hp_xname); - prtkey(UNIT(dev), sc); + uprintf("%s: not ready\n", sc->sc_dev.dv_xname); + prtkey(sc); break; } } @@ -681,7 +621,7 @@ retryselect: sc->sc_filepos = 0; #ifdef DEBUG if (st_debug & ST_FMKS) - printf("%s: open filepos = %d\n", sc->sc_hd->hp_xname, + printf("%s: open filepos = %d\n", sc->sc_dev.dv_xname, sc->sc_filepos); #endif @@ -704,7 +644,7 @@ stclose(dev, flag) dev_t dev; int flag; { - register struct st_softc *sc = &st_softc[UNIT(dev)]; + struct st_softc *sc = st_cd.cd_devs[UNIT(dev)]; register int hit = 0; if ((sc->sc_flags & (STF_WMODE|STF_WRTTN)) == (STF_WMODE|STF_WRTTN)) { @@ -730,7 +670,7 @@ stclose(dev, flag) stcommand(dev, MTFSR, 0); #endif /* make stats available */ - stxsense(sc->sc_dq.dq_ctlr, sc->sc_dq.dq_slave, sc->sc_punit, sc); + stxsense(sc->sc_dev.dv_parent->dv_unit, sc->sc_target, sc->sc_lun, sc); sc->sc_flags &= ~(STF_OPEN|STF_WMODE|STF_WRTTN); tprintf_close(sc->sc_ctty); @@ -741,11 +681,14 @@ void ststrategy(bp) register struct buf *bp; { + struct st_softc *sc; struct buf *dp; int unit, s; unit = UNIT(bp->b_dev); - dp = &sttab[unit]; + sc = st_cd.cd_devs[unit]; + + dp = &sc->sc_tab; bp->b_actf = NULL; s = splbio(); bp->b_actb = dp->b_actb; @@ -758,34 +701,38 @@ ststrategy(bp) splx(s); } +void stustart(unit) int unit; { - if (scsireq(&st_softc[unit].sc_dq)) - ststart(unit); + struct st_softc *sc = st_cd.cd_devs[unit]; + + if (scsireq(sc->sc_dev.dv_parent, &sc->sc_sq)) + ststart(sc); } -ststart(unit) - int unit; +void +ststart(arg) + void *arg; { - struct hp_device *hp = st_softc[unit].sc_hd; + struct st_softc *sc = arg; - if (scsiustart(hp->hp_ctlr)) - stgo(unit); + if (scsiustart(sc->sc_dev.dv_parent->dv_unit)) + stgo(arg); } -stgo(unit) - int unit; +void +stgo(arg) + void *arg; { - register struct st_softc *sc = &st_softc[unit]; + struct st_softc *sc = arg; register struct scsi_fmt_cdb *cmd; - register struct buf *bp = sttab[unit].b_actf; - struct hp_device *hp = sc->sc_hd; + register struct buf *bp = sc->sc_tab.b_actf; int pad, stat; long nblks; if (sc->sc_flags & STF_CMD) { - cmd = &stcmd[unit]; + cmd = &sc->sc_cmdstore; pad = 0; } else { cmd = bp->b_flags & B_READ ? &st_read_cmd : &st_write_cmd; @@ -803,7 +750,7 @@ stgo(unit) if (bp->b_bcount % sc->sc_blklen) { tprintf(sc->sc_ctty, "%s: I/O not block aligned %d/%ld\n", - sc->sc_hd->hp_xname, sc->sc_blklen, + sc->sc_dev.dv_xname, sc->sc_blklen, bp->b_bcount); cmd->cdb[1] &= 0xfe; /* force error */ } @@ -834,47 +781,46 @@ stgo(unit) #ifdef DEBUG if (st_debug & ST_ODDIO) printf("%s: stgo: odd count %d using manual transfer\n", - sc->sc_hd->hp_xname, bp->b_bcount); + sc->sc_dev.dv_xname, bp->b_bcount); #endif - stat = scsi_tt_oddio(hp->hp_ctlr, hp->hp_slave, sc->sc_punit, - bp->b_un.b_addr, bp->b_bcount, - bp->b_flags, 1); + stat = scsi_tt_oddio(sc->sc_dev.dv_parent->dv_unit, + sc->sc_target, sc->sc_lun, bp->b_un.b_addr, bp->b_bcount, + bp->b_flags, 1); if (stat == 0) { bp->b_resid = 0; - stfinish(unit, sc, bp); + stfinish(sc, bp); } } else - stat = scsigo(hp->hp_ctlr, hp->hp_slave, sc->sc_punit, - bp, cmd, pad); + stat = scsigo(sc->sc_dev.dv_parent->dv_unit, + sc->sc_target, sc->sc_lun, bp, cmd, pad); if (stat) { bp->b_error = EIO; bp->b_flags |= B_ERROR; - stxsense(sc->sc_dq.dq_ctlr, sc->sc_dq.dq_slave, - sc->sc_punit, sc); - sterror(unit, sc, stat); - stfinish(unit, sc, bp); + stxsense(sc->sc_dev.dv_parent->dv_unit, sc->sc_target, + sc->sc_lun, sc); + sterror(sc, stat); + stfinish(sc, bp); } } -stfinish(unit, sc, bp) - int unit; +stfinish(sc, bp) struct st_softc *sc; struct buf *bp; { register struct buf *dp; - sttab[unit].b_errcnt = 0; + sc->sc_tab.b_errcnt = 0; if (dp = bp->b_actf) dp->b_actb = bp->b_actb; else - sttab[unit].b_actb = bp->b_actb; + sc->sc_tab.b_actb = bp->b_actb; *bp->b_actb = dp; iodone(bp); - scsifree(&sc->sc_dq); - if (sttab[unit].b_actf) - stustart(unit); + scsifree(sc->sc_dev.dv_parent, &sc->sc_sq); + if (sc->sc_tab.b_actf) + stustart(sc->sc_dev.dv_unit); else - sttab[unit].b_active = 0; + sc->sc_tab.b_active = 0; } int @@ -913,10 +859,10 @@ stioctl(dev, cmd, data, flag, p) int flag; struct proc *p; { - register struct st_softc *sc = &st_softc[UNIT(dev)]; + struct st_softc *sc = st_cd.cd_devs[UNIT(dev)]; register int cnt; register struct mtget *mtget; - register struct st_xsense *xp = &st_xsense[UNIT(dev)]; + register struct st_xsense *xp = &sc->sc_sense; register struct mtop *op; long resid; @@ -955,8 +901,8 @@ stioctl(dev, cmd, data, flag, p) /* drive status */ case MTIOCGET: mtget = (struct mtget *)data; - stxsense(sc->sc_dq.dq_ctlr, sc->sc_dq.dq_slave, - sc->sc_punit, sc); + stxsense(sc->sc_dev.dv_parent->dv_unit, sc->sc_target, + sc->sc_lun, sc); mtget->mt_type = sc->sc_tapeid; mtget->mt_dsreg = 0; mtget->mt_erreg = ((xp->sc_xsense.valid << 15) | @@ -993,19 +939,19 @@ stioctl(dev, cmd, data, flag, p) return(0); } +void stintr(arg, stat) void *arg; int stat; { register struct st_softc *sc = arg; - int unit = sc->sc_hd->hp_unit; - register struct st_xsense *xp = &st_xsense[unit]; - register struct buf *bp = sttab[unit].b_actf; - struct hp_device *hp = sc->sc_hd; + int unit = sc->sc_dev.dv_unit; + register struct st_xsense *xp = &sc->sc_sense; + register struct buf *bp = sc->sc_tab.b_actf; #ifdef DEBUG if (bp == NULL) { - printf("%s: bp == NULL\n", sc->sc_hd->hp_xname); + printf("%s: bp == NULL\n", sc->sc_dev.dv_xname); return; } #endif @@ -1017,8 +963,8 @@ stintr(arg, stat) /* more status */ case STS_CHECKCOND: - stxsense(sc->sc_dq.dq_ctlr, sc->sc_dq.dq_slave, - sc->sc_punit, sc); + stxsense(sc->sc_dev.dv_parent->dv_unit, sc->sc_target, + sc->sc_lun, sc); if (xp->sc_xsense.valid) { bp->b_resid = (u_long)((xp->sc_xsense.info1 << 24) | (xp->sc_xsense.info2 << 16) | @@ -1035,7 +981,7 @@ stintr(arg, stat) && xp->sc_xsense.key != XSK_NOTUSED1 && xp->sc_xsense.key != XSK_NOTUSEDC && xp->sc_xsense.key != XSK_NOTUSEDE) { - sterror(unit, sc, stat); + sterror(sc, stat); bp->b_flags |= B_ERROR; bp->b_error = EIO; break; @@ -1047,7 +993,7 @@ stintr(arg, stat) if (sc->sc_blklen) { tprintf(sc->sc_ctty, "%s: Incorrect Length Indicator, blkcnt diff %d\n", - sc->sc_hd->hp_xname, + sc->sc_dev.dv_xname, sc->sc_blklen - bp->b_resid); bp->b_flags |= B_ERROR; bp->b_error = EIO; @@ -1074,7 +1020,7 @@ stintr(arg, stat) if (!st_dmaoddretry) { tprintf(sc->sc_ctty, "%s: Odd length read %d\n", - sc->sc_hd->hp_xname, + sc->sc_dev.dv_xname, bp->b_bcount - bp->b_resid); bp->b_error = EIO; bp->b_flags |= B_ERROR; @@ -1086,24 +1032,25 @@ stintr(arg, stat) #ifdef DEBUG if (st_debug & ST_ODDIO) printf("%s: stintr odd count %d, do BSR then oddio\n", - sc->sc_hd->hp_xname, + sc->sc_dev.dv_xname, bp->b_bcount - bp->b_resid); #endif - stat = scsi_tt_oddio(hp->hp_ctlr, hp->hp_slave, - sc->sc_punit, 0, -1, 0, 0); + stat = + scsi_tt_oddio(sc->sc_dev.dv_parent->dv_unit, + sc->sc_target, sc->sc_lun, 0, -1, 0, 0); if (stat == 0) - stat = scsi_tt_oddio(hp->hp_ctlr, - hp->hp_slave, - sc->sc_punit, - bp->b_un.b_addr, - bp->b_bcount - bp->b_resid, - bp->b_flags, 0); + stat = scsi_tt_oddio( + sc->sc_dev.dv_parent->dv_unit, + sc->sc_target, sc->sc_lun, + bp->b_un.b_addr, + bp->b_bcount - bp->b_resid, + bp->b_flags, 0); if (stat) { bp->b_error = EIO; bp->b_flags |= B_ERROR; - stxsense(sc->sc_dq.dq_ctlr, sc->sc_dq.dq_slave, - sc->sc_punit, sc); - sterror(unit, sc, stat); + stxsense(sc->sc_dev.dv_parent->dv_unit, + sc->sc_target, sc->sc_lun, sc); + sterror(sc, stat); } } break; @@ -1114,13 +1061,13 @@ stintr(arg, stat) break; } tprintf(sc->sc_ctty, "%s: unknown scsi error\n", - sc->sc_hd->hp_xname); + sc->sc_dev.dv_xname); bp->b_flags |= B_ERROR; bp->b_error = EIO; break; default: - printf("%s: stintr unknown stat 0x%x\n", sc->sc_hd->hp_xname, + printf("%s: stintr unknown stat 0x%x\n", sc->sc_dev.dv_xname, stat); break; } @@ -1146,8 +1093,8 @@ stintr(arg, stat) * Mostly for TTi we, get a stxsense call in open and close. */ if (sc->sc_tticntdwn-- == 0) { - stxsense(sc->sc_dq.dq_ctlr, sc->sc_dq.dq_slave, - sc->sc_punit, sc); + stxsense(sc->sc_dev.dv_parent->dv_unit, + sc->sc_target, sc->sc_lun, sc); sc->sc_tticntdwn = 100; } #endif @@ -1160,14 +1107,14 @@ stcommand(dev, command, cnt) u_int command; int cnt; { - register struct st_softc *sc = &st_softc[UNIT(dev)]; - register struct buf *bp = &stbuf[UNIT(dev)]; - register struct scsi_fmt_cdb *cmd = &stcmd[UNIT(dev)]; + struct st_softc *sc = st_cd.cd_devs[UNIT(dev)]; + register struct buf *bp = &sc->sc_bufstore; + register struct scsi_fmt_cdb *cmd = &sc->sc_cmdstore; register cmdcnt; int s; cmd->len = 6; /* all tape commands are cdb6 */ - cmd->cdb[1] = sc->sc_punit; + cmd->cdb[1] = sc->sc_lun; cmd->cdb[2] = cmd->cdb[3] = cmd->cdb[4] = cmd->cdb[5] = 0; cmdcnt = 0; @@ -1234,7 +1181,7 @@ stcommand(dev, command, cnt) break; default: printf("%s: stcommand bad command 0x%x\n", - sc->sc_hd->hp_xname, command); + sc->sc_dev.dv_xname, command); } sc->sc_flags |= STF_CMD; @@ -1245,7 +1192,7 @@ again: #ifdef DEBUG if (st_debug & ST_FMKS) printf("%s: stcommand filepos %d cmdcnt %d cnt %d\n", - sc->sc_hd->hp_xname, sc->sc_filepos, cmdcnt, cnt); + sc->sc_dev.dv_xname, sc->sc_filepos, cmdcnt, cnt); #endif s = splbio(); while (bp->b_flags & B_BUSY) { @@ -1277,16 +1224,16 @@ again: sc->sc_flags &= ~(STF_CMD|STF_WRTTN); } -sterror(unit, sc, stat) - int unit, stat; +sterror(sc, stat) struct st_softc *sc; + int stat; { /* stxsense must have been called before sterror() */ if (stat & STS_CHECKCOND) - prtkey(unit, sc); + prtkey(sc); else if (stat) tprintf(sc->sc_ctty, - "%s: bad scsi status 0x%x\n", sc->sc_hd->hp_xname, + "%s: bad scsi status 0x%x\n", sc->sc_dev.dv_xname, stat); if ((sc->sc_flags & STF_CMD) && sc->sc_cmd == CMD_SPACE) /* fsf */ @@ -1300,16 +1247,15 @@ stxsense(ctlr, slave, unit, sc) u_char *sensebuf; unsigned len; - sensebuf = (u_char *)&st_xsense[sc->sc_dq.dq_unit]; + sensebuf = (u_char *)&sc->sc_sense; len = sc->sc_datalen[CMD_REQUEST_SENSE]; scsi_request_sense(ctlr, slave, unit, sensebuf, len); } -prtkey(unit, sc) - int unit; +prtkey(sc) struct st_softc *sc; { - register struct st_xsense *xp = &st_xsense[unit]; + register struct st_xsense *xp = &sc->sc_sense; switch (xp->sc_xsense.key) { case XSK_NOSENCE: @@ -1320,35 +1266,35 @@ prtkey(unit, sc) break; case XSK_REVERVED: tprintf(sc->sc_ctty, "%s: Reserved sense key 0x%x\n", - sc->sc_hd->hp_xname, xp->sc_xsense.key); + sc->sc_dev.dv_xname, xp->sc_xsense.key); break; case XSK_NOTRDY: - tprintf(sc->sc_ctty, "%s: NOT READY\n", sc->sc_hd->hp_xname); + tprintf(sc->sc_ctty, "%s: NOT READY\n", sc->sc_dev.dv_xname); break; case XSK_MEDERR: - tprintf(sc->sc_ctty, "%s: MEDIUM ERROR\n", sc->sc_hd->hp_xname); + tprintf(sc->sc_ctty, "%s: MEDIUM ERROR\n", sc->sc_dev.dv_xname); break; case XSK_HRDWERR: tprintf(sc->sc_ctty, "%s: HARDWARE ERROR\n", - sc->sc_hd->hp_xname); + sc->sc_dev.dv_xname); break; case XSK_ILLREQ: tprintf(sc->sc_ctty, "%s: ILLEGAL REQUEST\n", - sc->sc_hd->hp_xname); + sc->sc_dev.dv_xname); break; case XSK_UNTATTEN: tprintf(sc->sc_ctty, "%s: UNIT ATTENTION\n", - sc->sc_hd->hp_xname); + sc->sc_dev.dv_xname); break; case XSK_DATAPROT: - tprintf(sc->sc_ctty, "%s: DATA PROTECT\n", sc->sc_hd->hp_xname); + tprintf(sc->sc_ctty, "%s: DATA PROTECT\n", sc->sc_dev.dv_xname); break; case XSK_BLNKCHK: - tprintf(sc->sc_ctty, "%s: BLANK CHECK\n", sc->sc_hd->hp_xname); + tprintf(sc->sc_ctty, "%s: BLANK CHECK\n", sc->sc_dev.dv_xname); break; case XSK_VENDOR: tprintf(sc->sc_ctty, "%s: VENDER UNIQUE SENSE KEY ", - sc->sc_hd->hp_xname); + sc->sc_dev.dv_xname); switch (sc->sc_tapeid) { case MT_ISEXABYTE: tprintf(sc->sc_ctty, "Exabyte: "); @@ -1364,58 +1310,58 @@ prtkey(unit, sc) } break; case XSK_CPYABORT: - tprintf(sc->sc_ctty, "%s: COPY ABORTED\n", sc->sc_hd->hp_xname); + tprintf(sc->sc_ctty, "%s: COPY ABORTED\n", sc->sc_dev.dv_xname); break; case XSK_ABORTCMD: tprintf(sc->sc_ctty, "%s: ABORTED COMMAND\n", - sc->sc_hd->hp_xname); + sc->sc_dev.dv_xname); break; case XSK_VOLOVER: tprintf(sc->sc_ctty, "%s: VOLUME OVERFLOW\n", - sc->sc_hd->hp_xname); + sc->sc_dev.dv_xname); break; default: tprintf(sc->sc_ctty, "%s: unknown sense key 0x%x\n", - sc->sc_hd->hp_xname, xp->sc_xsense.key); + sc->sc_dev.dv_xname, xp->sc_xsense.key); } if (sc->sc_tapeid == MT_ISEXABYTE) { if (xp->exb_xsense.bpe) tprintf(sc->sc_ctty, "%s: Bus Parity Error", - sc->sc_hd->hp_xname); + sc->sc_dev.dv_xname); if (xp->exb_xsense.fpe) tprintf(sc->sc_ctty, "%s: Formatted Buffer Parity Error", - sc->sc_hd->hp_xname); + sc->sc_dev.dv_xname); if (xp->exb_xsense.eco) tprintf(sc->sc_ctty, "%s: Error Counter Overflow", - sc->sc_hd->hp_xname); + sc->sc_dev.dv_xname); if (xp->exb_xsense.tme) tprintf(sc->sc_ctty, "%s: Tape Motion Error", - sc->sc_hd->hp_xname); + sc->sc_dev.dv_xname); if (xp->exb_xsense.xfr) tprintf(sc->sc_ctty, "%s: Transfer About Error", - sc->sc_hd->hp_xname); + sc->sc_dev.dv_xname); if (xp->exb_xsense.tmd) tprintf(sc->sc_ctty, "%s: Tape Mark Detect Error", - sc->sc_hd->hp_xname); + sc->sc_dev.dv_xname); if (xp->exb_xsense.fmke) tprintf(sc->sc_ctty, "%s: Filemark Error", - sc->sc_hd->hp_xname); + sc->sc_dev.dv_xname); if (xp->exb_xsense.ure) tprintf(sc->sc_ctty, "%s: Under Run Error", - sc->sc_hd->hp_xname); + sc->sc_dev.dv_xname); if (xp->exb_xsense.sse) tprintf(sc->sc_ctty, "%s: Servo System Error", - sc->sc_hd->hp_xname); + sc->sc_dev.dv_xname); if (xp->exb_xsense.fe) tprintf(sc->sc_ctty, "%s: Formatter Error", - sc->sc_hd->hp_xname); + sc->sc_dev.dv_xname); if (xp->exb_xsense.wseb) tprintf(sc->sc_ctty, "%s: WSEB Error", - sc->sc_hd->hp_xname); + sc->sc_dev.dv_xname); if (xp->exb_xsense.wseo) tprintf(sc->sc_ctty, "%s: WSEO Error", - sc->sc_hd->hp_xname); + sc->sc_dev.dv_xname); } } @@ -1494,5 +1440,3 @@ prtmodstat(mode) mode->ex.motionthres, mode->ex.reconthres, mode->ex.gapthres); } #endif /* DEBUG */ - -#endif