diff options
author | Jason Downs <downsj@cvs.openbsd.org> | 1996-09-04 00:51:16 +0000 |
---|---|---|
committer | Jason Downs <downsj@cvs.openbsd.org> | 1996-09-04 00:51:16 +0000 |
commit | 7ca89df0f6fccfc79741fafc70e40a64756b7f9c (patch) | |
tree | 19c83b9ff9d8e64c0c5902b1a4d5a0be3fa50746 | |
parent | 206a918e9c83b16235d46ddaeeb5293cc0975e97 (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.c | 50 | ||||
-rw-r--r-- | sys/dev/atapi/atapiconf.c | 36 | ||||
-rw-r--r-- | sys/dev/atapi/atapilink.h | 37 | ||||
-rw-r--r-- | sys/dev/isa/wdc.c | 39 |
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; } |