From bb2aebf3ad252165a58525e2f972f955de04d46f Mon Sep 17 00:00:00 2001 From: John Baldwin Date: Thu, 14 May 2009 14:57:13 +0000 Subject: [PATCH] - Add a void pointer to the ata-pci controller softc to allow chipset-specific code to attach chipset-specific data. - Use chipset-specific data in the acard and promise chipsets rather than changing the ivars of ATA PCI devices. ivars are reserved for use by the parent bus driver and are _not_ available for use by devices directly. This fixes a panic during sysctl -a with certain Promise controllers with ACPI enabled. Reviewed by: mav Tested by: Magnus Kling (kingfon @ gmail) (on 7) MFC after: 3 days --- sys/dev/ata/ata-pci.h | 1 + sys/dev/ata/chipsets/ata-acard.c | 38 +++++++++++++++++------------- sys/dev/ata/chipsets/ata-promise.c | 8 +++---- 3 files changed, 26 insertions(+), 21 deletions(-) diff --git a/sys/dev/ata/ata-pci.h b/sys/dev/ata/ata-pci.h index b1f3eb70504..b6c1fd8b364 100644 --- a/sys/dev/ata/ata-pci.h +++ b/sys/dev/ata/ata-pci.h @@ -66,6 +66,7 @@ struct ata_pci_controller { void (*function)(void *); void *argument; } interrupt[8]; /* XXX SOS max ch# for now */ + void *chipset_data; }; /* defines for known chipset PCI id's */ diff --git a/sys/dev/ata/chipsets/ata-acard.c b/sys/dev/ata/chipsets/ata-acard.c index be6043882fd..552c00b6f7c 100644 --- a/sys/dev/ata/chipsets/ata-acard.c +++ b/sys/dev/ata/chipsets/ata-acard.c @@ -51,6 +51,12 @@ __FBSDID("$FreeBSD$"); #include #include +struct ata_serialize { + struct mtx locked_mtx; + int locked_ch; + int restart_ch; +}; + /* local prototypes */ static int ata_acard_chipinit(device_t dev); static int ata_acard_ch_attach(device_t dev); @@ -58,6 +64,7 @@ static int ata_acard_status(device_t dev); static void ata_acard_850_setmode(device_t dev, int mode); static void ata_acard_86X_setmode(device_t dev, int mode); static int ata_serialize(device_t dev, int flags); +static void ata_serialize_init(struct ata_serialize *serial); /* misc defines */ #define ATP_OLD 1 @@ -93,6 +100,7 @@ static int ata_acard_chipinit(device_t dev) { struct ata_pci_controller *ctlr = device_get_softc(dev); + struct ata_serialize *serial; if (ata_setup_interrupt(dev, ata_generic_intr)) return ENXIO; @@ -102,6 +110,10 @@ ata_acard_chipinit(device_t dev) if (ctlr->chip->cfg1 == ATP_OLD) { ctlr->setmode = ata_acard_850_setmode; ctlr->locking = ata_serialize; + serial = malloc(sizeof(struct ata_serialize), + M_TEMP, M_WAITOK | M_ZERO); + ata_serialize_init(serial); + ctlr->chipset_data = serial; } else ctlr->setmode = ata_acard_86X_setmode; @@ -225,11 +237,14 @@ ata_acard_86X_setmode(device_t dev, int mode) /* we could set PIO mode timings, but we assume the BIOS did that */ } -struct ata_serialize { - struct mtx locked_mtx; - int locked_ch; - int restart_ch; -}; +static void +ata_serialize_init(struct ata_serialize *serial) +{ + + mtx_init(&serial->locked_mtx, "ATA serialize lock", NULL, MTX_DEF); + serial->locked_ch = -1; + serial->restart_ch = -1; +} static int ata_serialize(device_t dev, int flags) @@ -237,20 +252,9 @@ ata_serialize(device_t dev, int flags) struct ata_pci_controller *ctlr = device_get_softc(device_get_parent(dev)); struct ata_channel *ch = device_get_softc(dev); struct ata_serialize *serial; - static int inited = 0; int res; - if (!inited) { - serial = malloc(sizeof(struct ata_serialize), - M_TEMP, M_NOWAIT | M_ZERO); - mtx_init(&serial->locked_mtx, "ATA serialize lock", NULL, MTX_DEF); - serial->locked_ch = -1; - serial->restart_ch = -1; - device_set_ivars(ctlr->dev, serial); - inited = 1; - } - else - serial = device_get_ivars(ctlr->dev); + serial = ctlr->chipset_data; mtx_lock(&serial->locked_mtx); switch (flags) { diff --git a/sys/dev/ata/chipsets/ata-promise.c b/sys/dev/ata/chipsets/ata-promise.c index 6b34596fa01..4577ee642a9 100644 --- a/sys/dev/ata/chipsets/ata-promise.c +++ b/sys/dev/ata/chipsets/ata-promise.c @@ -283,7 +283,7 @@ ata_promise_chipinit(device_t dev) mtx_init(&hpkt->mtx, "ATA promise HPKT lock", NULL, MTX_DEF); TAILQ_INIT(&hpkt->queue); hpkt->busy = 0; - device_set_ivars(dev, hpkt); + ctlr->chipset_data = hpkt; ctlr->ch_attach = ata_promise_mio_ch_attach; ctlr->ch_detach = ata_promise_mio_ch_detach; ctlr->reset = ata_promise_mio_reset; @@ -730,7 +730,7 @@ ata_promise_mio_reset(device_t dev) case PR_SX4X: /* softreset channel ATA module */ - hpktp = device_get_ivars(ctlr->dev); + hpktp = ctlr->chipset_data; ATA_OUTL(ctlr->r_res2, 0xc0260 + (ch->unit << 7), ch->unit + 1); ata_udelay(1000); ATA_OUTL(ctlr->r_res2, 0xc0260 + (ch->unit << 7), @@ -1208,7 +1208,7 @@ ata_promise_apkt(u_int8_t *bytep, struct ata_request *request) static void ata_promise_queue_hpkt(struct ata_pci_controller *ctlr, u_int32_t hpkt) { - struct ata_promise_sx4 *hpktp = device_get_ivars(ctlr->dev); + struct ata_promise_sx4 *hpktp = ctlr->chipset_data; mtx_lock(&hpktp->mtx); if (hpktp->busy) { @@ -1227,7 +1227,7 @@ ata_promise_queue_hpkt(struct ata_pci_controller *ctlr, u_int32_t hpkt) static void ata_promise_next_hpkt(struct ata_pci_controller *ctlr) { - struct ata_promise_sx4 *hpktp = device_get_ivars(ctlr->dev); + struct ata_promise_sx4 *hpktp = ctlr->chipset_data; struct host_packet *hp; mtx_lock(&hpktp->mtx);