summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sys/dev/ata/ata-all.c99
-rw-r--r--sys/dev/ata/ata-all.h34
-rw-r--r--sys/dev/ata/ata-card.c3
-rw-r--r--sys/dev/ata/ata-cbus.c5
-rw-r--r--sys/dev/ata/ata-chipset.c26
-rw-r--r--sys/dev/ata/ata-disk.c56
-rw-r--r--sys/dev/ata/ata-dma.c4
-rw-r--r--sys/dev/ata/ata-isa.c3
-rw-r--r--sys/dev/ata/ata-lowlevel.c82
-rw-r--r--sys/dev/ata/ata-pci.c3
-rw-r--r--sys/dev/ata/ata-queue.c244
-rw-r--r--sys/dev/ata/ata-raid.c9
-rw-r--r--sys/dev/ata/atapi-cd.c4
-rw-r--r--sys/dev/ata/atapi-fd.c3
-rw-r--r--sys/dev/ata/atapi-tape.c3
15 files changed, 358 insertions, 220 deletions
diff --git a/sys/dev/ata/ata-all.c b/sys/dev/ata/ata-all.c
index 88bfc56..05f40c2 100644
--- a/sys/dev/ata/ata-all.c
+++ b/sys/dev/ata/ata-all.c
@@ -1,5 +1,5 @@
/*-
- * Copyright (c) 1998 - 2003 Søren Schmidt <sos@FreeBSD.org>
+ * Copyright (c) 1998 - 2004 Søren Schmidt <sos@FreeBSD.org>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -40,7 +40,7 @@ __FBSDID("$FreeBSD$");
#include <sys/bus.h>
#include <sys/bio.h>
#include <sys/malloc.h>
-#include <sys/mutex.h>
+#include <sys/sema.h>
#include <sys/sysctl.h>
#include <sys/taskqueue.h>
#include <machine/stdarg.h>
@@ -60,13 +60,13 @@ static d_ioctl_t ata_ioctl;
static struct cdevsw ata_cdevsw = {
.d_ioctl = ata_ioctl,
.d_name = "ata",
- .d_maj = 159,
};
/* prototypes */
static void ata_shutdown(void *, int);
static int ata_getparam(struct ata_device *, u_int8_t);
static void ata_identify_devices(struct ata_channel *);
+static void ata_fail_requests(struct ata_channel *ch,struct ata_device *device);
static void ata_boot_attach(void);
static void bswap(int8_t *, int);
static void btrim(int8_t *, int);
@@ -175,7 +175,6 @@ int
ata_detach(device_t dev)
{
struct ata_channel *ch;
- struct ata_request *request;
if (!dev || !(ch = device_get_softc(dev)) || !ch->r_irq)
return ENXIO;
@@ -190,16 +189,9 @@ ata_detach(device_t dev)
#endif
/* fail outstanding requests on this channel */
- mtx_lock(&ch->queue_mtx);
- while ((request = TAILQ_FIRST(&ch->ata_queue))) {
- TAILQ_REMOVE(&ch->ata_queue, request, chain);
- request->status = ATA_S_ERROR;
- mtx_unlock(&ch->queue_mtx);
- ata_finish(request);
- mtx_lock(&ch->queue_mtx);
- }
- mtx_unlock(&ch->queue_mtx);
+ ata_fail_requests(ch, NULL);
+ /* flush cache and powerdown device */
if (ch->device[MASTER].param) {
if (ch->device[MASTER].param->support.command2 & ATA_SUPPORT_FLUSHCACHE)
ata_controlcmd(&ch->device[MASTER], ATA_FLUSHCACHE, 0, 0, 0);
@@ -237,42 +229,51 @@ ata_reinit(struct ata_channel *ch)
return ENXIO;
/* reset the HW */
- ata_printf(ch, -1, "resetting devices ..\n");
+ if (bootverbose)
+ ata_printf(ch, -1, "reiniting channel ..\n");
ATA_FORCELOCK_CH(ch, ATA_CONTROL);
+ ch->flags |= ATA_IMMEDIATE_MODE;
ch->running = NULL;
devices = ch->devices;
ch->hw.reset(ch);
ATA_UNLOCK_CH(ch);
+ if (bootverbose)
+ ata_printf(ch, -1, "resetting done ..\n");
+
/* detach what left the channel during reset */
if ((misdev = devices & ~ch->devices)) {
if ((misdev & (ATA_ATA_MASTER | ATA_ATAPI_MASTER)) &&
ch->device[MASTER].detach) {
if (request && (request->device == &ch->device[MASTER])) {
request->result = ENXIO;
- request->flags |= ATA_R_DONE;
if (request->callback)
(request->callback)(request);
else
- wakeup(request);
+ sema_post(&request->done);
}
ch->device[MASTER].detach(&ch->device[MASTER]);
+ ata_fail_requests(ch, &ch->device[MASTER]);
+ free(ch->device[MASTER].param, M_ATA);
+ ch->device[MASTER].param = NULL;
}
if ((misdev & (ATA_ATA_SLAVE | ATA_ATAPI_SLAVE)) &&
ch->device[SLAVE].detach) {
if (request && (request->device == &ch->device[SLAVE])) {
request->result = ENXIO;
- request->flags |= ATA_R_DONE;
if (request->callback)
(request->callback)(request);
else
- wakeup(request);
+ sema_post(&request->done);
}
ch->device[SLAVE].detach(&ch->device[SLAVE]);
+ ata_fail_requests(ch, &ch->device[SLAVE]);
+ free(ch->device[SLAVE].param, M_ATA);
+ ch->device[SLAVE].param = NULL;
}
}
-
- /* identify whats present on this channel now */
+
+ /* identify what is present on the channel now */
ata_identify_devices(ch);
/* attach new devices that appeared during reset */
@@ -285,17 +286,26 @@ ata_reinit(struct ata_channel *ch)
ch->device[SLAVE].attach(&ch->device[SLAVE]);
}
- /* restore transfermode on devices */
- if (ch->devices & (ATA_ATA_MASTER | ATA_ATAPI_MASTER))
+ /* restore device config and transfermode on devices */
+ if (ch->devices & (ATA_ATA_MASTER | ATA_ATAPI_MASTER)) {
+ if (ch->device[MASTER].config)
+ ch->device[MASTER].config(&ch->device[MASTER]);
ch->device[MASTER].setmode(&ch->device[MASTER],ch->device[MASTER].mode);
- if (ch->devices & (ATA_ATA_SLAVE | ATA_ATAPI_SLAVE))
+ }
+ if (ch->devices & (ATA_ATA_SLAVE | ATA_ATAPI_SLAVE)) {
+ if (ch->device[SLAVE].config)
+ ch->device[SLAVE].config(&ch->device[SLAVE]);
ch->device[SLAVE].setmode(&ch->device[SLAVE], ch->device[SLAVE].mode);
+ }
#ifdef DEV_ATAPICAM
atapi_cam_reinit_bus(ch);
#endif
- printf("done\n");
+ if (bootverbose)
+ ata_printf(ch, -1, "device config done ..\n");
+ ch->flags &= ~ATA_IMMEDIATE_MODE;
+ ata_start(ch);
return 0;
}
@@ -543,21 +553,18 @@ ata_ioctl(dev_t dev, u_long cmd, caddr_t addr, int32_t flag, struct thread *td)
static int
ata_getparam(struct ata_device *atadev, u_int8_t command)
{
- struct ata_params *atacap;
struct ata_request *request;
int error = ENOMEM;
- if (atadev->param)
- atacap = atadev->param;
- else
- atacap = malloc(sizeof(struct ata_params), M_ATA, M_NOWAIT);
- if (atacap) {
+ if (!atadev->param)
+ atadev->param = malloc(sizeof(struct ata_params), M_ATA, M_NOWAIT);
+ if (atadev->param) {
request = ata_alloc_request();
if (request) {
request->device = atadev;
request->u.ata.command = command;
- request->flags = (ATA_R_READ | ATA_R_QUIET);
- request->data = (caddr_t)atacap;
+ request->flags = (ATA_R_READ | ATA_R_AT_HEAD);
+ request->data = (caddr_t)atadev->param;
request->timeout = 2;
request->retries = 3;
request->bytecount = sizeof(struct ata_params);
@@ -566,18 +573,19 @@ ata_getparam(struct ata_device *atadev, u_int8_t command)
ata_queue_request(request);
if (!(error = request->result))
break;
- request->flags &= ~ATA_R_QUIET;
request->retries--;
}
ata_free_request(request);
}
- if (!isprint(atacap->model[0]) || !isprint(atacap->model[1]))
+ if (!isprint(atadev->param->model[0]) ||
+ !isprint(atadev->param->model[1]))
error = ENXIO;
if (error) {
+ free(atadev->param, M_ATA);
atadev->param = NULL;
- free(atacap, M_ATA);
}
else {
+ struct ata_params *atacap = atadev->param;
#if BYTE_ORDER == BIG_ENDIAN
int16_t *ptr;
@@ -598,7 +606,6 @@ ata_getparam(struct ata_device *atadev, u_int8_t command)
bswap(atacap->serial, sizeof(atacap->serial));
btrim(atacap->serial, sizeof(atacap->serial));
bpack(atacap->serial, atacap->serial, sizeof(atacap->serial));
- atadev->param = atacap;
if (bootverbose)
ata_prtdev(atadev,
"pio=0x%02x wdma=0x%02x udma=0x%02x cable=%spin\n",
@@ -694,6 +701,24 @@ ata_identify_devices(struct ata_channel *ch)
}
}
+static void
+ata_fail_requests(struct ata_channel *ch, struct ata_device *device)
+{
+ struct ata_request *request;
+
+ mtx_lock(&ch->queue_mtx);
+ while ((request = TAILQ_FIRST(&ch->ata_queue))) {
+ if (device == NULL || request->device == device) {
+ TAILQ_REMOVE(&ch->ata_queue, request, chain);
+ request->result = ENXIO;
+ mtx_unlock(&ch->queue_mtx);
+ ata_finish(request);
+ mtx_lock(&ch->queue_mtx);
+ }
+ }
+ mtx_unlock(&ch->queue_mtx);
+}
+
static void
ata_boot_attach(void)
{
@@ -964,12 +989,12 @@ ata_init(void)
printf("ata: malloc of delayed attach hook failed\n");
return;
}
-
ata_delayed_attach->ich_func = (void*)ata_boot_attach;
if (config_intrhook_establish(ata_delayed_attach) != 0) {
printf("ata: config_intrhook_establish failed\n");
free(ata_delayed_attach, M_TEMP);
}
+
/* Register a handler to flush write caches on shutdown */
if ((EVENTHANDLER_REGISTER(shutdown_post_sync, ata_shutdown,
NULL, SHUTDOWN_PRI_DEFAULT)) == NULL)
diff --git a/sys/dev/ata/ata-all.h b/sys/dev/ata/ata-all.h
index 18cf778..821d17c 100644
--- a/sys/dev/ata/ata-all.h
+++ b/sys/dev/ata/ata-all.h
@@ -1,5 +1,5 @@
/*-
- * Copyright (c) 1998 - 2003 Søren Schmidt <sos@FreeBSD.org>
+ * Copyright (c) 1998 - 2004 Søren Schmidt <sos@FreeBSD.org>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -182,21 +182,25 @@ struct ata_request {
u_int32_t donecount; /* bytes transferred */
caddr_t data; /* pointer to data buf */
int flags;
-#define ATA_R_DONE 0x0001
-#define ATA_R_CONTROL 0x0002
-#define ATA_R_READ 0x0004
-#define ATA_R_WRITE 0x0008
+#define ATA_R_CONTROL 0x0001
+#define ATA_R_READ 0x0002
+#define ATA_R_WRITE 0x0004
+#define ATA_R_DMA 0x0008
#define ATA_R_ATAPI 0x0010
#define ATA_R_QUIET 0x0020
-#define ATA_R_DMA 0x0040
+#define ATA_R_INTR_SEEN 0x0040
+#define ATA_R_TIMEOUT 0x0080
#define ATA_R_ORDERED 0x0100
#define ATA_R_AT_HEAD 0x0200
#define ATA_R_REQUEUE 0x0400
#define ATA_R_SKIPSTART 0x0800
+#define ATA_R_DEBUG 0x1000
+
void (*callback)(struct ata_request *request);
+ struct sema done; /* request done sema */
int retries; /* retry count */
int timeout; /* timeout for this cmd */
struct callout_handle timeout_handle; /* handle for untimeout */
@@ -206,6 +210,19 @@ struct ata_request {
TAILQ_ENTRY(ata_request) chain; /* list management */
};
+/* define this for debugging request processing */
+#if 0
+#define ATA_DEBUG_RQ(request, string) \
+ { \
+ if (request->flags & ATA_R_DEBUG) \
+ ata_prtdev(request->device, "req=%08x %s " string "\n", \
+ (u_int)request, ata_cmd2str(request)); \
+ }
+#else
+#define ATA_DEBUG_RQ(request, string)
+#endif
+
+
/* structure describing an ATA/ATAPI device */
struct ata_device {
struct ata_channel *channel;
@@ -218,6 +235,7 @@ struct ata_device {
void *softc; /* ptr to softc for device */
void (*attach)(struct ata_device *atadev);
void (*detach)(struct ata_device *atadev);
+ void (*config)(struct ata_device *atadev);
void (*start)(struct ata_device *atadev);
int flags;
#define ATA_D_USE_CHS 0x0001
@@ -289,6 +307,7 @@ struct ata_channel {
#define ATA_USE_PC98GEOM 0x04
#define ATA_ATAPI_DMA_RO 0x08
#define ATA_48BIT_ACTIVE 0x10
+#define ATA_IMMEDIATE_MODE 0x20
struct ata_device device[2]; /* devices on this channel */
#define MASTER 0x00
@@ -305,11 +324,12 @@ struct ata_channel {
#define ATA_ACTIVE 0x0001
#define ATA_CONTROL 0x0002
+ void (*reset)(struct ata_channel *);
void (*locking)(struct ata_channel *, int);
#define ATA_LF_LOCK 0x0001
#define ATA_LF_UNLOCK 0x0002
- struct mtx queue_mtx;
+ struct mtx queue_mtx; /* queue lock */
TAILQ_HEAD(, ata_request) ata_queue; /* head of ATA queue */
void *running; /* currently running request */
};
diff --git a/sys/dev/ata/ata-card.c b/sys/dev/ata/ata-card.c
index 220c5d0..08b172b 100644
--- a/sys/dev/ata/ata-card.c
+++ b/sys/dev/ata/ata-card.c
@@ -1,5 +1,5 @@
/*-
- * Copyright (c) 1998 - 2003 Søren Schmidt <sos@FreeBSD.org>
+ * Copyright (c) 1998 - 2004 Søren Schmidt <sos@FreeBSD.org>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -36,6 +36,7 @@ __FBSDID("$FreeBSD$");
#include <sys/module.h>
#include <sys/bus.h>
#include <sys/malloc.h>
+#include <sys/sema.h>
#include <sys/taskqueue.h>
#include <machine/stdarg.h>
#include <machine/resource.h>
diff --git a/sys/dev/ata/ata-cbus.c b/sys/dev/ata/ata-cbus.c
index 3fa82b2..8f065c1 100644
--- a/sys/dev/ata/ata-cbus.c
+++ b/sys/dev/ata/ata-cbus.c
@@ -1,5 +1,5 @@
/*-
- * Copyright (c) 2002, 2003 Søren Schmidt <sos@FreeBSD.org>
+ * Copyright (c) 2002 - 2004 Søren Schmidt <sos@FreeBSD.org>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -36,6 +36,7 @@ __FBSDID("$FreeBSD$");
#include <sys/ata.h>
#include <sys/bus.h>
#include <sys/malloc.h>
+#include <sys/sema.h>
#include <sys/taskqueue.h>
#include <machine/resource.h>
#include <machine/bus.h>
@@ -144,7 +145,7 @@ ata_cbus_attach(device_t dev)
return ENXIO;
}
- if ((bus_setup_intr(dev, ctlr->irq, INTR_TYPE_BIO | INTR_ENTROPY,
+ if ((bus_setup_intr(dev, ctlr->irq, ATA_INTR_FLAGS,
ata_cbus_intr, ctlr, &ctlr->ih))) {
device_printf(dev, "unable to setup interrupt\n");
bus_release_resource(dev, SYS_RES_IOPORT, ATA_IOADDR_RID, ctlr->io);
diff --git a/sys/dev/ata/ata-chipset.c b/sys/dev/ata/ata-chipset.c
index 8f07c40..2aae069 100644
--- a/sys/dev/ata/ata-chipset.c
+++ b/sys/dev/ata/ata-chipset.c
@@ -1,5 +1,5 @@
/*-
- * Copyright (c) 1998 - 2003 Søren Schmidt <sos@FreeBSD.org>
+ * Copyright (c) 1998 - 2004 Søren Schmidt <sos@FreeBSD.org>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -37,6 +37,7 @@ __FBSDID("$FreeBSD$");
#include <sys/ata.h>
#include <sys/bus.h>
#include <sys/malloc.h>
+#include <sys/sema.h>
#include <sys/taskqueue.h>
#include <machine/stdarg.h>
#include <machine/resource.h>
@@ -99,6 +100,7 @@ static int ata_serverworks_chipinit(device_t);
static void ata_serverworks_setmode(struct ata_device *, int);
static int ata_sii_chipinit(device_t);
static int ata_sii_mio_allocate(device_t, struct ata_channel *);
+static void ata_sii_reset(struct ata_channel *);
static void ata_sii_intr(void *);
static void ata_cmd_intr(void *);
static void ata_cmd_old_intr(void *);
@@ -1622,6 +1624,7 @@ ata_sii_chipinit(device_t dev)
device_printf(dev, "unable to setup interrupt\n");
return ENXIO;
}
+
rid = 0x24;
if (!(ctlr->r_io2 = bus_alloc_resource(dev, SYS_RES_MEMORY, &rid,
0, ~0, 1, RF_ACTIVE)))
@@ -1650,10 +1653,8 @@ ata_sii_chipinit(device_t dev)
pci_write_config(dev, 0xec, 0x40094009, 4);
ctlr->allocate = ata_sii_mio_allocate;
- if (ctlr->chip->max_dma >= ATA_SA150) {
+ if (ctlr->chip->max_dma >= ATA_SA150)
ctlr->setmode = ata_sata_setmode;
- ctlr->locking = ata_serialize;
- }
else
ctlr->setmode = ata_sii_setmode;
}
@@ -1699,17 +1700,31 @@ ata_sii_mio_allocate(device_t dev, struct ata_channel *ch)
ch->r_io[ATA_BMDTP_PORT].offset = 0x04 + (ch->unit << 3);
ch->r_io[ATA_BMDEVSPEC_0].res = ctlr->r_io2;
ch->r_io[ATA_BMDEVSPEC_0].offset = 0xa1 + (ch->unit << 6);
+ ch->r_io[ATA_BMDEVSPEC_1].res = ctlr->r_io2;
+ ch->r_io[ATA_BMDEVSPEC_1].offset = 0x100 + (ch->unit << 7);
ch->r_io[ATA_IDX_ADDR].res = ctlr->r_io2;
if (ctlr->chip->max_dma >= ATA_SA150)
ch->flags |= ATA_NO_SLAVE;
+
ctlr->dmainit(ch);
if (ctlr->chip->cfg2 & SIIBUG)
ch->dma->boundary = 8 * 1024;
+
+ ch->reset = ata_sii_reset;
+
return 0;
}
static void
+ata_sii_reset(struct ata_channel *ch)
+{
+ ATA_IDX_OUTL(ch, ATA_BMDEVSPEC_1, 0x00000001);
+ DELAY(25000);
+ ATA_IDX_OUTL(ch, ATA_BMDEVSPEC_1, 0x00000000);
+}
+
+static void
ata_sii_intr(void *data)
{
struct ata_pci_controller *ctlr = data;
@@ -1724,8 +1739,7 @@ ata_sii_intr(void *data)
if (ch->dma) {
int bmstat = ATA_IDX_INB(ch, ATA_BMSTAT_PORT) & ATA_BMSTAT_MASK;
- if ((bmstat & (ATA_BMSTAT_ACTIVE | ATA_BMSTAT_INTERRUPT)) !=
- ATA_BMSTAT_INTERRUPT)
+ if (!(bmstat & ATA_BMSTAT_INTERRUPT))
continue;
ATA_IDX_OUTB(ch, ATA_BMSTAT_PORT, bmstat & ~ATA_BMSTAT_ERROR);
DELAY(1);
diff --git a/sys/dev/ata/ata-disk.c b/sys/dev/ata/ata-disk.c
index 5c056ff..9953268 100644
--- a/sys/dev/ata/ata-disk.c
+++ b/sys/dev/ata/ata-disk.c
@@ -1,5 +1,5 @@
/*-
- * Copyright (c) 1998 - 2003 Søren Schmidt <sos@FreeBSD.org>
+ * Copyright (c) 1998 - 2004 Søren Schmidt <sos@FreeBSD.org>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -41,6 +41,7 @@ __FBSDID("$FreeBSD$");
#include <sys/disk.h>
#include <sys/cons.h>
#include <sys/sysctl.h>
+#include <sys/sema.h>
#include <sys/taskqueue.h>
#include <vm/vm.h>
#include <vm/pmap.h>
@@ -55,6 +56,7 @@ __FBSDID("$FreeBSD$");
/* prototypes */
static void ad_detach(struct ata_device *);
+static void ad_config(struct ata_device *);
static void ad_start(struct ata_device *);
static void ad_done(struct ata_request *);
static disk_open_t adopen;
@@ -79,7 +81,9 @@ ad_attach(struct ata_device *atadev)
atadev->attach = NULL;
return;
}
+ atadev->softc = adp;
adp->device = atadev;
+
#ifdef ATA_STATIC_ID
adp->lun = (device_get_unit(atadev->channel->dev)<<1)+ATA_DEV(atadev->unit);
#else
@@ -119,30 +123,16 @@ ad_attach(struct ata_device *atadev)
lbasize48 > 268435455)
adp->total_secs = lbasize48;
- /* enable read caching */
- ata_controlcmd(atadev, ATA_SETFEATURES, ATA_SF_ENAB_RCACHE, 0, 0);
-
- /* enable write caching if enabled */
- if (ata_wc)
- ata_controlcmd(atadev, ATA_SETFEATURES, ATA_SF_ENAB_WCACHE, 0, 0);
- else
- ata_controlcmd(atadev, ATA_SETFEATURES, ATA_SF_DIS_WCACHE, 0, 0);
-
- /* use multiple sectors/interrupt if device supports it */
- adp->max_iosize = DEV_BSIZE;
- if (ad_version(atadev->param->version_major)) {
- int secsperint = max(1, min(atadev->param->sectors_intr, 16));
-
- if (!ata_controlcmd(atadev, ATA_SET_MULTI, 0, 0, secsperint))
- adp->max_iosize = secsperint * DEV_BSIZE;
- }
-
/* setup the function ptrs */
atadev->detach = ad_detach;
+ atadev->config = ad_config;
atadev->start = ad_start;
- atadev->softc = adp;
+
+ /* config device features */
+ ad_config(atadev);
/* lets create the disk device */
+ adp->max_iosize = DEV_BSIZE;
adp->disk.d_open = adopen;
adp->disk.d_strategy = adstrategy;
adp->disk.d_dump = addump;
@@ -191,6 +181,30 @@ ad_detach(struct ata_device *atadev)
free(adp, M_AD);
}
+static void
+ad_config(struct ata_device *atadev)
+{
+ struct ad_softc *adp = atadev->softc;
+
+ /* enable read caching */
+ ata_controlcmd(atadev, ATA_SETFEATURES, ATA_SF_ENAB_RCACHE, 0, 0);
+
+ /* enable write caching if enabled */
+ if (ata_wc)
+ ata_controlcmd(atadev, ATA_SETFEATURES, ATA_SF_ENAB_WCACHE, 0, 0);
+ else
+ ata_controlcmd(atadev, ATA_SETFEATURES, ATA_SF_DIS_WCACHE, 0, 0);
+
+ /* use multiple sectors/interrupt if device supports it */
+ adp->max_iosize = DEV_BSIZE;
+ if (ad_version(atadev->param->version_major)) {
+ int secsperint = max(1, min(atadev->param->sectors_intr, 16));
+
+ if (!ata_controlcmd(atadev, ATA_SET_MULTI, 0, 0, secsperint))
+ adp->max_iosize = secsperint * DEV_BSIZE;
+ }
+}
+
static int
adopen(struct disk *dp)
{
@@ -243,7 +257,7 @@ ad_start(struct ata_device *atadev)
request->device = atadev;
request->driver = bp;
request->callback = ad_done;
- request->timeout = 10;
+ request->timeout = 5;
request->retries = 2;
request->data = bp->bio_data;
request->bytecount = bp->bio_bcount;
diff --git a/sys/dev/ata/ata-dma.c b/sys/dev/ata/ata-dma.c
index 1637f20..f22cb8a 100644
--- a/sys/dev/ata/ata-dma.c
+++ b/sys/dev/ata/ata-dma.c
@@ -1,5 +1,5 @@
/*-
- * Copyright (c) 1998 - 2003 Søren Schmidt <sos@FreeBSD.org>
+ * Copyright (c) 1998 - 2004 Søren Schmidt <sos@FreeBSD.org>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -36,7 +36,7 @@ __FBSDID("$FreeBSD$");
#include <sys/endian.h>
#include <sys/malloc.h>
#include <sys/lock.h>
-#include <sys/mutex.h>
+#include <sys/sema.h>
#include <sys/taskqueue.h>
#include <sys/bus.h>
#include <machine/bus.h>
diff --git a/sys/dev/ata/ata-isa.c b/sys/dev/ata/ata-isa.c
index f4e9ec8..dcbd8f1 100644
--- a/sys/dev/ata/ata-isa.c
+++ b/sys/dev/ata/ata-isa.c
@@ -1,5 +1,5 @@
/*-
- * Copyright (c) 1998 - 2003 Søren Schmidt <sos@FreeBSD.org>
+ * Copyright (c) 1998 - 2004 Søren Schmidt <sos@FreeBSD.org>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -37,6 +37,7 @@ __FBSDID("$FreeBSD$");
#include <sys/module.h>
#include <sys/bus.h>
#include <sys/malloc.h>
+#include <sys/sema.h>
#include <sys/taskqueue.h>
#include <machine/stdarg.h>
#include <machine/resource.h>
diff --git a/sys/dev/ata/ata-lowlevel.c b/sys/dev/ata/ata-lowlevel.c
index c3837f8..39eeb9a 100644
--- a/sys/dev/ata/ata-lowlevel.c
+++ b/sys/dev/ata/ata-lowlevel.c
@@ -1,5 +1,5 @@
/*-
- * Copyright (c) 1998 - 2003 Søren Schmidt <sos@FreeBSD.org>
+ * Copyright (c) 1998 - 2004 Søren Schmidt <sos@FreeBSD.org>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -36,7 +36,7 @@ __FBSDID("$FreeBSD$");
#include <sys/kernel.h>
#include <sys/conf.h>
#include <sys/bus.h>
-#include <sys/mutex.h>
+#include <sys/sema.h>
#include <sys/taskqueue.h>
#include <machine/bus.h>
#include <sys/rman.h>
@@ -69,9 +69,17 @@ ata_generic_hw(struct ata_channel *ch)
static int
ata_transaction(struct ata_request *request)
{
+ /* safety check, device might have been detached FIXME SOS */
+ if (!request->device->param) {
+ request->result = ENXIO;
+ return ATA_OP_FINISHED;
+ }
+
/* record the request as running */
request->device->channel->running = request;
+ ATA_DEBUG_RQ(request, "transaction");
+
/* disable ATAPI DMA writes if HW doesn't support it */
if ((request->device->channel->flags & ATA_ATAPI_DMA_RO) &&
((request->flags & (ATA_R_ATAPI | ATA_R_DMA | ATA_R_WRITE)) ==
@@ -83,7 +91,7 @@ ata_transaction(struct ata_request *request)
/* ATA PIO data transfer and control commands */
default:
{
- /* record command direction here as our request might be done later */
+ /* record command direction here as our request might be gone later */
int write = (request->flags & ATA_R_WRITE);
/* issue command */
@@ -106,6 +114,7 @@ ata_transaction(struct ata_request *request)
ata_pio_write(request, request->transfersize);
}
}
+
/* return and wait for interrupt */
return ATA_OP_CONTINUES;
@@ -136,6 +145,7 @@ ata_transaction(struct ata_request *request)
request->result = EIO;
break;
}
+
/* return and wait for interrupt */
return ATA_OP_CONTINUES;
@@ -294,16 +304,23 @@ ata_interrupt(void *data)
return;
}
+ ATA_DEBUG_RQ(request, "interrupt");
+
/* ignore interrupt if device is busy */
- if (ATA_IDX_INB(ch, ATA_ALTSTAT) & ATA_S_BUSY) {
+ if (!(request->flags & ATA_R_TIMEOUT) &&
+ ATA_IDX_INB(ch, ATA_ALTSTAT) & ATA_S_BUSY) {
DELAY(100);
if (!(ATA_IDX_INB(ch, ATA_ALTSTAT) & ATA_S_DRQ))
return;
}
+ ATA_DEBUG_RQ(request, "interrupt accepted");
+
/* clear interrupt and get status */
request->status = ATA_IDX_INB(ch, ATA_STATUS);
+ request->flags |= ATA_R_INTR_SEEN;
+
switch (request->flags & (ATA_R_ATAPI | ATA_R_DMA | ATA_R_CONTROL)) {
/* ATA PIO data transfer and control commands */
@@ -492,6 +509,13 @@ ata_interrupt(void *data)
break;
}
+ /* if we timed out, we hold on to the channel, ata_reinit() will unlock */
+ if (request->flags & ATA_R_TIMEOUT) {
+ ata_finish(request);
+ return;
+ }
+
+ /* schedule completition for this request */
ata_finish(request);
/* unlock the ATA channel for new work */
@@ -529,7 +553,7 @@ ata_reset(struct ata_channel *ch)
}
}
- /* if nothing showed up no need to get any further */
+ /* if nothing showed up there is no need to get any further */
/* SOS is that too strong?, we just might loose devices here XXX */
ch->devices = 0;
if (!mask)
@@ -539,7 +563,11 @@ ata_reset(struct ata_channel *ch)
ata_printf(ch, -1, "reset tp1 mask=%02x ostat0=%02x ostat1=%02x\n",
mask, ostat0, ostat1);
- /* reset channel */
+ /* reset host end of channel (if supported) */
+ if (ch->reset)
+ ch->reset(ch);
+
+ /* reset (both) devices on this channel */
ATA_IDX_OUTB(ch, ATA_DRIVE, ATA_D_IBM | ATA_MASTER);
DELAY(10);
ATA_IDX_OUTB(ch, ATA_ALTSTAT, ATA_A_IDS | ATA_A_RESET);
@@ -617,6 +645,10 @@ ata_reset(struct ata_channel *ch)
DELAY(100000);
}
+ /* enable interrupt */
+ DELAY(10);
+ ATA_IDX_OUTB(ch, ATA_ALTSTAT, ATA_A_4BIT);
+
if (stat0 & ATA_S_BUSY)
mask &= ~0x01;
if (stat1 & ATA_S_BUSY)
@@ -627,41 +659,6 @@ ata_reset(struct ata_channel *ch)
"reset tp2 mask=%02x stat0=%02x stat1=%02x devices=0x%b\n",
mask, stat0, stat1, ch->devices,
"\20\4ATAPI_SLAVE\3ATAPI_MASTER\2ATA_SLAVE\1ATA_MASTER");
-#if 0
- if (!mask)
- return;
-
- if (mask & 0x01 && ostat0 != 0x00 &&
- !(ch->devices & (ATA_ATA_MASTER | ATA_ATAPI_MASTER))) {
- ATA_IDX_OUTB(ch, ATA_DRIVE, ATA_D_IBM | ATA_MASTER);
- DELAY(10);
- ATA_IDX_OUTB(ch, ATA_ERROR, 0x58);
- ATA_IDX_OUTB(ch, ATA_CYL_LSB, 0xa5);
- err = ATA_IDX_INB(ch, ATA_ERROR);
- lsb = ATA_IDX_INB(ch, ATA_CYL_LSB);
- if (bootverbose)
- ata_printf(ch, ATA_MASTER, "ATA err=0x%02x lsb=0x%02x\n", err, lsb);
- if (err != 0x58 && lsb == 0xa5)
- ch->devices |= ATA_ATA_MASTER;
- }
- if (mask & 0x02 && ostat1 != 0x00 &&
- !(ch->devices & (ATA_ATA_SLAVE | ATA_ATAPI_SLAVE))) {
- ATA_IDX_OUTB(ch, ATA_DRIVE, ATA_D_IBM | ATA_SLAVE);
- DELAY(10);
- ATA_IDX_OUTB(ch, ATA_ERROR, 0x58);
- ATA_IDX_OUTB(ch, ATA_CYL_LSB, 0xa5);
- err = ATA_IDX_INB(ch, ATA_ERROR);
- lsb = ATA_IDX_INB(ch, ATA_CYL_LSB);
- if (bootverbose)
- ata_printf(ch, ATA_SLAVE, "ATA err=0x%02x lsb=0x%02x\n", err, lsb);
- if (err != 0x58 && lsb == 0xa5)
- ch->devices |= ATA_ATA_SLAVE;
- }
-
- if (bootverbose)
- ata_printf(ch, -1, "reset tp3 devices=0x%b\n", ch->devices,
- "\20\4ATAPI_SLAVE\3ATAPI_MASTER\2ATA_SLAVE\1ATA_MASTER");
-#endif
}
static int
@@ -736,9 +733,6 @@ ata_command(struct ata_device *atadev, u_int8_t command,
return -1;
}
- /* enable interrupt */
- ATA_IDX_OUTB(atadev->channel, ATA_ALTSTAT, ATA_A_4BIT);
-
/* only use 48bit addressing if needed (avoid bugs and overhead) */
if ((lba > 268435455 || count > 256) && atadev->param &&
atadev->param->support.command2 & ATA_SUPPORT_ADDRESS48) {
diff --git a/sys/dev/ata/ata-pci.c b/sys/dev/ata/ata-pci.c
index 027556d..79a8eda 100644
--- a/sys/dev/ata/ata-pci.c
+++ b/sys/dev/ata/ata-pci.c
@@ -1,5 +1,5 @@
/*-
- * Copyright (c) 1998 - 2003 Søren Schmidt <sos@FreeBSD.org>
+ * Copyright (c) 1998 - 2004 Søren Schmidt <sos@FreeBSD.org>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -36,6 +36,7 @@ __FBSDID("$FreeBSD$");
#include <sys/module.h>
#include <sys/bus.h>
#include <sys/malloc.h>
+#include <sys/sema.h>
#include <sys/taskqueue.h>
#include <machine/stdarg.h>
#include <machine/resource.h>
diff --git a/sys/dev/ata/ata-queue.c b/sys/dev/ata/ata-queue.c
index 6fd30fc..415d398 100644
--- a/sys/dev/ata/ata-queue.c
+++ b/sys/dev/ata/ata-queue.c
@@ -1,5 +1,5 @@
/*-
- * Copyright (c) 1998 - 2003 Søren Schmidt <sos@FreeBSD.org>
+ * Copyright (c) 1998 - 2004 Søren Schmidt <sos@FreeBSD.org>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -37,8 +37,7 @@ __FBSDID("$FreeBSD$");
#include <sys/malloc.h>
#include <sys/bus.h>
#include <sys/conf.h>
-#include <sys/lock.h>
-#include <sys/mutex.h>
+#include <sys/sema.h>
#include <sys/taskqueue.h>
#include <machine/bus.h>
#include <sys/rman.h>
@@ -51,7 +50,6 @@ static char *ata_skey2str(u_int8_t);
/* local vars */
static MALLOC_DEFINE(M_ATA_REQ, "ATA request", "ATA request");
-static int atadebug = 0;
/*
* ATA request related functions
@@ -64,42 +62,65 @@ ata_alloc_request(void)
request = malloc(sizeof(struct ata_request), M_ATA_REQ, M_NOWAIT | M_ZERO);
if (!request)
printf("FAILURE - malloc ATA request failed\n");
+ sema_init(&request->done, 0, "ATA request done");
return request;
}
void
ata_free_request(struct ata_request *request)
{
+ sema_destroy(&request->done);
free(request, M_ATA_REQ);
}
void
ata_queue_request(struct ata_request *request)
{
- /* mark request as virgin (it might be a reused one) */
+ /* mark request as virgin (it might be a retry) */
request->result = request->status = request->error = 0;
- request->flags &= ~ATA_R_DONE;
- /* put request on the locked queue at the specified location */
- mtx_lock(&request->device->channel->queue_mtx);
- if (request->flags & ATA_R_AT_HEAD)
- TAILQ_INSERT_HEAD(&request->device->channel->ata_queue, request, chain);
- else
- TAILQ_INSERT_TAIL(&request->device->channel->ata_queue, request, chain);
- mtx_unlock(&request->device->channel->queue_mtx);
+ if (request->device->channel->flags & ATA_IMMEDIATE_MODE) {
- /* should we skip start ? */
- if (!(request->flags & ATA_R_SKIPSTART))
- ata_start(request->device->channel);
+ // request->flags |= ATA_R_DEBUG;
- /* if this was a requeue op callback/sleep already setup */
- if (request->flags & ATA_R_REQUEUE)
- return;
+ /* arm timeout */
+ if (!request->timeout_handle.callout && !dumping) {
+ request->timeout_handle =
+ timeout((timeout_t*)ata_timeout, request, request->timeout*hz);
+ }
- /* if this is not a callback and we havn't seen DONE yet -> sleep */
- if (!request->callback) {
- while (!(request->flags & ATA_R_DONE))
- tsleep(request, PRIBIO, "atareq", hz/10);
+ /* kick HW into action */
+ if (request->device->channel->hw.transaction(request) ==
+ ATA_OP_CONTINUES) {
+ ATA_DEBUG_RQ(request, "wait for completition");
+ sema_wait(&request->done);
+ }
+ }
+ else {
+ /* put request on the locked queue at the specified location */
+ mtx_lock(&request->device->channel->queue_mtx);
+ if (request->flags & ATA_R_AT_HEAD)
+ TAILQ_INSERT_HEAD(&request->device->channel->ata_queue,
+ request, chain);
+ else
+ TAILQ_INSERT_TAIL(&request->device->channel->ata_queue,
+ request, chain);
+ mtx_unlock(&request->device->channel->queue_mtx);
+
+ ATA_DEBUG_RQ(request, "queued");
+
+ /* should we skip start ? */
+ if (!(request->flags & ATA_R_SKIPSTART))
+ ata_start(request->device->channel);
+
+ /* if this is a requeued request callback/sleep is already setup */
+ if (request->flags & ATA_R_REQUEUE)
+ return;
+ /* if this is not a callback wait until request is completed */
+ if (!request->callback) {
+ ATA_DEBUG_RQ(request, "wait for completition");
+ sema_wait(&request->done);
+ }
}
}
@@ -156,14 +177,16 @@ ata_start(struct ata_channel *ch)
{
struct ata_request *request;
+ /* if in immediate mode, just skip start requests (stall queue) */
+ if (ch->flags & ATA_IMMEDIATE_MODE)
+ return;
+
/* lock the ATA HW for this request */
ch->locking(ch, ATA_LF_LOCK);
if (!ATA_LOCK_CH(ch, ATA_ACTIVE)) {
return;
}
-if (atadebug && mtx_owned(&Giant)) printf("ata_start holds GIANT!!!\n");
-
/* if we dont have any work, ask the subdriver(s) */
mtx_lock(&ch->queue_mtx);
if (TAILQ_EMPTY(&ch->ata_queue)) {
@@ -178,6 +201,8 @@ if (atadebug && mtx_owned(&Giant)) printf("ata_start holds GIANT!!!\n");
TAILQ_REMOVE(&ch->ata_queue, request, chain);
mtx_unlock(&ch->queue_mtx);
+ ATA_DEBUG_RQ(request, "starting");
+
/* arm timeout */
if (!request->timeout_handle.callout && !dumping) {
request->timeout_handle =
@@ -188,8 +213,6 @@ if (atadebug && mtx_owned(&Giant)) printf("ata_start holds GIANT!!!\n");
if (ch->hw.transaction(request) == ATA_OP_CONTINUES)
return;
- /* untimeout request */
- untimeout((timeout_t *)ata_timeout, request, request->timeout_handle);
ata_finish(request);
}
else
@@ -202,9 +225,16 @@ if (atadebug && mtx_owned(&Giant)) printf("ata_start holds GIANT!!!\n");
void
ata_finish(struct ata_request *request)
{
+ ATA_DEBUG_RQ(request, "taskqueue completition");
+
/* request is done schedule it for completition */
- TASK_INIT(&request->task, 0, ata_completed, request);
- taskqueue_enqueue(taskqueue_swi, &request->task);
+ if (request->device->channel->flags & ATA_IMMEDIATE_MODE) {
+ ata_completed(request, 0);
+ }
+ else {
+ TASK_INIT(&request->task, 0, ata_completed, request);
+ taskqueue_enqueue(taskqueue_swi, &request->task);
+ }
}
/* current command finished, clean up and return result */
@@ -214,27 +244,60 @@ ata_completed(void *context, int pending)
struct ata_request *request = (struct ata_request *)context;
struct ata_channel *channel = request->device->channel;
- /* untimeout request now we have control back */
- untimeout((timeout_t *)ata_timeout, request, request->timeout_handle);
+ ATA_DEBUG_RQ(request, "completed called");
- /* do the all the magic for completition evt retry etc etc */
- if ((request->status & (ATA_S_CORR | ATA_S_ERROR)) == ATA_S_CORR)
- ata_prtdev(request->device, "WARNING - %s soft error (ECC corrected)\n",
- ata_cmd2str(request));
+ if (request->flags & ATA_R_TIMEOUT) {
+ ata_reinit(channel);
- /* if this is a UDMA CRC error, retry request */
- if (request->flags & ATA_R_DMA && request->error & ATA_E_ICRC) {
- if (request->retries--) {
- ata_prtdev(request->device,
- "WARNING - %s UDMA ICRC error (retrying request)\n",
- ata_cmd2str(request));
- request->flags &= ~ATA_R_SKIPSTART;
+ /* if retries still permit, reinject this request */
+ if (request->retries-- > 0) {
+ request->flags &= ~(ATA_R_TIMEOUT | ATA_R_SKIPSTART);
+ request->flags |= (ATA_R_AT_HEAD | ATA_R_REQUEUE);
ata_queue_request(request);
return;
}
+
+ /* otherwise just finish with error */
+ else {
+ if (!(request->flags & ATA_R_QUIET))
+ ata_prtdev(request->device,
+ "FAILURE - %s timed out\n",
+ ata_cmd2str(request));
+ request->result = EIO;
+ }
+ }
+ else {
+ /* untimeout request now we have control back */
+ untimeout((timeout_t *)ata_timeout, request, request->timeout_handle);
+
+ /* do the all the magic for completition evt retry etc etc */
+ if ((request->status & (ATA_S_CORR | ATA_S_ERROR)) == ATA_S_CORR) {
+ ata_prtdev(request->device,
+ "WARNING - %s soft error (ECC corrected)",
+ ata_cmd2str(request));
+ if (!(request->flags & (ATA_R_ATAPI | ATA_R_CONTROL)))
+ printf(" LBA=%llu", (unsigned long long)request->u.ata.lba);
+ printf("\n");
+ }
+
+ /* if this is a UDMA CRC error, retry request */
+ if (request->flags & ATA_R_DMA && request->error & ATA_E_ICRC) {
+ if (request->retries-- > 0) {
+ ata_prtdev(request->device,
+ "WARNING - %s UDMA ICRC error (retrying request)",
+ ata_cmd2str(request));
+ if (!(request->flags & (ATA_R_ATAPI | ATA_R_CONTROL)))
+ printf(" LBA=%llu", (unsigned long long)request->u.ata.lba);
+ printf("\n");
+ request->flags &= ~ATA_R_SKIPSTART;
+ ata_queue_request(request);
+ return;
+ }
+ }
}
switch (request->flags & ATA_R_ATAPI) {
+
/* ATA errors */
default:
if (request->status & ATA_S_ERROR) {
@@ -250,8 +313,7 @@ ata_completed(void *context, int pending)
if ((request->flags & ATA_R_DMA) &&
(request->dmastat & ATA_BMSTAT_ERROR))
printf(" dma=0x%02x", request->dmastat);
- if (!(request->flags & ATA_R_ATAPI) &&
- !(request->flags & ATA_R_CONTROL))
+ if (!(request->flags & (ATA_R_ATAPI | ATA_R_CONTROL)))
printf(" LBA=%llu", (unsigned long long)request->u.ata.lba);
printf("\n");
}
@@ -306,74 +368,67 @@ ata_completed(void *context, int pending)
break;
}
- request->flags |= ATA_R_DONE;
+ ATA_DEBUG_RQ(request, "completed callback/wakeup");
+
if (request->callback)
(request->callback)(request);
else
- wakeup(request);
+ sema_post(&request->done);
+
ata_start(channel);
}
static void
ata_timeout(struct ata_request *request)
{
- struct ata_channel *ch = request->device->channel;
- int quiet = request->flags & ATA_R_QUIET;
+ ATA_DEBUG_RQ(request, "timeout");
/* clear timeout etc */
request->timeout_handle.callout = NULL;
- /* call hw.interrupt to try finish up the command */
- ch->hw.interrupt(request->device->channel);
- if (ch->running != request) {
- if (!quiet)
- ata_prtdev(request->device,
- "WARNING - %s recovered from missing interrupt\n",
+ if (request->flags & ATA_R_INTR_SEEN) {
+ if (request->retries-- > 0) {
+ ata_prtdev(request->device,
+ "WARNING - %s interrupt was seen but timeout fired",
+ ata_cmd2str(request));
+ if (!(request->flags & (ATA_R_ATAPI | ATA_R_CONTROL)))
+ printf(" LBA=%llu", (unsigned long long)request->u.ata.lba);
+ printf("\n");
+
+ /* re-arm timeout */
+ if (!request->timeout_handle.callout && !dumping) {
+ request->timeout_handle =
+ timeout((timeout_t*)ata_timeout, request,
+ request->timeout * hz);
+ }
+ }
+ else {
+ ata_prtdev(request->device,
+ "WARNING - %s interrupt was seen but taskqueue stalled",
ata_cmd2str(request));
+ if (!(request->flags & (ATA_R_ATAPI | ATA_R_CONTROL)))
+ printf(" LBA=%llu", (unsigned long long)request->u.ata.lba);
+ printf("\n");
+ ata_completed(request, 0);
+ }
return;
}
- /* if this was a DMA request stop the engine to be on the safe side */
- if (request->flags & ATA_R_DMA) {
- request->dmastat =
- request->device->channel->dma->stop(request->device->channel);
- }
-
/* report that we timed out */
- if (request->retries > 0 && !(request->flags & ATA_R_QUIET))
+ if (!(request->flags & ATA_R_QUIET)) {
ata_prtdev(request->device,
- "TIMEOUT - %s retrying (%d retr%s left)\n",
+ "TIMEOUT - %s retrying (%d retr%s left)",
ata_cmd2str(request), request->retries,
request->retries == 1 ? "y" : "ies");
-
- /* try to adjust HW's attitude towards work */
- ata_reinit(request->device->channel);
-
- /* if device disappeared nothing more to do here */
- if (!request->device->softc) {
- if (!(request->flags & ATA_R_QUIET))
- ata_prtdev(request->device,
- "FAILURE - %s device lockup/removed\n",
- ata_cmd2str(request));
- return;
+ if (!(request->flags & (ATA_R_ATAPI | ATA_R_CONTROL)))
+ printf(" LBA=%llu", (unsigned long long)request->u.ata.lba);
+ printf("\n");
}
- /* if retries still permit, reinject this request */
- if (request->retries-- > 0) {
- request->flags |= (ATA_R_AT_HEAD | ATA_R_REQUEUE);
- request->flags &= ~ATA_R_SKIPSTART;
- ata_queue_request(request);
- }
- /* otherwise just schedule finish with error */
- else {
- if (!(request->flags & ATA_R_QUIET))
- ata_prtdev(request->device,
- "FAILURE - %s timed out\n",
- ata_cmd2str(request));
- request->status = ATA_S_ERROR;
- TASK_INIT(&request->task, 0, ata_completed, request);
- taskqueue_enqueue(taskqueue_swi, &request->task);
- }
+ /* now simulate the missing interrupt */
+ request->flags |= ATA_R_TIMEOUT;
+ request->device->channel->hw.interrupt(request->device->channel);
+ return;
}
char *
@@ -464,7 +519,16 @@ ata_cmd2str(struct ata_request *request)
case 0xe7: return ("FLUSHCACHE");
case 0xea: return ("FLUSHCACHE48");
case 0xec: return ("ATA_IDENTIFY");
- case 0xef: return ("SETFEATURES");
+ case 0xef:
+ switch (request->u.ata.feature) {
+ case 0x03: return ("SETFEATURES SET TRANSFER MODE");
+ case 0x02: return ("SETFEATURES ENABLE WCACHE");
+ case 0x82: return ("SETFEATURES DISABLE WCACHE");
+ case 0xaa: return ("SETFEATURES ENABLE RCACHE");
+ case 0x55: return ("SETFEATURES DISABLE RCACHE");
+ }
+ sprintf(buffer, "SETFEATURES 0x%02x", request->u.ata.feature);
+ return buffer;
}
}
sprintf(buffer, "unknown CMD (0x%02x)", request->u.ata.command);
diff --git a/sys/dev/ata/ata-raid.c b/sys/dev/ata/ata-raid.c
index 95df9f6..323c0ca 100644
--- a/sys/dev/ata/ata-raid.c
+++ b/sys/dev/ata/ata-raid.c
@@ -1,5 +1,5 @@
/*-
- * Copyright (c) 2000 - 2003 Søren Schmidt <sos@FreeBSD.org>
+ * Copyright (c) 2000 - 2004 Søren Schmidt <sos@FreeBSD.org>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -43,6 +43,7 @@ __FBSDID("$FreeBSD$");
#include <sys/cons.h>
#include <sys/unistd.h>
#include <sys/kthread.h>
+#include <sys/sema.h>
#include <sys/taskqueue.h>
#include <machine/bus.h>
#include <sys/rman.h>
@@ -711,7 +712,7 @@ arstrategy(struct bio *bp)
return;
}
- buf1 = malloc(sizeof(struct ar_buf), M_AR, M_NOWAIT | M_ZERO);
+ buf1 = malloc(sizeof(struct ar_buf), M_AR, M_NOWAIT | M_ZERO); /* XXX */
buf1->bp.bio_pblkno = lba;
if ((buf1->drive = drv) > 0)
buf1->bp.bio_pblkno += rdp->offset;
@@ -819,7 +820,7 @@ arstrategy(struct bio *bp)
((rdp->flags & AR_F_REBUILDING) &&
(rdp->disks[buf1->drive].flags & AR_DF_SPARE) &&
buf1->bp.bio_pblkno < rdp->lock_start)) {
- buf2 = malloc(sizeof(struct ar_buf), M_AR, M_NOWAIT);
+ buf2 = malloc(sizeof(struct ar_buf), M_AR, M_NOWAIT); /* XXX */
bcopy(buf1, buf2, sizeof(struct ar_buf));
buf1->mirror = buf2;
buf2->mirror = buf1;
@@ -1020,7 +1021,7 @@ ar_rebuild(void *arg)
rdp->lock_end = rdp->lock_start + AR_REBUILD_SIZE;
rdp->flags |= AR_F_REBUILDING;
splx(s);
- buffer = malloc(AR_REBUILD_SIZE * DEV_BSIZE, M_AR, M_NOWAIT | M_ZERO);
+ buffer = malloc(AR_REBUILD_SIZE * DEV_BSIZE, M_AR, M_NOWAIT | M_ZERO); /* XXX */
/* now go copy entire disk(s) */
while (rdp->lock_end < (rdp->total_sectors / rdp->width)) {
diff --git a/sys/dev/ata/atapi-cd.c b/sys/dev/ata/atapi-cd.c
index ec35c4e..6cdbaea 100644
--- a/sys/dev/ata/atapi-cd.c
+++ b/sys/dev/ata/atapi-cd.c
@@ -1,5 +1,5 @@
/*-
- * Copyright (c) 1998 - 2003 Søren Schmidt <sos@FreeBSD.org>
+ * Copyright (c) 1998 - 2004 Søren Schmidt <sos@FreeBSD.org>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -46,7 +46,7 @@ __FBSDID("$FreeBSD$");
#include <sys/conf.h>
#include <sys/ctype.h>
#include <sys/taskqueue.h>
-#include <sys/mutex.h>
+#include <sys/sema.h>
#include <machine/bus.h>
#include <geom/geom.h>
#include <dev/ata/ata-all.h>
diff --git a/sys/dev/ata/atapi-fd.c b/sys/dev/ata/atapi-fd.c
index 91f2110..0c0f4ac 100644
--- a/sys/dev/ata/atapi-fd.c
+++ b/sys/dev/ata/atapi-fd.c
@@ -1,5 +1,5 @@
/*-
- * Copyright (c) 1998 - 2003 Søren Schmidt <sos@FreeBSD.org>
+ * Copyright (c) 1998 - 2004 Søren Schmidt <sos@FreeBSD.org>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -38,6 +38,7 @@ __FBSDID("$FreeBSD$");
#include <sys/bus.h>
#include <sys/conf.h>
#include <sys/cdio.h>
+#include <sys/sema.h>
#include <sys/taskqueue.h>
#include <machine/bus.h>
#include <geom/geom_disk.h>
diff --git a/sys/dev/ata/atapi-tape.c b/sys/dev/ata/atapi-tape.c
index f442258..1a5d6ca 100644
--- a/sys/dev/ata/atapi-tape.c
+++ b/sys/dev/ata/atapi-tape.c
@@ -1,5 +1,5 @@
/*-
- * Copyright (c) 1998 - 2003 Søren Schmidt <sos@FreeBSD.org>
+ * Copyright (c) 1998 - 2004 Søren Schmidt <sos@FreeBSD.org>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -40,6 +40,7 @@ __FBSDID("$FreeBSD$");
#include <sys/bus.h>
#include <sys/mtio.h>
#include <sys/devicestat.h>
+#include <sys/sema.h>
#include <sys/taskqueue.h>
#include <machine/bus.h>
#include <dev/ata/ata-all.h>
OpenPOWER on IntegriCloud