diff options
author | mdodd <mdodd@FreeBSD.org> | 2003-03-29 08:30:45 +0000 |
---|---|---|
committer | mdodd <mdodd@FreeBSD.org> | 2003-03-29 08:30:45 +0000 |
commit | 17572bf81ce7a80b29d6c0e015977079bcb2b654 (patch) | |
tree | f754c77209c0705a05db1aba8a4d86c1fb7c3d37 /sys/dev/dpt | |
parent | ebb10b6a3fecd2a638cbcdb52111e82230dd9b66 (diff) | |
download | FreeBSD-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.h | 21 | ||||
-rw-r--r-- | sys/dev/dpt/dpt_eisa.c | 59 | ||||
-rw-r--r-- | sys/dev/dpt/dpt_isa.c | 164 | ||||
-rw-r--r-- | sys/dev/dpt/dpt_pci.c | 60 | ||||
-rw-r--r-- | sys/dev/dpt/dpt_scsi.c | 101 |
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. |