summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sys/alpha/include/md_var.h7
-rw-r--r--sys/alpha/pci/pcibus.c37
-rw-r--r--sys/dev/ata/ata-all.c1225
-rw-r--r--sys/dev/ata/ata-all.h46
-rw-r--r--sys/dev/ata/ata-disk.c75
-rw-r--r--sys/dev/ata/ata-disk.h2
-rw-r--r--sys/dev/ata/ata-dma.c87
-rw-r--r--sys/dev/ata/atapi-all.c48
-rw-r--r--sys/dev/ata/atapi-all.h5
-rw-r--r--sys/dev/ata/atapi-cd.c102
-rw-r--r--sys/dev/ata/atapi-cd.h1
-rw-r--r--sys/dev/ata/atapi-fd.c32
-rw-r--r--sys/dev/ata/atapi-fd.h1
-rw-r--r--sys/dev/ata/atapi-tape.c37
-rw-r--r--sys/dev/ata/atapi-tape.h1
-rw-r--r--sys/kern/subr_disk.c5
-rw-r--r--sys/powerpc/include/md_var.h7
17 files changed, 1106 insertions, 612 deletions
diff --git a/sys/alpha/include/md_var.h b/sys/alpha/include/md_var.h
index 42d40f3..bdcba94 100644
--- a/sys/alpha/include/md_var.h
+++ b/sys/alpha/include/md_var.h
@@ -57,7 +57,12 @@ int fill_fpregs __P((struct proc *, struct fpreg *));
int set_fpregs __P((struct proc *, struct fpreg *));
void alpha_register_pci_scsi __P((int bus, int slot, struct cam_sim *sim));
#ifdef _SYS_BUS_H_
-int alpha_platform_setup_ide_intr(int chan, driver_intr_t *fn, void *arg);
+struct resource *alpha_platform_alloc_ide_intr(int chan);
+int alpha_platform_release_ide_intr(int chan, struct resource *res);
+int alpha_platform_setup_ide_intr(struct resource *res,
+ driver_intr_t *fn, void *arg,
+ void **cookiep);
+int alpha_platform_teardown_ide_intr(struct resource *res, void *cookie);
#endif
void alpha_platform_assign_pciintr(struct pcicfg *cfg);
diff --git a/sys/alpha/pci/pcibus.c b/sys/alpha/pci/pcibus.c
index b668c82..a137558 100644
--- a/sys/alpha/pci/pcibus.c
+++ b/sys/alpha/pci/pcibus.c
@@ -140,22 +140,31 @@ alpha_platform_assign_pciintr(pcicfgregs *cfg)
platform.pci_intr_map((void *)cfg);
}
+struct resource *
+alpha_platform_alloc_ide_intr(int chan)
+{
+ int irqs[2] = { 14, 15 };
+ return isa_alloc_intr(0, 0, irqs[chan]);
+}
+
int
-alpha_platform_setup_ide_intr(int chan, driver_intr_t *fn, void *arg)
+alpha_platform_release_ide_intr(int chan, struct resource *res)
{
- if (platform.pci_setup_ide_intr)
- return platform.pci_setup_ide_intr(chan, fn, arg);
- else {
- int irqs[2] = { 14, 15 };
- void *junk;
- struct resource *res;
- res = isa_alloc_intr(0, 0, irqs[chan]);
- if (res)
- return isa_setup_intr(0, 0, res, INTR_TYPE_BIO,
- fn, arg, &junk);
- else
- return ENOMEM;
- }
+ return isa_release_intr(0, 0, res);
+}
+
+int
+alpha_platform_setup_ide_intr(struct resource *res,
+ driver_intr_t *fn, void *arg,
+ void **cookiep)
+{
+ return isa_setup_intr(0, 0, res, INTR_TYPE_BIO, fn, arg, cookiep);
+}
+
+int
+alpha_platform_teardown_ide_intr(struct resource *res, void *cookie)
+{
+ return isa_teardown_intr(0, 0, res, cookie);
}
static struct rman irq_rman, port_rman, mem_rman;
diff --git a/sys/dev/ata/ata-all.c b/sys/dev/ata/ata-all.c
index 3a497e5..e5f120e 100644
--- a/sys/dev/ata/ata-all.c
+++ b/sys/dev/ata/ata-all.c
@@ -29,8 +29,8 @@
*/
#include "ata.h"
-#include "apm.h"
#include "isa.h"
+#include "card.h"
#include "pci.h"
#include "atadisk.h"
#include "atapicd.h"
@@ -65,34 +65,37 @@
#include <machine/smp.h>
#include <i386/isa/intr_machdep.h>
#endif
-#if NAPM > 0
-#include <machine/apm_bios.h>
+#ifdef __alpha__
+#include <machine/md_var.h>
#endif
#include <dev/ata/ata-all.h>
#include <dev/ata/ata-disk.h>
#include <dev/ata/atapi-all.h>
/* misc defines */
-#if SMP == 0
-#define isa_apic_irq(x) x
-#endif
-#define IOMASK 0xfffffffc
+#define IOMASK 0xfffffffc
+#define ATA_IOADDR_RID 0
+#define ATA_ALTIOADDR_RID 1
+#define ATA_BMADDR_RID 2
/* prototypes */
-static int32_t ata_probe(int32_t, int32_t, int32_t, device_t, int32_t *);
-static void ata_attach(void *);
+static int ata_probe(device_t);
+static int ata_attach(device_t);
+static int ata_detach(device_t);
+static int ata_resume(device_t);
+static void ata_boot_attach(void);
+static void ata_intr(void *);
static int32_t ata_getparam(struct ata_softc *, int32_t, u_int8_t);
-static void ataintr(void *);
static int8_t *active2str(int32_t);
static void bswap(int8_t *, int32_t);
static void btrim(int8_t *, int32_t);
static void bpack(int8_t *, int8_t *, int32_t);
/* local vars */
-static int32_t atanlun = 2;
-static struct intr_config_hook *ata_attach_hook = NULL;
static devclass_t ata_devclass;
-struct ata_softc *atadevices[MAXATA];
+static devclass_t ata_pci_devclass;
+static struct intr_config_hook *ata_delayed_attach = NULL;
+static char ata_conf[256];
MALLOC_DEFINE(M_ATA, "ATA generic", "ATA driver generic layer");
#if NISA > 0
@@ -105,91 +108,134 @@ static struct isa_pnp_id ata_ids[] = {
};
static int
-ata_isaprobe(device_t dev)
+ata_isa_probe(device_t dev)
{
+ struct ata_softc *scp = device_get_softc(dev);
struct resource *port;
int rid;
- int32_t ctlr, res;
- int32_t lun;
+ u_long tmp;
- /* Check isapnp ids */
+ /* check isapnp ids */
if (ISA_PNP_PROBE(device_get_parent(dev), dev, ata_ids) == ENXIO)
return ENXIO;
- /* Allocate the port range */
- rid = 0;
- port = bus_alloc_resource(dev, SYS_RES_IOPORT, &rid, 0, ~0, 1, RF_ACTIVE);
+ /* allocate the port range */
+ rid = ATA_IOADDR_RID;
+ port = bus_alloc_resource(dev, SYS_RES_IOPORT, &rid, 0, ~0,
+ ATA_IOSIZE, RF_ACTIVE);
if (!port)
return ENOMEM;
- /* check if allready in use by a PCI device */
- for (ctlr = 0; ctlr < atanlun; ctlr++) {
- if (atadevices[ctlr] && atadevices[ctlr]->ioaddr==rman_get_start(port)){
- printf("ata-isa%d: already registered as ata%d\n",
- device_get_unit(dev), ctlr);
- bus_release_resource(dev, SYS_RES_IOPORT, 0, port);
- return ENXIO;
- }
+ /* alloctate the altport range */
+ if (bus_get_resource(dev, SYS_RES_IOPORT, 1, &tmp, &tmp)) {
+ bus_set_resource(dev, SYS_RES_IOPORT, 1,
+ rman_get_start(port) + ATA_ALTPORT,
+ ATA_ALTIOSIZE);
}
+ bus_release_resource(dev, SYS_RES_IOPORT, 0, port);
+ scp->unit = device_get_unit(dev);
+ scp->flags |= ATA_USE_16BIT;
+ return ata_probe(dev);
+}
- lun = 0;
- res = ata_probe(rman_get_start(port), rman_get_start(port) + ATA_ALTPORT,
- 0, dev, &lun);
+static device_method_t ata_isa_methods[] = {
+ /* device interface */
+ DEVMETHOD(device_probe, ata_isa_probe),
+ DEVMETHOD(device_attach, ata_attach),
+ DEVMETHOD(device_resume, ata_resume),
+ { 0, 0 }
+};
- bus_release_resource(dev, SYS_RES_IOPORT, 0, port);
+static driver_t ata_isa_driver = {
+ "ata",
+ ata_isa_methods,
+ sizeof(struct ata_softc),
+};
- if (res) {
- isa_set_portsize(dev, res);
- *(int *)device_get_softc(dev) = lun;
- atadevices[lun]->flags |= ATA_USE_16BIT;
- return 0;
- }
- return ENXIO;
-}
+DRIVER_MODULE(ata, isa, ata_isa_driver, ata_devclass, 0, 0);
+#endif
+#if NCARD > 0
static int
-ata_isaattach(device_t dev)
+ata_pccard_probe(device_t dev)
{
+ struct ata_softc *scp = device_get_softc(dev);
struct resource *port;
- struct resource *irq;
- void *ih;
int rid;
+ u_long tmp;
- /* Allocate the port range and interrupt */
- rid = 0;
- port = bus_alloc_resource(dev, SYS_RES_IOPORT, &rid, 0, ~0, 1, RF_ACTIVE);
+ /* allocate the port range */
+ rid = ATA_IOADDR_RID;
+ port = bus_alloc_resource(dev, SYS_RES_IOPORT, &rid, 0, ~0,
+ ATA_IOSIZE, RF_ACTIVE);
if (!port)
- return (ENOMEM);
+ return ENOMEM;
- rid = 0;
- irq = bus_alloc_resource(dev, SYS_RES_IRQ, &rid, 0, ~0, 1, RF_ACTIVE);
- if (!irq) {
- bus_release_resource(dev, SYS_RES_IOPORT, 0, port);
- return (ENOMEM);
+ /* alloctate the altport range */
+ if (bus_get_resource(dev, SYS_RES_IOPORT, 1, &tmp, &tmp)) {
+ bus_set_resource(dev, SYS_RES_IOPORT, 1,
+ rman_get_start(port) + ATA_ALTPORT_PCCARD,
+ ATA_ALTIOSIZE);
}
- return bus_setup_intr(dev, irq, INTR_TYPE_BIO, ataintr,
- atadevices[*(int *)device_get_softc(dev)], &ih);
+ bus_release_resource(dev, SYS_RES_IOPORT, 0, port);
+ scp->unit = device_get_unit(dev);
+ scp->flags |= ATA_USE_16BIT;
+ return ata_probe(dev);
}
-static device_method_t ata_isa_methods[] = {
- /* Device interface */
- DEVMETHOD(device_probe, ata_isaprobe),
- DEVMETHOD(device_attach, ata_isaattach),
+static device_method_t ata_pccard_methods[] = {
+ /* device interface */
+ DEVMETHOD(device_probe, ata_pccard_probe),
+ DEVMETHOD(device_attach, ata_attach),
+ DEVMETHOD(device_detach, ata_detach),
+ DEVMETHOD(device_resume, ata_resume),
{ 0, 0 }
};
-static driver_t ata_isa_driver = {
+static driver_t ata_pccard_driver = {
"ata",
- ata_isa_methods,
- sizeof(int),
+ ata_pccard_methods,
+ sizeof(struct ata_softc),
};
-DRIVER_MODULE(ata, isa, ata_isa_driver, ata_devclass, 0, 0);
+DRIVER_MODULE(ata, pccard, ata_pccard_driver, ata_devclass, 0, 0);
#endif
#if NPCI > 0
+struct ata_pci_softc {
+ struct resource *bmio;
+ struct resource bmio_1;
+ struct resource bmio_2;
+ struct resource *irq;
+ int32_t irqcnt;
+};
+
+static int32_t
+ata_find_dev(device_t dev, int32_t type)
+{
+ device_t *children, child;
+ int nchildren, i;
+
+ if (device_get_children(device_get_parent(dev), &children, &nchildren))
+ return 0;
+
+ for (i = 0; i < nchildren; i++) {
+ child = children[i];
+
+ /* check that it's on the same silicon and the device we want */
+ if (pci_get_slot(dev) == pci_get_slot(child) &&
+ pci_get_vendor(child) == (type & 0xffff) &&
+ pci_get_device(child) == ((type & 0xffff0000) >> 16)) {
+ free(children, M_TEMP);
+ return 1;
+ }
+ }
+ free(children, M_TEMP);
+ return 0;
+}
+
static const char *
-ata_pcimatch(device_t dev)
+ata_pci_match(device_t dev)
{
if (pci_get_class(dev) != PCIC_STORAGE)
return NULL;
@@ -204,54 +250,61 @@ ata_pcimatch(device_t dev)
case 0x71118086:
case 0x71998086:
- return "Intel PIIX4 ATA-33 controller";
+ return "Intel PIIX4 ATA33 controller";
case 0x24118086:
- return "Intel ICH ATA-66 controller";
+ return "Intel ICH ATA66 controller";
case 0x24218086:
- return "Intel ICH0 ATA-33 controller";
+ return "Intel ICH0 ATA33 controller";
case 0x522910b9:
- return "AcerLabs Aladdin ATA-33 controller";
+ return "AcerLabs Aladdin ATA33 controller";
- case 0x05711106: /* 82c586 & 82c686 */
+ case 0x05711106:
if (ata_find_dev(dev, 0x05861106))
- return "VIA 82C586 ATA-33 controller";
+ return "VIA 82C586 ATA33 controller";
if (ata_find_dev(dev, 0x05961106))
- return "VIA 82C596 ATA-33 controller";
+ return "VIA 82C596 ATA33 controller";
if (ata_find_dev(dev, 0x06861106))
- return "VIA 82C686 ATA-66 controller";
+ return "VIA 82C686 ATA66 controller";
return "VIA Apollo ATA controller";
case 0x55131039:
- return "SiS 5591 ATA-33 controller";
+ return "SiS 5591 ATA33 controller";
+
+ case 0x06461095:
+ return "CMD 646 ATA controller";
case 0x74091022:
- return "AMD 756 ATA-66 controller";
+ return "AMD 756 ATA66 controller";
case 0x4d33105a:
- return "Promise ATA-33 controller";
+ return "Promise ATA33 controller";
case 0x4d38105a:
- return "Promise ATA-66 controller";
+ return "Promise ATA66 controller";
case 0x00041103:
- return "HighPoint HPT366 ATA-66 controller";
+ return "HighPoint HPT366 ATA66 controller";
/* unsupported but known chipsets, generic DMA only */
- case 0x06401095:
- return "CMD 640 ATA controller (generic mode)";
+ case 0x10001042:
+ case 0x10011042:
+ return "RZ 100? ATA controller !WARNING! buggy chip data loss possible";
- case 0x06461095:
- return "CMD 646 ATA controller (generic mode)";
+ case 0x06401095:
+ return "CMD 640 ATA controller !WARNING! buggy chip data loss possible";
case 0xc6931080:
- return "Cypress 82C693 ATA controller (generic mode)";
+ if (pci_get_subclass(dev) == PCIS_STORAGE_IDE)
+ return "Cypress 82C693 ATA controller (generic mode)";
+ break;
case 0x01021078:
return "Cyrix 5530 ATA controller (generic mode)";
+ /* unknown chipsets, try generic DMA if it seems possible */
default:
if (pci_get_class(dev) == PCIC_STORAGE &&
(pci_get_subclass(dev) == PCIS_STORAGE_IDE))
@@ -261,9 +314,9 @@ ata_pcimatch(device_t dev)
}
static int
-ata_pciprobe(device_t dev)
+ata_pci_probe(device_t dev)
{
- const char *desc = ata_pcimatch(dev);
+ const char *desc = ata_pci_match(dev);
if (desc) {
device_set_desc(dev, desc);
@@ -274,17 +327,31 @@ ata_pciprobe(device_t dev)
}
static int
-ata_pciattach(device_t dev)
+ata_pci_add_child(device_t dev, int unit)
{
- int unit = device_get_unit(dev);
- struct ata_softc *scp;
- u_int32_t type;
+ device_t child;
+ int lun;
+
+ /* check if this is located at one of the std addresses */
+ if (pci_get_progif(dev) & PCIP_STORAGE_IDE_MASTERDEV)
+ lun = unit;
+ else
+ lun = -1;
+
+ if (!(child = device_add_child(dev, "ata", lun)))
+ return ENOMEM;
+
+ device_set_ivars(child, (void *)(uintptr_t) unit);
+ return 0;
+}
+
+static int
+ata_pci_attach(device_t dev)
+{
+ struct ata_pci_softc *sc = device_get_softc(dev);
u_int8_t class, subclass;
- u_int32_t cmd;
- int32_t iobase_1, iobase_2, altiobase_1, altiobase_2;
- int32_t bmaddr_1 = 0, bmaddr_2 = 0, irq1, irq2;
- struct resource *irq = NULL;
- int32_t lun;
+ u_int32_t type, cmd;
+ int rid;
/* set up vendor-specific stuff */
type = pci_get_devid(dev);
@@ -292,62 +359,32 @@ ata_pciattach(device_t dev)
subclass = pci_get_subclass(dev);
cmd = pci_read_config(dev, PCIR_COMMAND, 4);
-#ifdef ATA_DEBUG
- printf("ata-pci%d: type=%08x class=%02x subclass=%02x cmd=%08x if=%02x\n",
- unit, type, class, subclass, cmd, pci_get_progif(dev));
-#endif
-
- if (pci_get_progif(dev) & PCIP_STORAGE_IDE_MASTERDEV) {
- iobase_1 = IO_WD1;
- altiobase_1 = iobase_1 + ATA_ALTPORT;
- irq1 = 14;
- }
- else {
- iobase_1 = pci_read_config(dev, 0x10, 4) & IOMASK;
- altiobase_1 = pci_read_config(dev, 0x14, 4) & IOMASK;
- irq1 = pci_read_config(dev, PCI_INTERRUPT_REG, 4) & 0xff;
- /* this is needed for old non-std systems */
- if (iobase_1 == IO_WD1 && irq1 == 0x00)
- irq1 = 14;
- }
-
- if (pci_get_progif(dev) & PCIP_STORAGE_IDE_MASTERDEV) {
- iobase_2 = IO_WD2;
- altiobase_2 = iobase_2 + ATA_ALTPORT;
- irq2 = 15;
- }
- else {
- iobase_2 = pci_read_config(dev, 0x18, 4) & IOMASK;
- altiobase_2 = pci_read_config(dev, 0x1c, 4) & IOMASK;
- irq2 = pci_read_config(dev, PCI_INTERRUPT_REG, 4) & 0xff;
- /* this is needed for old non-std systems */
- if (iobase_2 == IO_WD2 && irq2 == 0x00)
- irq2 = 15;
- }
-
/* is this controller busmaster DMA capable ? */
if (pci_get_progif(dev) & PCIP_STORAGE_IDE_MASTERDEV) {
/* is busmastering support turned on ? */
if ((cmd & (PCIM_CMD_PORTEN | PCIM_CMD_BUSMASTEREN)) ==
(PCIM_CMD_PORTEN | PCIM_CMD_BUSMASTEREN)) {
+
/* is there a valid port range to connect to ? */
- if ((bmaddr_1 = pci_read_config(dev, 0x20, 4) & IOMASK))
- bmaddr_2 = bmaddr_1 + ATA_BM_OFFSET1;
- else
- printf("ata-pci%d: Busmastering DMA not configured\n", unit);
+ rid = 0x20;
+ sc->bmio = bus_alloc_resource(dev, SYS_RES_IOPORT, &rid,
+ 0, ~0, 1, RF_ACTIVE);
+ if (!sc->bmio)
+ device_printf(dev, "Busmastering DMA not configured\n");
}
else
- printf("ata-pci%d: Busmastering DMA not enabled\n", unit);
+ device_printf(dev, "Busmastering DMA not enabled\n");
}
else {
if (type == 0x4d33105a || type == 0x4d38105a || type == 0x00041103) {
/* Promise and HPT366 controllers support busmastering DMA */
- bmaddr_1 = pci_read_config(dev, 0x20, 4) & IOMASK;
- bmaddr_2 = bmaddr_1 + ATA_BM_OFFSET1;
+ rid = 0x20;
+ sc->bmio = bus_alloc_resource(dev, SYS_RES_IOPORT, &rid,
+ 0, ~0, 1, RF_ACTIVE);
}
else
/* we dont know this controller, no busmastering DMA */
- printf("ata-pci%d: Busmastering DMA not supported\n", unit);
+ device_printf(dev, "Busmastering DMA not supported\n");
}
/* do extra chipset specific setups */
@@ -356,12 +393,15 @@ ata_pciattach(device_t dev)
pci_write_config(dev, 0x53,
(pci_read_config(dev, 0x53, 1) & ~0x01) | 0x02, 1);
break;
+
case 0x4d38105a: /* Promise 66's need their clock changed */
- outb(bmaddr_1 + 0x11, inb(bmaddr_1 + 0x11) | 0x0a);
+ outb(rman_get_start(sc->bmio) + 0x11,
+ inb(rman_get_start(sc->bmio) + 0x11) | 0x0a);
/* FALLTHROUGH */
case 0x4d33105a: /* Promise's need burst mode to be turned on */
- outb(bmaddr_1 + 0x1f, inb(bmaddr_1 + 0x1f) | 0x01);
+ outb(rman_get_start(sc->bmio) + 0x1f,
+ inb(rman_get_start(sc->bmio) + 0x1f) | 0x01);
break;
case 0x00041103: /* HPT366 turn of fast interrupt prediction */
@@ -388,159 +428,339 @@ ata_pciattach(device_t dev)
pci_write_config(dev, 0x60, DEV_BSIZE, 2);
pci_write_config(dev, 0x68, DEV_BSIZE, 2);
- /* set the chiptype to the hostchip ID, makes life easier */
- if (ata_find_dev(dev, 0x05861106))
- type = 0x05861106;
- if (ata_find_dev(dev, 0x05961106))
- type = 0x05961106;
+ /* prepare for ATA-66 on the 82C686 */
if (ata_find_dev(dev, 0x06861106)) {
- type = 0x06861106;
- /* prepare for ATA-66 on the 82C686 */
pci_write_config(dev, 0x50,
pci_read_config(dev, 0x50, 4) | 0x070f070f, 4);
}
break;
}
-
- /* now probe the addresse found for "real" ATA/ATAPI hardware */
- lun = 0;
- if (iobase_1 && ata_probe(iobase_1, altiobase_1, bmaddr_1, dev, &lun)) {
- int rid;
- void *ih;
-
- scp = atadevices[lun];
- scp->chiptype = type;
- rid = 0;
- if (iobase_1 == IO_WD1) {
-#ifdef __alpha__
- alpha_platform_setup_ide_intr(0, ataintr, scp);
-#else
- bus_set_resource(dev, SYS_RES_IRQ, rid, irq1, 1);
- if (!(irq = bus_alloc_resource(dev, SYS_RES_IRQ, &rid, 0, ~0, 1,
- RF_SHAREABLE | RF_ACTIVE)))
- printf("ata_pciattach: Unable to alloc interrupt\n");
-#endif
- } else {
- if (!(irq = bus_alloc_resource(dev, SYS_RES_IRQ, &rid, 0, ~0, 1,
- RF_SHAREABLE | RF_ACTIVE)))
- printf("ata_pciattach: Unable to alloc interrupt\n");
+
+ ata_pci_add_child(dev, 0);
+
+ if (pci_get_progif(dev) & PCIP_STORAGE_IDE_MASTERDEV ||
+ pci_read_config(dev, 0x18, 4) & IOMASK)
+ ata_pci_add_child(dev, 1);
+
+ return bus_generic_attach(dev);
+}
+
+static int
+ata_pci_print_child(device_t dev, device_t child)
+{
+ struct ata_softc *scp = device_get_softc(child);
+ int unit = (uintptr_t) device_get_ivars(child);
+ int retval = 0;
+
+ retval += bus_print_child_header(dev, child);
+ retval += printf(": at 0x%x", scp->ioaddr);
+
+ if (pci_get_progif(dev) & PCIP_STORAGE_IDE_MASTERDEV)
+ retval += printf(" irq %d", 14 + unit);
+
+ retval += bus_print_child_footer(dev, child);
+
+ return retval;
+}
+
+static struct resource *
+ata_pci_alloc_resource(device_t dev, device_t child, int type, int *rid,
+ u_long start, u_long end, u_long count, u_int flags)
+{
+ struct ata_pci_softc *sc = device_get_softc(dev);
+ int masterdev = pci_get_progif(dev) & PCIP_STORAGE_IDE_MASTERDEV;
+ int unit = (int)device_get_ivars(child);
+ int myrid;
+
+ if (type == SYS_RES_IOPORT) {
+ switch (*rid) {
+ case ATA_IOADDR_RID:
+ if (masterdev) {
+ myrid = 0;
+ start = (unit == 0 ? IO_WD1 : IO_WD2);
+ end = start + ATA_IOSIZE - 1;
+ count = ATA_IOSIZE;
+ }
+ else
+ myrid = 0x10 + 8 * unit;
+ break;
+
+ case ATA_ALTIOADDR_RID:
+ if (masterdev) {
+ myrid = 0;
+ start = (unit == 0 ? IO_WD1 : IO_WD2) + ATA_ALTPORT;
+ end = start + ATA_ALTIOSIZE - 1;
+ count = ATA_ALTIOSIZE;
+ }
+ else
+ myrid = 0x14 + 8 * unit;
+ break;
+
+ case ATA_BMADDR_RID:
+ /* the busmaster resource is shared between the two channels */
+ if (sc->bmio) {
+ if (unit == 0) {
+ sc->bmio_1 = *sc->bmio;
+ sc->bmio_1.r_end = sc->bmio->r_start + ATA_BM_OFFSET1;
+ return &sc->bmio_1;
+ } else {
+ sc->bmio_2 = *sc->bmio;
+ sc->bmio_2.r_start = sc->bmio->r_start + ATA_BM_OFFSET1;
+ sc->bmio_2.r_end = sc->bmio_2.r_start + ATA_BM_OFFSET1;
+ return &sc->bmio_2;
+ }
+ }
+ break;
+
+ default:
+ return 0;
}
- if (irq)
- bus_setup_intr(dev, irq, INTR_TYPE_BIO, ataintr, scp, &ih);
- printf("ata%d at 0x%04x irq %d on ata-pci%d\n",
- lun, iobase_1, isa_apic_irq(irq1), unit);
+
+ if (masterdev)
+ /* make the parent just pass through the allocation. */
+ return BUS_ALLOC_RESOURCE(device_get_parent(dev), child,
+ SYS_RES_IOPORT, &myrid,
+ start, end, count, flags);
+ else
+ /* we are using the parent resource directly. */
+ return BUS_ALLOC_RESOURCE(device_get_parent(dev), dev,
+ SYS_RES_IOPORT, &myrid,
+ start, end, count, flags);
}
- lun = 1;
- if (iobase_2 && ata_probe(iobase_2, altiobase_2, bmaddr_2, dev, &lun)) {
- int rid;
- void *ih;
-
- scp = atadevices[lun];
- scp->chiptype = type;
- if (iobase_2 == IO_WD2) {
-#ifdef __alpha__
- alpha_platform_setup_ide_intr(1, ataintr, scp);
+
+ if (type == SYS_RES_IRQ) {
+ if (*rid != 0)
+ return 0;
+
+ if (masterdev) {
+#ifdef __i386__
+ int irq = (unit == 0 ? 14 : 15);
+
+ return BUS_ALLOC_RESOURCE(device_get_parent(dev), child,
+ SYS_RES_IRQ, rid,
+ irq, irq, 1, flags & ~RF_SHAREABLE);
#else
- rid = 1;
- bus_set_resource(dev, SYS_RES_IRQ, rid, irq2, 1);
- if (!(irq = bus_alloc_resource(dev, SYS_RES_IRQ, &rid, 0, ~0, 1,
- RF_SHAREABLE | RF_ACTIVE)))
- printf("ata_pciattach: Unable to alloc interrupt\n");
+ return alpha_platform_alloc_ide_intr(unit);
#endif
} else {
- rid = 0;
- if (irq1 != irq2 || irq == NULL) {
- if (!(irq = bus_alloc_resource(dev, SYS_RES_IRQ, &rid, 0, ~0, 1,
- RF_SHAREABLE | RF_ACTIVE)))
- printf("ata_pciattach: Unable to alloc interrupt\n");
- }
+ /* primary and secondary channels share the same interrupt */
+ sc->irqcnt++;
+ if (!sc->irq)
+ sc->irq = BUS_ALLOC_RESOURCE(device_get_parent(dev), dev,
+ SYS_RES_IRQ, rid, 0, ~0, 1, flags);
+ return sc->irq;
}
- if (irq)
- bus_setup_intr(dev, irq, INTR_TYPE_BIO, ataintr, scp, &ih);
- printf("ata%d at 0x%04x irq %d on ata-pci%d\n",
- lun, iobase_2, isa_apic_irq(irq2), unit);
}
return 0;
}
-int32_t
-ata_find_dev(device_t dev, int32_t type)
+static int
+ata_pci_release_resource(device_t dev, device_t child, int type, int rid,
+ struct resource *r)
{
- device_t *children, child;
- int nchildren, i;
+ struct ata_pci_softc *sc = device_get_softc(dev);
+ int unit = (uintptr_t) device_get_ivars(child);
+ int masterdev = pci_get_progif(dev) & PCIP_STORAGE_IDE_MASTERDEV;
+ int myrid = 0;
+
+ if (type == SYS_RES_IOPORT) {
+ switch (rid) {
+ case ATA_IOADDR_RID:
+ if (masterdev)
+ myrid = 0;
+ else
+ myrid = 0x10 + 8 * unit;
+ break;
- if (device_get_children(device_get_parent(dev), &children, &nchildren))
- return 0;
+ case ATA_ALTIOADDR_RID:
+ if (masterdev)
+ myrid = 0;
+ else
+ myrid = 0x14 + 8 * unit;
+ break;
- for (i = 0; i < nchildren; i++) {
- child = children[i];
+ case ATA_BMADDR_RID:
+ return 0;
- /* check that it's on the same silicon and the device we want */
- if (pci_get_slot(dev) == pci_get_slot(child) &&
- pci_get_vendor(child) == (type & 0xffff) &&
- pci_get_device(child) == ((type & 0xffff0000)>>16)) {
- free(children, M_TEMP);
- return 1;
+ default:
+ return ENOENT;
}
+
+ if (masterdev)
+ /* make the parent just pass through the allocation. */
+ return BUS_RELEASE_RESOURCE(device_get_parent(dev), child,
+ SYS_RES_IOPORT, myrid, r);
+ else
+ /* we are using the parent resource directly. */
+ return BUS_RELEASE_RESOURCE(device_get_parent(dev), dev,
+ SYS_RES_IOPORT, myrid, r);
}
- free(children, M_TEMP);
- return 0;
+ if (type == SYS_RES_IRQ) {
+ if (rid != 0)
+ return ENOENT;
+
+ if (masterdev) {
+#ifdef __i386__
+ return BUS_RELEASE_RESOURCE(device_get_parent(dev),
+ child, SYS_RES_IRQ, rid, r);
+#else
+ return alpha_platform_release_ide_intr(unit, r);
+#endif
+ }
+ else {
+ if (--sc->irqcnt)
+ return 0;
+
+ return BUS_RELEASE_RESOURCE(device_get_parent(dev),
+ dev, SYS_RES_IRQ, rid, r);
+ }
+ }
+ return EINVAL;
+}
+
+static int
+ata_pci_setup_intr(device_t dev, device_t child, struct resource *irq,
+ int flags, driver_intr_t *intr, void *arg,
+ void **cookiep)
+{
+ if (pci_get_progif(dev) & PCIP_STORAGE_IDE_MASTERDEV) {
+#ifdef __i386__
+ return BUS_SETUP_INTR(device_get_parent(dev), child, irq,
+ flags, intr, arg, cookiep);
+#else
+ return alpha_platform_setup_ide_intr(irq, intr, arg, cookiep);
+#endif
+ }
+ else
+ return BUS_SETUP_INTR(device_get_parent(dev), dev, irq,
+ flags, intr, arg, cookiep);
+}
+
+static int
+ata_pci_teardown_intr(device_t dev, device_t child, struct resource *irq,
+ void *cookie)
+{
+ if (pci_get_progif(dev) & PCIP_STORAGE_IDE_MASTERDEV) {
+#ifdef __i386__
+ return BUS_TEARDOWN_INTR(device_get_parent(dev), child, irq, cookie);
+#else
+ return alpha_platform_teardown_ide_intr(irq, cookie);
+#endif
+ }
+ else
+ return BUS_TEARDOWN_INTR(device_get_parent(dev), dev, irq, cookie);
}
static device_method_t ata_pci_methods[] = {
- /* Device interface */
- DEVMETHOD(device_probe, ata_pciprobe),
- DEVMETHOD(device_attach, ata_pciattach),
+ /* device interface */
+ DEVMETHOD(device_probe, ata_pci_probe),
+ DEVMETHOD(device_attach, ata_pci_attach),
+ DEVMETHOD(device_shutdown, bus_generic_shutdown),
+ DEVMETHOD(device_suspend, bus_generic_suspend),
+ DEVMETHOD(device_resume, bus_generic_resume),
+
+ /* bus methods */
+ DEVMETHOD(bus_print_child, ata_pci_print_child),
+ DEVMETHOD(bus_alloc_resource, ata_pci_alloc_resource),
+ DEVMETHOD(bus_release_resource, ata_pci_release_resource),
+ DEVMETHOD(bus_activate_resource, bus_generic_activate_resource),
+ DEVMETHOD(bus_deactivate_resource, bus_generic_deactivate_resource),
+ DEVMETHOD(bus_setup_intr, ata_pci_setup_intr),
+ DEVMETHOD(bus_teardown_intr, ata_pci_teardown_intr),
{ 0, 0 }
};
static driver_t ata_pci_driver = {
- "ata-pci",
+ "atapci",
ata_pci_methods,
- sizeof(int),
+ sizeof(struct ata_pci_softc),
};
-DRIVER_MODULE(ata, pci, ata_pci_driver, ata_devclass, 0, 0);
-#endif
+DRIVER_MODULE(atapci, pci, ata_pci_driver, ata_devclass, 0, 0);
-static int32_t
-ata_probe(int32_t ioaddr, int32_t altioaddr, int32_t bmaddr,
- device_t dev, int32_t *unit)
+static int
+ata_pcisub_probe(device_t dev)
{
- struct ata_softc *scp;
- int32_t lun, mask = 0;
- u_int8_t status0, status1;
+ struct ata_softc *scp = device_get_softc(dev);
+
+ /* kids of pci ata chipsets has their physical unit number in ivars */
+ scp->unit = (uintptr_t) device_get_ivars(dev);
+
+ /* set the chiptype to the hostchip ID, makes life easier */
+ if (ata_find_dev(device_get_parent(dev), 0x05861106))
+ scp->chiptype = 0x05861106;
+ else if (ata_find_dev(device_get_parent(dev), 0x05961106))
+ scp->chiptype = 0x05961106;
+ else if (ata_find_dev(device_get_parent(dev), 0x06861106))
+ scp->chiptype = 0x06861106;
+ else
+ scp->chiptype = pci_get_devid(device_get_parent(dev));
+ return ata_probe(dev);
+}
- if (atanlun > MAXATA) {
- printf("ata: unit out of range(%d)\n", atanlun);
- return 0;
- }
+static device_method_t ata_pcisub_methods[] = {
+ /* device interface */
+ DEVMETHOD(device_probe, ata_pcisub_probe),
+ DEVMETHOD(device_attach, ata_attach),
+ DEVMETHOD(device_detach, ata_detach),
+ DEVMETHOD(device_resume, ata_resume),
+ { 0, 0 }
+};
- /* check if this is located at one of the std addresses */
- if (ioaddr == IO_WD1)
- lun = 0;
- else if (ioaddr == IO_WD2)
- lun = 1;
- else
- lun = atanlun++;
+static driver_t ata_pcisub_driver = {
+ "ata",
+ ata_pcisub_methods,
+ sizeof(struct ata_softc),
+};
- if ((scp = atadevices[lun])) {
- ata_printf(scp, -1, "unit already attached\n");
- return 0;
- }
- scp = malloc(sizeof(struct ata_softc), M_ATA, M_NOWAIT);
- if (scp == NULL) {
- ata_printf(scp, -1, "failed to allocate driver storage\n");
- return 0;
- }
- bzero(scp, sizeof(struct ata_softc));
+DRIVER_MODULE(ata, atapci, ata_pcisub_driver, ata_pci_devclass, 0, 0);
+#endif
+
+static int
+ata_probe(device_t dev)
+{
+ struct ata_softc *scp = device_get_softc(dev);
+ struct resource *io = 0;
+ struct resource *altio = 0;
+ struct resource *bmio = 0;
+ int rid;
+ int32_t ioaddr, altioaddr, bmaddr;
+ int32_t mask = 0;
+ u_int8_t status0, status1;
+
+ if (!scp || scp->flags & ATA_ATTACHED)
+ return ENXIO;
+ /* initialize the softc basics */
+ scp->active = ATA_IDLE;
+ scp->dev = dev;
+ scp->devices = 0;
+
+ rid = ATA_IOADDR_RID;
+ io = bus_alloc_resource(dev, SYS_RES_IOPORT, &rid, 0, ~0, 1, RF_ACTIVE);
+ if (!io)
+ goto failure;
+ ioaddr = rman_get_start(io);
+
+ rid = ATA_ALTIOADDR_RID;
+ altio = bus_alloc_resource(dev, SYS_RES_IOPORT, &rid, 0, ~0, 1, RF_ACTIVE);
+ if (!altio)
+ goto failure;
+ altioaddr = rman_get_start(altio);
+
+ rid = ATA_BMADDR_RID;
+ bmio = bus_alloc_resource(dev, SYS_RES_IOPORT, &rid, 0, ~0, 1, RF_ACTIVE);
+ bmaddr = bmio ? rman_get_start(bmio) : 0;
+
+ /* store the IO resources for eventual later release */
+ scp->r_io = io;
+ scp->r_altio = altio;
+ scp->r_bmio = bmio;
+
+ /* store the physical IO addresse for easy access */
scp->ioaddr = ioaddr;
scp->altioaddr = altioaddr;
scp->bmaddr = bmaddr;
- scp->lun = lun;
- scp->unit = *unit;
- scp->active = ATA_IDLE;
if (bootverbose)
ata_printf(scp, -1, "iobase=0x%04x altiobase=0x%04x bmaddr=0x%04x\n",
@@ -553,26 +773,23 @@ ata_probe(int32_t ioaddr, int32_t altioaddr, int32_t bmaddr,
outb(scp->ioaddr + ATA_DRIVE, ATA_D_IBM | ATA_SLAVE);
DELAY(1);
status1 = inb(scp->ioaddr + ATA_STATUS);
- if ((status0 & 0xf8) != 0xf8)
+ if ((status0 & 0xf8) != 0xf8 && status0 != 0xa5)
mask |= 0x01;
- if ((status1 & 0xf8) != 0xf8)
+ if ((status1 & 0xf8) != 0xf8 && status1 != 0xa5)
mask |= 0x02;
if (bootverbose)
ata_printf(scp, -1, "mask=%02x status0=%02x status1=%02x\n",
mask, status0, status1);
- if (!mask) {
- free(scp, M_DEVBUF);
- return 0;
- }
+ if (!mask)
+ goto failure;
+
ata_reset(scp, &mask);
- if (!mask) {
- free(scp, M_DEVBUF);
- return 0;
- }
+ if (!mask)
+ goto failure;
+
/*
- * OK, we have at least one device on the chain,
- * check for ATAPI signatures, if none check if its
- * a good old ATA device.
+ * OK, we have at least one device on the chain, check for ATAPI
+ * signatures, if none check if its a good old ATA device.
*/
outb(scp->ioaddr + ATA_DRIVE, (ATA_D_IBM | ATA_MASTER));
DELAY(1);
@@ -609,92 +826,122 @@ ata_probe(int32_t ioaddr, int32_t altioaddr, int32_t bmaddr,
if (bootverbose)
ata_printf(scp, -1, "devices = 0x%x\n", scp->devices);
if (!scp->devices) {
- free(scp, M_DEVBUF);
- return 0;
+ goto failure;
}
TAILQ_INIT(&scp->ata_queue);
TAILQ_INIT(&scp->atapi_queue);
- *unit = scp->lun;
- scp->dev = dev;
- atadevices[scp->lun] = scp;
-
- /* register callback for when interrupts are enabled */
- if (!ata_attach_hook) {
- if (!(ata_attach_hook = (struct intr_config_hook *)
- malloc(sizeof(struct intr_config_hook),
- M_TEMP, M_NOWAIT))) {
- ata_printf(scp, -1, "ERROR malloc attach_hook failed\n");
- return 0;
- }
- bzero(ata_attach_hook, sizeof(struct intr_config_hook));
-
- ata_attach_hook->ich_func = ata_attach;
- if (config_intrhook_establish(ata_attach_hook) != 0) {
- ata_printf(scp, -1, "config_intrhook_establish failed\n");
- free(ata_attach_hook, M_TEMP);
- }
- }
-#if NAPM > 0
- scp->resume_hook.ah_fun = (void *)ata_reinit;
- scp->resume_hook.ah_arg = scp;
- scp->resume_hook.ah_name = "ATA driver";
- scp->resume_hook.ah_order = APM_MID_ORDER;
- apm_hook_establish(APM_HOOK_RESUME, &scp->resume_hook);
-#endif
- return ATA_IOSIZE;
+ return 0;
+
+failure:
+ if (io)
+ bus_release_resource(dev, SYS_RES_IOPORT, ATA_IOADDR_RID, io);
+ if (altio)
+ bus_release_resource(dev, SYS_RES_IOPORT, ATA_ALTIOADDR_RID, altio);
+ if (bmio)
+ bus_release_resource(dev, SYS_RES_IOPORT, ATA_BMADDR_RID, bmio);
+ if (bootverbose)
+ ata_printf(scp, -1, "probe allocation failed\n");
+ return ENXIO;
}
-void
-ata_attach(void *dummy)
+static int
+ata_attach(device_t dev)
{
- int32_t ctlr;
+ struct ata_softc *scp = device_get_softc(dev);
+ int rid = 0;
+ void *ih;
+
+ if (!scp || scp->flags & ATA_ATTACHED)
+ return ENXIO;
+
+ scp->r_irq = bus_alloc_resource(dev, SYS_RES_IRQ, &rid, 0, ~0, 1,
+ RF_SHAREABLE | RF_ACTIVE);
+ if (!scp->r_irq) {
+ ata_printf(scp, -1, "unable to allocate interrupt\n");
+ return ENXIO;
+ }
+ bus_setup_intr(dev, scp->r_irq, INTR_TYPE_BIO, ata_intr, scp, &ih);
/*
- * run through atadevices[] and look for real ATA & ATAPI devices
- * using the hints we found in the early probe to avoid probing
- * of non-exsistent devices and thereby long delays
+ * do not attach devices if we are in early boot, this is done later
+ * when interrupts are enabled by a hook into the boot process.
+ * otherwise attach what the probe has found in scp->devices.
*/
- for (ctlr=0; ctlr<MAXATA; ctlr++) {
- if (!atadevices[ctlr]) continue;
- if (atadevices[ctlr]->devices & ATA_ATA_SLAVE)
- if (ata_getparam(atadevices[ctlr], ATA_SLAVE, ATA_C_ATA_IDENTIFY))
- atadevices[ctlr]->devices &= ~ATA_ATA_SLAVE;
- if (atadevices[ctlr]->devices & ATA_ATAPI_SLAVE)
- if (ata_getparam(atadevices[ctlr], ATA_SLAVE, ATA_C_ATAPI_IDENTIFY))
- atadevices[ctlr]->devices &= ~ATA_ATAPI_SLAVE;
- if (atadevices[ctlr]->devices & ATA_ATA_MASTER)
- if (ata_getparam(atadevices[ctlr], ATA_MASTER, ATA_C_ATA_IDENTIFY))
- atadevices[ctlr]->devices &= ~ATA_ATA_MASTER;
- if (atadevices[ctlr]->devices & ATA_ATAPI_MASTER)
- if (ata_getparam(atadevices[ctlr], ATA_MASTER,ATA_C_ATAPI_IDENTIFY))
- atadevices[ctlr]->devices &= ~ATA_ATAPI_MASTER;
+ if (!ata_delayed_attach) {
+ if (scp->devices & ATA_ATA_SLAVE)
+ if (ata_getparam(scp, ATA_SLAVE, ATA_C_ATA_IDENTIFY))
+ scp->devices &= ~ATA_ATA_SLAVE;
+ if (scp->devices & ATA_ATAPI_SLAVE)
+ if (ata_getparam(scp, ATA_SLAVE, ATA_C_ATAPI_IDENTIFY))
+ scp->devices &= ~ATA_ATAPI_SLAVE;
+ if (scp->devices & ATA_ATA_MASTER)
+ if (ata_getparam(scp, ATA_MASTER, ATA_C_ATA_IDENTIFY))
+ scp->devices &= ~ATA_ATA_MASTER;
+ if (scp->devices & ATA_ATAPI_MASTER)
+ if (ata_getparam(scp, ATA_MASTER,ATA_C_ATAPI_IDENTIFY))
+ scp->devices &= ~ATA_ATAPI_MASTER;
+#if NATADISK > 0
+ if (scp->devices & ATA_ATA_MASTER)
+ ad_attach(scp, ATA_MASTER);
+ if (scp->devices & ATA_ATA_SLAVE)
+ ad_attach(scp, ATA_SLAVE);
+#endif
+#if NATAPICD > 0 || NATAPIFD > 0 || NATAPIST > 0
+ if (scp->devices & ATA_ATAPI_MASTER)
+ atapi_attach(scp, ATA_MASTER);
+ if (scp->devices & ATA_ATAPI_SLAVE)
+ atapi_attach(scp, ATA_SLAVE);
+#endif
}
+ scp->flags |= ATA_ATTACHED;
+ return 0;
+}
+
+static int
+ata_detach(device_t dev)
+{
+ struct ata_softc *scp = device_get_softc(dev);
+
+ if (!scp || !(scp->flags & ATA_ATTACHED))
+ return ENXIO;
#if NATADISK > 0
- /* now we know whats there, do the real attach, first the ATA disks */
- for (ctlr=0; ctlr<MAXATA; ctlr++) {
- if (!atadevices[ctlr]) continue;
- if (atadevices[ctlr]->devices & ATA_ATA_MASTER)
- ad_attach(atadevices[ctlr], ATA_MASTER);
- if (atadevices[ctlr]->devices & ATA_ATA_SLAVE)
- ad_attach(atadevices[ctlr], ATA_SLAVE);
- }
+ if (scp->devices & ATA_ATA_MASTER)
+ ad_detach(scp, ATA_MASTER);
+ if (scp->devices & ATA_ATA_SLAVE)
+ ad_detach(scp, ATA_SLAVE);
#endif
#if NATAPICD > 0 || NATAPIFD > 0 || NATAPIST > 0
- /* then the atapi devices */
- for (ctlr=0; ctlr<MAXATA; ctlr++) {
- if (!atadevices[ctlr]) continue;
- if (atadevices[ctlr]->devices & ATA_ATAPI_MASTER)
- atapi_attach(atadevices[ctlr], ATA_MASTER);
- if (atadevices[ctlr]->devices & ATA_ATAPI_SLAVE)
- atapi_attach(atadevices[ctlr], ATA_SLAVE);
- }
+ if (scp->devices & ATA_ATAPI_MASTER)
+ atapi_detach(scp, ATA_MASTER);
+ if (scp->devices & ATA_ATAPI_SLAVE)
+ atapi_detach(scp, ATA_SLAVE);
#endif
- if (ata_attach_hook) {
- config_intrhook_disestablish(ata_attach_hook);
- free(ata_attach_hook, M_ATA);
- ata_attach_hook = NULL;
+ if (scp->dev_param[ATA_DEV(ATA_MASTER)]) {
+ free(scp->dev_param[ATA_DEV(ATA_MASTER)], M_ATA);
+ scp->dev_param[ATA_DEV(ATA_MASTER)] = NULL;
}
+ if (scp->dev_param[ATA_DEV(ATA_SLAVE)]) {
+ free(scp->dev_param[ATA_DEV(ATA_SLAVE)], M_ATA);
+ scp->dev_param[ATA_DEV(ATA_SLAVE)] = NULL;
+ }
+ scp->mode[ATA_DEV(ATA_MASTER)] = ATA_PIO;
+ scp->mode[ATA_DEV(ATA_SLAVE)] = ATA_PIO;
+ bus_release_resource(dev, SYS_RES_IRQ, 0, scp->r_irq);
+ bus_release_resource(dev, SYS_RES_IOPORT, ATA_BMADDR_RID, scp->r_bmio);
+ bus_release_resource(dev, SYS_RES_IOPORT, ATA_ALTIOADDR_RID, scp->r_altio);
+ bus_release_resource(dev, SYS_RES_IOPORT, ATA_IOADDR_RID, scp->r_io);
+ scp->flags &= ~ATA_ATTACHED;
+ return 0;
+}
+
+static int
+ata_resume(device_t dev)
+{
+ struct ata_softc *scp = device_get_softc(dev);
+
+ ata_reinit(scp);
+ return 0;
}
static int32_t
@@ -708,7 +955,7 @@ ata_getparam(struct ata_softc *scp, int32_t device, u_int8_t command)
outb(scp->ioaddr + ATA_DRIVE, ATA_D_IBM | device);
DELAY(1);
- /* enable interrupts */
+ /* enable interrupt */
outb(scp->altioaddr, ATA_A_4BIT);
DELAY(1);
@@ -719,7 +966,7 @@ ata_getparam(struct ata_softc *scp, int32_t device, u_int8_t command)
return -1;
}
if (retry++ > 4) {
- ata_printf(scp, device, "drive wont come ready after identify\n");
+ ata_printf(scp, device, "identify retries exceeded\n");
return -1;
}
} while (ata_wait(scp, device,
@@ -729,7 +976,7 @@ ata_getparam(struct ata_softc *scp, int32_t device, u_int8_t command)
insw(scp->ioaddr + ATA_DATA, buffer, sizeof(buffer)/sizeof(int16_t));
ata_parm = malloc(sizeof(struct ata_params), M_ATA, M_NOWAIT);
if (!ata_parm) {
- ata_printf(scp, device, "malloc for ata_param failed\n");
+ ata_printf(scp, device, "malloc for identify data failed\n");
return -1;
}
bcopy(buffer, ata_parm, sizeof(struct ata_params));
@@ -746,15 +993,72 @@ ata_getparam(struct ata_softc *scp, int32_t device, u_int8_t command)
return 0;
}
+static void
+ata_boot_attach(void)
+{
+ struct ata_softc *scp;
+ int32_t ctlr;
+
+ /*
+ * run through all ata devices and look for real ATA & ATAPI devices
+ * using the hints we found in the early probe, this avoids some of
+ * the delays probing of non-exsistent devices can cause.
+ */
+ for (ctlr=0; ctlr<devclass_get_maxunit(ata_devclass); ctlr++) {
+ if (!(scp = devclass_get_softc(ata_devclass, ctlr)))
+ continue;
+ if (scp->devices & ATA_ATA_SLAVE)
+ if (ata_getparam(scp, ATA_SLAVE, ATA_C_ATA_IDENTIFY))
+ scp->devices &= ~ATA_ATA_SLAVE;
+ if (scp->devices & ATA_ATAPI_SLAVE)
+ if (ata_getparam(scp, ATA_SLAVE, ATA_C_ATAPI_IDENTIFY))
+ scp->devices &= ~ATA_ATAPI_SLAVE;
+ if (scp->devices & ATA_ATA_MASTER)
+ if (ata_getparam(scp, ATA_MASTER, ATA_C_ATA_IDENTIFY))
+ scp->devices &= ~ATA_ATA_MASTER;
+ if (scp->devices & ATA_ATAPI_MASTER)
+ if (ata_getparam(scp, ATA_MASTER,ATA_C_ATAPI_IDENTIFY))
+ scp->devices &= ~ATA_ATAPI_MASTER;
+ }
+
+#if NATADISK > 0
+ /* now we know whats there, do the real attach, first the ATA disks */
+ for (ctlr=0; ctlr<devclass_get_maxunit(ata_devclass); ctlr++) {
+ if (!(scp = devclass_get_softc(ata_devclass, ctlr)))
+ continue;
+ if (scp->devices & ATA_ATA_MASTER)
+ ad_attach(scp, ATA_MASTER);
+ if (scp->devices & ATA_ATA_SLAVE)
+ ad_attach(scp, ATA_SLAVE);
+ }
+#endif
+#if NATAPICD > 0 || NATAPIFD > 0 || NATAPIST > 0
+ /* then the atapi devices */
+ for (ctlr=0; ctlr<devclass_get_maxunit(ata_devclass); ctlr++) {
+ if (!(scp = devclass_get_softc(ata_devclass, ctlr)))
+ continue;
+ if (scp->devices & ATA_ATAPI_MASTER)
+ atapi_attach(scp, ATA_MASTER);
+ if (scp->devices & ATA_ATAPI_SLAVE)
+ atapi_attach(scp, ATA_SLAVE);
+ }
+#endif
+ if (ata_delayed_attach) {
+ config_intrhook_disestablish(ata_delayed_attach);
+ free(ata_delayed_attach, M_ATA);
+ ata_delayed_attach = NULL;
+ }
+}
+
static void
-ataintr(void *data)
+ata_intr(void *data)
{
struct ata_softc *scp = (struct ata_softc *)data;
u_int8_t dmastat;
/*
* since we might share the IRQ with another device, and in some
- * case with our twin channel, we only want to process interrupts
+ * cases with our twin channel, we only want to process interrupts
* that we know this channel generated.
*/
switch (scp->chiptype) {
@@ -767,9 +1071,13 @@ ataintr(void *data)
case 0x4d33105a: /* Promise 33's */
case 0x4d38105a: /* Promise 66's */
- if (!(inl((pci_read_config(scp->dev, 0x20, 4) & IOMASK) + 0x1c) &
+ {
+ struct ata_pci_softc *sc=device_get_softc(device_get_parent(scp->dev));
+
+ if (!(inl(rman_get_start(sc->bmio) + 0x1c) &
((scp->unit) ? 0x00004000 : 0x00000400)))
return;
+ }
/* FALLTHROUGH */
#endif
default:
@@ -904,7 +1212,7 @@ void
ata_reset(struct ata_softc *scp, int32_t *mask)
{
int32_t timeout;
- int8_t status0, status1;
+ u_int8_t status0 = 0, status1 = 0;
/* reset channel */
outb(scp->ioaddr + ATA_DRIVE, ATA_D_IBM | ATA_MASTER);
@@ -954,29 +1262,31 @@ ata_reinit(struct ata_softc *scp)
scp->active = ATA_REINITING;
scp->running = NULL;
- ata_printf(scp, -1, "resetting devices .. ");
if (scp->devices & (ATA_ATA_MASTER | ATA_ATAPI_MASTER))
mask |= 0x01;
if (scp->devices & (ATA_ATA_SLAVE | ATA_ATAPI_SLAVE))
mask |= 0x02;
- omask = mask;
- ata_reset(scp, &mask);
- if (omask != mask)
- printf(" device dissapeared! %d ", omask & ~mask);
+ if (mask) {
+ omask = mask;
+ ata_printf(scp, -1, "resetting devices .. ");
+ ata_reset(scp, &mask);
+ if (omask != mask)
+ printf(" device dissapeared! %d ", omask & ~mask);
#if NATADISK > 0
- if (scp->devices & (ATA_ATA_MASTER) && scp->dev_softc[0])
- ad_reinit((struct ad_softc *)scp->dev_softc[0]);
- if (scp->devices & (ATA_ATA_SLAVE) && scp->dev_softc[1])
- ad_reinit((struct ad_softc *)scp->dev_softc[1]);
+ if (scp->devices & (ATA_ATA_MASTER) && scp->dev_softc[0])
+ ad_reinit((struct ad_softc *)scp->dev_softc[0]);
+ if (scp->devices & (ATA_ATA_SLAVE) && scp->dev_softc[1])
+ ad_reinit((struct ad_softc *)scp->dev_softc[1]);
#endif
#if NATAPICD > 0 || NATAPIFD > 0 || NATAPIST > 0
- if (scp->devices & (ATA_ATAPI_MASTER) && scp->dev_softc[0])
- atapi_reinit((struct atapi_softc *)scp->dev_softc[0]);
- if (scp->devices & (ATA_ATAPI_SLAVE) && scp->dev_softc[1])
- atapi_reinit((struct atapi_softc *)scp->dev_softc[1]);
+ if (scp->devices & (ATA_ATAPI_MASTER) && scp->dev_softc[0])
+ atapi_reinit((struct atapi_softc *)scp->dev_softc[0]);
+ if (scp->devices & (ATA_ATAPI_SLAVE) && scp->dev_softc[1])
+ atapi_reinit((struct atapi_softc *)scp->dev_softc[1]);
#endif
- printf("done\n");
+ printf("done\n");
+ }
scp->active = ATA_IDLE;
ata_start(scp);
return 0;
@@ -1103,6 +1413,38 @@ ata_command(struct ata_softc *scp, int32_t device, u_int32_t command,
return 0;
}
+int
+ata_printf(struct ata_softc *scp, int32_t device, const char * fmt, ...)
+{
+ va_list ap;
+ int ret;
+
+ if (device == -1)
+ ret = printf("ata%d: ", device_get_unit(scp->dev));
+ else
+ ret = printf("ata%d-%s: ", device_get_unit(scp->dev),
+ (device == ATA_MASTER) ? "master" : "slave");
+ va_start(ap, fmt);
+ ret += vprintf(fmt, ap);
+ va_end(ap);
+ return ret;
+}
+
+int
+ata_get_lun(u_int32_t *map)
+{
+ int lun = ffs(~*map) - 1;
+
+ *map |= (1 << lun);
+ return lun;
+}
+
+void
+ata_free_lun(u_int32_t *map, int lun)
+{
+ *map &= ~(1 << lun);
+}
+
int8_t *
ata_mode2str(int32_t mode)
{
@@ -1134,6 +1476,54 @@ ata_pio2mode(int32_t pio)
}
}
+int
+ata_pmode(struct ata_params *ap)
+{
+ if (ap->atavalid & ATA_FLAG_64_70) {
+ if (ap->apiomodes & 2)
+ return 4;
+ if (ap->apiomodes & 1)
+ return 3;
+ }
+ if (ap->opiomode == 2)
+ return 2;
+ if (ap->opiomode == 1)
+ return 1;
+ if (ap->opiomode == 0)
+ return 0;
+ return -1;
+}
+
+int
+ata_wmode(struct ata_params *ap)
+{
+ if (ap->wdmamodes & 4)
+ return 2;
+ if (ap->wdmamodes & 2)
+ return 1;
+ if (ap->wdmamodes & 1)
+ return 0;
+ return -1;
+}
+
+int
+ata_umode(struct ata_params *ap)
+{
+ if (ap->atavalid & ATA_FLAG_88) {
+ if (ap->udmamodes & 0x10)
+ return (ap->cblid ? 4 : 2);
+ if (ap->udmamodes & 0x08)
+ return (ap->cblid ? 3 : 2);
+ if (ap->udmamodes & 0x04)
+ return 2;
+ if (ap->udmamodes & 0x02)
+ return 1;
+ if (ap->udmamodes & 0x01)
+ return 0;
+ }
+ return -1;
+}
+
static int8_t *
active2str(int32_t active)
{
@@ -1162,60 +1552,25 @@ active2str(int32_t active)
}
}
-int32_t
-ata_pmode(struct ata_params *ap)
-{
- if (ap->atavalid & ATA_FLAG_64_70) {
- if (ap->apiomodes & 2) return 4;
- if (ap->apiomodes & 1) return 3;
- }
- if (ap->opiomode == 2) return 2;
- if (ap->opiomode == 1) return 1;
- if (ap->opiomode == 0) return 0;
- return -1;
-}
-
-int32_t
-ata_wmode(struct ata_params *ap)
-{
- if (ap->wdmamodes & 4) return 2;
- if (ap->wdmamodes & 2) return 1;
- if (ap->wdmamodes & 1) return 0;
- return -1;
-}
-
-int32_t
-ata_umode(struct ata_params *ap)
-{
- if (ap->atavalid & ATA_FLAG_88) {
- if (ap->udmamodes & 0x10) return (ap->cblid ? 4 : 2);
- if (ap->udmamodes & 0x08) return (ap->cblid ? 3 : 2);
- if (ap->udmamodes & 0x04) return 2;
- if (ap->udmamodes & 0x02) return 1;
- if (ap->udmamodes & 0x01) return 0;
- }
- return -1;
-}
-
static void
bswap(int8_t *buf, int32_t len)
{
- u_int16_t *p = (u_int16_t*)(buf + len);
+ u_int16_t *ptr = (u_int16_t*)(buf + len);
- while (--p >= (u_int16_t*)buf)
- *p = ntohs(*p);
+ while (--ptr >= (u_int16_t*)buf)
+ *ptr = ntohs(*ptr);
}
static void
btrim(int8_t *buf, int32_t len)
{
- int8_t *p;
+ int8_t *ptr;
- for (p = buf; p < buf+len; ++p)
- if (!*p)
- *p = ' ';
- for (p = buf + len - 1; p >= buf && *p == ' '; --p)
- *p = 0;
+ for (ptr = buf; ptr < buf+len; ++ptr)
+ if (!*ptr)
+ *ptr = ' ';
+ for (ptr = buf + len - 1; ptr >= buf && *ptr == ' '; --ptr)
+ *ptr = 0;
}
static void
@@ -1241,25 +1596,6 @@ bpack(int8_t *src, int8_t *dst, int32_t len)
dst[j] = 0x00;
}
-int32_t
-ata_printf(struct ata_softc *scp, int32_t device, const char * fmt, ...)
-{
- va_list ap;
- int ret;
-
- if (device == -1)
- ret = printf("ata%d: ", scp->lun);
- else
- ret = printf("ata%d-%s: ", scp->lun,
- (device == ATA_MASTER) ? "master" : "slave");
- va_start(ap, fmt);
- ret += vprintf(fmt, ap);
- va_end(ap);
- return ret;
-}
-
-static char ata_conf[1024];
-
static void
ata_change_mode(struct ata_softc *scp, int32_t device, int32_t mode)
{
@@ -1279,17 +1615,22 @@ ata_change_mode(struct ata_softc *scp, int32_t device, int32_t mode)
static int
sysctl_hw_ata SYSCTL_HANDLER_ARGS
{
- int error, i;
+ struct ata_softc *scp;
+ int ctlr, error, i;
/* readout internal state */
bzero(ata_conf, sizeof(ata_conf));
- for (i = 0; i < (atanlun << 1); i++) {
- if (!atadevices[i >> 1] || !atadevices[ i >> 1]->dev_softc[i & 1])
- strcat(ata_conf, "---,");
- else if (atadevices[i >> 1]->mode[i & 1] >= ATA_DMA)
- strcat(ata_conf, "dma,");
- else
- strcat(ata_conf, "pio,");
+ for (ctlr=0; ctlr<devclass_get_maxunit(ata_devclass); ctlr++) {
+ if (!(scp = devclass_get_softc(ata_devclass, ctlr)))
+ continue;
+ for (i = 0; i < 2; i++) {
+ if (!scp->dev_softc[i])
+ strcat(ata_conf, "---,");
+ else if (scp->mode[i] >= ATA_DMA)
+ strcat(ata_conf, "dma,");
+ else
+ strcat(ata_conf, "pio,");
+ }
}
error = sysctl_handle_string(oidp, ata_conf, sizeof(ata_conf), req);
if (error == 0 && req->newptr != NULL) {
@@ -1299,28 +1640,44 @@ sysctl_hw_ata SYSCTL_HANDLER_ARGS
i = 0;
while (*ptr) {
if (!strncmp(ptr, "pio", 3) || !strncmp(ptr, "PIO", 3)) {
- if (atadevices[i >> 1] &&
- atadevices[i >> 1]->dev_softc[i & 1] &&
- atadevices[i >>1 ]->mode[i & 1] >= ATA_DMA)
- ata_change_mode(atadevices[i >> 1],
- (i & 1) ? ATA_SLAVE : ATA_MASTER, ATA_PIO);
+ if ((scp = devclass_get_softc(ata_devclass, i >> 1)) &&
+ scp->dev_softc[i & 1] && scp->mode[i & 1] >= ATA_DMA)
+ ata_change_mode(scp, (i & 1)?ATA_SLAVE:ATA_MASTER, ATA_PIO);
}
else if (!strncmp(ptr, "dma", 3) || !strncmp(ptr, "DMA", 3)) {
- if (atadevices[i >> 1] &&
- atadevices[i >> 1]->dev_softc[i & 1] &&
- atadevices[i >> 1]->mode[i & 1] < ATA_DMA)
- ata_change_mode(atadevices[i >> 1],
- (i & 1) ? ATA_SLAVE : ATA_MASTER, ATA_DMA);
+ if ((scp = devclass_get_softc(ata_devclass, i >> 1)) &&
+ scp->dev_softc[i & 1] && scp->mode[i & 1] < ATA_DMA)
+ ata_change_mode(scp, (i & 1)?ATA_SLAVE:ATA_MASTER, ATA_DMA);
}
else if (strncmp(ptr, "---", 3))
break;
ptr+=3;
- if (*ptr++ != ',' || ++i > (atanlun << 1))
+ if (*ptr++ != ',' ||
+ ++i > (devclass_get_maxunit(ata_devclass) << 1))
break;
}
}
return error;
}
-
SYSCTL_PROC(_hw, OID_AUTO, atamodes, CTLTYPE_STRING | CTLFLAG_RW,
0, sizeof(ata_conf), sysctl_hw_ata, "A", "");
+
+static void
+ata_init(void)
+{
+ /* register boot attach to be run when interrupts are enabled */
+ if (!(ata_delayed_attach = (struct intr_config_hook *)
+ malloc(sizeof(struct intr_config_hook),
+ M_TEMP, M_NOWAIT))) {
+ printf("ata: malloc of delayed attach hook failed\n");
+ return;
+ }
+ bzero(ata_delayed_attach, sizeof(struct intr_config_hook));
+
+ 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);
+ }
+}
+SYSINIT(atadev, SI_SUB_DRIVERS, SI_ORDER_SECOND, ata_init, NULL)
diff --git a/sys/dev/ata/ata-all.h b/sys/dev/ata/ata-all.h
index 009827e..317926f 100644
--- a/sys/dev/ata/ata-all.h
+++ b/sys/dev/ata/ata-all.h
@@ -86,11 +86,14 @@
#define ATA_S_READY 0x40 /* drive ready */
#define ATA_S_BUSY 0x80 /* busy */
-#define ATA_ALTPORT 0x206 /* alternate Status register */
+#define ATA_ALTPORT 0x206 /* alternate status register */
+#define ATA_ALTPORT_PCCARD 0x8 /* ditto on PCCARD devices */
#define ATA_A_IDS 0x02 /* disable interrupts */
#define ATA_A_RESET 0x04 /* RESET controller */
#define ATA_A_4BIT 0x08 /* 4 head bits */
+#define ATA_ALTIOSIZE 0x01
+
/* misc defines */
#define ATA_MASTER 0x00
#define ATA_SLAVE 0x10
@@ -121,6 +124,8 @@
#define ATA_BMDTP_PORT 0x04
+#define ATA_BMIOSIZE 0x20
+
/* structure for holding DMA address data */
struct ata_dmaentry {
u_int32_t base;
@@ -249,12 +254,15 @@ struct ata_params {
/* structure describing an ATA device */
struct ata_softc {
- int32_t unit; /* unit on this controller */
- int32_t lun; /* logical unit # */
struct device *dev; /* device handle */
- int32_t ioaddr; /* port addr */
- int32_t altioaddr; /* alternate port addr */
- int32_t bmaddr; /* bus master DMA port */
+ int32_t unit; /* unit on this controller */
+ struct resource *r_io; /* io addr resource handle */
+ struct resource *r_altio; /* altio addr resource handle */
+ struct resource *r_bmio; /* bmio addr resource handle */
+ struct resource *r_irq; /* interrupt of this channel */
+ int32_t ioaddr; /* physical port addr */
+ int32_t altioaddr; /* physical alt port addr */
+ int32_t bmaddr; /* physical bus master port */
int32_t chiptype; /* pciid of controller chip */
struct ata_params *dev_param[2]; /* ptr to devices params */
void *dev_softc[2]; /* ptr to devices softc's */
@@ -275,6 +283,7 @@ struct ata_softc {
#define ATA_DMA_ACTIVE 0x01
#define ATA_ATAPI_DMA_RO 0x02
#define ATA_USE_16BIT 0x04
+#define ATA_ATTACHED 0x08
int32_t devices; /* what is present */
#define ATA_ATA_MASTER 0x01
@@ -297,15 +306,10 @@ struct ata_softc {
TAILQ_HEAD(, ad_request) ata_queue; /* head of ATA queue */
TAILQ_HEAD(, atapi_request) atapi_queue; /* head of ATAPI queue */
void *running; /* currently running request */
-#if NAPM > 0
- struct apmhook resume_hook; /* hook for apm */
-#endif
-
};
-/* array to hold all ata softc's */
-extern struct ata_softc *atadevices[];
-#define MAXATA 16
+/* To convert unit numbers to devices */
+extern devclass_t ata_devclass;
/* public prototypes */
void ata_start(struct ata_softc *);
@@ -313,15 +317,17 @@ void ata_reset(struct ata_softc *, int32_t *);
int32_t ata_reinit(struct ata_softc *);
int32_t ata_wait(struct ata_softc *, int32_t, u_int8_t);
int32_t ata_command(struct ata_softc *, int32_t, u_int32_t, u_int32_t, u_int32_t, u_int32_t, u_int32_t, u_int32_t, int32_t);
+int ata_printf(struct ata_softc *, int32_t, const char *, ...) __printflike(3, 4);
+int ata_get_lun(u_int32_t *);
+void ata_free_lun(u_int32_t *, int);
+int8_t *ata_mode2str(int32_t);
+int8_t ata_pio2mode(int32_t);
+int ata_pmode(struct ata_params *);
+int ata_wmode(struct ata_params *);
+int ata_umode(struct ata_params *);
+
void ata_dmainit(struct ata_softc *, int32_t, int32_t, int32_t, int32_t);
int32_t ata_dmasetup(struct ata_softc *, int32_t, int8_t *, int32_t, int32_t);
void ata_dmastart(struct ata_softc *);
int32_t ata_dmastatus(struct ata_softc *);
int32_t ata_dmadone(struct ata_softc *);
-int32_t ata_pmode(struct ata_params *);
-int32_t ata_wmode(struct ata_params *);
-int32_t ata_umode(struct ata_params *);
-int8_t *ata_mode2str(int32_t);
-int8_t ata_pio2mode(int32_t);
-int32_t ata_find_dev(device_t, int32_t);
-int32_t ata_printf(struct ata_softc *, int32_t, const char *, ...) __printflike(3, 4);
diff --git a/sys/dev/ata/ata-disk.c b/sys/dev/ata/ata-disk.c
index 0629442..301fe6b 100644
--- a/sys/dev/ata/ata-disk.c
+++ b/sys/dev/ata/ata-disk.c
@@ -48,16 +48,13 @@
#include <vm/vm_object.h>
#include <machine/clock.h>
#include <machine/md_var.h>
-#if NAPM > 0
-#include <machine/apm_bios.h>
-#endif
#include <dev/ata/ata-all.h>
#include <dev/ata/ata-disk.h>
+/* device structures */
static d_open_t adopen;
static d_strategy_t adstrategy;
static d_dump_t addump;
-
static struct cdevsw ad_cdevsw = {
/* open */ adopen,
/* close */ nullclose,
@@ -99,6 +96,7 @@ static void ad_timeout(struct ad_request *);
static int32_t ad_version(u_int16_t);
/* internal vars */
+static u_int32_t adp_lun_map = 0;
MALLOC_DEFINE(M_AD, "AD driver", "ATA disk driver");
/* defines */
@@ -109,22 +107,23 @@ void
ad_attach(struct ata_softc *scp, int32_t device)
{
struct ad_softc *adp;
- static int32_t adnlun = 0;
- dev_t dev1;
+ dev_t dev;
int32_t secsperint;
-#ifdef ATA_STATIC_ID
- adnlun = (scp->lun << 1) + ATA_DEV(device);
-#endif
+
if (!(adp = malloc(sizeof(struct ad_softc), M_AD, M_NOWAIT))) {
- printf("ad%d: failed to allocate driver storage\n", adnlun);
+ ata_printf(scp, device, "failed to allocate driver storage\n");
return;
}
bzero(adp, sizeof(struct ad_softc));
scp->dev_softc[ATA_DEV(device)] = adp;
adp->controller = scp;
adp->unit = device;
- adp->lun = adnlun++;
+#ifdef ATA_STATIC_ID
+ adp->lun = (device_get_unit(scp->dev) << 1) + ATA_DEV(device);
+#else
+ adp->lun = ata_get_lun(&adp_lun_map);
+#endif
adp->heads = AD_PARAM->heads;
adp->sectors = AD_PARAM->sectors;
adp->total_secs = AD_PARAM->cylinders * adp->heads * adp->sectors;
@@ -162,7 +161,7 @@ ad_attach(struct ata_softc *scp, int32_t device)
if (bootverbose) {
printf("ad%d: <%.40s/%.8s> ATA-%d disk at ata%d as %s\n",
adp->lun, AD_PARAM->model, AD_PARAM->revision,
- ad_version(AD_PARAM->versmajor), scp->lun,
+ ad_version(AD_PARAM->versmajor), device_get_unit(scp->dev),
(adp->unit == ATA_MASTER) ? "master" : "slave");
printf("ad%d: %luMB (%u sectors), %u cyls, %u heads, %u S/T, %u B/S\n",
@@ -184,7 +183,7 @@ ad_attach(struct ata_softc *scp, int32_t device)
printf("ad%d: %luMB <%.40s> [%d/%d/%d] at ata%d-%s using %s\n",
adp->lun, adp->total_secs / ((1024L * 1024L) / DEV_BSIZE),
AD_PARAM->model, adp->total_secs / (adp->heads * adp->sectors),
- adp->heads, adp->sectors, scp->lun,
+ adp->heads, adp->sectors, device_get_unit(scp->dev),
(adp->unit == ATA_MASTER) ? "master" : "slave",
ata_mode2str(adp->controller->mode[ATA_DEV(adp->unit)]));
@@ -193,18 +192,34 @@ ad_attach(struct ata_softc *scp, int32_t device)
DEVSTAT_TYPE_DIRECT | DEVSTAT_TYPE_IF_IDE,
DEVSTAT_PRIORITY_DISK);
- dev1 = disk_create(adp->lun, &adp->disk, 0, &ad_cdevsw, &addisk_cdevsw);
- dev1->si_drv1 = adp;
- dev1->si_iosize_max = 256 * DEV_BSIZE;
+ dev = disk_create(adp->lun, &adp->disk, 0, &ad_cdevsw, &addisk_cdevsw);
+ dev->si_drv1 = adp;
+ dev->si_iosize_max = 256 * DEV_BSIZE;
+ adp->dev1 = dev;
- dev1 = disk_create(adp->lun, &adp->disk, 0, &fakewd_cdevsw,
+ dev = disk_create(adp->lun, &adp->disk, 0, &fakewd_cdevsw,
&fakewddisk_cdevsw);
- dev1->si_drv1 = adp;
- dev1->si_iosize_max = 256 * DEV_BSIZE;
+ dev->si_drv1 = adp;
+ dev->si_iosize_max = 256 * DEV_BSIZE;
+ adp->dev2 = dev;
bufq_init(&adp->queue);
}
+void
+ad_detach(struct ata_softc *scp, int32_t device)
+{
+ struct ad_softc *adp = scp->dev_softc[ATA_DEV(device)];
+
+ disk_invalidate(&adp->disk);
+ disk_destroy(adp->dev1);
+ disk_destroy(adp->dev2);
+ devstat_remove_entry(&adp->stats);
+ ata_free_lun(&adp_lun_map, adp->lun);
+ free(adp, M_AD);
+ scp->dev_softc[ATA_DEV(device)] = NULL;
+}
+
static int
adopen(dev_t dev, int32_t flags, int32_t fmt, struct proc *p)
{
@@ -300,7 +315,7 @@ addump(dev_t dev)
}
if (ata_wait(adp->controller, adp->unit, ATA_S_READY | ATA_S_DSC) < 0)
- printf("addump: timeout waiting for final ready\n");
+ printf("ad%d: timeout waiting for final ready\n", adp->lun);
return 0;
}
@@ -315,7 +330,7 @@ ad_start(struct ad_softc *adp)
return;
if (!(request = malloc(sizeof(struct ad_request), M_AD, M_NOWAIT))) {
- printf("ad_start: out of memory\n");
+ printf("ad%d: out of memory in start\n", adp->lun);
return;
}
@@ -365,7 +380,8 @@ ad_transfer(struct ad_request *request)
count = howmany(request->bytecount, DEV_BSIZE);
if (count > 256) {
count = 256;
- printf("ad%d: count=%d not supported\n", adp->lun, count);
+ printf("ad%d: count %d size transfers not supported\n",
+ adp->lun, count);
}
if (adp->flags & AD_F_LBA_ENABLED) {
@@ -406,7 +422,7 @@ ad_transfer(struct ad_request *request)
if (ata_command(adp->controller, adp->unit, cmd,
cylinder, head, sector, count, 0, ATA_IMMEDIATE)) {
- printf("ad%d: wouldn't take transfer command\n", adp->lun);
+ printf("ad%d: error executing command\n", adp->lun);
return;
}
@@ -452,7 +468,7 @@ ad_interrupt(struct ad_request *request)
/* get drive status */
if (ata_wait(adp->controller, adp->unit, 0) < 0)
- printf("ad_interrupt: timeout waiting for status");
+ printf("ad%d: timeout waiting for status", adp->lun);
/* do we have a corrected soft error ? */
if (adp->controller->status & ATA_S_CORR)
@@ -499,7 +515,7 @@ oops:
/* if we arrived here with forced PIO mode, DMA doesn't work right */
if (request->flags & AR_F_FORCE_PIO)
- printf("ad%d: DMA problem, fallback to PIO mode\n", adp->lun);
+ printf("ad%d: DMA problem fallback to PIO mode\n", adp->lun);
/* if this was a PIO read operation, get the data */
if (!(request->flags & AR_F_DMA_USED) &&
@@ -508,11 +524,11 @@ oops:
/* ready to receive data? */
if ((adp->controller->status & (ATA_S_READY | ATA_S_DSC | ATA_S_DRQ))
!= (ATA_S_READY | ATA_S_DSC | ATA_S_DRQ))
- printf("ad_interrupt: read interrupt arrived early");
+ printf("ad%d: read interrupt arrived early", adp->lun);
if (ata_wait(adp->controller, adp->unit,
(ATA_S_READY | ATA_S_DSC | ATA_S_DRQ)) != 0) {
- printf("ad_interrupt: read error detected late");
+ printf("ad%d: read error detected late", adp->lun);
goto oops;
}
@@ -574,13 +590,14 @@ ad_timeout(struct ad_request *request)
int32_t s = splbio();
adp->controller->running = NULL;
- printf("ad%d: ad_timeout: lost disk contact - resetting\n", adp->lun);
+ printf("ad%d: %s command timeout - resetting\n",
+ adp->lun, (request->flags & AR_F_READ) ? "READ" : "WRITE");
if (request->flags & AR_F_DMA_USED) {
ata_dmadone(adp->controller);
if (request->retries == AD_MAX_RETRIES) {
ata_dmainit(adp->controller, adp->unit, ata_pmode(AD_PARAM), -1,-1);
- printf("ad%d: ad_timeout: trying fallback to PIO mode\n", adp->lun);
+ printf("ad%d: trying fallback to PIO mode\n", adp->lun);
request->retries = 0;
}
}
diff --git a/sys/dev/ata/ata-disk.h b/sys/dev/ata/ata-disk.h
index eadfeb12..47f9f78 100644
--- a/sys/dev/ata/ata-disk.h
+++ b/sys/dev/ata/ata-disk.h
@@ -47,6 +47,7 @@ struct ad_softc {
struct buf_queue_head queue; /* head of request queue */
struct devstat stats; /* devstat entry */
struct disk disk; /* disklabel/slice stuff */
+ dev_t dev1, dev2; /* device place holder */
};
struct ad_request {
@@ -70,6 +71,7 @@ struct ad_request {
};
void ad_attach(struct ata_softc *, int32_t);
+void ad_detach(struct ata_softc *, int32_t);
void ad_transfer(struct ad_request *);
int32_t ad_interrupt(struct ad_request *);
void ad_reinit(struct ad_softc *);
diff --git a/sys/dev/ata/ata-dma.c b/sys/dev/ata/ata-dma.c
index 1751648..5463b05 100644
--- a/sys/dev/ata/ata-dma.c
+++ b/sys/dev/ata/ata-dma.c
@@ -29,7 +29,6 @@
*/
#include "pci.h"
-#include "apm.h"
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/buf.h>
@@ -42,9 +41,6 @@
#if NPCI > 0
#include <pci/pcivar.h>
#endif
-#if NAPM > 0
-#include <machine/apm_bios.h>
-#endif
#include <dev/ata/ata-all.h>
#include <dev/ata/ata-disk.h>
@@ -64,6 +60,7 @@ void
ata_dmainit(struct ata_softc *scp, int32_t device,
int32_t apiomode, int32_t wdmamode, int32_t udmamode)
{
+ device_t parent = device_get_parent(scp->dev);
int32_t devno = (scp->unit << 1) + ATA_DEV(device);
int32_t error;
@@ -116,8 +113,8 @@ ata_dmainit(struct ata_softc *scp, int32_t device,
if (!error) {
mask48 = (1 << devno) + (3 << (16 + (devno << 2)));
new48 = (1 << devno) + (2 << (16 + (devno << 2)));
- pci_write_config(scp->dev, 0x48,
- (pci_read_config(scp->dev, 0x48, 4) &
+ pci_write_config(parent, 0x48,
+ (pci_read_config(parent, 0x48, 4) &
~mask48) | new48, 4);
scp->mode[ATA_DEV(device)] = ATA_UDMA2;
return;
@@ -130,9 +127,9 @@ ata_dmainit(struct ata_softc *scp, int32_t device,
int32_t mask40, new40, mask44, new44;
/* if SITRE not set doit for both channels */
- if (!((pci_read_config(scp->dev, 0x40, 4)>>(scp->unit<<8))&0x4000)){
- new40 = pci_read_config(scp->dev, 0x40, 4);
- new44 = pci_read_config(scp->dev, 0x44, 4);
+ if (!((pci_read_config(parent, 0x40, 4)>>(scp->unit<<8))&0x4000)){
+ new40 = pci_read_config(parent, 0x40, 4);
+ new44 = pci_read_config(parent, 0x44, 4);
if (!(new40 & 0x00004000)) {
new44 &= ~0x0000000f;
new44 |= ((new40&0x00003000)>>10)|((new40&0x00000300)>>8);
@@ -142,8 +139,8 @@ ata_dmainit(struct ata_softc *scp, int32_t device,
new44 |= ((new40&0x30000000)>>22)|((new40&0x03000000)>>20);
}
new40 |= 0x40004000;
- pci_write_config(scp->dev, 0x40, new40, 4);
- pci_write_config(scp->dev, 0x44, new44, 4);
+ pci_write_config(parent, 0x40, new40, 4);
+ pci_write_config(parent, 0x44, new44, 4);
}
error = ata_command(scp, device, ATA_C_SETFEATURES, 0, 0, 0,
ATA_WDMA2, ATA_C_F_SETXFER, ATA_WAIT_READY);
@@ -172,11 +169,11 @@ ata_dmainit(struct ata_softc *scp, int32_t device,
mask44 <<= 4;
new44 <<= 4;
}
- pci_write_config(scp->dev, 0x40,
- (pci_read_config(scp->dev, 0x40, 4) & ~mask40)|
+ pci_write_config(parent, 0x40,
+ (pci_read_config(parent, 0x40, 4) & ~mask40)|
new40, 4);
- pci_write_config(scp->dev, 0x44,
- (pci_read_config(scp->dev, 0x44, 4) & ~mask44)|
+ pci_write_config(parent, 0x44,
+ (pci_read_config(parent, 0x44, 4) & ~mask44)|
new44, 4);
scp->mode[ATA_DEV(device)] = ATA_WDMA2;
return;
@@ -189,7 +186,7 @@ ata_dmainit(struct ata_softc *scp, int32_t device,
if (wdmamode >= 2 && apiomode >= 4) {
int32_t word40;
- word40 = pci_read_config(scp->dev, 0x40, 4);
+ word40 = pci_read_config(parent, 0x40, 4);
word40 >>= scp->unit * 16;
/* Check for timing config usable for DMA on controller */
@@ -218,7 +215,7 @@ ata_dmainit(struct ata_softc *scp, int32_t device,
break;
}
if (udmamode >= 2) {
- int32_t word54 = pci_read_config(scp->dev, 0x54, 4);
+ int32_t word54 = pci_read_config(parent, 0x54, 4);
error = ata_command(scp, device, ATA_C_SETFEATURES, 0, 0, 0,
ATA_UDMA2, ATA_C_F_SETXFER, ATA_WAIT_READY);
@@ -229,9 +226,9 @@ ata_dmainit(struct ata_softc *scp, int32_t device,
if (!error) {
word54 |= 0x5555;
word54 |= (0x0a << (16 + (scp->unit << 3) + (device << 2)));
- pci_write_config(scp->dev, 0x54, word54, 4);
- pci_write_config(scp->dev, 0x53,
- pci_read_config(scp->dev, 0x53, 1) | 0x03, 1);
+ pci_write_config(parent, 0x54, word54, 4);
+ pci_write_config(parent, 0x53,
+ pci_read_config(parent, 0x53, 1) | 0x03, 1);
scp->flags |= ATA_ATAPI_DMA_RO;
scp->mode[ATA_DEV(device)] = ATA_UDMA2;
return;
@@ -245,8 +242,8 @@ ata_dmainit(struct ata_softc *scp, int32_t device,
"%s setting up WDMA2 mode on Aladdin chip\n",
(error) ? "failed" : "success");
if (!error) {
- pci_write_config(scp->dev, 0x53,
- pci_read_config(scp->dev, 0x53, 1) | 0x03, 1);
+ pci_write_config(parent, 0x53,
+ pci_read_config(parent, 0x53, 1) | 0x03, 1);
scp->flags |= ATA_ATAPI_DMA_RO;
scp->mode[ATA_DEV(device)] = ATA_WDMA2;
return;
@@ -264,7 +261,7 @@ ata_dmainit(struct ata_softc *scp, int32_t device,
"%s setting up UDMA4 mode on VIA chip\n",
(error) ? "failed" : "success");
if (!error) {
- pci_write_config(scp->dev, 0x53 - devno, 0xe8, 1);
+ pci_write_config(parent, 0x53 - devno, 0xe8, 1);
scp->mode[ATA_DEV(device)] = ATA_UDMA4;
return;
}
@@ -277,7 +274,7 @@ ata_dmainit(struct ata_softc *scp, int32_t device,
"%s setting up UDMA2 mode on VIA chip\n",
(error) ? "failed" : "success");
if (!error) {
- pci_write_config(scp->dev, 0x53 - devno, 0xea, 1);
+ pci_write_config(parent, 0x53 - devno, 0xea, 1);
scp->mode[ATA_DEV(device)] = ATA_UDMA2;
return;
}
@@ -293,7 +290,7 @@ ata_dmainit(struct ata_softc *scp, int32_t device,
"%s setting up UDMA4 mode on AMD chip\n",
(error) ? "failed" : "success");
if (!error) {
- pci_write_config(scp->dev, 0x53 - devno, 0xc3, 1);
+ pci_write_config(parent, 0x53 - devno, 0xc3, 1);
scp->mode[ATA_DEV(device)] = ATA_UDMA4;
return;
}
@@ -315,7 +312,7 @@ ata_dmainit(struct ata_softc *scp, int32_t device,
(error) ? "failed" : "success",
(scp->chiptype == 0x74091022) ? "AMD" : "VIA");
if (!error) {
- pci_write_config(scp->dev, 0x53 - devno, 0xc0, 1);
+ pci_write_config(parent, 0x53 - devno, 0xc0, 1);
scp->mode[ATA_DEV(device)] = ATA_UDMA2;
return;
}
@@ -332,8 +329,8 @@ via_generic:
(error) ? "failed" : "success",
(scp->chiptype == 0x74091022) ? "AMD" : "VIA");
if (!error) {
- pci_write_config(scp->dev, 0x53 - devno, 0x82, 1);
- pci_write_config(scp->dev, 0x4b - devno, 0x31, 1);
+ pci_write_config(parent, 0x53 - devno, 0x82, 1);
+ pci_write_config(parent, 0x4b - devno, 0x31, 1);
scp->mode[ATA_DEV(device)] = ATA_WDMA2;
return;
}
@@ -350,7 +347,7 @@ via_generic:
"%s setting up UDMA2 mode on SiS chip\n",
(error) ? "failed" : "success");
if (!error) {
- pci_write_config(scp->dev, 0x40 + (devno << 1), 0xa301, 2);
+ pci_write_config(parent, 0x40 + (devno << 1), 0xa301, 2);
scp->mode[ATA_DEV(device)] = ATA_UDMA2;
return;
}
@@ -363,7 +360,26 @@ via_generic:
"%s setting up WDMA2 mode on SiS chip\n",
(error) ? "failed" : "success");
if (!error) {
- pci_write_config(scp->dev, 0x40 + (devno << 1), 0x0301, 2);
+ pci_write_config(parent, 0x40 + (devno << 1), 0x0301, 2);
+ scp->mode[ATA_DEV(device)] = ATA_WDMA2;
+ return;
+ }
+ }
+ /* we could set PIO mode timings, but we assume the BIOS did that */
+ break;
+
+ case 0x06461095: /* CMD 646 ATA controller */
+ if (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)
+ ata_printf(scp, device,
+ "%s setting up WDMA2 mode on CMD646 chip\n",
+ error ? "failed" : "success");
+ if (!error) {
+ int32_t offset = (devno < 3) ? (devno << 1) : 7;
+
+ pci_write_config(parent, 0x54 + offset, 0x3f, 1);
scp->mode[ATA_DEV(device)] = ATA_WDMA2;
return;
}
@@ -379,7 +395,7 @@ via_generic:
break;
if (udmamode >=4 && scp->chiptype == 0x4d38105a &&
- !(pci_read_config(scp->dev, 0x50, 2)&(scp->unit ? 1<<11 : 1<<10))) {
+ !(pci_read_config(parent, 0x50, 2)&(scp->unit ? 1<<11 : 1<<10))) {
error = ata_command(scp, device, ATA_C_SETFEATURES, 0, 0, 0,
ATA_UDMA4, ATA_C_F_SETXFER, ATA_WAIT_READY);
if (bootverbose)
@@ -436,7 +452,7 @@ via_generic:
(device == ATA_SLAVE && scp->devices & ATA_ATAPI_SLAVE))
break;
- if (udmamode >=4 && !(pci_read_config(scp->dev, 0x5a, 1) & 0x2)) {
+ if (udmamode >=4 && !(pci_read_config(parent, 0x5a, 1) & 0x2)) {
error = ata_command(scp, device, ATA_C_SETFEATURES, 0, 0, 0,
ATA_UDMA4, ATA_C_F_SETXFER, ATA_WAIT_READY);
if (bootverbose)
@@ -648,15 +664,16 @@ promise_timing(struct ata_softc *scp, int32_t devno, int32_t mode)
}
break;
}
- pci_write_config(scp->dev, 0x60 + (devno << 2), timing, 4);
+ pci_write_config(device_get_parent(scp->dev), 0x60 + (devno<<2), timing, 4);
}
static void
hpt366_timing(struct ata_softc *scp, int32_t devno, int32_t mode)
{
+ device_t parent = device_get_parent(scp->dev);
u_int32_t timing;
- switch (pci_read_config(scp->dev, 0x41 + (devno << 2), 1)) {
+ switch (pci_read_config(parent, 0x41 + (devno << 2), 1)) {
case 0x85: /* 25Mhz */
switch (mode) {
case ATA_PIO0: timing = 0xc0d08585; break;
@@ -697,7 +714,7 @@ hpt366_timing(struct ata_softc *scp, int32_t devno, int32_t mode)
default: timing = 0x0120d9d9;
}
}
- pci_write_config(scp->dev, 0x40 + (devno << 2) , (timing & ~0x80000000), 4);
+ pci_write_config(parent, 0x40 + (devno << 2) , (timing & ~0x80000000), 4);
}
#else /* NPCI > 0 */
diff --git a/sys/dev/ata/atapi-all.c b/sys/dev/ata/atapi-all.c
index b31290a..8f1e67a 100644
--- a/sys/dev/ata/atapi-all.c
+++ b/sys/dev/ata/atapi-all.c
@@ -28,7 +28,6 @@
* $FreeBSD$
*/
-#include "apm.h"
#include "atapicd.h"
#include "atapist.h"
#include "atapifd.h"
@@ -41,9 +40,6 @@
#include <sys/bus.h>
#include <sys/malloc.h>
#include <machine/clock.h>
-#if NAPM > 0
-#include <machine/apm_bios.h>
-#endif
#include <dev/ata/ata-all.h>
#include <dev/ata/atapi-all.h>
@@ -59,6 +55,9 @@ static int8_t *atapi_skey2str(u_int8_t);
int32_t acdattach(struct atapi_softc *);
int32_t afdattach(struct atapi_softc *);
int32_t astattach(struct atapi_softc *);
+void acddetach(struct atapi_softc *);
+void afddetach(struct atapi_softc *);
+void astdetach(struct atapi_softc *);
/* internal vars */
MALLOC_DEFINE(M_ATAPI, "ATAPI generic", "ATAPI driver generic layer");
@@ -73,7 +72,7 @@ atapi_attach(struct ata_softc *scp, int32_t device)
struct atapi_softc *atp;
if (!(atp = malloc(sizeof(struct atapi_softc), M_ATAPI, M_NOWAIT))) {
- printf("atapi: failed to allocate driver storage\n");
+ ata_printf(scp, device, "failed to allocate driver storage\n");
return;
}
bzero(atp, sizeof(struct atapi_softc));
@@ -131,10 +130,38 @@ notfound:
scp->dev_softc[ATA_DEV(device)] = atp;
}
+void
+atapi_detach(struct ata_softc *scp, int32_t device)
+{
+ struct atapi_softc *atp = scp->dev_softc[ATA_DEV(device)];
+
+ switch (ATP_PARAM->device_type) {
+#if NATAPICD > 0
+ case ATAPI_TYPE_CDROM:
+ acddetach(atp);
+ break;
+#endif
+#if NATAPIFD > 0
+ case ATAPI_TYPE_DIRECT:
+ afddetach(atp);
+ break;
+#endif
+#if NATAPIST > 0
+ case ATAPI_TYPE_TAPE:
+ astdetach(atp);
+ break;
+#endif
+ default:
+ return;
+ }
+ free(atp, M_ATAPI);
+ scp->dev_softc[ATA_DEV(device)] = NULL;
+}
+
int32_t
atapi_queue_cmd(struct atapi_softc *atp, int8_t *ccb, void *data,
int32_t count, int32_t flags, int32_t timeout,
- atapi_callback_t callback, void *driver, struct buf *bp)
+ atapi_callback_t callback, void *unused, struct buf *bp)
{
struct atapi_request *request;
int32_t error, s;
@@ -153,7 +180,6 @@ atapi_queue_cmd(struct atapi_softc *atp, int8_t *ccb, void *data,
if (callback) {
request->callback = callback;
request->bp = bp;
- request->driver = driver;
}
s = splbio();
@@ -273,7 +299,7 @@ atapi_interrupt(struct atapi_request *request)
if (reason == ATAPI_P_CMDOUT) {
if (!(atp->controller->status & ATA_S_DRQ)) {
request->result = inb(atp->controller->ioaddr + ATA_ERROR);
- printf("%s: command interrupt, but no DRQ\n", atp->devname);
+ printf("%s: command interrupt without DRQ\n", atp->devname);
goto op_finished;
}
outsw(atp->controller->ioaddr + ATA_DATA, request->ccb,
@@ -469,7 +495,6 @@ atapi_read(struct atapi_request *request, int32_t length)
if (request->bytecount < length) {
printf("%s: read data overrun %d/%d\n",
request->device->devname, length, request->bytecount);
-
for (resid=request->bytecount; resid<length; resid+=sizeof(int16_t))
inw(request->device->controller->ioaddr + ATA_DATA);
}
@@ -498,7 +523,6 @@ atapi_write(struct atapi_request *request, int32_t length)
if (request->bytecount < length) {
printf("%s: write data underrun %d/%d\n",
request->device->devname, length, request->bytecount);
-
for (resid=request->bytecount; resid<length; resid+=sizeof(int16_t))
outw(request->device->controller->ioaddr + ATA_DATA, 0);
}
@@ -513,7 +537,7 @@ atapi_timeout(struct atapi_request *request)
int32_t s = splbio();
atp->controller->running = NULL;
- printf("%s: atapi_timeout: cmd=%s - resetting\n",
+ printf("%s: %s command timeout - resetting\n",
atp->devname, atapi_cmd2str(request->ccb[0]));
if (request->flags & ATAPI_F_DMA_USED)
@@ -597,7 +621,7 @@ atapi_cmd2str(u_int8_t cmd)
case 0xbe: return ("READ_CD");
default: {
static int8_t buffer[16];
- sprintf(buffer, "Unknown CMD (0x%02x)", cmd);
+ sprintf(buffer, "unknown CMD (0x%02x)", cmd);
return buffer;
}
}
diff --git a/sys/dev/ata/atapi-all.h b/sys/dev/ata/atapi-all.h
index 26cf7ad..ca7a55f 100644
--- a/sys/dev/ata/atapi-all.h
+++ b/sys/dev/ata/atapi-all.h
@@ -134,8 +134,9 @@ struct atapi_reqsense {
};
struct atapi_softc {
- struct ata_softc *controller; /* ptr to parent ctrl */
+ struct ata_softc *controller; /* ptr to controller softc */
int32_t unit; /* ATA_MASTER or ATA_SLAVE */
+ void *driver; /* ptr to subdriver softc */
int8_t *devname; /* this devices name */
int8_t cmd; /* last cmd executed */
u_int32_t flags; /* drive flags */
@@ -149,7 +150,6 @@ typedef int32_t atapi_callback_t(struct atapi_request *);
struct atapi_request {
struct atapi_softc *device; /* ptr to parent device */
- void *driver; /* ptr to calling driver */
u_int8_t ccb[16]; /* command control block */
int32_t ccbsize; /* size of ccb (12 | 16) */
u_int32_t bytecount; /* bytes to transfer */
@@ -169,6 +169,7 @@ struct atapi_request {
};
void atapi_attach(struct ata_softc *, int32_t);
+void atapi_detach(struct ata_softc *, int32_t);
void atapi_transfer(struct atapi_request *);
int32_t atapi_interrupt(struct atapi_request *);
int32_t atapi_queue_cmd(struct atapi_softc *, int8_t [], void *, int32_t, int32_t, int32_t, atapi_callback_t, void *, struct buf *);
diff --git a/sys/dev/ata/atapi-cd.c b/sys/dev/ata/atapi-cd.c
index dbacde7..f35f964 100644
--- a/sys/dev/ata/atapi-cd.c
+++ b/sys/dev/ata/atapi-cd.c
@@ -28,7 +28,6 @@
* $FreeBSD$
*/
-#include "apm.h"
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/kernel.h>
@@ -44,18 +43,15 @@
#include <sys/fcntl.h>
#include <sys/conf.h>
#include <sys/stat.h>
-#if NAPM > 0
-#include <machine/apm_bios.h>
-#endif
#include <dev/ata/ata-all.h>
#include <dev/ata/atapi-all.h>
#include <dev/ata/atapi-cd.h>
+/* device structures */
static d_open_t acdopen;
static d_close_t acdclose;
static d_ioctl_t acdioctl;
static d_strategy_t acdstrategy;
-
static struct cdevsw acd_cdevsw = {
/* open */ acdopen,
/* close */ acdclose,
@@ -75,7 +71,8 @@ static struct cdevsw acd_cdevsw = {
/* prototypes */
int32_t acdattach(struct atapi_softc *);
-static struct acd_softc *acd_init_lun(struct atapi_softc *, int32_t, struct devstat *);
+void acddetach(struct atapi_softc *);
+static struct acd_softc *acd_init_lun(struct atapi_softc *, struct devstat *);
static void acd_describe(struct acd_softc *);
static void lba2msf(int32_t, u_int8_t *, u_int8_t *, u_int8_t *);
static int32_t msf2lba(u_int8_t, u_int8_t, u_int8_t);
@@ -101,6 +98,7 @@ static int32_t acd_mode_select(struct acd_softc *, void *, int32_t);
static int32_t acd_set_speed(struct acd_softc *cdp, int32_t);
/* internal vars */
+static u_int32_t acd_lun_map = 0;
MALLOC_DEFINE(M_ACD, "ACD driver", "ATAPI CD driver buffers");
int
@@ -109,14 +107,14 @@ acdattach(struct atapi_softc *atp)
struct acd_softc *cdp;
struct changer *chp;
int32_t count, error = 0;
- static int32_t acd_cdev_done = 0, acdnlun = 0;
+ static int32_t acd_cdev_done = 0;
if (!acd_cdev_done) {
cdevsw_add(&acd_cdevsw);
acd_cdev_done++;
}
- if ((cdp = acd_init_lun(atp, acdnlun, NULL)) == NULL) {
+ if ((cdp = acd_init_lun(atp, NULL)) == NULL) {
printf("acd: out of memory\n");
return -1;
}
@@ -162,7 +160,7 @@ acdattach(struct atapi_softc *atp)
chp->table_length = htons(chp->table_length);
for (count = 0; count < chp->slots; count++) {
if (count > 0) {
- tmpcdp = acd_init_lun(atp, acdnlun, cdp->stats);
+ tmpcdp = acd_init_lun(atp, cdp->stats);
if (!tmpcdp) {
printf("acd: out of memory\n");
return -1;
@@ -171,9 +169,8 @@ acdattach(struct atapi_softc *atp)
tmpcdp->slot = count;
tmpcdp->changer_info = chp;
if (bootverbose)
- printf("acd%d: changer slot %d %s\n", acdnlun, count,
+ printf("acd%d: changer slot %d %s\n", tmpcdp->lun, count,
(chp->slot[count].present ? "CD present" : "empty"));
- acdnlun++;
}
sprintf(string, "acd%d-", cdp->lun);
devstat_add_entry(cdp->stats, string, tmpcdp->lun, DEV_BSIZE,
@@ -187,51 +184,73 @@ acdattach(struct atapi_softc *atp)
DEVSTAT_NO_ORDERED_TAGS,
DEVSTAT_TYPE_CDROM | DEVSTAT_TYPE_IF_IDE,
DEVSTAT_PRIORITY_CD);
- acdnlun++;
}
acd_describe(cdp);
return 0;
}
+void
+acddetach(struct atapi_softc *atp)
+{
+ struct acd_softc *cdp = atp->driver;
+
+ destroy_dev(cdp->dev1);
+ destroy_dev(cdp->dev2);
+ if (cdp->changer_info) {
+ /* should free all cdp's here, not possible yet SOS XXX */
+ free(cdp->changer_info, M_ACD);
+ }
+ devstat_remove_entry(cdp->stats);
+ free(cdp->stats, M_ACD);
+ free(cdp->atp->devname, M_ACD);
+ ata_free_lun(&acd_lun_map, cdp->lun);
+ free(cdp, M_ACD);
+}
+
static struct acd_softc *
-acd_init_lun(struct atapi_softc *atp, int32_t lun, struct devstat *stats)
+acd_init_lun(struct atapi_softc *atp, struct devstat *stats)
{
- struct acd_softc *acd;
+ struct acd_softc *cdp;
dev_t dev;
- if (!(acd = malloc(sizeof(struct acd_softc), M_ACD, M_NOWAIT)))
+ if (!(cdp = malloc(sizeof(struct acd_softc), M_ACD, M_NOWAIT)))
return NULL;
- bzero(acd, sizeof(struct acd_softc));
- bufq_init(&acd->buf_queue);
- acd->atp = atp;
- acd->lun = lun;
- acd->flags &= ~(F_WRITTEN|F_DISK_OPEN|F_TRACK_OPEN);
- acd->block_size = 2048;
- acd->slot = -1;
- acd->changer_info = NULL;
- acd->atp->flags |= ATAPI_F_MEDIA_CHANGED;
+ bzero(cdp, sizeof(struct acd_softc));
+ bufq_init(&cdp->buf_queue);
+ cdp->atp = atp;
+ cdp->lun = ata_get_lun(&acd_lun_map);
+ cdp->flags &= ~(F_WRITTEN|F_DISK_OPEN|F_TRACK_OPEN);
+ cdp->block_size = 2048;
+ cdp->slot = -1;
+ cdp->changer_info = NULL;
if (stats == NULL) {
- if (!(acd->stats = malloc(sizeof(struct devstat), M_ACD, M_NOWAIT))) {
- free(acd, M_ACD);
+ if (!(cdp->stats = malloc(sizeof(struct devstat), M_ACD, M_NOWAIT))) {
+ free(cdp, M_ACD);
return NULL;
}
- bzero(acd->stats, sizeof(struct devstat));
+ bzero(cdp->stats, sizeof(struct devstat));
}
else
- acd->stats = stats;
- dev = make_dev(&acd_cdevsw, dkmakeminor(lun, 0, 0),
- UID_ROOT, GID_OPERATOR, 0644, "acd%da", lun);
- dev->si_drv1 = acd;
+ cdp->stats = stats;
+
+ cdp->atp->flags |= ATAPI_F_MEDIA_CHANGED;
+ cdp->atp->driver = cdp;
+
+ dev = make_dev(&acd_cdevsw, dkmakeminor(cdp->lun, 0, 0),
+ UID_ROOT, GID_OPERATOR, 0644, "acd%da", cdp->lun);
+ dev->si_drv1 = cdp;
dev->si_iosize_max = 252 * DEV_BSIZE;
dev->si_bsize_phys = 2048; /* XXX SOS */
- dev = make_dev(&acd_cdevsw, dkmakeminor(lun, 0, RAW_PART),
- UID_ROOT, GID_OPERATOR, 0644, "acd%dc", lun);
- dev->si_drv1 = acd;
+ cdp->dev1 = dev;
+ dev = make_dev(&acd_cdevsw, dkmakeminor(cdp->lun, 0, RAW_PART),
+ UID_ROOT, GID_OPERATOR, 0644, "acd%dc", cdp->lun);
+ dev->si_drv1 = cdp;
dev->si_iosize_max = 252 * DEV_BSIZE;
dev->si_bsize_phys = 2048; /* XXX SOS */
- if ((acd->atp->devname = malloc(8, M_ACD, M_NOWAIT)))
- sprintf(acd->atp->devname, "acd%d", acd->lun);
- return acd;
+ cdp->dev2 = dev;
+ if ((cdp->atp->devname = malloc(8, M_ACD, M_NOWAIT)))
+ sprintf(cdp->atp->devname, "acd%d", cdp->lun);
+ return cdp;
}
static void
@@ -249,7 +268,7 @@ acd_describe(struct acd_softc *cdp)
(cdp->cap.write_cdrw) ? "CD-RW" :
(cdp->cap.write_cdr) ? "CD-R" :
(cdp->cap.read_dvdrom) ? "DVD-ROM" : "CDROM",
- cdp->atp->controller->lun,
+ device_get_unit(cdp->atp->controller->dev),
(cdp->atp->unit == ATA_MASTER) ? "master" : "slave");
printf("acd%d:", cdp->lun);
@@ -415,7 +434,7 @@ acd_describe(struct acd_softc *cdp)
(cdp->cap.write_cdr) ? "CD-R" :
(cdp->cap.read_dvdrom) ? "DVD-ROM" : "CDROM",
changer, ATA_PARAM(cdp->atp->controller, cdp->atp->unit)->model,
- cdp->atp->controller->lun,
+ device_get_unit(cdp->atp->controller->dev),
(cdp->atp->unit == ATA_MASTER) ? "master" : "slave",
ata_mode2str(cdp->atp->controller->mode[ATA_DEV(cdp->atp->unit)])
);
@@ -1062,7 +1081,6 @@ acd_start(struct acd_softc *cdp)
}
acd_select_slot(cdp);
-
if (!(bp->b_flags & B_READ) &&
(!(cdp->flags & F_DISK_OPEN) || !(cdp->flags & F_TRACK_OPEN))) {
printf("acd%d: sequence error (no open)\n", cdp->lun);
@@ -1084,7 +1102,7 @@ acd_start(struct acd_softc *cdp)
ccb[0] = ATAPI_READ_BIG;
else {
ccb[0] = ATAPI_READ_CD;
- ccb[9] = 0x10;
+ ccb[9] = 0xf8;
}
}
else
@@ -1108,7 +1126,7 @@ static int32_t
acd_done(struct atapi_request *request)
{
struct buf *bp = request->bp;
- struct acd_softc *cdp = request->driver;
+ struct acd_softc *cdp = request->device->driver;
if (request->error) {
bp->b_error = request->error;
diff --git a/sys/dev/ata/atapi-cd.h b/sys/dev/ata/atapi-cd.h
index 6345ded..2fb760c 100644
--- a/sys/dev/ata/atapi-cd.h
+++ b/sys/dev/ata/atapi-cd.h
@@ -341,4 +341,5 @@ struct acd_softc {
int32_t slot; /* this lun's slot number */
u_int32_t block_size; /* blocksize currently used */
struct devstat *stats; /* devstat entry */
+ dev_t dev1, dev2; /* device place holders */
};
diff --git a/sys/dev/ata/atapi-fd.c b/sys/dev/ata/atapi-fd.c
index df30c26..3423f5b 100644
--- a/sys/dev/ata/atapi-fd.c
+++ b/sys/dev/ata/atapi-fd.c
@@ -28,7 +28,6 @@
* $FreeBSD$
*/
-#include "apm.h"
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/kernel.h>
@@ -40,18 +39,15 @@
#include <sys/disk.h>
#include <sys/devicestat.h>
#include <sys/cdio.h>
-#if NAPM > 0
-#include <machine/apm_bios.h>
-#endif
#include <dev/ata/ata-all.h>
#include <dev/ata/atapi-all.h>
#include <dev/ata/atapi-fd.h>
+/* device structures */
static d_open_t afdopen;
static d_close_t afdclose;
static d_ioctl_t afdioctl;
static d_strategy_t afdstrategy;
-
static struct cdevsw afd_cdevsw = {
/* open */ afdopen,
/* close */ afdclose,
@@ -72,6 +68,7 @@ static struct cdevsw afddisk_cdevsw;
/* prototypes */
int32_t afdattach(struct atapi_softc *);
+void afddetach(struct atapi_softc *);
static int32_t afd_sense(struct afd_softc *);
static void afd_describe(struct afd_softc *);
static void afd_start(struct afd_softc *);
@@ -82,6 +79,7 @@ static int32_t afd_start_stop(struct afd_softc *, int32_t);
static int32_t afd_prevent_allow(struct afd_softc *, int32_t);
/* internal vars */
+static u_int32_t afd_lun_map = 0;
MALLOC_DEFINE(M_AFD, "AFD driver", "ATAPI floppy driver buffers");
int32_t
@@ -89,7 +87,6 @@ afdattach(struct atapi_softc *atp)
{
struct afd_softc *fdp;
dev_t dev;
- static int32_t afdnlun = 0;
fdp = malloc(sizeof(struct afd_softc), M_AFD, M_NOWAIT);
if (!fdp) {
@@ -99,8 +96,9 @@ afdattach(struct atapi_softc *atp)
bzero(fdp, sizeof(struct afd_softc));
bufq_init(&fdp->buf_queue);
fdp->atp = atp;
- fdp->lun = afdnlun++;
+ fdp->lun = ata_get_lun(&afd_lun_map);
fdp->atp->flags |= ATAPI_F_MEDIA_CHANGED;
+ fdp->atp->driver = fdp;
if (afd_sense(fdp)) {
free(fdp, M_AFD);
@@ -118,12 +116,26 @@ afdattach(struct atapi_softc *atp)
dev = disk_create(fdp->lun, &fdp->disk, 0, &afd_cdevsw, &afddisk_cdevsw);
dev->si_drv1 = fdp;
dev->si_iosize_max = 252 * DEV_BSIZE;
+ fdp->dev = dev;
if ((fdp->atp->devname = malloc(8, M_AFD, M_NOWAIT)))
sprintf(fdp->atp->devname, "afd%d", fdp->lun);
afd_describe(fdp);
return 0;
}
+void
+afddetach(struct atapi_softc *atp)
+{
+ struct afd_softc *fdp = atp->driver;
+
+ disk_invalidate(&fdp->disk);
+ disk_destroy(fdp->dev);
+ devstat_remove_entry(&fdp->stats);
+ free(fdp->atp->devname, M_AFD);
+ ata_free_lun(&afd_lun_map, fdp->lun);
+ free(fdp, M_AFD);
+}
+
static int32_t
afd_sense(struct afd_softc *fdp)
{
@@ -160,7 +172,7 @@ afd_describe(struct afd_softc *fdp)
printf("afd%d: <%.40s/%.8s> rewriteable drive at ata%d as %s\n",
fdp->lun, ATA_PARAM(fdp->atp->controller, fdp->atp->unit)->model,
ATA_PARAM(fdp->atp->controller, fdp->atp->unit)->revision,
- fdp->atp->controller->lun,
+ device_get_unit(fdp->atp->controller->dev),
(fdp->atp->unit == ATA_MASTER) ? "master" : "slave");
printf("afd%d: %luMB (%u sectors), %u cyls, %u heads, %u S/T, %u B/S\n",
fdp->lun,
@@ -200,7 +212,7 @@ afd_describe(struct afd_softc *fdp)
((1024L * 1024L) / fdp->cap.sector_size),
ATA_PARAM(fdp->atp->controller, fdp->atp->unit)->model,
fdp->cap.cylinders, fdp->cap.heads, fdp->cap.sectors,
- fdp->atp->controller->lun,
+ device_get_unit(fdp->atp->controller->dev),
(fdp->atp->unit == ATA_MASTER) ? "master" : "slave",
ata_mode2str(fdp->atp->controller->mode[ATA_DEV(fdp->atp->unit)])
);
@@ -364,7 +376,7 @@ static int32_t
afd_done(struct atapi_request *request)
{
struct buf *bp = request->bp;
- struct afd_softc *fdp = request->driver;
+ struct afd_softc *fdp = request->device->driver;
if (request->error || (bp->b_flags & B_ERROR)) {
bp->b_error = request->error;
diff --git a/sys/dev/ata/atapi-fd.h b/sys/dev/ata/atapi-fd.h
index f2c77f0..b141625 100644
--- a/sys/dev/ata/atapi-fd.h
+++ b/sys/dev/ata/atapi-fd.h
@@ -79,5 +79,6 @@ struct afd_softc {
struct afd_cappage cap; /* capabilities page info */
struct disk disk; /* virtual drives */
struct devstat stats;
+ dev_t dev; /* device place holder */
};
diff --git a/sys/dev/ata/atapi-tape.c b/sys/dev/ata/atapi-tape.c
index 71c69ca..9d41648 100644
--- a/sys/dev/ata/atapi-tape.c
+++ b/sys/dev/ata/atapi-tape.c
@@ -28,7 +28,6 @@
* $FreeBSD$
*/
-#include "apm.h"
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/kernel.h>
@@ -39,18 +38,15 @@
#include <sys/mtio.h>
#include <sys/disklabel.h>
#include <sys/devicestat.h>
-#if NAPM > 0
-#include <machine/apm_bios.h>
-#endif
#include <dev/ata/ata-all.h>
#include <dev/ata/atapi-all.h>
#include <dev/ata/atapi-tape.h>
+/* device structures */
static d_open_t astopen;
static d_close_t astclose;
static d_ioctl_t astioctl;
static d_strategy_t aststrategy;
-
static struct cdevsw ast_cdevsw = {
/* open */ astopen,
/* close */ astclose,
@@ -70,6 +66,7 @@ static struct cdevsw ast_cdevsw = {
/* prototypes */
int32_t astattach(struct atapi_softc *);
+void astdetach(struct atapi_softc *);
static int32_t ast_sense(struct ast_softc *);
static void ast_describe(struct ast_softc *);
static void ast_start(struct ast_softc *);
@@ -86,6 +83,7 @@ static int32_t ast_rewind(struct ast_softc *);
static int32_t ast_erase(struct ast_softc *);
/* internal vars */
+static u_int32_t ast_lun_map = 0;
static u_int64_t ast_total = 0;
MALLOC_DEFINE(M_AST, "AST driver", "ATAPI tape driver buffers");
@@ -95,7 +93,7 @@ astattach(struct atapi_softc *atp)
struct ast_softc *stp;
struct ast_readposition position;
dev_t dev;
- static int32_t ast_cdev_done = 0, astnlun = 0;
+ static int32_t ast_cdev_done = 0;
if (!ast_cdev_done) {
cdevsw_add(&ast_cdevsw);
@@ -109,12 +107,14 @@ astattach(struct atapi_softc *atp)
bzero(stp, sizeof(struct ast_softc));
bufq_init(&stp->buf_queue);
stp->atp = atp;
- stp->lun = astnlun++;
- stp->atp->flags |= ATAPI_F_MEDIA_CHANGED;
+ stp->lun = ata_get_lun(&ast_lun_map);
if (ast_sense(stp)) {
free(stp, M_AST);
return -1;
}
+ stp->atp->flags |= ATAPI_F_MEDIA_CHANGED;
+ stp->atp->driver = stp;
+
if (!strcmp(ATA_PARAM(stp->atp->controller, stp->atp->unit)->model,
"OnStream DI-30")) {
struct ast_transferpage transfer;
@@ -139,16 +139,31 @@ astattach(struct atapi_softc *atp)
UID_ROOT, GID_OPERATOR, 0640, "ast%d", stp->lun);
dev->si_drv1 = stp;
dev->si_iosize_max = 252 * DEV_BSIZE;
+ stp->dev1 = dev;
dev = make_dev(&ast_cdevsw, dkmakeminor(stp->lun, 0, 1),
UID_ROOT, GID_OPERATOR, 0640, "nast%d", stp->lun);
dev->si_drv1 = stp;
dev->si_iosize_max = 252 * DEV_BSIZE;
+ stp->dev2 = dev;
if ((stp->atp->devname = malloc(8, M_AST, M_NOWAIT)))
sprintf(stp->atp->devname, "ast%d", stp->lun);
ast_describe(stp);
return 0;
}
+void
+astdetach(struct atapi_softc *atp)
+{
+ struct ast_softc *stp = atp->driver;
+
+ destroy_dev(stp->dev1);
+ destroy_dev(stp->dev2);
+ devstat_remove_entry(&stp->stats);
+ free(stp->atp->devname, M_AST);
+ ata_free_lun(&ast_lun_map, stp->lun);
+ free(stp, M_AST);
+}
+
static int32_t
ast_sense(struct ast_softc *stp)
{
@@ -184,7 +199,7 @@ ast_describe(struct ast_softc *stp)
printf("ast%d: <%.40s/%.8s> tape drive at ata%d as %s\n",
stp->lun, ATA_PARAM(stp->atp->controller, stp->atp->unit)->model,
ATA_PARAM(stp->atp->controller, stp->atp->unit)->revision,
- stp->atp->controller->lun,
+ device_get_unit(stp->atp->controller->dev),
(stp->atp->unit == ATA_MASTER) ? "master" : "slave");
printf("ast%d: ", stp->lun);
printf("%dKB/s, ", stp->cap.max_speed);
@@ -225,7 +240,7 @@ ast_describe(struct ast_softc *stp)
else {
printf("ast%d: TAPE <%.40s> at ata%d-%s using %s\n",
stp->lun, ATA_PARAM(stp->atp->controller, stp->atp->unit)->model,
- stp->atp->controller->lun,
+ device_get_unit(stp->atp->controller->dev),
(stp->atp->unit == ATA_MASTER) ? "master" : "slave",
ata_mode2str(stp->atp->controller->mode[ATA_DEV(stp->atp->unit)])
);
@@ -482,7 +497,7 @@ static int32_t
ast_done(struct atapi_request *request)
{
struct buf *bp = request->bp;
- struct ast_softc *stp = request->driver;
+ struct ast_softc *stp = request->device->driver;
if (request->error) {
bp->b_error = request->error;
diff --git a/sys/dev/ata/atapi-tape.h b/sys/dev/ata/atapi-tape.h
index 98719bf..bccd665 100644
--- a/sys/dev/ata/atapi-tape.h
+++ b/sys/dev/ata/atapi-tape.h
@@ -158,4 +158,5 @@ struct ast_softc {
struct atapi_params *param; /* drive parameters table */
struct ast_cappage cap; /* capabilities page info */
struct devstat stats; /* devstat entry */
+ dev_t dev1, dev2; /* device place holders */
};
diff --git a/sys/kern/subr_disk.c b/sys/kern/subr_disk.c
index fa5eff9..cf1b3cc 100644
--- a/sys/kern/subr_disk.c
+++ b/sys/kern/subr_disk.c
@@ -88,12 +88,15 @@ disk_dumpcheck(dev_t dev, u_int *count, u_int *blkno, u_int *secsize)
void
disk_invalidate (struct disk *disk)
{
- dsgone(&disk->d_slice);
+ if (disk->d_slice)
+ dsgone(&disk->d_slice);
}
void
disk_destroy(dev_t dev)
{
+ dev->si_disk = NULL;
+ destroy_dev(dev);
return;
}
diff --git a/sys/powerpc/include/md_var.h b/sys/powerpc/include/md_var.h
index 42d40f3..bdcba94 100644
--- a/sys/powerpc/include/md_var.h
+++ b/sys/powerpc/include/md_var.h
@@ -57,7 +57,12 @@ int fill_fpregs __P((struct proc *, struct fpreg *));
int set_fpregs __P((struct proc *, struct fpreg *));
void alpha_register_pci_scsi __P((int bus, int slot, struct cam_sim *sim));
#ifdef _SYS_BUS_H_
-int alpha_platform_setup_ide_intr(int chan, driver_intr_t *fn, void *arg);
+struct resource *alpha_platform_alloc_ide_intr(int chan);
+int alpha_platform_release_ide_intr(int chan, struct resource *res);
+int alpha_platform_setup_ide_intr(struct resource *res,
+ driver_intr_t *fn, void *arg,
+ void **cookiep);
+int alpha_platform_teardown_ide_intr(struct resource *res, void *cookie);
#endif
void alpha_platform_assign_pciintr(struct pcicfg *cfg);
OpenPOWER on IntegriCloud