summaryrefslogtreecommitdiffstats
path: root/sys/dev/ata
diff options
context:
space:
mode:
authorsos <sos@FreeBSD.org>2004-03-15 12:03:48 +0000
committersos <sos@FreeBSD.org>2004-03-15 12:03:48 +0000
commitdc99d6d221faeb25117b57ba2bcdb8aca0e539a0 (patch)
tree31a9d6667678aa55b9fa75ad9df738b13820030f /sys/dev/ata
parenta745e2bbf146ec1885fcb077a44b9983794dac64 (diff)
downloadFreeBSD-src-dc99d6d221faeb25117b57ba2bcdb8aca0e539a0.zip
FreeBSD-src-dc99d6d221faeb25117b57ba2bcdb8aca0e539a0.tar.gz
Add support for detaching PCI controllers.
This adds support for cardbus ATA/SATA controllers. I get roughly the same transfer speeds as on true PCI controllers. Nice to be able to add a couble of "real" disks to a laptop :)
Diffstat (limited to 'sys/dev/ata')
-rw-r--r--sys/dev/ata/ata-all.c19
-rw-r--r--sys/dev/ata/ata-all.h2
-rw-r--r--sys/dev/ata/ata-chipset.c92
-rw-r--r--sys/dev/ata/ata-lowlevel.c4
-rw-r--r--sys/dev/ata/ata-pci.c68
-rw-r--r--sys/dev/ata/ata-pci.h8
-rw-r--r--sys/dev/ata/ata-queue.c33
7 files changed, 129 insertions, 97 deletions
diff --git a/sys/dev/ata/ata-all.c b/sys/dev/ata/ata-all.c
index dd369b0..8fff15a 100644
--- a/sys/dev/ata/ata-all.c
+++ b/sys/dev/ata/ata-all.c
@@ -69,7 +69,6 @@ static struct cdevsw ata_cdevsw = {
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);
@@ -710,24 +709,6 @@ 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)
{
diff --git a/sys/dev/ata/ata-all.h b/sys/dev/ata/ata-all.h
index da86b4e..ad0203c 100644
--- a/sys/dev/ata/ata-all.h
+++ b/sys/dev/ata/ata-all.h
@@ -332,6 +332,7 @@ struct ata_channel {
#define ATA_ATAPI_DMA_RO 0x08
#define ATA_48BIT_ACTIVE 0x10
#define ATA_IMMEDIATE_MODE 0x20
+#define ATA_HWGONE 0x40
struct ata_device device[2]; /* devices on this channel */
#define MASTER 0x00
@@ -396,6 +397,7 @@ int ata_controlcmd(struct ata_device *atadev, u_int8_t command, u_int16_t featur
int ata_atapicmd(struct ata_device *atadev, u_int8_t *ccb, caddr_t data, int count, int flags, int timeout);
void ata_queue_request(struct ata_request *request);
void ata_finish(struct ata_request *request);
+void ata_fail_requests(struct ata_channel *ch, struct ata_device *device);
char *ata_cmd2str(struct ata_request *request);
/* ata-lowlevel.c: */
diff --git a/sys/dev/ata/ata-chipset.c b/sys/dev/ata/ata-chipset.c
index 9621a10..deac794 100644
--- a/sys/dev/ata/ata-chipset.c
+++ b/sys/dev/ata/ata-chipset.c
@@ -512,7 +512,7 @@ ata_cyrix_chipinit(device_t dev)
if (ata_setup_interrupt(dev))
return ENXIO;
- if (ctlr->r_io1)
+ if (ctlr->r_res1)
ctlr->setmode = ata_cyrix_setmode;
else
ctlr->setmode = ata_generic_setmode;
@@ -1145,14 +1145,14 @@ ata_promise_chipinit(device_t dev)
switch (ctlr->chip->cfg1) {
case PRNEW:
/* setup clocks */
- ATA_OUTB(ctlr->r_io1, 0x11, ATA_INB(ctlr->r_io1, 0x11) | 0x0a);
+ ATA_OUTB(ctlr->r_res1, 0x11, ATA_INB(ctlr->r_res1, 0x11) | 0x0a);
ctlr->dmainit = ata_promise_new_dmainit;
/* FALLTHROUGH */
case PROLD:
/* enable burst mode */
- ATA_OUTB(ctlr->r_io1, 0x1f, ATA_INB(ctlr->r_io1, 0x1f) | 0x01);
+ ATA_OUTB(ctlr->r_res1, 0x1f, ATA_INB(ctlr->r_res1, 0x1f) | 0x01);
if ((bus_setup_intr(dev, ctlr->r_irq, ATA_INTR_FLAGS,
ata_promise_old_intr, ctlr, &ctlr->handle))) {
@@ -1170,21 +1170,23 @@ ata_promise_chipinit(device_t dev)
break;
case PRMIO:
- rid = 0x1c;
- if (!(ctlr->r_io2 = bus_alloc_resource(dev, SYS_RES_MEMORY, &rid,
- 0, ~0, 1, RF_ACTIVE)))
+ ctlr->r_type2 = SYS_RES_MEMORY;
+ ctlr->r_rid2 = 0x1c;
+ if (!(ctlr->r_res2 =
+ bus_alloc_resource(dev, ctlr->r_type2, &ctlr->r_rid2,
+ 0, ~0, 1, RF_ACTIVE)))
return ENXIO;
ctlr->dmainit = ata_promise_mio_dmainit;
ctlr->allocate = ata_promise_mio_allocate;
if (ctlr->chip->cfg2 & PRDUAL) {
- ctlr->channels = ((ATA_INL(ctlr->r_io2, 0x48) & 0x01) > 0) +
- ((ATA_INL(ctlr->r_io2, 0x48) & 0x02) > 0) + 2;
+ ctlr->channels = ((ATA_INL(ctlr->r_res2, 0x48) & 0x01) > 0) +
+ ((ATA_INL(ctlr->r_res2, 0x48) & 0x02) > 0) + 2;
}
else if (ctlr->chip->cfg2 & PRSATA) {
- ATA_OUTL(ctlr->r_io2, 0x06c, 0x00ff0033);
- ctlr->channels = ((ATA_INL(ctlr->r_io2, 0x48) & 0x02) > 0) + 3;
+ ATA_OUTL(ctlr->r_res2, 0x06c, 0x00ff0033);
+ ctlr->channels = ((ATA_INL(ctlr->r_res2, 0x48) & 0x02) > 0) + 3;
}
else
ctlr->channels = 4;
@@ -1208,18 +1210,18 @@ ata_promise_mio_allocate(device_t dev, struct ata_channel *ch)
int i;
for (i = ATA_DATA; i <= ATA_STATUS; i++) {
- ch->r_io[i].res = ctlr->r_io2;
+ ch->r_io[i].res = ctlr->r_res2;
ch->r_io[i].offset = 0x200 + (i << 2) + (ch->unit << 7);
}
- ch->r_io[ATA_ALTSTAT].res = ctlr->r_io2;
+ ch->r_io[ATA_ALTSTAT].res = ctlr->r_res2;
ch->r_io[ATA_ALTSTAT].offset = 0x238 + (ch->unit << 7);
- ch->r_io[ATA_BMCMD_PORT].res = ctlr->r_io2;
+ ch->r_io[ATA_BMCMD_PORT].res = ctlr->r_res2;
ch->r_io[ATA_BMCMD_PORT].offset = 0x260 + (ch->unit << 7);
- ch->r_io[ATA_BMDTP_PORT].res = ctlr->r_io2;
+ ch->r_io[ATA_BMDTP_PORT].res = ctlr->r_res2;
ch->r_io[ATA_BMDTP_PORT].offset = 0x244 + (ch->unit << 7);
- ch->r_io[ATA_BMDEVSPEC_0].res = ctlr->r_io2;
+ ch->r_io[ATA_BMDEVSPEC_0].res = ctlr->r_res2;
ch->r_io[ATA_BMDEVSPEC_0].offset = ((ch->unit + 1) << 2);
- ch->r_io[ATA_IDX_ADDR].res = ctlr->r_io2;
+ ch->r_io[ATA_IDX_ADDR].res = ctlr->r_res2;
ATA_IDX_OUTL(ch, ATA_BMCMD_PORT,
(ATA_IDX_INL(ch, ATA_BMCMD_PORT) & ~0x00003f9f) |
@@ -1242,7 +1244,7 @@ ata_promise_old_intr(void *data)
for (unit = 0; unit < 2; unit++) {
if (!(ch = ctlr->interrupt[unit].argument))
continue;
- if (ATA_INL(ctlr->r_io1, 0x1c) & (ch->unit ? 0x00004000 : 0x00000400)) {
+ if (ATA_INL(ctlr->r_res1, 0x1c) & (ch->unit ? 0x00004000 : 0x00000400)) {
if (ch->dma && (ch->dma->flags & ATA_DMA_ACTIVE)) {
int bmstat = ATA_IDX_INB(ch, ATA_BMSTAT_PORT) & ATA_BMSTAT_MASK;
@@ -1292,7 +1294,7 @@ ata_promise_mio_intr(void *data)
u_int32_t irq_vector;
int unit;
- irq_vector = ATA_INL(ctlr->r_io2, 0x0040);
+ irq_vector = ATA_INL(ctlr->r_res2, 0x0040);
for (unit = 0; unit < ctlr->channels; unit++) {
if (irq_vector & (1 << (unit + 1))) {
if ((ch = ctlr->interrupt[unit].argument)) {
@@ -1398,9 +1400,9 @@ ata_promise_new_dmastart(struct ata_channel *ch)
device_get_softc(device_get_parent(ch->dev));
if (ch->flags & ATA_48BIT_ACTIVE) {
- ATA_OUTB(ctlr->r_io1, 0x11,
- ATA_INB(ctlr->r_io1, 0x11) | (ch->unit ? 0x08 : 0x02));
- ATA_OUTL(ctlr->r_io1, 0x20,
+ ATA_OUTB(ctlr->r_res1, 0x11,
+ ATA_INB(ctlr->r_res1, 0x11) | (ch->unit ? 0x08 : 0x02));
+ ATA_OUTL(ctlr->r_res1, 0x20,
((ch->dma->flags & ATA_DMA_READ) ? 0x05000000 : 0x06000000) |
(ch->dma->cur_iosize >> 1));
}
@@ -1421,9 +1423,9 @@ ata_promise_new_dmastop(struct ata_channel *ch)
int error;
if (ch->flags & ATA_48BIT_ACTIVE) {
- ATA_OUTB(ctlr->r_io1, 0x11,
- ATA_INB(ctlr->r_io1, 0x11) & ~(ch->unit ? 0x08 : 0x02));
- ATA_OUTL(ctlr->r_io1, 0x20, 0);
+ ATA_OUTB(ctlr->r_res1, 0x11,
+ ATA_INB(ctlr->r_res1, 0x11) & ~(ch->unit ? 0x08 : 0x02));
+ ATA_OUTL(ctlr->r_res1, 0x20, 0);
}
error = ATA_IDX_INB(ch, ATA_BMSTAT_PORT);
ATA_IDX_OUTB(ch, ATA_BMCMD_PORT,
@@ -1630,9 +1632,11 @@ ata_sii_chipinit(device_t dev)
return ENXIO;
}
- rid = 0x24;
- if (!(ctlr->r_io2 = bus_alloc_resource(dev, SYS_RES_MEMORY, &rid,
- 0, ~0, 1, RF_ACTIVE)))
+ ctlr->r_type2 = SYS_RES_MEMORY;
+ ctlr->r_rid2 = 0x24;
+ if (!(ctlr->r_res2 =
+ bus_alloc_resource(dev, ctlr->r_type2, &ctlr->r_rid2,
+ 0, ~0, 1, RF_ACTIVE)))
return ENXIO;
if (ctlr->chip->cfg2 & SIISETCLK) {
@@ -1644,23 +1648,12 @@ ata_sii_chipinit(device_t dev)
ctlr->chip->text);
}
- if (ctlr->chip->cfg2 & SII4CH)
- ctlr->channels = 4;
-
/* enable interrupt as BIOS might not */
pci_write_config(dev, 0x8a, (pci_read_config(dev, 0x8a, 1) & 0x3f), 1);
- /* setup chipset defaults as BIOS might not */
-#if 0
- pci_write_config(dev, 0xa2, 0x328a, 2);
- pci_write_config(dev, 0xa4, 0x328a328a, 4);
- pci_write_config(dev, 0xa8, 0x22082208, 4);
- pci_write_config(dev, 0xac, 0x40094009, 4);
- pci_write_config(dev, 0xe2, 0x328a, 2);
- pci_write_config(dev, 0xe4, 0x328a328a, 4);
- pci_write_config(dev, 0xe8, 0x22082208, 4);
- pci_write_config(dev, 0xec, 0x40094009, 4);
-#endif
+ if (ctlr->chip->cfg2 & SII4CH)
+ ctlr->channels = 4;
+
ctlr->allocate = ata_sii_mio_allocate;
if (ctlr->chip->max_dma >= ATA_SA150)
ctlr->setmode = ata_sata_setmode;
@@ -1697,22 +1690,22 @@ ata_sii_mio_allocate(device_t dev, struct ata_channel *ch)
int i;
for (i = ATA_DATA; i <= ATA_STATUS; i++) {
- ch->r_io[i].res = ctlr->r_io2;
+ ch->r_io[i].res = ctlr->r_res2;
ch->r_io[i].offset = 0x80 + i + (unit01 << 6) + (unit10 << 9);
}
- ch->r_io[ATA_ALTSTAT].res = ctlr->r_io2;
+ ch->r_io[ATA_ALTSTAT].res = ctlr->r_res2;
ch->r_io[ATA_ALTSTAT].offset = 0x8a + (unit01 << 6) + (unit10 << 9);
- ch->r_io[ATA_BMCMD_PORT].res = ctlr->r_io2;
+ ch->r_io[ATA_BMCMD_PORT].res = ctlr->r_res2;
ch->r_io[ATA_BMCMD_PORT].offset = 0x00 + (unit01 << 3) + (unit10 << 9);
- ch->r_io[ATA_BMSTAT_PORT].res = ctlr->r_io2;
+ ch->r_io[ATA_BMSTAT_PORT].res = ctlr->r_res2;
ch->r_io[ATA_BMSTAT_PORT].offset = 0x02 + (unit01 << 3) + (unit10 << 9);
- ch->r_io[ATA_BMDTP_PORT].res = ctlr->r_io2;
+ ch->r_io[ATA_BMDTP_PORT].res = ctlr->r_res2;
ch->r_io[ATA_BMDTP_PORT].offset = 0x04 + (unit01 << 3) + (unit10 << 9);
- ch->r_io[ATA_BMDEVSPEC_0].res = ctlr->r_io2;
+ ch->r_io[ATA_BMDEVSPEC_0].res = ctlr->r_res2;
ch->r_io[ATA_BMDEVSPEC_0].offset = 0xa1 + (unit01 << 6) + (unit10 << 9);
- ch->r_io[ATA_BMDEVSPEC_1].res = ctlr->r_io2;
+ ch->r_io[ATA_BMDEVSPEC_1].res = ctlr->r_res2;
ch->r_io[ATA_BMDEVSPEC_1].offset = 0x100 + (unit01 << 7) + (unit10 << 9);
- ch->r_io[ATA_IDX_ADDR].res = ctlr->r_io2;
+ ch->r_io[ATA_IDX_ADDR].res = ctlr->r_res2;
if (ctlr->chip->max_dma >= ATA_SA150) {
ch->flags |= ATA_NO_SLAVE;
@@ -1723,7 +1716,6 @@ ata_sii_mio_allocate(device_t dev, struct ata_channel *ch)
if (ctlr->chip->cfg2 & SIIBUG)
ch->dma->boundary = 8 * 1024;
-
return 0;
}
diff --git a/sys/dev/ata/ata-lowlevel.c b/sys/dev/ata/ata-lowlevel.c
index 1bbf5b2..8592e58 100644
--- a/sys/dev/ata/ata-lowlevel.c
+++ b/sys/dev/ata/ata-lowlevel.c
@@ -70,8 +70,8 @@ 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) {
+ /* safetybelt for HW that went away */
+ if (!request->device->param || request->device->channel->flags&ATA_HWGONE) {
request->result = ENXIO;
return ATA_OP_FINISHED;
}
diff --git a/sys/dev/ata/ata-pci.c b/sys/dev/ata/ata-pci.c
index 81013ac..8fab433 100644
--- a/sys/dev/ata/ata-pci.c
+++ b/sys/dev/ata/ata-pci.c
@@ -154,21 +154,9 @@ static int
ata_pci_attach(device_t dev)
{
struct ata_pci_controller *ctlr = device_get_softc(dev);
- u_int8_t class, subclass;
- u_int32_t type, cmd;
+ u_int32_t cmd;
int unit;
- /* set up vendor-specific stuff */
- type = pci_get_devid(dev);
- class = pci_get_class(dev);
- subclass = pci_get_subclass(dev);
- cmd = pci_read_config(dev, PCIR_COMMAND, 2);
-
- if (!(cmd & (PCIM_CMD_PORTEN | PCIM_CMD_MEMEN))) {
- device_printf(dev, "ATA channel disabled by BIOS\n");
- return 0;
- }
-
/* do chipset specific setups only needed once */
if (ATA_MASTERDEV(dev) || pci_read_config(dev, 0x18, 4) & IOMASK)
ctlr->channels = 2;
@@ -178,18 +166,19 @@ ata_pci_attach(device_t dev)
ctlr->dmainit = ata_pci_dmainit;
ctlr->locking = ata_pci_locknoop;
-#ifdef __sparc64__
+ /* if needed try to enable busmastering */
+ cmd = pci_read_config(dev, PCIR_COMMAND, 2);
if (!(cmd & PCIM_CMD_BUSMASTEREN)) {
pci_write_config(dev, PCIR_COMMAND, cmd | PCIM_CMD_BUSMASTEREN, 2);
cmd = pci_read_config(dev, PCIR_COMMAND, 2);
}
-#endif
- /* if busmastering configured get the I/O resource */
- if ((cmd & PCIM_CMD_BUSMASTEREN) == PCIM_CMD_BUSMASTEREN) {
- int rid = ATA_BMADDR_RID;
- ctlr->r_io1 = bus_alloc_resource(dev, SYS_RES_IOPORT, &rid,
- 0, ~0, 1, RF_ACTIVE);
+ /* if busmastering mode "stuck" use it */
+ if ((cmd & PCIM_CMD_BUSMASTEREN) == PCIM_CMD_BUSMASTEREN) {
+ ctlr->r_type1 = SYS_RES_IOPORT;
+ ctlr->r_rid1 = ATA_BMADDR_RID;
+ ctlr->r_res1 = bus_alloc_resource(dev, ctlr->r_type1, &ctlr->r_rid1,
+ 0, ~0, 1, RF_ACTIVE);
}
ctlr->chipinit(dev);
@@ -199,9 +188,34 @@ ata_pci_attach(device_t dev)
device_add_child(dev, "ata", ATA_MASTERDEV(dev) ?
unit : devclass_find_free_unit(ata_devclass, 2));
- return bus_generic_attach(dev);
-}
+ return bus_generic_attach(dev); }
+static int
+ata_pci_detach(device_t dev)
+{
+ struct ata_pci_controller *ctlr = device_get_softc(dev);
+ struct ata_channel *ch;
+ int unit;
+
+ /* mark HW as gone, we dont want to issue commands to HW no longer there */
+ for (unit = 0; unit < ctlr->channels; unit++) {
+ if ((ch = ctlr->interrupt[unit].argument))
+ ch->flags |= ATA_HWGONE;
+ }
+
+ bus_generic_detach(dev);
+
+ if (ctlr->r_irq) {
+ bus_teardown_intr(dev, ctlr->r_irq, ctlr->handle);
+ bus_release_resource(dev, SYS_RES_IRQ, ATA_IRQ_RID, ctlr->r_irq);
+ }
+ if (ctlr->r_res2)
+ bus_release_resource(dev, ctlr->r_type2, ctlr->r_rid2, ctlr->r_res2);
+ if (ctlr->r_res1)
+ bus_release_resource(dev, ctlr->r_type1, ctlr->r_rid1, ctlr->r_res1);
+
+ return 0;
+}
static int
ata_pci_print_child(device_t dev, device_t child)
@@ -420,9 +434,9 @@ ata_pci_allocate(device_t dev, struct ata_channel *ch)
ch->r_io[ATA_ALTSTAT].offset = 0;
ch->r_io[ATA_IDX_ADDR].res = io;
- if (ctlr->r_io1) {
+ if (ctlr->r_res1) {
for (i = ATA_BMCMD_PORT; i <= ATA_BMDTP_PORT; i++) {
- ch->r_io[i].res = ctlr->r_io1;
+ ch->r_io[i].res = ctlr->r_res1;
ch->r_io[i].offset = (i - ATA_BMCMD_PORT)+(ch->unit * ATA_BMIOSIZE);
}
@@ -481,6 +495,7 @@ static device_method_t ata_pci_methods[] = {
/* device interface */
DEVMETHOD(device_probe, ata_pci_probe),
DEVMETHOD(device_attach, ata_pci_attach),
+ DEVMETHOD(device_detach, ata_pci_detach),
DEVMETHOD(device_shutdown, bus_generic_shutdown),
DEVMETHOD(device_suspend, bus_generic_suspend),
DEVMETHOD(device_resume, bus_generic_resume),
@@ -514,6 +529,9 @@ ata_pcisub_probe(device_t dev)
device_t *children;
int count, error, i;
+ /* take care of green memory */
+ bzero(ch, sizeof(struct ata_channel));
+
/* find channel number on this controller */
device_get_children(device_get_parent(dev), &children, &count);
for (i = 0; i < count; i++) {
@@ -528,6 +546,8 @@ ata_pcisub_probe(device_t dev)
ch->device[MASTER].setmode = ctlr->setmode;
ch->device[SLAVE].setmode = ctlr->setmode;
ch->locking = ctlr->locking;
+ if (ch->reset)
+ ch->reset(ch);
return ata_probe(dev);
}
diff --git a/sys/dev/ata/ata-pci.h b/sys/dev/ata/ata-pci.h
index b39ac0c..5d4ec26 100644
--- a/sys/dev/ata/ata-pci.h
+++ b/sys/dev/ata/ata-pci.h
@@ -40,8 +40,12 @@ struct ata_chip_id {
/* structure describing a PCI ATA controller */
struct ata_pci_controller {
- struct resource *r_io1;
- struct resource *r_io2;
+ int r_type1;
+ int r_rid1;
+ struct resource *r_res1;
+ int r_type2;
+ int r_rid2;
+ struct resource *r_res2;
struct resource *r_irq;
void *handle;
struct ata_chip_id *chip;
diff --git a/sys/dev/ata/ata-queue.c b/sys/dev/ata/ata-queue.c
index 667bd99..ef6d20f 100644
--- a/sys/dev/ata/ata-queue.c
+++ b/sys/dev/ata/ata-queue.c
@@ -459,6 +459,39 @@ ata_timeout(struct ata_request *request)
return;
}
+void
+ata_fail_requests(struct ata_channel *ch, struct ata_device *device)
+{
+ struct ata_request *request;
+
+ /* fail all requests queued on this channel */
+ mtx_lock(&ch->queue_mtx);
+ while ((request = TAILQ_FIRST(&ch->ata_queue))) {
+ if (!device || request->device == device) {
+ TAILQ_REMOVE(&ch->ata_queue, request, chain);
+ request->result = ENXIO;
+ if (request->callback)
+ (request->callback)(request);
+ else
+ sema_post(&request->done);
+ }
+ }
+ mtx_unlock(&ch->queue_mtx);
+
+ /* if we have a request "in flight" fail it as well */
+ if ((!device || request->device == device) && (request = ch->running)) {
+ untimeout((timeout_t *)ata_timeout, request, request->timeout_handle);
+ ATA_UNLOCK_CH(request->device->channel);
+ request->device->channel->locking(request->device->channel,
+ ATA_LF_UNLOCK);
+ request->result = ENXIO;
+ if (request->callback)
+ (request->callback)(request);
+ else
+ sema_post(&request->done);
+ }
+}
+
char *
ata_cmd2str(struct ata_request *request)
{
OpenPOWER on IntegriCloud