Pull in pieces of Manuel's patch6:
authordownsj <downsj@openbsd.org>
Wed, 4 Sep 1996 00:51:13 +0000 (00:51 +0000)
committerdownsj <downsj@openbsd.org>
Wed, 4 Sep 1996 00:51:13 +0000 (00:51 +0000)
- At Milton Ngan's request, wdc now probes for atapi devices first, and
  then wd drives, because some old atapi devices were detected as ide
     drives.
   - Integration of Milton Ngan's fix for some
 'wdc_atapi_intr: unknown phase 1' due to a timing problem.

Some additional changes (like ADEV_* -> AQUIRK_*) for the sake of
compatibility.  Manuel's additional quirk type was added as well.

I'm not sure I like the retry change to wdc.c; please let me know if anyone
has any problems with their drives.

sys/dev/atapi/acd.c
sys/dev/atapi/atapiconf.c
sys/dev/atapi/atapilink.h
sys/dev/isa/wdc.c

index 5384fd3..0e981a6 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: acd.c,v 1.10 1996/08/09 06:57:58 niklas Exp $ */
+/*     $OpenBSD: acd.c,v 1.11 1996/09/04 00:51:13 downsj Exp $ */
 
 /*
  * Copyright (c) 1996 Manuel Bouyer.  All rights reserved.
@@ -144,7 +144,6 @@ int acd_read_toc __P((struct acd_softc *, int, int, void *, int));
 static void lba2msf __P((u_int32_t, u_int8_t *, u_int8_t *, u_int8_t *));
 #endif
 static __inline u_int32_t msf2lba __P((u_int8_t, u_int8_t, u_int8_t));
-static __inline void bswap __P((u_int8_t *, int));
 
 struct dkdriver acddkdriver = { acdstrategy };
 
@@ -165,7 +164,7 @@ acdmatch(parent, match, aux)
 #endif
 
        if (((sa->id.config.device_type & ATAPI_DEVICE_TYPE_MASK) ==
-           ATAPI_DEVICE_TYPE_CD) || (sa->quirks & ADEV_CDROM))
+           ATAPI_DEVICE_TYPE_CD) || (sa->quirks & AQUIRK_CDROM))
                return 1;
        return 0;
 }
@@ -677,17 +676,6 @@ msf2lba (m, s, f)
        return (((m * CD_SECS) + s) * CD_FRAMES + f) - CD_BLOCK_OFFSET;
 }
 
-static __inline void
-bswap (buf, len)
-       u_int8_t *buf;
-       int len;
-{       
-       u_int16_t *p = (u_int16_t *)(buf + len);
-
-       while (--p >= (u_int16_t *)buf)
-               *p = (*p & 0xff) << 8 | (*p >> 8 & 0xff);
-}
-
 /*
  * Perform special action on behalf of the user.
  * Knows about the internals of this device
@@ -789,7 +777,7 @@ acdioctl(dev, cmd, addr, flag, p)
                error = acd_read_toc(acd, 0, 0, &hdr, sizeof(hdr));
                if (error)
                        return error;
-               if (acd->ad_link->quirks & ADEV_LITTLETOC) {
+               if (acd->ad_link->quirks & AQUIRK_LITTLETOC) {
 #if BYTE_ORDER == BIG_ENDIAN
                        bswap((u_int8_t *)&hdr.len, sizeof(hdr.len));
 #endif
@@ -822,7 +810,7 @@ acdioctl(dev, cmd, addr, flag, p)
                    for (ntracks = th->ending_track - th->starting_track + 1;
                         ntracks >= 0; ntracks--) {
                        toc.tab[ntracks].addr_type = CD_LBA_FORMAT;
-                       if (acd->ad_link->quirks & ADEV_LITTLETOC) {
+                       if (acd->ad_link->quirks & AQUIRK_LITTLETOC) {
 #if BYTE_ORDER == BIG_ENDIAN
                                bswap((u_int8_t*)&toc.tab[ntracks].addr.addr, sizeof(toc.tab[ntracks].addr.addr));
 #endif
@@ -830,7 +818,7 @@ acdioctl(dev, cmd, addr, flag, p)
                                (u_int32_t)(*toc.tab[ntracks].addr.addr) = ntohl((u_int32_t)(*toc.tab[ntracks].addr.addr));
                    }
                }
-               if (acd->ad_link->quirks & ADEV_LITTLETOC) {
+               if (acd->ad_link->quirks & AQUIRK_LITTLETOC) {
 #if BYTE_ORDER == BIG_ENDIAN
                                bswap((u_int8_t*)&th->len, sizeof(th->len));
 #endif
@@ -1007,8 +995,8 @@ acdgetdisklabel(acd)
  * Find out from the device what it's capacity is
  */
 u_long
-acd_size(cd, flags)
-       struct acd_softc *cd;
+acd_size(acd, flags)
+       struct acd_softc *acd;
        int flags;
 {
        struct atapi_read_cd_capacity_data rdcap;
@@ -1016,6 +1004,17 @@ acd_size(cd, flags)
        u_long blksize;
        u_long size;
 
+       if (acd->ad_link->quirks & AQUIRK_NOCAPACITY) {
+               /*
+                * the drive doesn't support the READ_CD_CAPACITY command
+                * use a fake size
+                */
+               acd->params.blksize = 2048;
+               acd->params.disksize = 400000;
+
+               return 400000;
+       }
+
        /*
         * make up a atapi command and ask the atapi driver to do
         * it for you.
@@ -1028,21 +1027,14 @@ acd_size(cd, flags)
         * If the command works, interpret the result as a 4 byte
         * number of blocks and a blocksize
         */
-       if (atapi_exec_cmd(cd->ad_link, &cmd , sizeof(cmd),
+       if (atapi_exec_cmd(acd->ad_link, &cmd, sizeof(cmd),
            &rdcap, sizeof(rdcap), B_READ, 0) != 0) {
                ATAPI_DEBUG_PRINT(("ATAPI_READ_CD_CAPACITY failed\n"));
                return 0;
        }
 
-       blksize = _4btol((u_int8_t*)&rdcap.blksize);
-       if (blksize < 512)
-               blksize = 2048; /* some drives lie ! */
-       cd->params.blksize = blksize;
-
-       size = _4btol((u_int8_t*)&rdcap.size);
-       if (size < 100)
-               size = 400000;  /* ditto */
-       cd->params.disksize = size;
+       acd->params.blksize = _4btol((u_int8_t*)&rdcap.blksize);
+       acd->params.disksize = _4btol((u_int8_t*)&rdcap.size);
 
        ATAPI_DEBUG_PRINT(("acd_size: %ld %ld\n",blksize,size));
        return size;
index 75f82b9..6fe038d 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: atapiconf.c,v 1.7 1996/08/09 01:33:57 niklas Exp $    */
+/*     $OpenBSD: atapiconf.c,v 1.8 1996/09/04 00:51:13 downsj Exp $    */
 
 /*
  * Copyright (c) 1996 Manuel Bouyer.  All rights reserved.
@@ -61,9 +61,6 @@ struct atapibus_softc {
 
 LIST_HEAD(pkt_free_list, atapi_command_packet) pkt_free_list;
 
-static __inline void bswap __P((char *, int));
-static __inline void btrim __P((char *, int));
-
 int atapi_error __P((struct atapi_command_packet *));
 void atapi_sense __P((struct atapi_command_packet *, u_int8_t, u_int8_t));
 void at_print_addr __P((struct at_dev_link *, u_int8_t));
@@ -97,10 +94,10 @@ struct atapi_quirk_inquiry_pattern {
 
 struct atapi_quirk_inquiry_pattern atapi_quirk_inquiry_patterns[] = {
        {ATAPI_DEVICE_TYPE_CD, ATAPI_REMOVABLE,
-        "GCD-R580B", "1.00", ADEV_LITTLETOC},  /* GoldStar 8X */
+        "GCD-R580B", "1.00", AQUIRK_LITTLETOC},/* GoldStar 8X */
 
        {ATAPI_DEVICE_TYPE_DAD, ATAPI_REMOVABLE,
-        "NEC                 CD-ROM DRIVE:260", "3.04", ADEV_CDROM},
+        "NEC                 CD-ROM DRIVE:260", "3.04", AQUIRK_CDROM},
                                                /* NEC Multispin 2Vi */
 
        {0, 0, NULL, NULL, 0}                   /* The End */
@@ -279,33 +276,6 @@ atapibusattach(parent, self, aux)
        }
 }
 
-static __inline void
-bswap (buf, len)
-       char *buf;
-       int len;
-{       
-       u_int16_t *p = (u_int16_t *)(buf + len);
-
-       while (--p >= (u_int16_t *)buf)
-               *p = (*p & 0xff) << 8 | (*p >> 8 & 0xff);
-}
-
-static __inline void
-btrim (buf, len)
-       char *buf;
-       int len;
-{
-       char *p; 
-
-       /* Remove the trailing spaces. */
-       for (p = buf; p < buf + len; ++p)
-               if (*p == '\0')
-                       *p = ' ';
-
-       for (p = buf + len - 1; p >= buf && *p == ' '; --p)
-               *p = '\0';
-}
-
 int
 atapi_exec_cmd(ad_link, cmd, cmd_size, databuf, datalen, rw, flags)
        struct at_dev_link *ad_link;
index cd9c202..d39b10c 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: atapilink.h,v 1.5 1996/08/07 01:56:29 downsj Exp $    */
+/*     $OpenBSD: atapilink.h,v 1.6 1996/09/04 00:51:14 downsj Exp $    */
 
 /*
  * Copyright (c) 1996 Manuel Bouyer.  All rights reserved.
@@ -150,8 +150,9 @@ struct at_dev_link {
 #define ACAP_DRQ_ACCEL         0x0200  /* accelerated DRQ */
 #define ACAP_LEN               0x0400  /* 16 bit commands */
        u_int8_t quirks;                /* per-device oddities */
-#define ADEV_CDROM             0x01    /* device is a CD-ROM */
-#define ADEV_LITTLETOC         0x02    /* Audio TOC uses wrong byte order */
+#define AQUIRK_CDROM           0x01    /* device is a CD-ROM */
+#define AQUIRK_LITTLETOC       0x02    /* Audio TOC uses wrong byte order */
+#define AQUIRK_NOCAPACITY      0x04    /* no READ_CD_CAPACITY command */
        void    (*start) __P((void *)); /* device start routine */
        int     (*done) __P((void *));  /* device done routine */
 };
@@ -218,6 +219,9 @@ static __inline u_int32_t _2ltol __P((u_int8_t *bytes));
 static __inline u_int32_t _3ltol __P((u_int8_t *bytes));
 static __inline u_int32_t _4ltol __P((u_int8_t *bytes));
 
+static __inline void bswap __P((char *, int));
+static __inline void btrim __P((char *, int));
+
 static __inline void
 _lto2b(val, bytes)
        u_int32_t val;
@@ -366,3 +370,30 @@ _4ltol(bytes)
             (bytes[3] << 24);
        return (rv);
 }
+
+static __inline void
+bswap (buf, len)
+       char *buf;
+       int len;
+{
+       u_int16_t *p = (u_int16_t *)(buf + len);
+
+       while (--p >= (u_int16_t *)buf)
+               *p = (*p & 0xff) << 8 | (*p >> 8 & 0xff);
+}
+
+static __inline void
+btrim (buf, len)
+       char *buf;
+       int len;
+{
+       char *p;
+
+       /* Remove the trailing spaces. */
+       for (p = buf; p < buf + len; ++p)
+               if (*p == '\0')
+                       *p = ' ';
+
+       for (p = buf + len - 1; p >= buf && *p == ' '; --p)
+               *p = '\0';
+}
index 2dd372f..1e141db 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: wdc.c,v 1.5 1996/08/17 06:24:54 downsj Exp $  */
+/*     $OpenBSD: wdc.c,v 1.6 1996/09/04 00:51:15 downsj Exp $  */
 /*     $NetBSD: wd.c,v 1.150 1996/05/12 23:54:03 mycroft Exp $ */
 
 /*
@@ -227,6 +227,21 @@ wdcattach(parent, self, aux)
        wdc_nxfer = 0;
 #endif
 
+       /*
+        * Attach an ATAPI bus, if configured.
+        */
+       wdc->ab_link = malloc(sizeof(struct bus_link), M_DEVBUF, M_NOWAIT);
+       if (wdc->ab_link == NULL) {
+               printf("%s: can't allocate ATAPI link\n", self->dv_xname);
+               return;
+       }
+       bzero(wdc->ab_link,sizeof(struct bus_link));
+       wdc->ab_link->type = BUS;
+       wdc->ab_link->wdc_softc = (caddr_t)wdc;
+       wdc->ab_link->ctlr_link = &(wdc->ctlr_link);
+       wdc->ab_link->ctrl = self->dv_unit;
+       (void)config_found(self, (void *)wdc->ab_link, NULL);
+
        /*
         * Attach standard IDE/ESDI/etc. disks to the controller.
         */
@@ -263,21 +278,6 @@ wdcattach(parent, self, aux)
                            wdcprint);
                }
        }
-
-       /*
-        * Attach an ATAPI bus, if configured.
-        */
-       wdc->ab_link = malloc(sizeof(struct bus_link), M_DEVBUF, M_NOWAIT);
-       if (wdc->ab_link == NULL) {
-               printf("%s: can't allocate ATAPI link\n", self->dv_xname);
-               return;
-       }
-       bzero(wdc->ab_link,sizeof(struct bus_link));
-       wdc->ab_link->type = BUS;
-       wdc->ab_link->wdc_softc = (caddr_t)wdc;
-       wdc->ab_link->ctlr_link = &(wdc->ctlr_link);
-       wdc->ab_link->ctrl = self->dv_unit;
-       (void)config_found(self, (void *)wdc->ab_link, NULL);
 }
 
 /*
@@ -1602,7 +1602,7 @@ wdc_atapi_intr(wdc, xfer)
        bus_chipset_tag_t bc = wdc->sc_bc;
        bus_io_handle_t ioh = wdc->sc_ioh;
        struct atapi_command_packet *acp = xfer->atapi_cmd;
-       int len, phase, i;
+       int len, phase, i, retries = 0;
        int err, st, ire;
 
        if (wait_for_unbusy(wdc) < 0) {
@@ -1616,6 +1616,7 @@ wdc_atapi_intr(wdc, xfer)
        printf("wdc_atapi_intr: %s\n", wdc->sc_dev.dv_xname);
 #endif
 
+again:
        len = bus_io_read_1(bc, ioh, wd_cyl_lo) +
            256 * bus_io_read_1(bc, ioh, wd_cyl_hi);
 
@@ -1725,6 +1726,10 @@ wdc_atapi_intr(wdc, xfer)
                break;
 
        default: 
+               if (++retries < 500) {
+                       DELAY(100);
+                       goto again;
+               }
                printf("wdc_atapi_intr: unknown phase %d\n", phase);
                acp->status = ERROR;
        }