- 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.
This commit is contained in:
Matthew N. Dodd 2003-03-29 08:30:45 +00:00
parent cb3b23ef1e
commit 4ada039b14
5 changed files with 283 additions and 132 deletions

View File

@ -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);

View File

@ -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,36 +99,22 @@ 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;
dpt = device_get_softc(dev);
dpt->io_rid = 0;
dpt->io_type = SYS_RES_IOPORT;
dpt->irq_rid = 0;
error = dpt_alloc_resources(dev);
if (error) {
goto bad;
}
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 = dpt_alloc(dev, rman_get_bustag(io),
rman_get_bushandle(io) + DPT_EISA_EATA_REG_OFFSET);
if (dpt == NULL) {
error = ENOMEM;
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 */
@ -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);

View File

@ -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");
dpt = device_get_softc(dev);
dpt->io_rid = 0;
dpt->io_type = SYS_RES_IOPORT;
dpt->irq_rid = 0;
error = dpt_alloc_resources(dev);
if (error) {
goto bad;
}
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));
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;
goto bad;
}
dpt = dpt_alloc(dev, rman_get_bustag(io), rman_get_bushandle(io));
if (dpt == NULL) {
error = ENXIO;
goto bad;
}
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);

View File

@ -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);

View File

@ -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.