- 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
This commit is contained in:
parent
3af3ff479b
commit
bb2aebf3ad
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=192105
@ -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 */
|
||||
|
@ -51,6 +51,12 @@ __FBSDID("$FreeBSD$");
|
||||
#include <dev/ata/ata-pci.h>
|
||||
#include <ata_if.h>
|
||||
|
||||
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) {
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user