summaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
authorsos <sos@FreeBSD.org>2001-08-21 11:35:47 +0000
committersos <sos@FreeBSD.org>2001-08-21 11:35:47 +0000
commit20971d752c9fe30b7e67b7e8053e5587320f878d (patch)
tree0ea5b67cdaaf8444abee34c257d2015a352c1a6d /sys
parent569bf91b79a1c9607f84cc3c6b51ee7fede1b215 (diff)
downloadFreeBSD-src-20971d752c9fe30b7e67b7e8053e5587320f878d.zip
FreeBSD-src-20971d752c9fe30b7e67b7e8053e5587320f878d.tar.gz
Finally commit some of the minor things I've collected over the last month(s):
Add tagged queueing support for new IBM drives. Add support for Yet Another Promise ATA 100 chip. Flush disk cache on close. Dont flush the disk cache on BIO_ORDERED anymore. Cleanup the tests for DMA on ATAPI devices. Allow to share ALL irq's even the std irg 14 & 15. Fix calculation bug in end of media code on CD's. Add REZERO on opening a CDR/CDRW. Cleanup ataioctl a bit.
Diffstat (limited to 'sys')
-rw-r--r--sys/dev/ata/ata-all.c23
-rw-r--r--sys/dev/ata/ata-all.h1
-rw-r--r--sys/dev/ata/ata-disk.c31
-rw-r--r--sys/dev/ata/ata-dma.c44
-rw-r--r--sys/dev/ata/ata-pci.c10
-rw-r--r--sys/dev/ata/atapi-all.c2
-rw-r--r--sys/dev/ata/atapi-all.h2
-rw-r--r--sys/dev/ata/atapi-cd.c11
-rw-r--r--sys/dev/ata/atapi-tape.c2
9 files changed, 76 insertions, 50 deletions
diff --git a/sys/dev/ata/ata-all.c b/sys/dev/ata/ata-all.c
index 01ebc46..023f73a 100644
--- a/sys/dev/ata/ata-all.c
+++ b/sys/dev/ata/ata-all.c
@@ -287,10 +287,9 @@ ata_resume(device_t dev)
static int
ataioctl(dev_t dev, u_long cmd, caddr_t addr, int32_t flag, struct proc *p)
{
-
struct ata_cmd *iocmd = (struct ata_cmd *)addr;
device_t device;
- int error = 0;
+ int error;
if (cmd != IOCATA)
return ENOTTY;
@@ -304,15 +303,16 @@ ataioctl(dev_t dev, u_long cmd, caddr_t addr, int32_t flag, struct proc *p)
switch (iocmd->cmd) {
case ATAATTACH: {
/* should enable channel HW on controller that can SOS XXX */
- if (!(error = ata_probe(device)))
+ error = ata_probe(device);
+ if (!error)
error = ata_attach(device);
- break;
+ return error;
}
case ATADETACH: {
error = ata_detach(device);
/* should disable channel HW on controller that can SOS XXX */
- break;
+ return error;
}
case ATAREINIT: {
@@ -329,7 +329,7 @@ ataioctl(dev_t dev, u_long cmd, caddr_t addr, int32_t flag, struct proc *p)
tsleep((caddr_t)&s, PRIBIO, "atachm", hz/4);
error = ata_reinit(scp);
splx(s);
- break;
+ return error;
}
case ATAGMODE: {
@@ -346,7 +346,7 @@ ataioctl(dev_t dev, u_long cmd, caddr_t addr, int32_t flag, struct proc *p)
iocmd->u.mode.mode[SLAVE] = scp->mode[SLAVE];
else
iocmd->u.mode.mode[SLAVE] = -1;
- break;
+ return 0;
}
case ATASMODE: {
@@ -368,7 +368,7 @@ ataioctl(dev_t dev, u_long cmd, caddr_t addr, int32_t flag, struct proc *p)
}
else
iocmd->u.mode.mode[SLAVE] = -1;
- break;
+ return 0;
}
case ATAGPARM: {
@@ -394,13 +394,10 @@ ataioctl(dev_t dev, u_long cmd, caddr_t addr, int32_t flag, struct proc *p)
if (scp->dev_param[SLAVE])
bcopy(scp->dev_param[SLAVE], &iocmd->u.param.params[SLAVE],
sizeof(struct ata_params));
- break;
+ return 0;
}
-
- default:
- error = ENOTTY;
}
- return error;
+ return ENOTTY;
}
static int
diff --git a/sys/dev/ata/ata-all.h b/sys/dev/ata/ata-all.h
index 9eab30b..652255b 100644
--- a/sys/dev/ata/ata-all.h
+++ b/sys/dev/ata/ata-all.h
@@ -74,6 +74,7 @@
#define ATA_C_READ_DMA 0xc8 /* read w/DMA command */
#define ATA_C_WRITE_DMA 0xca /* write w/DMA command */
#define ATA_C_WRITE_DMA_QUEUED 0xcc /* write w/DMA QUEUED command */
+#define ATA_C_SLEEP 0xe6 /* sleep command */
#define ATA_C_FLUSHCACHE 0xe7 /* flush cache to disk */
#define ATA_C_ATA_IDENTIFY 0xec /* get ATA params */
#define ATA_C_SETFEATURES 0xef /* features command */
diff --git a/sys/dev/ata/ata-disk.c b/sys/dev/ata/ata-disk.c
index d1950af..338485f 100644
--- a/sys/dev/ata/ata-disk.c
+++ b/sys/dev/ata/ata-disk.c
@@ -53,11 +53,12 @@
/* device structures */
static d_open_t adopen;
+static d_close_t adclose;
static d_strategy_t adstrategy;
static d_dump_t addump;
static struct cdevsw ad_cdevsw = {
/* open */ adopen,
- /* close */ nullclose,
+ /* close */ adclose,
/* read */ physread,
/* write */ physwrite,
/* ioctl */ noioctl,
@@ -103,7 +104,7 @@ SYSCTL_INT(_hw_ata, OID_AUTO, tags, CTLFLAG_RD, &ata_tags, 0,
#define AD_PARAM ATA_PARAM(adp->controller, adp->unit)
/* experimental cache flush on BIO_ORDERED */
-#define ATA_FLUSHCACHE_ON
+#undef ATA_FLUSHCACHE_ON
void
ad_attach(struct ata_softc *scp, int device)
@@ -260,6 +261,18 @@ adopen(dev_t dev, int flags, int fmt, struct proc *p)
return 0;
}
+static int
+adclose(dev_t dev, int flags, int fmt, struct proc *p)
+{
+ struct ad_softc *adp = dev->si_drv1;
+
+ if (ata_command(adp->controller, adp->unit, ATA_C_FLUSHCACHE,
+ 0, 0, 0, 0, 0, ATA_WAIT_READY))
+ ata_printf(adp->controller, adp->unit,
+ "flushing cache on close failed\n");
+ return 0;
+}
+
static void
adstrategy(struct bio *bp)
{
@@ -582,9 +595,10 @@ ad_interrupt(struct ad_request *request)
struct ad_softc *adp = request->device;
int dma_stat = 0;
+#ifdef ATA_FLUSHCACHE_ON
if (request->flags & ADR_F_FLUSHCACHE)
goto finish;
-
+#endif
/* finish DMA transfer */
if (request->flags & ADR_F_DMA_USED)
dma_stat = ata_dmadone(adp->controller);
@@ -700,8 +714,8 @@ ad_interrupt(struct ad_request *request)
else
return ATA_OP_CONTINUES;
}
-#endif
finish:
+#endif
biofinish(request->bp, &adp->stats, 0);
ad_free(request);
adp->outstanding--;
@@ -856,6 +870,15 @@ ad_tagsupported(struct ad_softc *adp)
return 1;
i++;
}
+ /*
+ * check IBM's new obscure way of naming drives
+ * we want "IC" (IBM CORP) and "AT" or "AV" (ATA interface)
+ * but doesn't care about the other info (size, capacity etc)
+ */
+ if (!strncmp(AD_PARAM->model, "IC", 2) &&
+ (!strncmp(AD_PARAM->model + 8, "AT", 2) ||
+ !strncmp(AD_PARAM->model + 8, "AV", 2)))
+ return 1;
}
return 0;
}
diff --git a/sys/dev/ata/ata-dma.c b/sys/dev/ata/ata-dma.c
index d5c5311..2230291 100644
--- a/sys/dev/ata/ata-dma.c
+++ b/sys/dev/ata/ata-dma.c
@@ -54,6 +54,10 @@ static void hpt_timing(struct ata_softc *, int, int);
#undef vtophys
#define vtophys(va) alpha_XXX_dmamap((vm_offset_t)va)
#endif
+#define ATAPI_DEVICE(scp, device) \
+ ((device == ATA_MASTER && scp->devices & ATA_ATAPI_MASTER) || \
+ (device == ATA_SLAVE && scp->devices & ATA_ATAPI_SLAVE))
+
void *
ata_dmaalloc(struct ata_softc *scp, int device)
@@ -718,18 +722,11 @@ via_82c586:
/* we could set PIO mode timings, but we assume the BIOS did that */
break;
- case 0x4d33105a: /* Promise Ultra/FastTrak 33 controllers */
- case 0x4d38105a: /* Promise Ultra/FastTrak 66 controllers */
case 0x4d30105a: /* Promise Ultra/FastTrak 100 controllers */
case 0x0d30105a: /* Promise OEM ATA100 controllers */
case 0x4d68105a: /* Promise TX2 ATA100 controllers */
- /* the Promise can only do DMA on ATA disks not on ATAPI devices */
- if ((device == ATA_MASTER && scp->devices & ATA_ATAPI_MASTER) ||
- (device == ATA_SLAVE && scp->devices & ATA_ATAPI_SLAVE))
- break;
-
- if (udmamode >= 5 && (scp->chiptype == 0x4d30105a ||
- scp->chiptype == 0x0d30105a || scp->chiptype == 0x4d68105a) &&
+ case 0x6268105a: /* Promise TX2v2 ATA100 controllers */
+ if (!ATAPI_DEVICE(scp, device) && udmamode >= 5 &&
!(pci_read_config(parent, 0x50, 2)&(scp->channel ? 1<<11 : 1<<10))){
error = ata_command(scp, device, ATA_C_SETFEATURES, 0, 0, 0,
ATA_UDMA5, ATA_C_F_SETXFER, ATA_WAIT_READY);
@@ -743,9 +740,10 @@ via_82c586:
return;
}
}
- if (udmamode >= 4 &&
- (scp->chiptype == 0x4d38105a || scp->chiptype == 0x4d30105a ||
- scp->chiptype == 0x0d30105a || scp->chiptype == 0x4d68105a) &&
+ /* FALLTHROUGH */
+
+ case 0x4d38105a: /* Promise Ultra/FastTrak 66 controllers */
+ if (!ATAPI_DEVICE(scp, device) && udmamode >= 4 &&
!(pci_read_config(parent, 0x50, 2)&(scp->channel ? 1<<11 : 1<<10))){
error = ata_command(scp, device, ATA_C_SETFEATURES, 0, 0, 0,
ATA_UDMA4, ATA_C_F_SETXFER, ATA_WAIT_READY);
@@ -759,7 +757,10 @@ via_82c586:
return;
}
}
- if (udmamode >= 2) {
+ /* FALLTHROUGH */
+
+ case 0x4d33105a: /* Promise Ultra/FastTrak 33 controllers */
+ if (!ATAPI_DEVICE(scp, device) && udmamode >= 2) {
error = ata_command(scp, device, ATA_C_SETFEATURES, 0, 0, 0,
ATA_UDMA2, ATA_C_F_SETXFER, ATA_WAIT_READY);
if (bootverbose)
@@ -772,7 +773,7 @@ via_82c586:
return;
}
}
- if (wdmamode >= 2 && apiomode >= 4) {
+ if (!ATAPI_DEVICE(scp, device) && wdmamode >= 2 && apiomode >= 4) {
error = ata_command(scp, device, ATA_C_SETFEATURES, 0, 0, 0,
ATA_WDMA2, ATA_C_F_SETXFER, ATA_WAIT_READY);
if (bootverbose)
@@ -798,12 +799,8 @@ via_82c586:
return;
case 0x00041103: /* HighPoint HPT366/368/370 controllers */
- /* no ATAPI devices for now */
- if ((device == ATA_MASTER && scp->devices & ATA_ATAPI_MASTER) ||
- (device == ATA_SLAVE && scp->devices & ATA_ATAPI_SLAVE))
- break;
-
- if (udmamode >=5 && pci_get_revid(parent) >= 0x03 &&
+ if (!ATAPI_DEVICE(scp, device) &&
+ udmamode >=5 && pci_get_revid(parent) >= 0x03 &&
!(pci_read_config(parent, 0x5a, 1) & (scp->channel ? 0x01:0x02))) {
error = ata_command(scp, device, ATA_C_SETFEATURES, 0, 0, 0,
ATA_UDMA5, ATA_C_F_SETXFER, ATA_WAIT_READY);
@@ -817,7 +814,7 @@ via_82c586:
return;
}
}
- if (udmamode >=4 &&
+ if (!ATAPI_DEVICE(scp, device) && udmamode >=4 &&
!(pci_read_config(parent, 0x5a, 1) & (scp->channel ? 0x01:0x02))) {
error = ata_command(scp, device, ATA_C_SETFEATURES, 0, 0, 0,
ATA_UDMA4, ATA_C_F_SETXFER, ATA_WAIT_READY);
@@ -831,7 +828,7 @@ via_82c586:
return;
}
}
- if (udmamode >= 2) {
+ if (!ATAPI_DEVICE(scp, device) && udmamode >= 2) {
error = ata_command(scp, device, ATA_C_SETFEATURES, 0, 0, 0,
ATA_UDMA2, ATA_C_F_SETXFER, ATA_WAIT_READY);
if (bootverbose)
@@ -844,7 +841,7 @@ via_82c586:
return;
}
}
- if (wdmamode >= 2 && apiomode >= 4) {
+ if (!ATAPI_DEVICE(scp, device) && wdmamode >= 2 && apiomode >= 4) {
error = ata_command(scp, device, ATA_C_SETFEATURES, 0, 0, 0,
ATA_WDMA2, ATA_C_F_SETXFER, ATA_WAIT_READY);
if (bootverbose)
@@ -1048,6 +1045,7 @@ promise_timing(struct ata_softc *scp, int devno, int mode)
case 0x4d30105a: /* Promise Ultra/Fasttrak 100 */
case 0x0d30105a: /* Promise OEM ATA 100 */
case 0x4d68105a: /* Promise TX2 ATA 100 */
+ case 0x6268105a: /* Promise TX2v2 ATA 100 */
switch (mode) {
default:
case ATA_PIO0: t->pa = 15; t->pb = 31; t->mb = 7; t->mc = 15; break;
diff --git a/sys/dev/ata/ata-pci.c b/sys/dev/ata/ata-pci.c
index 0e79b0f..3a743bd 100644
--- a/sys/dev/ata/ata-pci.c
+++ b/sys/dev/ata/ata-pci.c
@@ -173,6 +173,7 @@ ata_pci_match(device_t dev)
case 0x0d30105a:
case 0x4d30105a:
case 0x4d68105a:
+ case 0x6268105a:
return "Promise ATA100 controller";
case 0x00041103:
@@ -280,6 +281,7 @@ ata_pci_attach(device_t dev)
case 0x4d30105a:
case 0x0d30105a:
case 0x4d68105a:
+ case 0x6268105a:
ATA_OUTB(sc->bmio, 0x11, ATA_INB(sc->bmio, 0x11) | 0x0a);
/* FALLTHROUGH */
@@ -335,9 +337,9 @@ ata_pci_attach(device_t dev)
/* prepare for ATA-66 on the 82C686 and rev 0x12 and newer 82C596's */
if (ata_find_dev(dev, 0x06861106, 0) ||
- ata_find_dev(dev, 0x05961106, 0x12)) {
+ ata_find_dev(dev, 0x05961106, 0x12))
pci_write_config(dev, 0x50, 0x030b030b, 4);
- }
+
break;
case 0x10001042: /* RZ 100? known bad, no DMA */
@@ -403,6 +405,7 @@ ata_pci_intr(struct ata_softc *scp)
case 0x4d30105a: /* Promise Ultra/Fasttrak 100 */
case 0x0d30105a: /* Promise OEM ATA100 */
case 0x4d68105a: /* Promise TX2 ATA100 */
+ case 0x6268105a: /* Promise TX2v2 ATA100 */
if (!(ATA_INL(scp->r_bmio, (scp->channel ? 0x14 : 0x1c)) &
(scp->channel ? 0x00004000 : 0x00000400)))
return 1;
@@ -514,8 +517,7 @@ ata_pci_alloc_resource(device_t dev, device_t child, int type, int *rid,
int irq = (channel == 0 ? 14 : 15);
return BUS_ALLOC_RESOURCE(device_get_parent(dev), child,
- SYS_RES_IRQ, rid,
- irq, irq, 1, flags & ~RF_SHAREABLE);
+ SYS_RES_IRQ, rid, irq, irq, 1, flags);
#endif
}
else {
diff --git a/sys/dev/ata/atapi-all.c b/sys/dev/ata/atapi-all.c
index b7d902b..9737298 100644
--- a/sys/dev/ata/atapi-all.c
+++ b/sys/dev/ata/atapi-all.c
@@ -675,7 +675,7 @@ atapi_cmd2str(u_int8_t cmd)
{
switch (cmd) {
case 0x00: return ("TEST_UNIT_READY");
- case 0x01: return ("REWIND");
+ case 0x01: return ("REZERO");
case 0x03: return ("REQUEST_SENSE");
case 0x04: return ("FORMAT_UNIT");
case 0x08: return ("READ");
diff --git a/sys/dev/ata/atapi-all.h b/sys/dev/ata/atapi-all.h
index 186009c..0b06177 100644
--- a/sys/dev/ata/atapi-all.h
+++ b/sys/dev/ata/atapi-all.h
@@ -64,7 +64,7 @@
/* ATAPI commands */
#define ATAPI_TEST_UNIT_READY 0x00 /* check if device is ready */
-#define ATAPI_REWIND 0x01 /* rewind */
+#define ATAPI_REZERO 0x01 /* rewind */
#define ATAPI_REQUEST_SENSE 0x03 /* get sense data */
#define ATAPI_FORMAT 0x04 /* format unit */
#define ATAPI_READ 0x08 /* read data */
diff --git a/sys/dev/ata/atapi-cd.c b/sys/dev/ata/atapi-cd.c
index 89abf69..3db545a 100644
--- a/sys/dev/ata/atapi-cd.c
+++ b/sys/dev/ata/atapi-cd.c
@@ -1142,11 +1142,12 @@ acd_start(struct atapi_softc *atp)
/* if transfer goes beyond range adjust it to be within limits */
if (lba + count > lastlba) {
/* if we are entirely beyond EOM return EOF */
- if ((count = lastlba - lba) <= 0) {
+ if (lastlba <= lba) {
bp->bio_resid = bp->bio_bcount;
biodone(bp);
return;
}
+ count = lastlba - lba;
}
switch (blocksize) {
case 2048:
@@ -1380,9 +1381,13 @@ acd_select_slot(struct acd_softc *cdp)
static int
acd_open_disk(struct acd_softc *cdp)
{
- int8_t ccb[16] = { ATAPI_SEND_OPC_INFO, 0x01, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0 };
+ int8_t ccb[16];
+ bzero(ccb, sizeof(ccb));
+ ccb[0] = ATAPI_REZERO;
+ atapi_queue_cmd(cdp->atp, ccb, NULL, 0, ATPR_F_QUIET, 60, NULL, NULL);
+ ccb[0] = ATAPI_SEND_OPC_INFO;
+ ccb[1] = 0x01;
atapi_queue_cmd(cdp->atp, ccb, NULL, 0, ATPR_F_QUIET, 30, NULL, NULL);
return 0;
}
diff --git a/sys/dev/ata/atapi-tape.c b/sys/dev/ata/atapi-tape.c
index fb02a1f..98114c3 100644
--- a/sys/dev/ata/atapi-tape.c
+++ b/sys/dev/ata/atapi-tape.c
@@ -642,7 +642,7 @@ ast_load_unload(struct ast_softc *stp, u_int8_t function)
static int
ast_rewind(struct ast_softc *stp)
{
- int8_t ccb[16] = { ATAPI_REWIND, 0x01, 0, 0, 0, 0, 0, 0,
+ int8_t ccb[16] = { ATAPI_REZERO, 0x01, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0 };
int error;
OpenPOWER on IntegriCloud