summaryrefslogtreecommitdiffstats
path: root/sys/dev/dpt
diff options
context:
space:
mode:
authormdodd <mdodd@FreeBSD.org>2003-03-29 08:30:45 +0000
committermdodd <mdodd@FreeBSD.org>2003-03-29 08:30:45 +0000
commit17572bf81ce7a80b29d6c0e015977079bcb2b654 (patch)
treef754c77209c0705a05db1aba8a4d86c1fb7c3d37 /sys/dev/dpt
parentebb10b6a3fecd2a638cbcdb52111e82230dd9b66 (diff)
downloadFreeBSD-src-17572bf81ce7a80b29d6c0e015977079bcb2b654.zip
FreeBSD-src-17572bf81ce7a80b29d6c0e015977079bcb2b654.tar.gz
- Track resources in our softc.
- Sanitize dpt_alloc(). - Add helper functions for resource alloc/release. - Add detach method. - Relocate definition of devclass_t. - Move some debugging output behind bootverbose. - Implement an identify method for ISA devices but don't use it right now.
Diffstat (limited to 'sys/dev/dpt')
-rw-r--r--sys/dev/dpt/dpt.h21
-rw-r--r--sys/dev/dpt/dpt_eisa.c59
-rw-r--r--sys/dev/dpt/dpt_isa.c164
-rw-r--r--sys/dev/dpt/dpt_pci.c60
-rw-r--r--sys/dev/dpt/dpt_scsi.c101
5 files changed, 278 insertions, 127 deletions
diff --git a/sys/dev/dpt/dpt.h b/sys/dev/dpt/dpt.h
index 3fb3a1d..6b909a9 100644
--- a/sys/dev/dpt/dpt.h
+++ b/sys/dev/dpt/dpt.h
@@ -51,8 +51,6 @@
#undef DPT_USE_DLM_SWI
-extern u_long dpt_unit;
-
#define DPT_RELEASE 1
#define DPT_VERSION 4
#define DPT_PATCH 5
@@ -1021,6 +1019,19 @@ struct sg_map_node {
/* Main state machine and interface structure */
typedef struct dpt_softc {
+
+ struct resource * io_res;
+ int io_rid;
+ int io_type;
+ int io_offset;
+
+ struct resource * irq_res;
+ int irq_rid;
+ void * ih;
+
+ struct resource * drq_res;
+ int drq_rid;
+
bus_space_tag_t tag;
bus_space_handle_t bsh;
bus_dma_tag_t buffer_dmat; /* dmat for buffer I/O */
@@ -1269,9 +1280,13 @@ dpt_time_delta(struct timeval start,
extern TAILQ_HEAD(dpt_softc_list, dpt_softc) dpt_softcs;
extern int dpt_controllers_present;
+extern devclass_t dpt_devclass;
#ifdef _KERNEL
-dpt_softc_t * dpt_alloc(device_t, bus_space_tag_t, bus_space_handle_t);
+void dpt_alloc(device_t);
+int dpt_detach(device_t);
+int dpt_alloc_resources(device_t);
+void dpt_release_resources(device_t);
#endif
void dpt_free(struct dpt_softc *dpt);
int dpt_init(struct dpt_softc *dpt);
diff --git a/sys/dev/dpt/dpt_eisa.c b/sys/dev/dpt/dpt_eisa.c
index fb2a7fd..1479403 100644
--- a/sys/dev/dpt/dpt_eisa.c
+++ b/sys/dev/dpt/dpt_eisa.c
@@ -43,7 +43,7 @@
#include <dev/dpt/dpt.h>
-#define DPT_EISA_IOSIZE 0x100
+#define DPT_EISA_IOSIZE 0x9
#define DPT_EISA_SLOT_OFFSET 0x0c00
#define DPT_EISA_EATA_REG_OFFSET 0x0088
@@ -67,7 +67,6 @@ static const char * dpt_eisa_match (eisa_id_t);
static int dpt_eisa_probe (device_t);
static int dpt_eisa_attach (device_t);
-
static int
dpt_eisa_probe (device_t dev)
{
@@ -80,9 +79,11 @@ dpt_eisa_probe (device_t dev)
return (ENXIO);
device_set_desc(dev, desc);
- io_base = (eisa_get_slot(dev) * EISA_SLOT_SIZE) + DPT_EISA_SLOT_OFFSET;
+ io_base = (eisa_get_slot(dev) * EISA_SLOT_SIZE) +
+ DPT_EISA_SLOT_OFFSET +
+ DPT_EISA_EATA_REG_OFFSET;
- conf = dpt_pio_get_conf(io_base + DPT_EISA_EATA_REG_OFFSET);
+ conf = dpt_pio_get_conf(io_base);
if (!conf) {
printf("dpt: dpt_pio_get_conf() failed.\n");
return (ENXIO);
@@ -98,37 +99,23 @@ dpt_eisa_probe (device_t dev)
static int
dpt_eisa_attach (device_t dev)
{
- dpt_softc_t * dpt;
- struct resource *io = 0;
- struct resource *irq = 0;
+ dpt_softc_t * dpt;
int s;
- int rid;
- void * ih;
int error = 0;
- rid = 0;
- io = bus_alloc_resource(dev, SYS_RES_IOPORT, &rid, 0, ~0, 1, RF_ACTIVE);
- if (!io) {
- device_printf(dev, "No I/O space?!\n");
- error = ENOMEM;
- goto bad;
- }
+ dpt = device_get_softc(dev);
- rid = 0;
- irq = bus_alloc_resource(dev, SYS_RES_IRQ, &rid, 0, ~0, 1, RF_ACTIVE);
- if (!irq) {
- device_printf(dev, "No irq?!\n");
- error = ENOMEM;
- goto bad;
- }
+ dpt->io_rid = 0;
+ dpt->io_type = SYS_RES_IOPORT;
+ dpt->irq_rid = 0;
- dpt = dpt_alloc(dev, rman_get_bustag(io),
- rman_get_bushandle(io) + DPT_EISA_EATA_REG_OFFSET);
- if (dpt == NULL) {
- error = ENOMEM;
+ error = dpt_alloc_resources(dev);
+ if (error) {
goto bad;
}
+ dpt_alloc(dev);
+
/* Allocate a dmatag representing the capabilities of this attachment */
/* XXX Should be a child of the EISA bus dma tag */
if (bus_dma_tag_create( /* parent */ NULL,
@@ -143,7 +130,6 @@ dpt_eisa_attach (device_t dev)
/* maxsegsz */ BUS_SPACE_MAXSIZE_32BIT,
/* flags */0,
&dpt->parent_dmat) != 0) {
- dpt_free(dpt);
error = ENXIO;
goto bad;
}
@@ -151,7 +137,7 @@ dpt_eisa_attach (device_t dev)
s = splcam();
if (dpt_init(dpt) != 0) {
- dpt_free(dpt);
+ splx(s);
error = ENXIO;
goto bad;
}
@@ -161,8 +147,8 @@ dpt_eisa_attach (device_t dev)
splx(s);
- if (bus_setup_intr(dev, irq, INTR_TYPE_CAM | INTR_ENTROPY, dpt_intr,
- dpt, &ih)) {
+ if (bus_setup_intr(dev, dpt->irq_res, INTR_TYPE_CAM | INTR_ENTROPY,
+ dpt_intr, dpt, &dpt->ih)) {
device_printf(dev, "Unable to register interrupt handler\n");
error = ENXIO;
goto bad;
@@ -171,10 +157,10 @@ dpt_eisa_attach (device_t dev)
return (error);
bad:
- if (io)
- bus_release_resource(dev, SYS_RES_IOPORT, 0, io);
- if (irq)
- bus_release_resource(dev, SYS_RES_IRQ, 0, irq);
+ dpt_release_resources(dev);
+
+ if (dpt)
+ dpt_free(dpt);
return (error);
}
@@ -210,6 +196,7 @@ static device_method_t dpt_eisa_methods[] = {
/* Device interface */
DEVMETHOD(device_probe, dpt_eisa_probe),
DEVMETHOD(device_attach, dpt_eisa_attach),
+ DEVMETHOD(device_detach, dpt_detach),
{ 0, 0 }
};
@@ -220,6 +207,4 @@ static driver_t dpt_eisa_driver = {
sizeof(dpt_softc_t),
};
-static devclass_t dpt_devclass;
-
DRIVER_MODULE(dpt, eisa, dpt_eisa_driver, dpt_devclass, 0, 0);
diff --git a/sys/dev/dpt/dpt_isa.c b/sys/dev/dpt/dpt_isa.c
index 6032ca5..8b0b131 100644
--- a/sys/dev/dpt/dpt_isa.c
+++ b/sys/dev/dpt/dpt_isa.c
@@ -43,8 +43,71 @@
#include <dev/dpt/dpt.h>
+static void dpt_isa_identify (driver_t *, device_t);
static int dpt_isa_probe (device_t);
static int dpt_isa_attach (device_t);
+static int dpt_isa_detach (device_t);
+
+static int dpt_isa_valid_irq (int);
+static int dpt_isa_valid_ioport (int);
+
+static int
+dpt_isa_valid_irq (int irq)
+{
+ switch (irq) {
+ case 11:
+ case 12:
+ case 14:
+ case 15:
+ return (0);
+ default:
+ return (1);
+ };
+ return (1);
+}
+
+static int
+dpt_isa_valid_ioport (int ioport)
+{
+ switch (ioport) {
+ case 0x170:
+ case 0x1f0:
+ case 0x230:
+ case 0x330:
+ return (0);
+ default:
+ return (1);
+ };
+ return (1);
+}
+
+static void
+dpt_isa_identify (driver_t *driver, device_t parent)
+{
+ device_t child;
+ dpt_conf_t * conf;
+ int isa_bases[] = { 0x1f0, 0x170, 0x330, 0x230, 0 };
+ int i;
+
+ for (i = 0; isa_bases[i]; i++) {
+ conf = dpt_pio_get_conf(isa_bases[i]);
+ if (!conf) {
+ if (bootverbose)
+ device_printf(parent, "dpt: dpt_pio_get_conf(%x) failed.\n",
+ isa_bases[i]);
+ continue;
+ }
+
+ child = BUS_ADD_CHILD(parent, ISA_ORDER_SPECULATIVE, "dpt", -1);
+ if (child == 0) {
+ device_printf(parent, "dpt: BUS_ADD_CHILD() failed!\n");
+ continue;
+ }
+ device_set_driver(child, driver);
+ bus_set_resource(child, SYS_RES_IOPORT, 0, isa_bases[i], 0x9);
+ }
+ return;
+}
static int
dpt_isa_probe (device_t dev)
@@ -59,11 +122,17 @@ dpt_isa_probe (device_t dev)
if ((io_base = bus_get_resource_start(dev, SYS_RES_IOPORT, 0)) == 0)
return (ENXIO);
+ if (dpt_isa_valid_ioport(io_base))
+ ;
+
conf = dpt_pio_get_conf(io_base);
- if (!conf) {
- printf("dpt: dpt_pio_get_conf() failed.\n");
- return (ENXIO);
- }
+ if (!conf) {
+ printf("dpt: dpt_pio_get_conf() failed.\n");
+ return (ENXIO);
+ }
+
+ if (dpt_isa_valid_irq(conf->IRQ))
+ ;
device_set_desc(dev, "ISA DPT SCSI controller");
bus_set_resource(dev, SYS_RES_IRQ, 0, conf->IRQ, 1);
@@ -75,52 +144,40 @@ dpt_isa_probe (device_t dev)
static int
dpt_isa_attach (device_t dev)
{
- dpt_softc_t * dpt = NULL;
- struct resource *io = 0;
- struct resource *irq = 0;
- struct resource *drq = 0;
+ dpt_softc_t * dpt;
int s;
- int rid;
- void * ih;
int error = 0;
- rid = 0;
- io = bus_alloc_resource(dev, SYS_RES_IOPORT, &rid, 0, ~0, 1, RF_ACTIVE);
- if (!io) {
- device_printf(dev, "No I/O space?!\n");
- error = ENOMEM;
- goto bad;
- }
+ dpt = device_get_softc(dev);
- rid = 0;
- irq = bus_alloc_resource(dev, SYS_RES_IRQ, &rid, 0, ~0, 1, RF_ACTIVE);
- if (!irq) {
- device_printf(dev, "No IRQ!\n");
- error = ENOMEM;
- goto bad;
- }
- rid = 0;
- drq = bus_alloc_resource(dev, SYS_RES_DRQ, &rid, 0, ~0, 1, RF_ACTIVE);
- if (!drq) {
- device_printf(dev, "No DRQ?!\n");
- error = ENOMEM;
+ dpt->io_rid = 0;
+ dpt->io_type = SYS_RES_IOPORT;
+ dpt->irq_rid = 0;
+
+ error = dpt_alloc_resources(dev);
+ if (error) {
goto bad;
}
- dpt = dpt_alloc(dev, rman_get_bustag(io), rman_get_bushandle(io));
- if (dpt == NULL) {
- error = ENXIO;
+ dpt->drq_rid = 0;
+ dpt->drq_res = bus_alloc_resource(dev, SYS_RES_DRQ, &dpt->drq_rid,
+ 0, ~0, 1, RF_ACTIVE);
+ if (!dpt->drq_res) {
+ device_printf(dev, "No DRQ!\n");
+ error = ENOMEM;
goto bad;
}
+ isa_dma_acquire(rman_get_start(dpt->drq_res));
+ isa_dmacascade(rman_get_start(dpt->drq_res));
- isa_dmacascade(rman_get_start(drq));
+ dpt_alloc(dev);
/* Allocate a dmatag representing the capabilities of this attachment */
if (bus_dma_tag_create( /* parent */ NULL,
/* alignemnt */ 1,
/* boundary */ 0,
- /* lowaddr */ BUS_SPACE_MAXADDR_24BIT,
+ /* lowaddr */ BUS_SPACE_MAXADDR_32BIT,
/* highaddr */ BUS_SPACE_MAXADDR,
/* filter */ NULL,
/* filterarg */ NULL,
@@ -146,8 +203,8 @@ dpt_isa_attach (device_t dev)
splx(s);
- if (bus_setup_intr(dev, irq, INTR_TYPE_CAM | INTR_ENTROPY, dpt_intr,
- dpt, &ih)) {
+ if (bus_setup_intr(dev, dpt->irq_res, INTR_TYPE_CAM | INTR_ENTROPY,
+ dpt_intr, dpt, &dpt->ih)) {
device_printf(dev, "Unable to register interrupt handler\n");
error = ENXIO;
goto bad;
@@ -156,22 +213,43 @@ dpt_isa_attach (device_t dev)
return (error);
bad:
+ if (dpt->drq_res) {
+ isa_dma_release(rman_get_start(dpt->drq_res));
+ }
+
+ dpt_release_resources(dev);
+
if (dpt)
dpt_free(dpt);
- if (io)
- bus_release_resource(dev, SYS_RES_IOPORT, 0, io);
- if (irq)
- bus_release_resource(dev, SYS_RES_IRQ, 0, irq);
- if (drq)
- bus_release_resource(dev, SYS_RES_DRQ, 0, drq);
return (error);
}
+static int
+dpt_isa_detach (device_t dev)
+{
+ dpt_softc_t * dpt;
+ int dma;
+ int error;
+
+ dpt = device_get_softc(dev);
+
+ dma = rman_get_start(dpt->drq_res);
+ error = dpt_detach(dev);
+ isa_dma_release(dma);
+
+ return (error);
+}
+
+
static device_method_t dpt_isa_methods[] = {
/* Device interface */
+#ifdef notyet
+ DEVMETHOD(device_identify, dpt_isa_identify),
+#endif
DEVMETHOD(device_probe, dpt_isa_probe),
DEVMETHOD(device_attach, dpt_isa_attach),
+ DEVMETHOD(device_detach, dpt_isa_detach),
{ 0, 0 }
};
@@ -182,6 +260,4 @@ static driver_t dpt_isa_driver = {
sizeof(dpt_softc_t),
};
-static devclass_t dpt_devclass;
-
DRIVER_MODULE(dpt, isa, dpt_isa_driver, dpt_devclass, 0, 0);
diff --git a/sys/dev/dpt/dpt_pci.c b/sys/dev/dpt/dpt_pci.c
index 90b62fe..88e88da 100644
--- a/sys/dev/dpt/dpt_pci.c
+++ b/sys/dev/dpt/dpt_pci.c
@@ -74,41 +74,43 @@ static int
dpt_pci_attach (device_t dev)
{
dpt_softc_t * dpt;
- struct resource *io = 0;
- struct resource *irq = 0;
int s;
- int rid;
- void * ih;
int error = 0;
- int iotype = 0;
u_int32_t command;
+ dpt = device_get_softc(dev);
+
command = pci_read_config(dev, PCIR_COMMAND, /*bytes*/1);
#ifdef DPT_ALLOW_MMIO
if ((command & PCIM_CMD_MEMEN) != 0) {
- rid = DPT_PCI_MEMADDR;
- iotype = SYS_RES_MEMORY;
- io = bus_alloc_resource(dev, iotype, &rid, 0, ~0, 1, RF_ACTIVE);
+ dpt->io_rid = DPT_PCI_MEMADDR;
+ dpt->io_type = SYS_RES_MEMORY;
+ dpt->io_res = bus_alloc_resource(dev, dpt->io_type,
+ &dpt->io_rid,
+ 0, ~0, 1, RF_ACTIVE);
}
#endif
- if (io == NULL && (command & PCIM_CMD_PORTEN) != 0) {
- rid = DPT_PCI_IOADDR;
- iotype = SYS_RES_IOPORT;
- io = bus_alloc_resource(dev, iotype, &rid, 0, ~0, 1, RF_ACTIVE);
+ if (dpt->io_res == NULL && (command & PCIM_CMD_PORTEN) != 0) {
+ dpt->io_rid = DPT_PCI_IOADDR;
+ dpt->io_type = SYS_RES_IOPORT;
+ dpt->io_res = bus_alloc_resource(dev, dpt->io_type,
+ &dpt->io_rid,
+ 0, ~0, 1, RF_ACTIVE);
}
- if (io == NULL) {
+ if (dpt->io_res == NULL) {
device_printf(dev, "can't allocate register resources\n");
error = ENOMEM;
goto bad;
}
+ dpt->io_offset = 0x10;
- rid = 0;
- irq = bus_alloc_resource(dev, SYS_RES_IRQ, &rid, 0, ~0, 1,
- RF_ACTIVE | RF_SHAREABLE);
- if (!irq) {
+ dpt->irq_rid = 0;
+ dpt->irq_res = bus_alloc_resource(dev, SYS_RES_IRQ, &dpt->irq_rid,
+ 0, ~0, 1, RF_ACTIVE | RF_SHAREABLE);
+ if (dpt->irq_res == NULL) {
device_printf(dev, "No irq?!\n");
error = ENOMEM;
goto bad;
@@ -118,7 +120,7 @@ dpt_pci_attach (device_t dev)
command |= PCIM_CMD_BUSMASTEREN;
pci_write_config(dev, PCIR_COMMAND, command, /*bytes*/1);
- if (rman_get_start(io) == (ISA_PRIMARY_WD_ADDRESS - 0x10)) {
+ if (rman_get_start(dpt->io_res) == (ISA_PRIMARY_WD_ADDRESS - 0x10)) {
#ifdef DPT_DEBUG_WARN
device_printf(dev, "Mapped as an IDE controller. "
"Disabling SCSI setup\n");
@@ -127,12 +129,7 @@ dpt_pci_attach (device_t dev)
goto bad;
}
- /* Device registers are offset 0x10 into the register window. FEH */
- dpt = dpt_alloc(dev, rman_get_bustag(io), rman_get_bushandle(io) + 0x10);
- if (dpt == NULL) {
- error = ENXIO;
- goto bad;
- }
+ dpt_alloc(dev);
/* Allocate a dmatag representing the capabilities of this attachment */
/* XXX Should be a child of the PCI bus dma tag */
@@ -166,8 +163,8 @@ dpt_pci_attach (device_t dev)
splx(s);
- if (bus_setup_intr(dev, irq, INTR_TYPE_CAM | INTR_ENTROPY, dpt_intr,
- dpt, &ih)) {
+ if (bus_setup_intr(dev, dpt->irq_res, INTR_TYPE_CAM | INTR_ENTROPY,
+ dpt_intr, dpt, &dpt->ih)) {
device_printf(dev, "Unable to register interrupt handler\n");
error = ENXIO;
goto bad;
@@ -176,10 +173,10 @@ dpt_pci_attach (device_t dev)
return (error);
bad:
- if (io)
- bus_release_resource(dev, iotype, 0, io);
- if (irq)
- bus_release_resource(dev, SYS_RES_IRQ, 0, irq);
+ dpt_release_resources(dev);
+
+ if (dpt)
+ dpt_free(dpt);
return (error);
}
@@ -188,6 +185,7 @@ static device_method_t dpt_pci_methods[] = {
/* Device interface */
DEVMETHOD(device_probe, dpt_pci_probe),
DEVMETHOD(device_attach, dpt_pci_attach),
+ DEVMETHOD(device_detach, dpt_detach),
{ 0, 0 }
};
@@ -198,6 +196,4 @@ static driver_t dpt_pci_driver = {
sizeof(dpt_softc_t),
};
-static devclass_t dpt_devclass;
-
DRIVER_MODULE(dpt, pci, dpt_pci_driver, dpt_devclass, 0, 0);
diff --git a/sys/dev/dpt/dpt_scsi.c b/sys/dev/dpt/dpt_scsi.c
index f035a8c..922e95b 100644
--- a/sys/dev/dpt/dpt_scsi.c
+++ b/sys/dev/dpt/dpt_scsi.c
@@ -60,6 +60,10 @@
#include <machine/bus_pio.h>
#include <machine/bus.h>
+#include <machine/resource.h>
+#include <sys/rman.h>
+
+#include <machine/clock.h>
#include <cam/cam.h>
#include <cam/cam_ccb.h>
@@ -75,9 +79,8 @@
#include <dev/dpt/dpt.h>
/* dpt_isa.c, dpt_eisa.c, and dpt_pci.c need this in a central place */
-int dpt_controllers_present;
-
-u_long dpt_unit; /* Next unit number to use */
+int dpt_controllers_present;
+devclass_t dpt_devclass;
/* The linked list of softc structures */
struct dpt_softc_list dpt_softcs = TAILQ_HEAD_INITIALIZER(dpt_softcs);
@@ -447,7 +450,8 @@ dpt_pio_get_conf (u_int32_t base)
for (i = 0; i < (sizeof(dpt_conf_t) / 2); i++) {
if (dpt_pio_wait(base, HA_RSTATUS, HA_SDRQ, 0)) {
- printf("dpt: timeout in data read.\n");
+ if (bootverbose)
+ printf("dpt: timeout in data read.\n");
return (NULL);
}
@@ -456,7 +460,8 @@ dpt_pio_get_conf (u_int32_t base)
}
if (inb(base + HA_RSTATUS) & HA_SERROR) {
- printf("dpt: error reading configuration data.\n");
+ if (bootverbose)
+ printf("dpt: error reading configuration data.\n");
return (NULL);
}
@@ -1178,15 +1183,14 @@ dpt_send_eata_command(dpt_softc_t *dpt, eata_ccb_t *cmd_block,
/* ==================== Exported Function definitions =======================*/
-dpt_softc_t *
-dpt_alloc(device_t dev, bus_space_tag_t tag, bus_space_handle_t bsh)
+void
+dpt_alloc(device_t dev)
{
dpt_softc_t *dpt = device_get_softc(dev);
int i;
- bzero(dpt, sizeof(dpt_softc_t));
- dpt->tag = tag;
- dpt->bsh = bsh;
+ dpt->tag = rman_get_bustag(dpt->io_res);
+ dpt->bsh = rman_get_bushandle(dpt->io_res) + dpt->io_offset;
dpt->unit = device_get_unit(dev);
SLIST_INIT(&dpt->free_dccb_list);
LIST_INIT(&dpt->pending_ccb_list);
@@ -1197,7 +1201,7 @@ dpt_alloc(device_t dev, bus_space_tag_t tag, bus_space_handle_t bsh)
#ifdef DPT_MEASURE_PERFORMANCE
dpt_reset_performance(dpt);
#endif /* DPT_MEASURE_PERFORMANCE */
- return (dpt);
+ return;
}
void
@@ -1232,9 +1236,59 @@ dpt_free(struct dpt_softc *dpt)
case 0:
break;
}
+
TAILQ_REMOVE(&dpt_softcs, dpt, links);
}
+int
+dpt_alloc_resources (device_t dev)
+{
+ dpt_softc_t * dpt;
+ int error;
+
+ dpt = device_get_softc(dev);
+
+ dpt->io_res = bus_alloc_resource(dev, dpt->io_type, &dpt->io_rid,
+ 0, ~0, 1, RF_ACTIVE);
+ if (dpt->io_res == NULL) {
+ device_printf(dev, "No I/O space?!\n");
+ error = ENOMEM;
+ goto bad;
+ }
+
+ dpt->irq_res = bus_alloc_resource(dev, SYS_RES_IRQ, &dpt->irq_rid,
+ 0, ~0, 1, RF_ACTIVE);
+ if (dpt->irq_res == NULL) {
+ device_printf(dev, "No IRQ!\n");
+ error = ENOMEM;
+ goto bad;
+ }
+
+ return (0);
+bad:
+ return(error);
+}
+
+
+void
+dpt_release_resources (device_t dev)
+{
+ struct dpt_softc * dpt;
+
+ dpt = device_get_softc(dev);
+
+ if (dpt->ih)
+ bus_teardown_intr(dev, dpt->irq_res, dpt->ih);
+ if (dpt->io_res)
+ bus_release_resource(dev, dpt->io_type, dpt->io_rid, dpt->io_res);
+ if (dpt->irq_res)
+ bus_release_resource(dev, SYS_RES_IRQ, dpt->irq_rid, dpt->irq_res);
+ if (dpt->drq_res)
+ bus_release_resource(dev, SYS_RES_DRQ, dpt->drq_rid, dpt->drq_res);
+
+ return;
+}
+
static u_int8_t string_sizes[] =
{
sizeof(((dpt_inq_t*)NULL)->vendor),
@@ -1522,6 +1576,31 @@ dpt_attach(dpt_softc_t *dpt)
return (i);
}
+int
+dpt_detach (device_t dev)
+{
+ struct dpt_softc * dpt;
+ int i;
+
+ dpt = device_get_softc(dev);
+
+ for (i = 0; i < dpt->channels; i++) {
+#if 0
+ xpt_async(AC_LOST_DEVICE, dpt->paths[i], NULL);
+#endif
+ xpt_free_path(dpt->paths[i]);
+ xpt_bus_deregister(cam_sim_path(dpt->sims[i]));
+ cam_sim_free(dpt->sims[i], /*free_devq*/TRUE);
+ }
+
+ dptshutdown((void *)dpt, SHUTDOWN_PRI_DEFAULT);
+
+ dpt_release_resources(dev);
+
+ dpt_free(dpt);
+
+ return (0);
+}
/*
* This is the interrupt handler for the DPT driver.
OpenPOWER on IntegriCloud