From fb974f8ed94734f43dfc82e27445b482593a491d Mon Sep 17 00:00:00 2001 From: sos Date: Wed, 3 Mar 1999 21:10:29 +0000 Subject: Added driver to support ATAPI floppies ie LS-120 & ZIP drives. Added "options ATA_STATIC_ID" that wires ATA disks like the old wd driver. Fixed problems: Dont use more sectors/intr than the drive supports. Fix announce of > 8.4G disks. Dont call ad_interrupt/ad_transfer when no disks config'd. Use the right page# for CDR write mode params. Fix breakage when no PCI support in kernel. Implement DEVFS stuff. General code clenaup. --- sys/dev/ata/ata-all.c | 99 +++++------ sys/dev/ata/ata-all.h | 11 +- sys/dev/ata/ata-disk.c | 68 +++++--- sys/dev/ata/ata-disk.h | 14 +- sys/dev/ata/atapi-all.c | 10 +- sys/dev/ata/atapi-all.h | 16 +- sys/dev/ata/atapi-cd.c | 366 +++++++++++++++++++-------------------- sys/dev/ata/atapi-cd.h | 266 ++++++++++++++--------------- sys/dev/ata/atapi-fd.c | 434 +++++++++++++++++++++++++++++++++++++++++++++++ sys/dev/ata/atapi-fd.h | 90 ++++++++++ sys/dev/ata/atapi-tape.c | 250 +++++++++++++-------------- sys/dev/ata/atapi-tape.h | 147 +++++++++------- 12 files changed, 1159 insertions(+), 612 deletions(-) create mode 100644 sys/dev/ata/atapi-fd.c create mode 100644 sys/dev/ata/atapi-fd.h (limited to 'sys/dev') diff --git a/sys/dev/ata/ata-all.c b/sys/dev/ata/ata-all.c index 50a82b2..d493ab6 100644 --- a/sys/dev/ata/ata-all.c +++ b/sys/dev/ata/ata-all.c @@ -25,12 +25,14 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * - * $Id: ata-all.c,v 1.4 1999/03/01 21:03:15 sos Exp sos $ + * $Id: ata-all.c,v 1.1 1999/03/01 21:19:18 sos Exp $ */ #include "ata.h" #if NATA > 0 +#include "isa.h" #include "pci.h" +#include "atadisk.h" #include #include #include @@ -53,24 +55,28 @@ #define UNIT(dev) (dev>>3 & 0x1f) /* assume 8 minor # per unit */ /* prototypes */ -void ataintr(int32_t); +#if NISA > 0 static int32_t ata_isaprobe(struct isa_device *); static int32_t ata_isaattach(struct isa_device *); +#endif +#if NPCI > 0 static const char *ata_pciprobe(pcici_t, pcidi_t); static void ata_pciattach(pcici_t, int32_t); +static void promise_intr(int32_t); +#endif static int32_t ata_probe(int32_t, int32_t, int32_t *); static int32_t ata_attach(int32_t); -static void promise_intr(int32_t); -static int32_t ata_reset(struct ata_softc *); +static void ataintr(int32_t); static int32_t ata_device_attach(struct ata_softc *, int32_t); static int32_t atapi_device_attach(struct ata_softc *, int32_t); static void bswap(int8_t *, int32_t); static void btrim(int8_t *, int32_t); -static int32_t atanlun, sysctrl = 0; +static int32_t atanlun = 0, sysctrl = 0; struct ata_softc *atadevices[MAXATA]; struct isa_driver atadriver = { ata_isaprobe, ata_isaattach, "ata" }; +#if NISA > 0 static int32_t ata_isaprobe(struct isa_device *devp) { @@ -85,7 +91,7 @@ ata_isaprobe(struct isa_device *devp) } res=ata_probe(devp->id_iobase, devp->id_iobase+ATA_ALTPORT, &devp->id_unit); if (res) - devp->id_intr = ataintr; + devp->id_intr = (inthand2_t *)ataintr; return res; } @@ -94,7 +100,9 @@ ata_isaattach(struct isa_device *devp) { return ata_attach(devp->id_unit); } +#endif +#if NPCI > 0 static u_long ata_pcicount; static struct pci_device ata_pcidevice = { "ata-pci", ata_pciprobe, ata_pciattach, &ata_pcicount, 0 @@ -127,7 +135,7 @@ ata_pciprobe(pcici_t tag, pcidi_t type) case 0x522910b9: return "Acer Aladdin IV/V IDE controller"; default: - return ("Unknown PCI IDE controller"); + return "Unknown PCI IDE controller"; } } return NULL; @@ -208,9 +216,10 @@ ata_pciattach(pcici_t tag, int32_t unit) register_intr(irq1, 0, 0, (inthand2_t *)ataintr, &bio_imask, lun); else { if (sysctrl) - pci_map_int(tag, promise_intr, (void *)lun, &bio_imask); + pci_map_int(tag, (inthand2_t *)promise_intr, + (void *)lun, &bio_imask); else - pci_map_int(tag, ataintr, (void *)lun, &bio_imask); + pci_map_int(tag, (inthand2_t *)ataintr, (void *)lun,&bio_imask); } printf("ata%d at 0x%04x irq %d on ata-pci%d\n", lun, iobase_1, irq1, unit); @@ -221,7 +230,7 @@ ata_pciattach(pcici_t tag, int32_t unit) register_intr(irq2, 0, 0, (inthand2_t *)ataintr, &bio_imask, lun); else { if (!sysctrl) - pci_map_int(tag, ataintr, (void *) lun, &bio_imask); + pci_map_int(tag, (inthand2_t *)ataintr, (void *)lun,&bio_imask); } printf("ata%d at 0x%04x irq %d on ata-pci%d\n", lun, iobase_2, irq2, unit); @@ -237,37 +246,42 @@ promise_intr(int32_t unit) if (inl(sysctrl) & 0x00004000) ataintr(unit+1); } +#endif static int32_t ata_probe(int32_t ioaddr, int32_t altioaddr, int32_t *unit) { struct ata_softc *scp = atadevices[atanlun]; - u_int8_t status0, status1; int32_t mask = 0; int32_t timeout; + int32_t lun = atanlun; + u_int8_t status0, status1; - if (atanlun > MAXATA) { - printf("ata: unit of of range(%d)\n", atanlun); - return(0); +#ifdef ATA_STATIC_ID + atanlun++; +#endif + if (lun > MAXATA) { + printf("ata: unit of of range(%d)\n", lun); + return 0; } if (scp) { - printf("ata%d: unit already attached\n", atanlun); - return(0); + printf("ata%d: unit already attached\n", lun); + return 0; } scp = malloc(sizeof(struct ata_softc), M_DEVBUF, M_NOWAIT); if (scp == NULL) { - printf("ata%d: failed to allocate driver storage\n", atanlun); - return(0); + printf("ata%d: failed to allocate driver storage\n", lun); + return 0; } bzero(scp, sizeof(struct ata_softc)); - scp->unit = atanlun; + scp->unit = lun; scp->ioaddr = ioaddr; scp->altioaddr = altioaddr; #ifdef ATA_DEBUG printf("ata%d: iobase=0x%04x altiobase=0x%04x\n", - atanlun, scp->ioaddr, scp->altioaddr); + scp->unit, scp->ioaddr, scp->altioaddr); #endif /* do we have any signs of ATA/ATAPI HW being present ? */ @@ -283,7 +297,7 @@ ata_probe(int32_t ioaddr, int32_t altioaddr, int32_t *unit) mask |= 0x02; #ifdef ATA_DEBUG printf("ata%d: mask=%02x status0=%02x status1=%02x\n", - atanlun, mask, status0, status1); + scp->unit, mask, status0, status1); #endif if (!mask) { free(scp, M_DEVBUF); @@ -325,7 +339,7 @@ ata_probe(int32_t ioaddr, int32_t altioaddr, int32_t *unit) mask &= ~0x02; #ifdef ATA_DEBUG printf("ata%d: mask=%02x status0=%02x status1=%02x\n", - atanlun, mask, status0, status1); + scp->unit, mask, status0, status1); #endif if (!mask) { free(scp, M_DEVBUF); @@ -370,7 +384,7 @@ ata_probe(int32_t ioaddr, int32_t altioaddr, int32_t *unit) } } #ifdef ATA_DEBUG - printf("ata%d: devices = 0x%x\n", atanlun, scp->devices); + printf("ata%d: devices = 0x%x\n", scp->unit, scp->devices); #endif if (!(scp->devices & (ATA_ATA_MASTER|ATA_ATAPI_MASTER))) scp->flags |= ATA_F_SLAVE_ONLY; @@ -380,8 +394,11 @@ ata_probe(int32_t ioaddr, int32_t altioaddr, int32_t *unit) } bufq_init(&scp->ata_queue); TAILQ_INIT(&scp->atapi_queue); - *unit = atanlun; - atadevices[atanlun++] = scp; + *unit = scp->unit; + atadevices[scp->unit] = scp; +#ifndef ATA_STATIC_ID + atanlun++; +#endif return ATA_IOSIZE; } @@ -410,7 +427,7 @@ ata_attach(int32_t unit) return scp->devices; } -void +static void ataintr(int32_t unit) { struct ata_softc *scp; @@ -431,16 +448,12 @@ ataintr(int32_t unit) /* find & call the responsible driver to process this interrupt */ switch (scp->active) { - case ATA_IDLE: - if (intcount++ < 5) - printf("ata%d: unwanted interrupt\n", unit); - break; - +#if NATADISK > 0 case ATA_ACTIVE_ATA: if ((ata_request = bufq_first(&scp->ata_queue))) ad_interrupt(ata_request); break; - +#endif case ATA_ACTIVE_ATAPI: if ((atapi_request = TAILQ_FIRST(&scp->atapi_queue))) atapi_interrupt(atapi_request); @@ -449,6 +462,12 @@ ataintr(int32_t unit) case ATA_IGNORE_INTR: scp->active = ATA_IDLE; break; + + default: + case ATA_IDLE: + if (intcount++ < 5) + printf("ata%d: unwanted interrupt\n", unit); + break; } } @@ -509,22 +528,6 @@ ata_wait(struct ata_softc *scp, u_int8_t mask) } static int32_t -ata_reset(struct ata_softc *scp) -{ - outb(scp->altioaddr, ATA_A_RESET | ATA_A_IDS); - DELAY(10000); - outb(scp->altioaddr, ATA_A_IDS); - DELAY(10000); - inb(scp->ioaddr + ATA_ERROR); - outb(scp->altioaddr, ATA_A_4BIT); - if (ata_wait(scp, 0) < 0) { - printf("ata%d: RESET failed\n", scp->unit); - return 1; - } - return 0; -} - -static int32_t ata_device_attach(struct ata_softc *scp, int32_t device) { struct ata_params *ata_parm; diff --git a/sys/dev/ata/ata-all.h b/sys/dev/ata/ata-all.h index df6791d..a63b4b32 100644 --- a/sys/dev/ata/ata-all.h +++ b/sys/dev/ata/ata-all.h @@ -25,11 +25,10 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * - * $Id: ata-all.h,v 1.3 1999/03/01 21:03:15 sos Exp sos $ + * $Id: ata-all.h,v 1.1 1999/03/01 21:19:18 sos Exp $ */ /* ATA register defines */ - #define ATA_DATA 0x00 /* data register */ #define ATA_ERROR 0x01 /* (R) error register */ #define ATA_PRECOMP 0x01 /* (W) precompensation */ @@ -153,9 +152,7 @@ struct ata_params { int16_t securelevel; }; -/* - * Structure describing an ATA device - */ +/* Structure describing an ATA device */ struct ata_softc { u_int32_t unit; /* this instance's number */ u_int32_t ioaddr; /* port addr */ @@ -178,10 +175,6 @@ struct ata_softc { struct ata_params *ata_parm[2]; /* ata device params */ TAILQ_HEAD(, atapi_request) atapi_queue; /* head of ATAPI queue */ struct atapi_params *atapi_parm[2]; /* atapi device params */ - -#ifdef DEVFS - static void *devfs_token; -#endif }; struct ata_request { diff --git a/sys/dev/ata/ata-disk.c b/sys/dev/ata/ata-disk.c index bfbf877..cf1551e 100644 --- a/sys/dev/ata/ata-disk.c +++ b/sys/dev/ata/ata-disk.c @@ -25,7 +25,7 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * - * $Id: ata-disk.c,v 1.14 1999/03/01 21:03:15 sos Exp sos $ + * $Id: ata-disk.c,v 1.1 1999/03/01 21:19:18 sos Exp $ */ #include "ata.h" @@ -58,8 +58,8 @@ static d_open_t adopen; static d_close_t adclose; -static d_write_t adwrite; static d_read_t adread; +static d_write_t adwrite; static d_ioctl_t adioctl; static d_strategy_t adstrategy; static d_psize_t adpsize; @@ -95,7 +95,7 @@ static void ad_attach(void *notused) { struct ad_softc *adp; - int32_t ctlr, dev; + int32_t ctlr, dev, secsperint; int8_t model_buf[40+1]; int8_t revision_buf[8+1]; @@ -103,6 +103,9 @@ ad_attach(void *notused) for (ctlr=0; ctlrata_parm[dev]) { +#ifdef ATA_STATIC_ID + adnlun = dev + ctlr * 2; +#endif adp = adtab[adnlun]; if (adp) printf("ad%d: unit already attached\n", adnlun); @@ -113,20 +116,23 @@ ad_attach(void *notused) adp->controller = atadevices[ctlr]; adp->ata_parm = atadevices[ctlr]->ata_parm[dev]; adp->unit = (dev == 0) ? ATA_MASTER : ATA_SLAVE; + adp->lun = adnlun; adp->cylinders = adp->ata_parm->cylinders; adp->heads = adp->ata_parm->heads; adp->sectors = adp->ata_parm->sectors; adp->total_secs = adp->ata_parm->lbasize; + if (!adp->total_secs) + adp->total_secs = adp->cylinders*adp->heads*adp->sectors; + if (adp->cylinders == 16383) + adp->cylinders = adp->total_secs/(adp->heads*adp->sectors); /* support multiple sectors / interrupt ? */ - if (ad_command(adp, ATA_C_SET_MULTI, 0, 0, 0, 16)) - adp->transfersize = DEV_BSIZE; - else { - if (ata_wait(adp->controller, ATA_S_DRDY) < 0) - adp->transfersize = DEV_BSIZE; - else - adp->transfersize = 16*DEV_BSIZE; - } + adp->transfersize = DEV_BSIZE; + secsperint = min(adp->ata_parm->nsecperint, 16); + if (!ad_command(adp, ATA_C_SET_MULTI, 0, 0, 0, secsperint) && + ata_wait(adp->controller, ATA_S_DRDY) >= 0) + adp->transfersize *= secsperint; + bpack(adp->ata_parm->model, model_buf, sizeof(model_buf)); bpack(adp->ata_parm->revision, revision_buf, sizeof(revision_buf)); @@ -152,6 +158,18 @@ ad_attach(void *notused) DEVSTAT_NO_ORDERED_TAGS, DEVSTAT_TYPE_DIRECT | DEVSTAT_TYPE_IF_IDE, 0x180); +#ifdef DEVFS + adp->cdevs_token = devfs_add_devswf(&ad_cdevsw, + dkmakeminor(adp->lun, 0, 0), + DV_CHR, + UID_ROOT, GID_OPERATOR, + 0640, "rad%d", adp->lun); + adp->bdevs_token = devfs_add_devswf(&ad_cdevsw, + dkmakeminor(adp->lun, 0, 0), + DV_BLK, + UID_ROOT, GID_OPERATOR, + 0640, "ad%d", adp->lun); +#endif bufq_init(&adp->queue); adtab[adnlun++] = adp; } @@ -245,17 +263,6 @@ adioctl(dev_t dev, u_long cmd, caddr_t addr, int32_t flags, struct proc *p) return ENOTTY; } -static int32_t -adpsize(dev_t dev) -{ - struct ad_softc *adp; - int32_t lun = UNIT(dev); - - if (lun >= adnlun || !(adp = adtab[lun])) - return -1; - return (dssize(dev, &adp->slices, adopen, adclose)); -} - static void adstrategy(struct buf *bp) { @@ -301,6 +308,17 @@ done: splx(s); } +static int32_t +adpsize(dev_t dev) +{ + struct ad_softc *adp; + int32_t lun = UNIT(dev); + + if (lun >= adnlun || !(adp = adtab[lun])) + return -1; + return dssize(dev, &adp->slices, adopen, adclose); +} + static void ad_strategy(struct buf *bp) { @@ -434,14 +452,14 @@ ad_interrupt(struct buf *bp) if (adp->controller->status & (ATA_S_ERROR | ATA_S_CORR)) { oops: printf("ad%d: status=%02x error=%02x\n", - adp->unit, adp->controller->status, adp->controller->error); + adp->lun, adp->controller->status, adp->controller->error); if (adp->controller->status & ATA_S_ERROR) { - printf("ad_interrupt: hard error"); + printf("ad_interrupt: hard error\n"); bp->b_error = EIO; bp->b_flags |= B_ERROR; } if (adp->controller->status & ATA_S_CORR) - printf("ad_interrupt: soft ECC"); + printf("ad_interrupt: soft ECC\n"); } /* if this was a read operation, get the data */ if (((bp->b_flags & (B_READ | B_ERROR)) == B_READ) && adp->active) { diff --git a/sys/dev/ata/ata-disk.h b/sys/dev/ata/ata-disk.h index 618b8e2..3da1752 100644 --- a/sys/dev/ata/ata-disk.h +++ b/sys/dev/ata/ata-disk.h @@ -25,17 +25,16 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * - * $Id: ata-disk.h,v 1.5 1999/03/01 12:11:01 sos Exp $ + * $Id: ata-disk.h,v 1.1 1999/03/01 21:19:18 sos Exp $ */ -/* - * Structure describing an ATA disk - */ +/* Structure describing an ATA disk */ struct ad_softc { struct ata_softc *controller; /* ptr to parent ctrl */ struct ata_params *ata_parm; /* ata device params */ struct diskslices *slices; int32_t unit; /* ATA_MASTER or ATA_SLAVE */ + int32_t lun; /* logical unit number */ u_int16_t cylinders; /* disk geometry (probed) */ u_int8_t heads; u_int8_t sectors; @@ -47,9 +46,12 @@ struct ad_softc { u_int32_t donecount; /* bytes transferred */ u_int32_t active; /* active processing request */ u_int32_t flags; /* drive flags */ -#define AD_F_LABELLING 0x0001 - struct devstat stats; /* devstat entry */ +#define AD_F_LABELLING 0x0001 +#ifdef DEVFS + void *cdevs_token; + void *bdevs_token; +#endif }; void ad_transfer(struct buf *); diff --git a/sys/dev/ata/atapi-all.c b/sys/dev/ata/atapi-all.c index a5c9fdd..b1a333a 100644 --- a/sys/dev/ata/atapi-all.c +++ b/sys/dev/ata/atapi-all.c @@ -25,13 +25,13 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * - * $Id: atapi-all.c,v 1.5 1999/03/01 21:03:15 sos Exp sos $ + * $Id: atapi-all.c,v 1.1 1999/03/01 21:19:18 sos Exp $ */ #include "ata.h" #include "atapicd.h" #include "atapist.h" -/*#include "atapifd.h"*/ +#include "atapifd.h" #include "opt_devfs.h" #if NATA > 0 @@ -326,7 +326,7 @@ printf("atapi_interrupt: length=%d reason=0x%02x\n", length, reason); TAILQ_REMOVE(&atp->controller->atapi_queue, request, chain); #ifdef ATAPI_DEBUG -printf("atapi_interrupt: error=%02x\n", request->result); +printf("atapi_interrupt: error=0x%02x\n", request->result); #endif if (request->callback) { (request->callback)(request); @@ -341,7 +341,7 @@ printf("atapi_interrupt: error=%02x\n", request->result); void atapi_error(struct atapi_softc *atp, int32_t error) { - printf("atapi: error = %02x\n", error); + printf("atapi: error = 0x%02x\n", error); } void @@ -350,7 +350,7 @@ atapi_dump(int8_t *label, void *data, int32_t len) u_int8_t *p = data; printf ("atapi: %s %x", label, *p++); - while (--len > 0) printf ("-%x", *p++); + while (--len > 0) printf ("-%02x", *p++); printf ("\n"); } diff --git a/sys/dev/ata/atapi-all.h b/sys/dev/ata/atapi-all.h index ba0e42e..9a12f64 100644 --- a/sys/dev/ata/atapi-all.h +++ b/sys/dev/ata/atapi-all.h @@ -25,7 +25,7 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * - * $Id: atapi-all.h,v 1.2 1999/03/01 12:11:01 sos Exp $ + * $Id: atapi-all.h,v 1.1 1999/03/01 21:19:18 sos Exp $ */ /* ATAPI misc defines */ @@ -88,25 +88,25 @@ /* ATAPI device parameter information */ struct atapi_params { - u_int cmdsize :2; /* packet command size */ + u_int8_t cmdsize :2; /* packet command size */ #define ATAPI_PSIZE_12 0 /* 12 bytes */ #define ATAPI_PSIZE_16 1 /* 16 bytes */ - u_int :3; - u_int drqtype :2; /* DRQ type */ + u_int8_t :3; + u_int8_t drqtype :2; /* DRQ type */ #define ATAPI_DRQT_MPROC 0 /* cpu 3 ms delay */ #define ATAPI_DRQT_INTR 1 /* intr 10 ms delay */ #define ATAPI_DRQT_ACCEL 2 /* accel 50 us delay */ - u_int removable :1; /* device is removable */ - u_int device_type :5; /* device type */ + u_int8_t removable :1; /* device is removable */ + u_int8_t device_type :5; /* device type */ #define ATAPI_TYPE_DIRECT 0 /* disk/floppy */ #define ATAPI_TYPE_TAPE 1 /* streaming tape */ #define ATAPI_TYPE_CDROM 5 /* CD-ROM device */ #define ATAPI_TYPE_OPTICAL 7 /* optical disk */ - u_int :1; - u_int proto :2; /* command protocol */ + u_int8_t :1; + u_int8_t proto :2; /* command protocol */ #define ATAPI_PROTO_ATAPI 2 int16_t reserved1[9]; diff --git a/sys/dev/ata/atapi-cd.c b/sys/dev/ata/atapi-cd.c index 6c16dd8..c9fb72d 100644 --- a/sys/dev/ata/atapi-cd.c +++ b/sys/dev/ata/atapi-cd.c @@ -25,7 +25,7 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * - * $Id: atapi-cd.c,v 1.5 1999/03/01 21:03:15 sos Exp sos $ + * $Id: atapi-cd.c,v 1.1 1999/03/01 21:19:18 sos Exp $ */ #include "ata.h" @@ -56,8 +56,8 @@ static d_open_t acdopen; static d_close_t acdclose; -static d_write_t acdwrite; static d_read_t acdread; +static d_write_t acdwrite; static d_ioctl_t acdioctl; static d_strategy_t acdstrategy; @@ -106,6 +106,9 @@ static int32_t acd_close_track(struct acd_softc *); static int32_t acd_close_disk(struct acd_softc *); static int32_t acd_read_track_info(struct acd_softc *, int, struct acd_track_info*); static int32_t acd_blank_disk(struct acd_softc *); +static void lba2msf(int32_t, u_int8_t *, u_int8_t *, u_int8_t *); +static int32_t msf2lba(u_int8_t, u_int8_t, u_int8_t); +static void acd_drvinit(void *); int acdattach(struct atapi_softc *atp) @@ -201,7 +204,7 @@ acdattach(struct atapi_softc *atp) return 0; } -struct acd_softc * +static struct acd_softc * acd_init_lun(struct atapi_softc *atp, int32_t lun, struct devstat *stats) { struct acd_softc *acd; @@ -227,27 +230,25 @@ acd_init_lun(struct atapi_softc *atp, int32_t lun, struct devstat *stats) else acd->stats = stats; #ifdef DEVFS - acd->ra_devfs_token = - devfs_add_devswf(&acd_cdevsw, dkmakeminor(lun, 0, 0), - DV_CHR, UID_ROOT, GID_OPERATOR, 0640, - "racd%da", lun); - acd->rc_devfs_token = - devfs_add_devswf(&acd_cdevsw, dkmakeminor(lun, 0, RAW_PART), - DV_CHR, UID_ROOT, GID_OPERATOR, 0640, - "racd%dc", lun); - acd->a_devfs_token = - devfs_add_devswf(&acd_cdevsw, dkmakeminor(lun, 0, 0), - DV_BLK, UID_ROOT, GID_OPERATOR, 0640, - "acd%da", lun); - acd->c_devfs_token = - devfs_add_devswf(&acd_cdevsw, dkmakeminor(lun, 0, RAW_PART), - DV_BLK, UID_ROOT, GID_OPERATOR, 0640, - "acd%dc", lun); + acd->a_cdevfs_token = devfs_add_devswf(&acd_cdevsw, dkmakeminor(lun, 0, 0), + DV_CHR, UID_ROOT, GID_OPERATOR, 0644, + "racd%da", lun); + acd->c_cdevfs_token = devfs_add_devswf(&acd_cdevsw, + dkmakeminor(lun, 0, RAW_PART), + DV_CHR, UID_ROOT, GID_OPERATOR, 0644, + "racd%dc", lun); + acd->a_bdevfs_token = devfs_add_devswf(&acd_cdevsw, dkmakeminor(lun, 0, 0), + DV_BLK, UID_ROOT, GID_OPERATOR, 0644, + "acd%da", lun); + acd->c_bdevfs_token = devfs_add_devswf(&acd_cdevsw, + dkmakeminor(lun, 0, RAW_PART), + DV_BLK, UID_ROOT, GID_OPERATOR, 0644, + "acd%dc", lun); #endif return acd; } -void +static void acd_describe(struct acd_softc *cdp) { int32_t comma; @@ -377,7 +378,24 @@ acd_describe(struct acd_softc *cdp) printf("\n"); } -static int +static __inline void +lba2msf(int32_t lba, u_int8_t *m, u_int8_t *s, u_int8_t *f) +{ + lba += 150; + lba &= 0xffffff; + *m = lba / (60 * 75); + lba %= (60 * 75); + *s = lba / 75; + *f = lba % 75; +} + +static __inline int32_t +msf2lba(u_int8_t m, u_int8_t s, u_int8_t f) +{ + return (m * 60 + s) * 75 + f - 150; +} + +static int32_t acdopen(dev_t dev, int32_t flags, int32_t fmt, struct proc *p) { int32_t lun = dkunit(dev); @@ -393,7 +411,7 @@ acdopen(dev_t dev, int32_t flags, int32_t fmt, struct proc *p) if (fmt == S_IFBLK) cdp->flags |= F_BOPEN; else - ++cdp->refcnt; + cdp->refcnt++; if ((flags & O_NONBLOCK) == 0) { if ((flags & FWRITE) != 0) { @@ -413,7 +431,7 @@ acdopen(dev_t dev, int32_t flags, int32_t fmt, struct proc *p) return 0; } -int32_t +static int32_t acdclose(dev_t dev, int32_t flags, int32_t fmt, struct proc *p) { int32_t lun = dkunit(dev); @@ -425,7 +443,7 @@ acdclose(dev_t dev, int32_t flags, int32_t fmt, struct proc *p) if (fmt == S_IFBLK) cdp->flags &= ~F_BOPEN; else - --cdp->refcnt; + cdp->refcnt--; /* Are we the last open ?? */ if (!(cdp->flags & F_BOPEN) && !cdp->refcnt) { @@ -442,155 +460,19 @@ acdclose(dev_t dev, int32_t flags, int32_t fmt, struct proc *p) return 0; } -static int +static int32_t acdread(dev_t dev, struct uio *uio, int32_t ioflag) { return physio(acdstrategy, NULL, dev, 1, minphys, uio); } -static int +static int32_t acdwrite(dev_t dev, struct uio *uio, int32_t ioflag) { return physio(acdstrategy, NULL, dev, 0, minphys, uio); } -void -acdstrategy(struct buf *bp) -{ - int32_t lun = dkunit(bp->b_dev); - struct acd_softc *cdp = acdtab[lun]; - int32_t x; - -#ifdef NOTYET - /* allow write only on CD-R/RW media */ /* all for now SOS */ - if (!(bp->b_flags & B_READ) && !(writeable_media)) { - bp->b_error = EROFS; - bp->b_flags |= B_ERROR; - biodone(bp); - return; - } -#endif - - if (bp->b_bcount == 0) { - bp->b_resid = 0; - biodone(bp); - return; - } - - /* check for valid blocksize SOS */ - - bp->b_pblkno = bp->b_blkno; - bp->b_resid = bp->b_bcount; - - x = splbio(); - bufqdisksort(&cdp->buf_queue, bp); - acd_start(cdp); - splx(x); -} - -static void -acd_start(struct acd_softc *cdp) -{ - struct buf *bp = bufq_first(&cdp->buf_queue); - u_long lba, count; - int8_t ccb[16]; - - if (!bp) - return; - bzero(ccb, sizeof(ccb)); - bufq_remove(&cdp->buf_queue, bp); - - /* Should reject all queued entries if media have changed. */ - if (cdp->flags & F_MEDIA_CHANGED) { - bp->b_error = EIO; - bp->b_flags |= B_ERROR; - biodone(bp); - return; - } - acd_select_slot(cdp); - if ((bp->b_flags & B_READ) == B_WRITE) { - if ((cdp->flags & F_TRACK_PREPED) == 0) { - if ((cdp->flags & F_TRACK_PREP) == 0) { - printf("acd%d: sequence error\n", cdp->lun); - bp->b_error = EIO; - bp->b_flags |= B_ERROR; - biodone(bp); - return; - } else { - if (acd_open_track(cdp, &cdp->preptrack) != 0) { - biodone(bp); - return; - } - cdp->flags |= F_TRACK_PREPED; - } - } - } - if (bp->b_flags & B_READ) { - lba = bp->b_blkno / (cdp->block_size / DEV_BSIZE); - ccb[0] = ATAPI_READ_BIG; - } - else { - lba = cdp->next_writeable_lba + (bp->b_offset / cdp->block_size); - ccb[0] = ATAPI_WRITE_BIG; - } - count = (bp->b_bcount + (cdp->block_size - 1)) / cdp->block_size; - - ccb[1] = 0; - ccb[2] = lba>>24; - ccb[3] = lba>>16; - ccb[4] = lba>>8; - ccb[5] = lba; - ccb[7] = count>>8; - ccb[8] = count; - - devstat_start_transaction(cdp->stats); - - atapi_queue_cmd(cdp->atp, ccb, bp->b_data, bp->b_bcount, - (bp->b_flags&B_READ)?A_READ : 0, acd_done, cdp, (void *)bp); -} - -static void -acd_done(struct atapi_request *request) -{ - struct buf *bp = request->bp; - struct acd_softc *cdp = request->driver; - - devstat_end_transaction(cdp->stats, bp->b_bcount-request->bytecount, - DEVSTAT_TAG_NONE, - (bp->b_flags&B_READ) ? DEVSTAT_READ:DEVSTAT_WRITE); - if (request->result) { - printf("acd_done: "); - atapi_error(request->device, request->result); - bp->b_error = EIO; - bp->b_flags |= B_ERROR; - } - else { - bp->b_resid = request->bytecount; - if ((bp->b_flags & B_READ) == B_WRITE) - cdp->flags |= F_WRITTEN; - } - biodone(bp); - acd_start(cdp); -} - -static __inline void -lba2msf(int32_t lba, u_int8_t *m, u_int8_t *s, u_int8_t *f) -{ - lba += 150; - lba &= 0xffffff; - *m = lba / (60 * 75); - lba %= (60 * 75); - *s = lba / 75; - *f = lba % 75; -} - -static __inline int32_t -msf2lba(u_int8_t m, u_int8_t s, u_int8_t f) -{ - return (m * 60 + s) * 75 + f - 150; -} - -int32_t +static int32_t acdioctl(dev_t dev, u_long cmd, caddr_t addr, int32_t flag, struct proc *p) { int32_t lun = dkunit(dev); @@ -634,7 +516,7 @@ acdioctl(dev_t dev, u_long cmd, caddr_t addr, int32_t flag, struct proc *p) case CDIOCRESET: error = suser(p->p_ucred, &p->p_acflag); if (error) - return (error); + return error; return acd_test_unit_ready(cdp); case CDIOCEJECT: @@ -658,7 +540,7 @@ acdioctl(dev_t dev, u_long cmd, caddr_t addr, int32_t flag, struct proc *p) struct ioc_read_toc_entry *te = (struct ioc_read_toc_entry *)addr; struct toc *toc = &cdp->toc; struct toc buf; - u_long len; + u_int32_t len; u_int8_t starting_track = te->starting_track; if (!cdp->toc.hdr.ending_track) @@ -741,7 +623,7 @@ acdioctl(dev_t dev, u_long cmd, caddr_t addr, int32_t flag, struct proc *p) struct ioc_read_subchannel *args = (struct ioc_read_subchannel *)addr; struct cd_sub_channel_info data; - u_long len = args->data_len; + u_int32_t len = args->data_len; int32_t abslba, rellba; int8_t ccb[16] = { ATAPI_READ_SUBCHANNEL, 0, 0x40, 1, 0, 0, 0, sizeof(cdp->subchan)>>8, sizeof(cdp->subchan), @@ -755,7 +637,7 @@ acdioctl(dev_t dev, u_long cmd, caddr_t addr, int32_t flag, struct proc *p) sizeof(cdp->subchan), A_READ, NULL, NULL, NULL)) return EIO; #ifdef ACD_DEBUG - atapi_dump("acd: subchan", &cdp->subchan, sizeof(cdp->subchan)); + atapi_dump("acd: subchan", &cdp->subchan, sizeof(cdp->subchan)); #endif abslba = cdp->subchan.abslba; @@ -807,7 +689,7 @@ acdioctl(dev_t dev, u_long cmd, caddr_t addr, int32_t flag, struct proc *p) case CDIOCPLAYTRACKS: { struct ioc_play_track *args = (struct ioc_play_track *)addr; - u_long start, len; + u_int32_t start, len; int32_t t1, t2; int8_t ccb[16]; @@ -1049,6 +931,128 @@ acdioctl(dev_t dev, u_long cmd, caddr_t addr, int32_t flag, struct proc *p) return error; } +static void +acdstrategy(struct buf *bp) +{ + int32_t lun = dkunit(bp->b_dev); + struct acd_softc *cdp = acdtab[lun]; + int32_t x; + +#ifdef NOTYET + /* allow write only on CD-R/RW media */ /* all for now SOS */ + if (!(bp->b_flags & B_READ) && !(writeable_media)) { + bp->b_error = EROFS; + bp->b_flags |= B_ERROR; + biodone(bp); + return; + } +#endif + + if (bp->b_bcount == 0) { + bp->b_resid = 0; + biodone(bp); + return; + } + + /* check for valid blocksize SOS */ + + bp->b_pblkno = bp->b_blkno; + bp->b_resid = bp->b_bcount; + + x = splbio(); + bufqdisksort(&cdp->buf_queue, bp); + acd_start(cdp); + splx(x); +} + +static void +acd_start(struct acd_softc *cdp) +{ + struct buf *bp = bufq_first(&cdp->buf_queue); + u_int32_t lba, count; + int8_t ccb[16]; + + if (!bp) + return; + + bufq_remove(&cdp->buf_queue, bp); + + /* Should reject all queued entries if media have changed. */ + if (cdp->flags & F_MEDIA_CHANGED) { + bp->b_error = EIO; + bp->b_flags |= B_ERROR; + biodone(bp); + return; + } + acd_select_slot(cdp); + if ((bp->b_flags & B_READ) == B_WRITE) { + if ((cdp->flags & F_TRACK_PREPED) == 0) { + if ((cdp->flags & F_TRACK_PREP) == 0) { + printf("acd%d: sequence error\n", cdp->lun); + bp->b_error = EIO; + bp->b_flags |= B_ERROR; + biodone(bp); + return; + } else { + if (acd_open_track(cdp, &cdp->preptrack) != 0) { + biodone(bp); + return; + } + cdp->flags |= F_TRACK_PREPED; + } + } + } + bzero(ccb, sizeof(ccb)); + if (bp->b_flags & B_READ) { + lba = bp->b_blkno / (cdp->block_size / DEV_BSIZE); + ccb[0] = ATAPI_READ_BIG; + } + else { + lba = cdp->next_writeable_lba + (bp->b_offset / cdp->block_size); + ccb[0] = ATAPI_WRITE_BIG; + } + count = (bp->b_bcount + (cdp->block_size - 1)) / cdp->block_size; + +#ifdef ACD_DEBUG + printf("acd%d: lba=%d, count=%d\n", cdp->lun, lba, count); +#endif + ccb[1] = 0; + ccb[2] = lba>>24; + ccb[3] = lba>>16; + ccb[4] = lba>>8; + ccb[5] = lba; + ccb[7] = count>>8; + ccb[8] = count; + + devstat_start_transaction(cdp->stats); + + atapi_queue_cmd(cdp->atp, ccb, bp->b_data, bp->b_bcount, + (bp->b_flags&B_READ)?A_READ : 0, acd_done, cdp, (void *)bp); +} + +static void +acd_done(struct atapi_request *request) +{ + struct buf *bp = request->bp; + struct acd_softc *cdp = request->driver; + + devstat_end_transaction(cdp->stats, bp->b_bcount-request->bytecount, + DEVSTAT_TAG_NONE, + (bp->b_flags&B_READ) ? DEVSTAT_READ:DEVSTAT_WRITE); + if (request->result) { + atapi_error(request->device, request->result); + bp->b_error = EIO; + bp->b_flags |= B_ERROR; + } + else { + bp->b_resid = request->bytecount; + if ((bp->b_flags & B_READ) == B_WRITE) + cdp->flags |= F_WRITTEN; + } + biodone(bp); + acd_start(cdp); +} + static int32_t acd_test_unit_ready(struct acd_softc *cdp) { @@ -1095,8 +1099,8 @@ acd_mode_sense(struct acd_softc *cdp, u_int8_t page, error = atapi_queue_cmd(cdp->atp, ccb, pagebuf, pagesize, A_READ, NULL, NULL, NULL); -#ifdef AST_DEBUG - atapi_dump("acd: mode sense ", &cdp->au, sizeof(cdp->au)); +#ifdef ACD_DEBUG + atapi_dump("acd: mode sense ", pagebuf, pagesize); #endif return error; } @@ -1107,8 +1111,9 @@ acd_mode_select(struct acd_softc *cdp, void *pagebuf, int32_t pagesize) int8_t ccb[16] = { ATAPI_MODE_SELECT, 0x10, 0, 0, 0, 0, 0, pagesize>>8, pagesize, 0, 0, 0, 0, 0, 0, 0 }; -#ifdef AST_DEBUG - atapi_dump("acd: mode select ", &cdp->au, sizeof(cdp->au)); +#ifdef ACD_DEBUG + printf("acd: modeselect pagesize=%d\n", pagesize); + atapi_dump("acd: mode select ", pagebuf, pagesize); #endif return atapi_queue_cmd(cdp->atp, ccb, pagebuf, pagesize, 0, NULL, NULL, NULL); @@ -1196,9 +1201,6 @@ acd_read_toc(struct acd_softc *cdp) return 0; } -/* - * Set up the audio channel masks. - */ static int32_t acd_setchan(struct acd_softc *cdp, u_int8_t c0, u_int8_t c1, u_int8_t c2, u_int8_t c3) @@ -1287,7 +1289,7 @@ acd_select_slot(struct acd_softc *cdp) acd_lock_device(cdp, 1); } -static int +static int32_t acd_rezero_unit(struct acd_softc *cdp) { int8_t ccb[16]; @@ -1297,14 +1299,14 @@ acd_rezero_unit(struct acd_softc *cdp) return atapi_queue_cmd(cdp->atp, ccb, NULL, 0, 0, NULL, NULL, NULL); } -static int +static int32_t acd_open_disk(struct acd_softc *cdp, int32_t test) { cdp->next_writeable_lba = 0; return 0; } -static int +static int32_t acd_close_disk(struct acd_softc *cdp) { int8_t ccb[16]; @@ -1316,7 +1318,7 @@ acd_close_disk(struct acd_softc *cdp) return atapi_queue_cmd(cdp->atp, ccb, NULL, 0, 0, NULL, NULL, NULL); } -static int +static int32_t acd_open_track(struct acd_softc *cdp, struct wormio_prepare_track *ptp) { struct write_param param; @@ -1386,7 +1388,7 @@ acd_open_track(struct acd_softc *cdp, struct wormio_prepare_track *ptp) return acd_mode_select(cdp, ¶m, sizeof(param)); } -static int +static int32_t acd_close_track(struct acd_softc *cdp) { int8_t ccb[16]; @@ -1396,7 +1398,7 @@ acd_close_track(struct acd_softc *cdp) return atapi_queue_cmd(cdp->atp, ccb, NULL, 0, 0, NULL, NULL, NULL); } -static int +static int32_t acd_read_track_info(struct acd_softc *cdp, int32_t lba, struct acd_track_info *info) { @@ -1418,7 +1420,7 @@ acd_read_track_info(struct acd_softc *cdp, return 0; } -static int +static int32_t acd_blank_disk(struct acd_softc *cdp) { int32_t error; diff --git a/sys/dev/ata/atapi-cd.h b/sys/dev/ata/atapi-cd.h index f602e37..2531989 100644 --- a/sys/dev/ata/atapi-cd.h +++ b/sys/dev/ata/atapi-cd.h @@ -25,21 +25,17 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * - * $Id: atapi-cd.h,v 1.3 1999/03/01 21:03:15 sos Exp sos $ + * $Id: atapi-cd.h,v 1.1 1999/03/01 21:19:18 sos Exp $ */ -/* - * CDROM Table Of Contents - */ +/* CDROM Table Of Contents */ #define MAXTRK 99 struct toc { - struct ioc_toc_header hdr; - struct cd_toc_entry tab[MAXTRK + 1]; + struct ioc_toc_header hdr; + struct cd_toc_entry tab[MAXTRK + 1]; }; -/* - * CDROM Audio Control Parameters Page - */ +/* CDROM Audio Control Parameters Page */ struct audiopage { /* Mode Page data header */ u_int16_t data_length; @@ -63,22 +59,21 @@ struct audiopage { u_int8_t reserved5; u_int16_t lb_per_sec; struct port_control { - u_int8_t channels:4; + u_int8_t channels:4; #define CHANNEL_0 1 #define CHANNEL_1 2 #define CHANNEL_2 4 #define CHANNEL_3 8 - u_int8_t volume; + + u_int8_t volume; } port[4]; }; -/* - * CDROM Capabilities and Mechanical Status Page - */ +/* CDROM Capabilities and Mechanical Status Page */ struct cappage { /* Mode data header */ u_int16_t data_length; - u_int8_t medium_type; /* Present media type */ + u_int8_t medium_type; #define MST_TYPE_MASK_LOW 0x0f #define MST_FMT_NONE 0x00 #define MST_DATA_120 0x01 @@ -108,55 +103,55 @@ struct cappage { #define ATAPI_CDROM_CAP_PAGE 0x2a u_int8_t param_len; - u_int8_t read_cdr :1; /* Supports CD-R read */ - u_int8_t read_cdrw :1; /* Supports CD-RW read */ - u_int8_t method2 :1; /* Supports reading packet tracks */ - u_int8_t byte2_37 :5; - u_int8_t write_cdr :1; /* Supports CD-R write */ - u_int8_t write_cdrw :1; /* Supports CD-RW write */ - u_int8_t test_write :1; /* Supports test writing */ - u_int8_t byte3_37 :5; - u_int8_t audio_play :1; /* Audio play supported */ - u_int8_t composite :1; /* Composite audio/video supported */ - u_int8_t dport1 :1; /* Digital audio on port 1 */ - u_int8_t dport2 :1; /* Digital audio on port 2 */ - u_int8_t mode2_form1 :1; /* Mode 2 form 1 (XA) read */ - u_int8_t mode2_form2 :1; /* Mode 2 form 2 format */ - u_int8_t multisession :1; /* Multi-session photo-CD */ + u_int8_t read_cdr :1; /* supports CD-R read */ + u_int8_t read_cdrw :1; /* supports CD-RW read */ + u_int8_t method2 :1; /* supports reading packet tracks */ + u_int8_t reserved2_37 :5; + u_int8_t write_cdr :1; /* supports CD-R write */ + u_int8_t write_cdrw :1; /* supports CD-RW write */ + u_int8_t test_write :1; /* supports test writing */ + u_int8_t reserved3_37 :5; + u_int8_t audio_play :1; /* audio play supported */ + u_int8_t composite :1; /* composite audio/video supported */ + u_int8_t dport1 :1; /* digital audio on port 1 */ + u_int8_t dport2 :1; /* digital audio on port 2 */ + u_int8_t mode2_form1 :1; /* mode 2 form 1 (XA) read */ + u_int8_t mode2_form2 :1; /* mode 2 form 2 format */ + u_int8_t multisession :1; /* multi-session photo-CD */ u_int8_t :1; - u_int8_t cd_da :1; /* Audio-CD read supported */ + u_int8_t cd_da :1; /* audio-CD read supported */ u_int8_t cd_da_stream :1; /* CD-DA streaming */ - u_int8_t rw :1; /* Combined R-W subchannels */ + u_int8_t rw :1; /* combined R-W subchannels */ u_int8_t rw_corr :1; /* R-W subchannel data corrected */ u_int8_t c2 :1; /* C2 error pointers supported */ - u_int8_t isrc :1; /* Can return the ISRC info */ - u_int8_t upc :1; /* Can return the catalog number UPC */ + u_int8_t isrc :1; /* can return the ISRC info */ + u_int8_t upc :1; /* can return the catalog number UPC */ u_int8_t :1; - u_int8_t lock :1; /* Can be locked */ - u_int8_t locked :1; /* Current lock state */ - u_int8_t prevent :1; /* Prevent jumper installed */ - u_int8_t eject :1; /* Can eject */ + u_int8_t lock :1; /* can be locked */ + u_int8_t locked :1; /* current lock state */ + u_int8_t prevent :1; /* prevent jumper installed */ + u_int8_t eject :1; /* can eject */ u_int8_t :1; - u_int8_t mech :3; /* Loading mechanism type */ + u_int8_t mech :3; /* loading mechanism type */ #define MST_MECH_CADDY 0 #define MST_MECH_TRAY 1 #define MST_MECH_POPUP 2 #define MST_MECH_CHANGER 4 #define MST_MECH_CARTRIDGE 5 - u_int8_t sep_vol :1; /* Independent volume of channels */ - u_int8_t sep_mute :1; /* Independent mute of channels */ + u_int8_t sep_vol :1; /* independent volume of channels */ + u_int8_t sep_mute :1; /* independent mute of channels */ u_int8_t:6; - u_int16_t max_speed; /* Max raw data rate in bytes/1000 */ - u_int16_t max_vol_levels; /* Number of discrete volume levels */ - u_int16_t buf_size; /* Internal buffer size in bytes/1024 */ - u_int16_t cur_speed; /* Current data rate in bytes/1000 */ + u_int16_t max_speed; /* max raw data rate in bytes/1000 */ + u_int16_t max_vol_levels; /* number of discrete volume levels */ + u_int16_t buf_size; /* internal buffer size in bytes/1024 */ + u_int16_t cur_speed; /* current data rate in bytes/1000 */ u_int8_t reserved3; - u_int8_t bckf :1; /* Data valid on failing edge of BCK */ - u_int8_t rch :1; /* High LRCK indicates left channel */ - u_int8_t lsbf :1; /* Set if LSB first */ + u_int8_t bckf :1; /* data valid on failing edge of BCK */ + u_int8_t rch :1; /* high LRCK indicates left channel */ + u_int8_t lsbf :1; /* set if LSB first */ u_int8_t dlen :2; #define MST_DLEN_32 0 #define MST_DLEN_16 1 @@ -167,42 +162,38 @@ struct cappage { u_int8_t reserved4[2]; }; -/* - * CDROM Changer mechanism status structure - */ +/* CDROM Changer mechanism status structure */ struct changer { - u_int8_t current_slot :5; /* Active changer slot */ - u_int8_t mech_state :2; /* Current changer state */ + u_int8_t current_slot :5; /* active changer slot */ + u_int8_t mech_state :2; /* current changer state */ #define CH_READY 0 #define CH_LOADING 1 #define CH_UNLOADING 2 #define CH_INITIALIZING 3 - u_int8_t fault :1; /* Fault in last operation */ + u_int8_t fault :1; /* fault in last operation */ u_int8_t reserved0 :5; - u_int8_t cd_state :3; /* Current mechanism state */ + u_int8_t cd_state :3; /* current mechanism state */ #define CD_IDLE 0 #define CD_AUDIO_ACTIVE 1 #define CD_AUDIO_SCAN 2 #define CD_HOST_ACTIVE 3 #define CD_NO_STATE 7 - u_int8_t current_lba[3]; /* Current LBA */ - u_int8_t slots; /* Number of available slots */ - u_int16_t table_length; /* Slot table length */ + u_int8_t current_lba[3]; /* current LBA */ + u_int8_t slots; /* number of available slots */ + u_int16_t table_length; /* slot table length */ struct { - u_int8_t changed :1; /* Media has changed in this slot */ - u_int8_t unused :6; - u_int8_t present :1; /* Slot has a CD present */ - u_int8_t reserved0; - u_int8_t reserved1; - u_int8_t reserved2; + u_int8_t changed :1; /* media has changed in this slot */ + u_int8_t unused :6; + u_int8_t present :1; /* slot has a CD present */ + u_int8_t reserved0; + u_int8_t reserved1; + u_int8_t reserved2; } slot[32]; }; -/* - * CDROM Write Parameters Mode Page (Burners ONLY) - */ +/* CDROM Write Parameters Mode Page (Burners ONLY) */ struct write_param { /* Mode Page data header */ u_int16_t data_length; @@ -213,63 +204,63 @@ struct write_param { /* Write Parameters mode page */ u_int8_t page_code; -#define ATAPI_CDROM_WRITE_PARAMETERS_PAGE 0x0e +#define ATAPI_CDROM_WRITE_PARAMETERS_PAGE 0x05 u_int8_t page_length; /* 0x32 */ - u_int8_t write_type :4; /* Write stream type */ + u_int8_t write_type :4; /* write stream type */ #define CDR_WTYPE_PACKET 0x00 #define CDR_WTYPE_TRACK 0x01 #define CDR_WTYPE_SESSION 0x02 #define CDR_WTYPE_RAW 0x03 - u_int8_t test_write :1; /* Test write enable */ + u_int8_t test_write :1; /* test write enable */ u_int8_t reserved2_567 :3; - u_int8_t track_mode :4; /* Track mode */ + u_int8_t track_mode :4; /* track mode */ #define CDR_TMODE_AUDIO 0x01 #define CDR_TMODE_INCR_DATA 0x01 #define CDR_TMODE_ALLOW_COPY 0x02 #define CDR_TMODE_DATA 0x04 #define CDR_TMODE_QUAD_AUDIO 0x08 - u_int8_t copy :1; /* Generation stamp */ - u_int8_t fp :1; /* Fixed packet type */ - u_int8_t multi_session :2; /* Multi-session type */ + u_int8_t copy :1; /* generation stamp */ + u_int8_t fp :1; /* fixed packet type */ + u_int8_t multi_session :2; /* multi-session type */ #define CDR_MSES_NONE 0x00 #define CDR_MSES_FINAL 0x01 #define CDR_MSES_RESERVED 0x02 #define CDR_MSES_NULTI 0x03 - u_int8_t data_block_type :4; /* Data block type code */ + u_int8_t data_block_type :4; /* data block type code */ #define CDR_DB_RAW 0x0 /* 2352 bytes of raw data */ #define CDR_DB_RAW_PQ 0x1 /* 2368 bytes raw data + P/Q subchan */ #define CDR_DB_RAW_PW 0x2 /* 2448 bytes raw data + P-W subchan */ #define CDR_DB_RAW_PW_R 0x3 /* 2448 bytes raw data + P-W raw sub */ -#define CDR_DB_RES_4 0x4 /* Reserved */ -#define CDR_DB_RES_5 0x5 /* Reserved */ -#define CDR_DB_RES_6 0x6 /* Reserved */ -#define CDR_DB_VS_7 0x7 /* Vendor specific */ +#define CDR_DB_RES_4 0x4 /* reserved */ +#define CDR_DB_RES_5 0x5 /* reserved */ +#define CDR_DB_RES_6 0x6 /* reserved */ +#define CDR_DB_VS_7 0x7 /* vendor specific */ #define CDR_DB_ROM_MODE1 0x8 /* 2048 bytes Mode 1 (ISO/IEC 10149) */ #define CDR_DB_ROM_MODE2 0x9 /* 2336 bytes Mode 2 (ISO/IEC 10149) */ #define CDR_DB_XA_MODE1 0x10 /* 2048 bytes Mode 1 (CD-ROM XA 1) */ #define CDR_DB_XA_MODE2_F1 0x11 /* 2056 bytes Mode 2 (CD-ROM XA 1) */ #define CDR_DB_XA_MODE2_F2 0x12 /* 2324 bytes Mode 2 (CD-ROM XA 2) */ #define CDR_DB_XA_MODE2_MIX 0x13 /* 2332 bytes Mode 2 (CD-ROM XA 1/2) */ -#define CDR_DB_RES_14 0x14 /* Reserved */ -#define CDR_DB_VS_15 0x15 /* Vendor specific */ +#define CDR_DB_RES_14 0x14 /* reserved */ +#define CDR_DB_VS_15 0x15 /* vendor specific */ u_int8_t reserved4_4567 :4; u_int8_t reserved5; u_int8_t reserved6; - u_int8_t host_app_code :6; /* Host application code */ + u_int8_t host_app_code :6; /* host application code */ u_int8_t reserved7_67 :2; - u_int8_t session_format; /* Session format */ + u_int8_t session_format; /* session format */ #define CDR_SESS_CDROM 0x00 #define CDR_SESS_CDI 0x10 #define CDR_SESS_CDROM_XA 0x20 u_int8_t reserved9; - u_int32_t packet_size; /* Packet size in bytes */ - u_int16_t audio_pause_length; /* Audio pause length in secs */ + u_int32_t packet_size; /* packet size in bytes */ + u_int16_t audio_pause_length; /* audio pause length in secs */ u_int8_t media_catalog_number[16]; u_int8_t isr_code[16]; u_int8_t sub_hdr_byte0; @@ -284,75 +275,72 @@ struct write_param { */ } __attribute__((packed)); -/* - * CDROM Read Track Information structure - */ + +/* CDROM Read Track Information structure */ struct acd_track_info { u_int16_t data_length; - u_int8_t track_number; /* Current track number */ - u_int8_t session_number; /* Current session number */ + u_int8_t track_number; /* current track number */ + u_int8_t session_number; /* current session number */ u_int8_t reserved4; - u_int8_t track_mode :4; /* Mode of this track */ - u_int8_t copy :1; /* Generation stamp */ - u_int8_t damage :1; /* Damaged track */ + u_int8_t track_mode :4; /* mode of this track */ + u_int8_t copy :1; /* generation stamp */ + u_int8_t damage :1; /* damaged track */ u_int8_t reserved5_67 :2; - u_int8_t data_mode :4; /* Data mode of this disc */ - u_int8_t fp :1; /* Fixed packet */ - u_int8_t packet :1; /* Packet track */ - u_int8_t blank :1; /* Blank (empty) track */ - u_int8_t rt :1; /* Reserved track */ + u_int8_t data_mode :4; /* data mode of this disc */ + u_int8_t fp :1; /* fixed packet */ + u_int8_t packet :1; /* packet track */ + u_int8_t blank :1; /* blank (empty) track */ + u_int8_t rt :1; /* reserved track */ u_int8_t nwa_valid :1; /* next_writeable_addr field valid */ u_int8_t reserved7_17 :7; - u_int track_start_addr; /* Start of this track */ - u_int next_writeable_addr; /* Next writeable addr on this disc */ - u_int free_blocks; /* Free block on this disc */ - u_int fixed_packet_size; /* Size of packets on this track */ - u_int track_length; /* Length of this track */ + u_int track_start_addr; /* start of this track */ + u_int next_writeable_addr; /* next writeable addr on this disc */ + u_int free_blocks; /* free block on this disc */ + u_int fixed_packet_size; /* size of packets on this track */ + u_int track_length; /* length of this track */ }; -/* - * Structure describing an ATAPI CDROM device - */ +/* Structure describing an ATAPI CDROM device */ struct acd_softc { - struct atapi_softc *atp; /* Controller structure */ - int32_t lun; /* Logical device unit */ - int32_t flags; /* Device state flags */ - int32_t refcnt; /* The number of raw opens */ + struct atapi_softc *atp; /* controller structure */ + int32_t lun; /* logical device unit */ + int32_t flags; /* device state flags */ + int32_t refcnt; /* the number of raw opens */ struct buf_queue_head buf_queue; /* Queue of i/o requests */ - struct toc toc; /* Table of disc contents */ + struct toc toc; /* table of disc contents */ struct { - u_int32_t volsize; /* Volume size in blocks */ - u_int32_t blksize; /* Block size in bytes */ - } info; - struct audiopage au; /* Audio page info */ - struct cappage cap; /* Capabilities page info */ - struct audiopage aumask; /* Audio page mask */ - struct { /* Subchannel info */ - u_int8_t void0; - u_int8_t audio_status; - u_int16_t data_length; - u_int8_t data_format; - u_int8_t control; - u_int8_t track; - u_int8_t indx; - u_int32_t abslba; - u_int32_t rellba; + u_int32_t volsize; /* volume size in blocks */ + u_int32_t blksize; /* block size in bytes */ + } info; + struct audiopage au; /* audio page info */ + struct cappage cap; /* capabilities page info */ + struct audiopage aumask; /* audio page mask */ + struct { /* subchannel info */ + u_int8_t void0; + u_int8_t audio_status; + u_int16_t data_length; + u_int8_t data_format; + u_int8_t control; + u_int8_t track; + u_int8_t indx; + u_int32_t abslba; + u_int32_t rellba; } subchan; - struct changer *changer_info; /* Changer info */ - int32_t slot; /* This lun's slot number */ - u_int32_t block_size; /* Blocksize currently used */ - u_int8_t dummy; /* Use dummy writes */ - u_int8_t speed; /* Select drive speed */ - u_int32_t next_writeable_lba; /* Next writable position */ - struct wormio_prepare_track preptrack; /* Scratch region */ + struct changer *changer_info; /* changer info */ + int32_t slot; /* this lun's slot number */ + u_int32_t block_size; /* blocksize currently used */ + u_int8_t dummy; /* use dummy writes */ + u_int8_t speed; /* select drive speed */ + u_int32_t next_writeable_lba; /* next writable position */ + struct wormio_prepare_track preptrack; /* scratch region */ struct devstat *stats; /* devstat entry */ #ifdef DEVFS - void *ra_devfs_token; - void *rc_devfs_token; - void *a_devfs_token; - void *c_devfs_token; + void *a_cdevfs_token; + void *c_cdevfs_token; + void *a_bdevfs_token; + void *c_bdevfs_token; #endif }; -#define CDRIOCBLANK _IO('c',100) /* Blank a CDRW disc */ +#define CDRIOCBLANK _IO('c',100) /* blank a CDRW disc */ #define CDRIOCNEXTWRITEABLEADDR _IOR('c',101,int) diff --git a/sys/dev/ata/atapi-fd.c b/sys/dev/ata/atapi-fd.c new file mode 100644 index 0000000..6aa18db --- /dev/null +++ b/sys/dev/ata/atapi-fd.c @@ -0,0 +1,434 @@ +/*- + * Copyright (c) 1998,1999 Søren Schmidt + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer, + * without modification, immediately at the beginning of the file. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * $Id$ + */ + +#include "ata.h" +#include "atapifd.h" +#include "opt_devfs.h" + +#if NATA > 0 && NATAPIFD > 0 + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef DEVFS +#include +#endif +#include +#include +#include + +static d_open_t afdopen; +static d_close_t afdclose; +static d_read_t afdread; +static d_write_t afdwrite; +static d_ioctl_t afdioctl; +static d_strategy_t afdstrategy; + +#define CDEV_MAJOR 87 +#define BDEV_MAJOR 1 + +static struct cdevsw afd_cdevsw = { + afdopen, afdclose, afdread, afdwrite, + afdioctl, nostop, nullreset, nodevtotty, + seltrue, nommap, afdstrategy, "afd", + NULL, -1 }; + +#define NUNIT 8 +#define UNIT(d) ((minor(d) >> 3) & 3) + +#define F_OPEN 0x0001 /* The device is opened */ +#define F_MEDIA_CHANGED 0x0002 /* The media have changed */ + +static struct afd_softc *afdtab[NUNIT]; /* Drive info by unit number */ +static int32_t afdnlun = 0; /* Number of config'd drives */ + +int32_t afdattach(struct atapi_softc *); +static int32_t afd_sense(struct afd_softc *); +static void afd_describe(struct afd_softc *); +static void afd_strategy(struct buf *); +static void afd_start(struct afd_softc *); +static void afd_done(struct atapi_request *); +static int32_t afd_start_device(struct afd_softc *, int32_t); +static int32_t afd_lock_device(struct afd_softc *, int32_t); +static int32_t afd_eject(struct afd_softc *, int32_t); +static void afd_drvinit(void *); + +int32_t +afdattach(struct atapi_softc *atp) +{ + struct afd_softc *fdp; + + if (afdnlun >= NUNIT) { + printf("afd: too many units\n"); + return -1; + } + fdp = malloc(sizeof(struct afd_softc), M_TEMP, M_NOWAIT); + if (!fdp) { + printf("afd: out of memory\n"); + return -1; + } + bzero(fdp, sizeof(struct afd_softc)); + bufq_init(&fdp->buf_queue); + fdp->atp = atp; + fdp->lun = afdnlun; + fdp->flags = F_MEDIA_CHANGED; + + if (afd_sense(fdp)) { + free(fdp, M_TEMP); + return -1; + } + + afd_describe(fdp); + afdtab[afdnlun++] = fdp; + devstat_add_entry(&fdp->stats, "afd", fdp->lun, DEV_BSIZE, + DEVSTAT_NO_ORDERED_TAGS, + DEVSTAT_TYPE_DIRECT | DEVSTAT_TYPE_IF_IDE, + 0x178); +#ifdef DEVFS + fdp->cdevs_token = devfs_add_devswf(&afd_cdevsw, dkmakeminor(fdp->lun, 0,0), + DV_CHR, UID_ROOT, GID_OPERATOR, + 0640, "rafd%d", fdp->lun); + fdp->bdevs_token = devfs_add_devswf(&afd_cdevsw, dkmakeminor(fdp->lun, 0,0), + DV_BLK, UID_ROOT, GID_OPERATOR, + 0640, "afd%d", fdp->lun); +#endif + return 0; +} + +static int32_t +afd_sense(struct afd_softc *fdp) +{ + int32_t error, count; + int8_t buffer[256]; + int8_t ccb[16] = { ATAPI_MODE_SENSE, 0, ATAPI_REWRITEABLE_CAP_PAGE, + 0, 0, 0, 0, sizeof(buffer)>>8, sizeof(buffer) & 0xff, + 0, 0, 0, 0, 0, 0, 0 }; + + bzero(buffer, sizeof(buffer)); + /* Get drive capabilities, some drives needs this repeated */ + for (count = 0 ; count < 5 ; count++) { + if (!(error = atapi_queue_cmd(fdp->atp, ccb, buffer, sizeof(buffer), + A_READ, NULL, NULL, NULL))) + break; + } +#ifdef AFD_DEBUG + atapi_dump("afd: sense", buffer, sizeof(buffer)); +#endif + if (error) + return error; + bcopy(buffer, &fdp->header, sizeof(struct afd_header)); + bcopy(buffer+sizeof(struct afd_header), &fdp->cap, + sizeof(struct afd_cappage)); + if (fdp->cap.page_code != ATAPI_REWRITEABLE_CAP_PAGE) + return 1; + fdp->cap.cylinders = ntohs(fdp->cap.cylinders); + fdp->cap.sector_size = ntohs(fdp->cap.sector_size); + return 0; +} + +static void +afd_describe(struct afd_softc *fdp) +{ + int8_t model_buf[40+1]; + int8_t revision_buf[8+1]; + + bpack(fdp->atp->atapi_parm->model, model_buf, sizeof(model_buf)); + bpack(fdp->atp->atapi_parm->revision, revision_buf, sizeof(revision_buf)); + printf("afd%d: <%s/%s> rewriteable drive at ata%d as %s\n", + fdp->lun, model_buf, revision_buf, + fdp->atp->controller->unit, + (fdp->atp->unit == ATA_MASTER) ? "master" : "slave "); + printf("afd%d: %luMB (%u sectors), %u cyls, %u heads, %u S/T, %u B/S\n", + afdnlun, + (fdp->cap.cylinders * fdp->cap.heads * fdp->cap.sectors) / + ((1024L * 1024L) / fdp->cap.sector_size), + fdp->cap.cylinders * fdp->cap.heads * fdp->cap.sectors, + fdp->cap.cylinders, fdp->cap.heads, fdp->cap.sectors, + fdp->cap.sector_size); + printf("afd%d: ", fdp->lun); + switch (fdp->header.medium_type) { + default: printf("Unknown media (0x%x)", fdp->header.medium_type); + } + if (fdp->header.wp) printf(", writeprotected"); + printf("\n"); +} + +static int32_t +afdopen(dev_t dev, int32_t flags, int32_t fmt, struct proc *p) +{ + struct afd_softc *fdp; + struct disklabel label; + int32_t lun = UNIT(dev); + + if (lun >= afdnlun || !(fdp = afdtab[lun])) + return ENXIO; + + fdp->flags &= ~F_MEDIA_CHANGED; + afd_lock_device(fdp, 1); + if (afd_sense(fdp)) + printf("afd%d: sense media type failed\n", fdp->lun); + + /* build disklabel and initilize slice tables */ + bzero(&label, sizeof label); + label.d_secsize = fdp->cap.sector_size; + label.d_nsectors = fdp->cap.sectors; + label.d_ntracks = fdp->cap.heads; + label.d_ncylinders = fdp->cap.cylinders; + label.d_secpercyl = fdp->cap.heads * fdp->cap.sectors; + label.d_secperunit = fdp->cap.heads * fdp->cap.sectors * fdp->cap.cylinders; + + /* Initialize slice tables. */ + return dsopen("afd", dev, fmt, 0, &fdp->slices, &label, afd_strategy, + (ds_setgeom_t *)NULL, &afd_cdevsw); +} + +static int32_t +afdclose(dev_t dev, int32_t flags, int32_t fmt, struct proc *p) +{ + int32_t lun = UNIT(dev); + struct afd_softc *fdp; + + if (lun >= afdnlun || !(fdp = afdtab[lun])) + return ENXIO; + + dsclose(dev, fmt, fdp->slices); + if(!dsisopen(fdp->slices)) + afd_lock_device(fdp, 0); + return 0; +} + +static int32_t +afdread(dev_t dev, struct uio *uio, int32_t ioflag) +{ + return physio(afdstrategy, NULL, dev, 1, minphys, uio); +} + +static int32_t +afdwrite(dev_t dev, struct uio *uio, int32_t ioflag) +{ + return physio(afdstrategy, NULL, dev, 0, minphys, uio); +} + +static int32_t +afdioctl(dev_t dev, u_long cmd, caddr_t addr, int32_t flag, struct proc *p) +{ + int32_t lun = UNIT(dev); + int32_t error = 0; + struct afd_softc *fdp; + + if (lun >= afdnlun || !(fdp = afdtab[lun])) + return ENXIO; + + switch (cmd) { + + case CDIOCEJECT: + if ((fdp->flags & F_OPEN) && fdp->refcnt) + return EBUSY; + return afd_eject(fdp, 0); + + case CDIOCCLOSE: + if ((fdp->flags & F_OPEN) && fdp->refcnt) + return 0; + return afd_eject(fdp, 1); + + default: + return ENOTTY; + } + return error; +} + +static void +afdstrategy(struct buf *bp) +{ + int32_t lun = UNIT(bp->b_dev); + struct afd_softc *fdp = afdtab[lun]; + int32_t x; + + if (bp->b_bcount == 0) { + bp->b_resid = 0; + biodone(bp); + return; + } + if (dscheck(bp, fdp->slices) <= 0) { + x = splbio(); + biodone(bp); + splx(x); + return; + } + x = splbio(); + bufq_insert_tail(&fdp->buf_queue, bp); + afd_start(fdp); + splx(x); +} + +static void +afd_strategy(struct buf *bp) +{ + afdstrategy(bp); +} + +static void +afd_start(struct afd_softc *fdp) +{ + struct buf *bp = bufq_first(&fdp->buf_queue); + u_int32_t lba, count; + int8_t ccb[16]; + + if (!bp) + return; + bzero(ccb, sizeof(ccb)); + bufq_remove(&fdp->buf_queue, bp); + + /* Should reject all queued entries if media have changed. */ + if (fdp->flags & F_MEDIA_CHANGED) { + bp->b_error = EIO; + bp->b_flags |= B_ERROR; + biodone(bp); + return; + } + + lba = bp->b_blkno / (fdp->cap.sector_size / DEV_BSIZE); + count = (bp->b_bcount + (fdp->cap.sector_size - 1)) / fdp->cap.sector_size; + + if (bp->b_flags & B_READ) + ccb[0] = ATAPI_READ_BIG; + else + ccb[0] = ATAPI_WRITE_BIG; + + ccb[1] = 0; + ccb[2] = lba>>24; + ccb[3] = lba>>16; + ccb[4] = lba>>8; + ccb[5] = lba; + ccb[7] = count>>8; + ccb[8] = count; + + devstat_start_transaction(&fdp->stats); + + atapi_queue_cmd(fdp->atp, ccb, bp->b_data, bp->b_bcount, + (bp->b_flags & B_READ) ? A_READ : 0, afd_done, fdp, bp); +} + +static void +afd_done(struct atapi_request *request) +{ + struct buf *bp = request->bp; + struct afd_softc *fdp = request->driver; + + devstat_end_transaction(&fdp->stats, bp->b_bcount-request->bytecount, + DEVSTAT_TAG_NONE, + (bp->b_flags&B_READ) ? DEVSTAT_READ:DEVSTAT_WRITE); + + if (request->result) { + printf("afd_done: "); + atapi_error(request->device, request->result); + bp->b_error = EIO; + bp->b_flags |= B_ERROR; + } + else + bp->b_resid = request->bytecount; + biodone(bp); + afd_start(fdp); +} + +static int32_t +afd_start_device(struct afd_softc *fdp, int32_t start) +{ + int8_t ccb[16] = { ATAPI_START_STOP, 0, 0, 0, start, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; + + return atapi_queue_cmd(fdp->atp, ccb, NULL, 0, 0, NULL, NULL, NULL); +} + +static int32_t +afd_lock_device(struct afd_softc *fdp, int32_t lock) +{ + int8_t ccb[16] = { ATAPI_PREVENT_ALLOW, 0, 0, 0, lock, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; + + return atapi_queue_cmd(fdp->atp, ccb, NULL, 0, 0, NULL, NULL, NULL); +} + +static int32_t +afd_eject(struct afd_softc *fdp, int32_t close) +{ + int32_t error; + + error = afd_start_device(fdp, 0); + if ((error & ATAPI_SK_MASK) && + ((error & ATAPI_SK_MASK) == ATAPI_SK_NOT_READY || + (error & ATAPI_SK_MASK) == ATAPI_SK_UNIT_ATTENTION)) { + + if (!close) + return 0; + if ((error = afd_start_device(fdp, 3))) + return error; + afd_lock_device(fdp, 1); + return 0; + } + if (error) { + atapi_error(fdp->atp, error); + return EIO; + } + if (close) + return 0; + + tsleep((caddr_t) &lbolt, PRIBIO, "afdej1", 0); + tsleep((caddr_t) &lbolt, PRIBIO, "afdej2", 0); + afd_lock_device(fdp, 0); + fdp->flags |= F_MEDIA_CHANGED; + return afd_start_device(fdp, 2); +} + + +static void +afd_drvinit(void *unused) +{ + static afd_devsw_installed = 0; + + if (!afd_devsw_installed) { + cdevsw_add_generic(BDEV_MAJOR, CDEV_MAJOR, &afd_cdevsw); + afd_devsw_installed = 1; + } +} + +SYSINIT(afddev, SI_SUB_DRIVERS, SI_ORDER_MIDDLE, afd_drvinit, NULL) +#endif /* NATA & NATAPIFD */ diff --git a/sys/dev/ata/atapi-fd.h b/sys/dev/ata/atapi-fd.h new file mode 100644 index 0000000..9904992 --- /dev/null +++ b/sys/dev/ata/atapi-fd.h @@ -0,0 +1,90 @@ +/*- + * Copyright (c) 1998,1999 Søren Schmidt + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer, + * without modification, immediately at the beginning of the file. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * $Id$ + */ + +/* MODE SENSE parameter header */ +struct afd_header { + u_int16_t data_length; + u_int8_t medium_type; +#define MFD_2DD_UN 0x10 +#define MFD_2DD 0x11 +#define MFD_2HD_UN 0x20 +#define MFD_2HD_12_98 0x22 +#define MFD_2HD_12 0x23 +#define MFD_2HD_144 0x24 +#define MFD_LS120 0x31 + +#define MFD_UNKNOWN 0x00 +#define MFD_NO_DISC 0x70 +#define MFD_DOOR_OPEN 0x71 +#define MFD_FMT_ERROR 0x72 + + u_int8_t reserved0 :7; + u_int8_t wp :1; /* write protect */ + u_int8_t unused[4]; +}; + +/* ATAPI Rewriteable drive Capabilities and Mechanical Status Page */ +#define ATAPI_REWRITEABLE_CAP_PAGE 0x05 + +struct afd_cappage { + u_int8_t page_code :6; + u_int8_t reserved1_6 :1; + u_int8_t ps :1; /* page save supported */ + u_int8_t page_length; /* page length */ + u_int16_t transfer_rate; /* in kilobits per second */ + u_int8_t heads; /* number of heads */ + u_int8_t sectors; /* number of sectors per track */ + u_int16_t sector_size; /* number of bytes per sector */ + u_int16_t cylinders; /* number of cylinders */ + u_int8_t reserved10[10]; + u_int8_t motor_delay; /* motor off delay */ + u_int8_t reserved21[7]; + u_int16_t rpm; /* rotations per minute */ + u_int8_t reserved30[2]; +}; + + +struct afd_softc { + struct atapi_softc *atp; /* controller structure */ + int32_t lun; /* logical device unit */ + int32_t flags; /* device state flags */ + int32_t refcnt; /* the number of raw opens */ + int32_t maxblks; /* transfer size limit */ + struct buf_queue_head buf_queue; /* queue of i/o requests */ + struct afd_header header; /* capabilities page info */ + struct afd_cappage cap; /* capabilities page info */ + struct diskslices *slices; /* virtual drives */ + struct devstat stats; +#ifdef DEVFS + void *cdevs_token; + void *bdevs_token; +#endif +}; + diff --git a/sys/dev/ata/atapi-tape.c b/sys/dev/ata/atapi-tape.c index ea21e99..c51521d 100644 --- a/sys/dev/ata/atapi-tape.c +++ b/sys/dev/ata/atapi-tape.c @@ -25,7 +25,7 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * - * $Id: atapi-tape.c,v 1.5 1999/03/01 21:03:15 sos Exp sos $ + * $Id: atapi-tape.c,v 1.1 1999/03/01 21:19:18 sos Exp $ */ #include "ata.h" @@ -41,6 +41,7 @@ #include #include #include +#include #include #ifdef DEVFS #include @@ -50,21 +51,21 @@ #include #include -static d_open_t astopen; -static d_read_t astread; -static d_write_t astwrite; -static d_close_t astclose; -static d_ioctl_t astioctl; -static d_strategy_t aststrategy; +static d_open_t astopen; +static d_close_t astclose; +static d_read_t astread; +static d_write_t astwrite; +static d_ioctl_t astioctl; +static d_strategy_t aststrategy; #define CDEV_MAJOR 90 #define BDEV_MAJOR 24 static struct cdevsw ast_cdevsw = { - astopen, astclose, astread, astwrite, - astioctl, nostop, nullreset, nodevtotty, - seltrue, nommap, aststrategy, "ast", - NULL, -1 }; + astopen, astclose, astread, astwrite, + astioctl, nostop, nullreset, nodevtotty, + seltrue, nommap, aststrategy, "ast", + NULL, -1 }; static u_int32_t ast_total = 0; @@ -123,12 +124,11 @@ astattach(struct atapi_softc *atp) DEVSTAT_NO_ORDERED_TAGS, DEVSTAT_TYPE_SEQUENTIAL | DEVSTAT_TYPE_IF_IDE, 0x178); - - #ifdef DEVFS - t->cdevs = devfs_add_devswf(&ast_cdevsw, 0, DV_CHR, UID_ROOT, GID_OPERATOR, - 0640, "rast%d", t->lun); -#endif /* DEVFS */ + stp->cdevs_token = devfs_add_devswf(&ast_cdevsw, dkmakeminor(stp->lun, 0,0), + DV_CHR, UID_ROOT, GID_OPERATOR, 0640, + "rast%d", stp->lun); +#endif return 0; } @@ -209,14 +209,14 @@ ast_describe(struct ast_softc *stp) printf("\n"); } -int +static int32_t astopen(dev_t dev, int32_t flags, int32_t fmt, struct proc *p) { int32_t lun = UNIT(dev); struct ast_softc *stp; if (lun >= astnlun || !(stp = asttab[lun])) - return(ENXIO); + return ENXIO; if (stp->flags == F_OPEN) return EBUSY; if (ast_sense(stp)) @@ -225,17 +225,17 @@ astopen(dev_t dev, int32_t flags, int32_t fmt, struct proc *p) stp->flags &= ~(F_DATA_WRITTEN | F_FM_WRITTEN); stp->flags |= F_OPEN; ast_total = 0; - return(0); + return 0; } -int32_t +static int32_t astclose(dev_t dev, int32_t flags, int32_t fmt, struct proc *p) { int32_t lun = UNIT(dev); struct ast_softc *stp; if (lun >= astnlun || !(stp = asttab[lun])) - return(ENXIO); + return ENXIO; /* Flush buffers, some drives fail here, but they should report ctl = 0 */ if (stp->cap.ctl && (stp->flags & F_DATA_WRITTEN)) @@ -254,111 +254,22 @@ astclose(dev_t dev, int32_t flags, int32_t fmt, struct proc *p) printf("ast%d: %ud total bytes transferred\n", stp->lun, ast_total); #endif stp->flags &= ~F_CTL_WARN; - return(0); + return 0; } -static int +static int32_t astread(dev_t dev, struct uio *uio, int32_t ioflag) { - return (physio(aststrategy, NULL, dev, 1, minphys, uio)); + return physio(aststrategy, NULL, dev, 1, minphys, uio); } -static int +static int32_t astwrite(dev_t dev, struct uio *uio, int32_t ioflag) { - return (physio(aststrategy, NULL, dev, 0, minphys, uio)); -} - -void -aststrategy(struct buf *bp) -{ - int32_t lun = UNIT(bp->b_dev); - struct ast_softc *stp = asttab[lun]; - int32_t x; - - /* If it's a null transfer, return immediatly. */ - if (bp->b_bcount == 0) { - bp->b_resid = 0; - biodone(bp); - return; - } - - /* Check for != blocksize requests */ - if (bp->b_bcount % stp->blksize) { - printf("ast%d: bad request, must be multiple of %d\n", - lun, stp->blksize); - bp->b_error = EIO; - bp->b_flags |= B_ERROR; - biodone(bp); - return; - } - if (bp->b_bcount > stp->blksize * stp->cap.ctl) { - if ((stp->flags & F_CTL_WARN) == 0) { - printf("ast%d: WARNING: CTL exceeded %ld>%d\n", - lun, bp->b_bcount, stp->blksize * stp->cap.ctl); - stp->flags |= F_CTL_WARN; - } - } - - x = splbio(); - ast_total += bp->b_bcount; - bufq_insert_tail(&stp->buf_queue, bp); - ast_start(stp); - splx(x); -} - -static void -ast_start(struct ast_softc *stp) -{ - struct buf *bp = bufq_first(&stp->buf_queue); - u_long blkcount; - int8_t ccb[16]; - - if (!bp) - return; - bzero(ccb, sizeof(ccb)); - bufq_remove(&stp->buf_queue, bp); - blkcount = bp->b_bcount / stp->blksize; - if (bp->b_flags & B_READ) { - ccb[0] = ATAPI_TAPE_READ_CMD; - } else { - ccb[0] = ATAPI_TAPE_WRITE_CMD; - stp->flags |= F_DATA_WRITTEN; - } - ccb[1] = 1; - ccb[2] = blkcount>>16; - ccb[3] = blkcount>>8; - ccb[4] = blkcount; - - devstat_start_transaction(&stp->stats); - - atapi_queue_cmd(stp->atp, ccb, bp->b_data, bp->b_bcount, - (bp->b_flags & B_READ) ? A_READ : 0, ast_done, stp, bp); -} - -static void -ast_done(struct atapi_request *request) -{ - struct buf *bp = request->bp; - struct ast_softc *stp = request->driver; - - devstat_end_transaction(&stp->stats, bp->b_bcount-request->bytecount, - DEVSTAT_TAG_NONE, - (bp->b_flags&B_READ) ? DEVSTAT_READ:DEVSTAT_WRITE); - - if (request->result) { - printf("ast_done: "); - atapi_error(request->device, request->result); - bp->b_error = EIO; - bp->b_flags |= B_ERROR; - } - else - bp->b_resid = request->bytecount; - biodone(bp); - ast_start(stp); + return physio(aststrategy, NULL, dev, 0, minphys, uio); } -int32_t +static int32_t astioctl(dev_t dev, u_long cmd, caddr_t addr, int32_t flag, struct proc *p) { int32_t lun = UNIT(dev); @@ -444,12 +355,100 @@ astioctl(dev_t dev, u_long cmd, caddr_t addr, int32_t flag, struct proc *p) return error; } default: - return(ENOTTY); + return ENOTTY; + } + return error; +} + +static void +aststrategy(struct buf *bp) +{ + int32_t lun = UNIT(bp->b_dev); + struct ast_softc *stp = asttab[lun]; + int32_t x; + + /* If it's a null transfer, return immediatly. */ + if (bp->b_bcount == 0) { + bp->b_resid = 0; + biodone(bp); + return; + } + + /* Check for != blocksize requests */ + if (bp->b_bcount % stp->blksize) { + printf("ast%d: bad request, must be multiple of %d\n", + lun, stp->blksize); + bp->b_error = EIO; + bp->b_flags |= B_ERROR; + biodone(bp); + return; + } + if (bp->b_bcount > stp->blksize * stp->cap.ctl) { + if ((stp->flags & F_CTL_WARN) == 0) { + printf("ast%d: WARNING: CTL exceeded %ld>%d\n", + lun, bp->b_bcount, stp->blksize * stp->cap.ctl); + stp->flags |= F_CTL_WARN; + } + } + + x = splbio(); + ast_total += bp->b_bcount; + bufq_insert_tail(&stp->buf_queue, bp); + ast_start(stp); + splx(x); +} + +static void +ast_start(struct ast_softc *stp) +{ + struct buf *bp = bufq_first(&stp->buf_queue); + u_int32_t blkcount; + int8_t ccb[16]; + + if (!bp) + return; + bzero(ccb, sizeof(ccb)); + bufq_remove(&stp->buf_queue, bp); + blkcount = bp->b_bcount / stp->blksize; + if (bp->b_flags & B_READ) { + ccb[0] = ATAPI_TAPE_READ_CMD; + } else { + ccb[0] = ATAPI_TAPE_WRITE_CMD; + stp->flags |= F_DATA_WRITTEN; + } + ccb[1] = 1; + ccb[2] = blkcount>>16; + ccb[3] = blkcount>>8; + ccb[4] = blkcount; + + devstat_start_transaction(&stp->stats); + + atapi_queue_cmd(stp->atp, ccb, bp->b_data, bp->b_bcount, + (bp->b_flags & B_READ) ? A_READ : 0, ast_done, stp, bp); +} + +static void +ast_done(struct atapi_request *request) +{ + struct buf *bp = request->bp; + struct ast_softc *stp = request->driver; + + devstat_end_transaction(&stp->stats, bp->b_bcount-request->bytecount, + DEVSTAT_TAG_NONE, + (bp->b_flags&B_READ) ? DEVSTAT_READ:DEVSTAT_WRITE); + + if (request->result) { + atapi_error(request->device, request->result); + bp->b_error = EIO; + bp->b_flags |= B_ERROR; } - return(error); + else + bp->b_resid = request->bytecount; + biodone(bp); + ast_start(stp); } -static int +static int32_t ast_space_cmd(struct ast_softc *stp, u_int8_t function, u_int32_t count) { int32_t error; @@ -463,14 +462,13 @@ ast_space_cmd(struct ast_softc *stp, u_int8_t function, u_int32_t count) ccb[4] = count; if ((error = atapi_queue_cmd(stp->atp, ccb, NULL, 0, 0, NULL, NULL, NULL))){ - printf("ast_space_cmd: "); atapi_error(stp->atp, error); return EIO; } return 0; } -static int +static int32_t ast_write_filemark(struct ast_softc *stp, u_int8_t function) { int32_t error; @@ -487,14 +485,13 @@ ast_write_filemark(struct ast_softc *stp, u_int8_t function) ccb[4] = function; if ((error = atapi_queue_cmd(stp->atp, ccb, NULL, 0, 0, NULL, NULL, NULL))){ - printf("ast_write_filemark: "); atapi_error(stp->atp, error); return EIO; } return 0; } -static int +static int32_t ast_load_unload(struct ast_softc *stp, u_int8_t function) { int32_t error; @@ -505,14 +502,13 @@ ast_load_unload(struct ast_softc *stp, u_int8_t function) ccb[4] = function; if ((error = atapi_queue_cmd(stp->atp, ccb, NULL, 0, 0, NULL, NULL, NULL))){ - printf("ast_load_unload: "); atapi_error(stp->atp, error); return EIO; } return 0; } -static int +static int32_t ast_erase(struct ast_softc *stp) { int32_t error; @@ -526,14 +522,13 @@ ast_erase(struct ast_softc *stp) ccb[1] = 3; if ((error = atapi_queue_cmd(stp->atp, ccb, NULL, 0, 0, NULL, NULL, NULL))){ - printf("ast_erase: "); atapi_error(stp->atp, error); return EIO; } return 0; } -static int +static int32_t ast_rewind(struct ast_softc *stp) { int32_t error; @@ -543,7 +538,6 @@ ast_rewind(struct ast_softc *stp) ccb[0] = ATAPI_TAPE_REWIND; if ((error = atapi_queue_cmd(stp->atp, ccb, NULL, 0, 0, NULL, NULL, NULL))){ - printf("ast_rewind: "); atapi_error(stp->atp, error); return EIO; } diff --git a/sys/dev/ata/atapi-tape.h b/sys/dev/ata/atapi-tape.h index fe0ecfa..cbc7461 100644 --- a/sys/dev/ata/atapi-tape.h +++ b/sys/dev/ata/atapi-tape.h @@ -1,3 +1,32 @@ +/*- + * Copyright (c) 1998,1999 Søren Schmidt + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer, + * without modification, immediately at the beginning of the file. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * $Id: atapi-tape.h,v 1.1 1999/03/01 21:19:18 sos Exp $ + */ /* ATAPI tape commands not in std ATAPI command set */ #define ATAPI_TAPE_REWIND 0x01 @@ -18,95 +47,89 @@ #define DSC_POLL_INTERVAL 10 -/* - * MODE SENSE parameter header - */ +/* MODE SENSE parameter header */ struct ast_header { - u_int8_t data_length; /* Total length of data */ - u_int8_t medium_type; /* Medium type (if any) */ - u_int8_t dsp; /* Device specific parameter */ - u_int8_t bdl; /* Block Descriptor Length */ + u_int8_t data_length; /* total length of data */ + u_int8_t medium_type; /* medium type (if any) */ + u_int8_t dsp; /* device specific parameter */ + u_int8_t bdl; /* block Descriptor Length */ }; -/* - * ATAPI tape drive Capabilities and Mechanical Status Page - */ +/* ATAPI tape drive Capabilities and Mechanical Status Page */ #define ATAPI_TAPE_CAP_PAGE 0x2a struct ast_cappage { - u_int8_t page_code :6; /* Page code == 0x2a */ + u_int8_t page_code :6; /* page code == 0x2a */ u_int8_t reserved1_67 :2; - u_int8_t page_length; /* Page Length == 0x12 */ + u_int8_t page_length; /* page Length == 0x12 */ u_int8_t reserved2; u_int8_t reserved3; - u_int8_t readonly :1; /* Read Only Mode */ + u_int8_t readonly :1; /* read Only Mode */ u_int8_t reserved4_1234 :4; - u_int8_t reverse :1; /* Supports reverse direction */ + u_int8_t reverse :1; /* supports reverse direction */ u_int8_t reserved4_67 :2; u_int8_t reserved5_012 :3; - u_int8_t eformat :1; /* Supports ERASE formatting */ + u_int8_t eformat :1; /* supports ERASE formatting */ u_int8_t reserved5_4 :1; - u_int8_t qfa :1; /* Supports QFA formats */ + u_int8_t qfa :1; /* supports QFA formats */ u_int8_t reserved5_67 :2; - u_int8_t lock :1; /* Supports locking media */ - u_int8_t locked :1; /* The media is locked */ - u_int8_t prevent :1; /* Defaults to prevent state */ - u_int8_t eject :1; /* Supports eject */ - u_int8_t disconnect :1; /* Can break request > ctl */ + u_int8_t lock :1; /* supports locking media */ + u_int8_t locked :1; /* the media is locked */ + u_int8_t prevent :1; /* defaults to prevent state */ + u_int8_t eject :1; /* supports eject */ + u_int8_t disconnect :1; /* can break request > ctl */ u_int8_t reserved6_5 :1; - u_int8_t ecc :1; /* Supports error correction */ - u_int8_t compress :1; /* Supports data compression */ + u_int8_t ecc :1; /* supports error correction */ + u_int8_t compress :1; /* supports data compression */ u_int8_t reserved7_0 :1; - u_int8_t blk512 :1; /* Supports 512b block size */ - u_int8_t blk1024 :1; /* Supports 1024b block size */ + u_int8_t blk512 :1; /* supports 512b block size */ + u_int8_t blk1024 :1; /* supports 1024b block size */ u_int8_t reserved7_3456 :4; - u_int8_t slowb :1; /* Restricts byte count */ - u_int16_t max_speed; /* Supported speed in KBps */ - u_int16_t max_defects; /* Max stored defect entries */ - u_int16_t ctl; /* Continuous Transfer Limit */ - u_int16_t speed; /* Current Speed, in KBps */ - u_int16_t buffer_size; /* Buffer Size, in 512 bytes */ + u_int8_t slowb :1; /* restricts byte count */ + u_int16_t max_speed; /* supported speed in KBps */ + u_int16_t max_defects; /* max stored defect entries */ + u_int16_t ctl; /* continuous transfer limit */ + u_int16_t speed; /* current Speed, in KBps */ + u_int16_t buffer_size; /* buffer Size, in 512 bytes */ u_int8_t reserved18; u_int8_t reserved19; }; -/* - * REQUEST SENSE structure - */ +/* REQUEST SENSE structure */ struct ast_reqsense { - u_int8_t error_code :7; /* Current or deferred errors */ - u_int8_t valid :1; /* Follows QIC-157C */ - u_int8_t reserved1; /* Segment Number - Reserved */ - u_int8_t sense_key :4; /* Sense Key */ - u_int8_t reserved2_4 :1; /* Reserved */ - u_int8_t ili :1; /* Incorrect Length Indicator */ - u_int8_t eom :1; /* End Of Medium */ - u_int8_t filemark :1; /* Filemark */ - u_int8_t info __attribute__((packed)); /* Cmd specific info */ - u_int8_t asl; /* Additional sense length (n-7) */ - u_int8_t command_specific; /* Additional cmd specific info */ - u_int8_t asc; /* Additional Sense Code */ - u_int8_t ascq; /* Additional Sense Code Qualifier */ - u_int8_t replaceable_unit_code; /* Field Replaceable Unit Code */ - u_int8_t sk_specific1 :7; /* Sense Key Specific */ - u_int8_t sksv :1; /* Sense Key Specific info valid */ - u_int8_t sk_specific2; /* Sense Key Specific */ - u_int8_t sk_specific3; /* Sense Key Specific */ - u_int8_t pad[2]; /* Padding */ + u_int8_t error_code :7; /* current or deferred errors */ + u_int8_t valid :1; /* follows QIC-157C */ + u_int8_t reserved1; /* Segment number - reserved */ + u_int8_t sense_key :4; /* sense key */ + u_int8_t reserved2_4 :1; /* reserved */ + u_int8_t ili :1; /* incorrect length indicator */ + u_int8_t eom :1; /* end of medium */ + u_int8_t filemark :1; /* filemark */ + u_int8_t info __attribute__((packed)); /* cmd specific info */ + u_int8_t asl; /* additional sense length (n-7) */ + u_int8_t command_specific; /* additional cmd specific info */ + u_int8_t asc; /* additional sense code */ + u_int8_t ascq; /* additional sense code qualifier */ + u_int8_t replaceable_unit_code; /* field replaceable unit code */ + u_int8_t sk_specific1 :7; /* sense key specific */ + u_int8_t sksv :1; /* sense key specific info valid */ + u_int8_t sk_specific2; /* sense key specific */ + u_int8_t sk_specific3; /* sense key Specific */ + u_int8_t pad[2]; /* padding */ }; struct ast_softc { - struct atapi_softc *atp; /* Controller structure */ - int32_t lun; /* Logical device unit */ - int32_t flags; /* Device state flags */ - int32_t blksize; /* Block size (512 | 1024) */ - struct buf_queue_head buf_queue; /* Queue of i/o requests */ - struct atapi_params *param; /* Drive parameters table */ + struct atapi_softc *atp; /* controller structure */ + int32_t lun; /* logical device unit */ + int32_t flags; /* device state flags */ + int32_t blksize; /* block size (512 | 1024) */ + struct buf_queue_head buf_queue; /* queue of i/o requests */ + struct atapi_params *param; /* drive parameters table */ struct ast_header header; /* MODE SENSE param header */ - struct ast_cappage cap; /* Capabilities page info */ + struct ast_cappage cap; /* capabilities page info */ struct devstat stats; /* devstat entry */ #ifdef DEVFS - void *cdevs; - void *bdevs; + void *cdevs_token; + void *bdevs_token; #endif }; -- cgit v1.1