summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJason Downs <downsj@cvs.openbsd.org>1996-09-04 00:51:16 +0000
committerJason Downs <downsj@cvs.openbsd.org>1996-09-04 00:51:16 +0000
commit7ca89df0f6fccfc79741fafc70e40a64756b7f9c (patch)
tree19c83b9ff9d8e64c0c5902b1a4d5a0be3fa50746
parent206a918e9c83b16235d46ddaeeb5293cc0975e97 (diff)
Pull in pieces of Manuel's patch6:
- 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.
-rw-r--r--sys/dev/atapi/acd.c50
-rw-r--r--sys/dev/atapi/atapiconf.c36
-rw-r--r--sys/dev/atapi/atapilink.h37
-rw-r--r--sys/dev/isa/wdc.c39
4 files changed, 80 insertions, 82 deletions
diff --git a/sys/dev/atapi/acd.c b/sys/dev/atapi/acd.c
index 5384fd32875..0e981a67d5e 100644
--- a/sys/dev/atapi/acd.c
+++ b/sys/dev/atapi/acd.c
@@ -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;
diff --git a/sys/dev/atapi/atapiconf.c b/sys/dev/atapi/atapiconf.c
index 75f82b9b546..6fe038dc437 100644
--- a/sys/dev/atapi/atapiconf.c
+++ b/sys/dev/atapi/atapiconf.c
@@ -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;
diff --git a/sys/dev/atapi/atapilink.h b/sys/dev/atapi/atapilink.h
index cd9c2025680..d39b10cfaee 100644
--- a/sys/dev/atapi/atapilink.h
+++ b/sys/dev/atapi/atapilink.h
@@ -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';
+}
diff --git a/sys/dev/isa/wdc.c b/sys/dev/isa/wdc.c
index 2dd372f4d94..1e141dbac30 100644
--- a/sys/dev/isa/wdc.c
+++ b/sys/dev/isa/wdc.c
@@ -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 $ */
/*
@@ -228,6 +228,21 @@ wdcattach(parent, self, aux)
#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.
*/
for (drive = 0; drive < 2; drive++) {
@@ -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;
}