Switch to using suspend/resume methods rather than the APM hooks.
Should have no effect, but does make things a little cleaner. I thought this was the race that was causing problems, but it turned out to be in pccardd waking up after the empty/insert events had happened and being confused. Minor cleanup: o Remove isahd from pccard_devinfo o remove extra from controller o formatting nits o use PCCARD_DEVINFO(d) rather than a bare device_get_ivars(d)
This commit is contained in:
parent
f077fb2703
commit
d95b5da991
@ -51,11 +51,6 @@
|
|||||||
#include <i386/isa/icu.h>
|
#include <i386/isa/icu.h>
|
||||||
#include <i386/isa/intr_machdep.h>
|
#include <i386/isa/intr_machdep.h>
|
||||||
|
|
||||||
#include "apm.h"
|
|
||||||
#if NAPM > 0
|
|
||||||
#include <machine/apm_bios.h>
|
|
||||||
#endif /* NAPM > 0 */
|
|
||||||
|
|
||||||
#include <pccard/cardinfo.h>
|
#include <pccard/cardinfo.h>
|
||||||
#include <pccard/driver.h>
|
#include <pccard/driver.h>
|
||||||
#include <pccard/pcic.h>
|
#include <pccard/pcic.h>
|
||||||
@ -98,19 +93,6 @@ static void disable_slot_to(void *);
|
|||||||
static int invalid_io_memory(unsigned long, int);
|
static int invalid_io_memory(unsigned long, int);
|
||||||
static void power_off_slot(void *);
|
static void power_off_slot(void *);
|
||||||
|
|
||||||
#if NAPM > 0
|
|
||||||
/*
|
|
||||||
* For the APM stuff, the apmhook structure is kept
|
|
||||||
* separate from the slot structure so that the slot
|
|
||||||
* drivers do not need to know about the hooks (or the
|
|
||||||
* data structures).
|
|
||||||
*/
|
|
||||||
static int slot_suspend(void *arg);
|
|
||||||
static int slot_resume(void *arg);
|
|
||||||
static struct apmhook s_hook[MAXSLOT]; /* APM suspend */
|
|
||||||
static struct apmhook r_hook[MAXSLOT]; /* APM resume */
|
|
||||||
#endif /* NAPM > 0 */
|
|
||||||
|
|
||||||
static struct slot *pccard_slots[MAXSLOT]; /* slot entries */
|
static struct slot *pccard_slots[MAXSLOT]; /* slot entries */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -223,55 +205,6 @@ disable_slot_spl0(struct slot *slt)
|
|||||||
slt->disable_ch = timeout(disable_slot_to, (caddr_t) slt, 0);
|
slt->disable_ch = timeout(disable_slot_to, (caddr_t) slt, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* APM hooks for suspending and resuming.
|
|
||||||
*/
|
|
||||||
#if NAPM > 0
|
|
||||||
static int
|
|
||||||
slot_suspend(void *arg)
|
|
||||||
{
|
|
||||||
struct slot *slt = arg;
|
|
||||||
|
|
||||||
/* This code stolen from pccard_event:card_removed */
|
|
||||||
if (slt->state == filled) {
|
|
||||||
int s = splhigh();
|
|
||||||
disable_slot(slt);
|
|
||||||
slt->laststate = filled;
|
|
||||||
slt->state = suspend;
|
|
||||||
splx(s);
|
|
||||||
printf("pccard: card disabled, slot %d\n", slt->slotnum);
|
|
||||||
}
|
|
||||||
/*
|
|
||||||
* Disable any pending timeouts for this slot since we're
|
|
||||||
* powering it down/disabling now.
|
|
||||||
*/
|
|
||||||
untimeout(power_off_slot, (caddr_t)slt, slt->disable_ch);
|
|
||||||
untimeout(power_off_slot, (caddr_t)slt, slt->poff_ch);
|
|
||||||
slt->ctrl->disable(slt);
|
|
||||||
return (0);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
slot_resume(void *arg)
|
|
||||||
{
|
|
||||||
struct slot *slt = arg;
|
|
||||||
|
|
||||||
if (pcic_resume_reset)
|
|
||||||
slt->ctrl->resume(slt);
|
|
||||||
/* This code stolen from pccard_event:card_inserted */
|
|
||||||
if (slt->state == suspend) {
|
|
||||||
slt->laststate = suspend;
|
|
||||||
slt->state = empty;
|
|
||||||
slt->insert_seq = 1;
|
|
||||||
untimeout(inserted, (void *)slt, slt->insert_ch);
|
|
||||||
inserted((void *) slt);
|
|
||||||
selwakeup(&slt->selp);
|
|
||||||
}
|
|
||||||
return (0);
|
|
||||||
}
|
|
||||||
#endif /* NAPM > 0 */
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* pccard_alloc_slot - Called from controller probe
|
* pccard_alloc_slot - Called from controller probe
|
||||||
* routine, this function allocates a new PC-CARD slot
|
* routine, this function allocates a new PC-CARD slot
|
||||||
@ -294,44 +227,12 @@ pccard_alloc_slot(struct slot_ctrl *ctrl)
|
|||||||
MALLOC(slt, struct slot *, sizeof(*slt), M_DEVBUF, M_WAITOK);
|
MALLOC(slt, struct slot *, sizeof(*slt), M_DEVBUF, M_WAITOK);
|
||||||
bzero(slt, sizeof(*slt));
|
bzero(slt, sizeof(*slt));
|
||||||
make_dev(&crd_cdevsw, slotno, 0, 0, 0600, "card%d", slotno);
|
make_dev(&crd_cdevsw, slotno, 0, 0, 0600, "card%d", slotno);
|
||||||
if (ctrl->extra) {
|
|
||||||
MALLOC(slt->cdata, void *, ctrl->extra, M_DEVBUF, M_WAITOK);
|
|
||||||
bzero(slt->cdata, ctrl->extra);
|
|
||||||
}
|
|
||||||
slt->ctrl = ctrl;
|
slt->ctrl = ctrl;
|
||||||
slt->slotnum = slotno;
|
slt->slotnum = slotno;
|
||||||
pccard_slots[slotno] = slt;
|
pccard_slots[slotno] = slt;
|
||||||
/*
|
|
||||||
* If this controller hasn't been seen before, then
|
|
||||||
* link it into the list of controllers.
|
|
||||||
*/
|
|
||||||
if (ctrl->slots++ == 0) {
|
|
||||||
if (ctrl->maxmem > NUM_MEM_WINDOWS)
|
|
||||||
ctrl->maxmem = NUM_MEM_WINDOWS;
|
|
||||||
if (ctrl->maxio > NUM_IO_WINDOWS)
|
|
||||||
ctrl->maxio = NUM_IO_WINDOWS;
|
|
||||||
}
|
|
||||||
callout_handle_init(&slt->insert_ch);
|
callout_handle_init(&slt->insert_ch);
|
||||||
callout_handle_init(&slt->poff_ch);
|
callout_handle_init(&slt->poff_ch);
|
||||||
callout_handle_init(&slt->disable_ch);
|
callout_handle_init(&slt->disable_ch);
|
||||||
#if NAPM > 0
|
|
||||||
{
|
|
||||||
struct apmhook *ap;
|
|
||||||
|
|
||||||
ap = &s_hook[slt->slotnum];
|
|
||||||
ap->ah_fun = slot_suspend;
|
|
||||||
ap->ah_arg = (void *)slt;
|
|
||||||
ap->ah_name = "pcccard";
|
|
||||||
ap->ah_order = APM_MID_ORDER;
|
|
||||||
apm_hook_establish(APM_HOOK_SUSPEND, ap);
|
|
||||||
ap = &r_hook[slt->slotnum];
|
|
||||||
ap->ah_fun = slot_resume;
|
|
||||||
ap->ah_arg = (void *)slt;
|
|
||||||
ap->ah_name = "pccard";
|
|
||||||
ap->ah_order = APM_MID_ORDER;
|
|
||||||
apm_hook_establish(APM_HOOK_RESUME, ap);
|
|
||||||
}
|
|
||||||
#endif /* NAPM > 0 */
|
|
||||||
return(slt);
|
return(slt);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -359,8 +260,7 @@ allocate_driver(struct slot *slt, struct dev_desc *desc)
|
|||||||
devi->slt = slt;
|
devi->slt = slt;
|
||||||
bcopy(desc->misc, devi->misc, sizeof(desc->misc));
|
bcopy(desc->misc, devi->misc, sizeof(desc->misc));
|
||||||
resource_list_init(&devi->resources);
|
resource_list_init(&devi->resources);
|
||||||
child = devi->isahd.id_device = device_add_child(pccarddev, devi->name,
|
child = device_add_child(pccarddev, devi->name, desc->unit);
|
||||||
desc->unit);
|
|
||||||
device_set_flags(child, desc->flags);
|
device_set_flags(child, desc->flags);
|
||||||
device_set_ivars(child, devi);
|
device_set_ivars(child, devi);
|
||||||
err = bus_set_resource(child, SYS_RES_IOPORT, 0, desc->iobase,
|
err = bus_set_resource(child, SYS_RES_IOPORT, 0, desc->iobase,
|
||||||
@ -774,3 +674,55 @@ invalid_io_memory(unsigned long adr, int size)
|
|||||||
return(1);
|
return(1);
|
||||||
return(0);
|
return(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static struct slot *
|
||||||
|
pccard_dev2slot(device_t dev)
|
||||||
|
{
|
||||||
|
return pccard_slots[device_get_unit(dev)];
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* APM hooks for suspending and resuming.
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
pccard_suspend(device_t dev)
|
||||||
|
{
|
||||||
|
struct slot *slt = pccard_dev2slot(dev);
|
||||||
|
|
||||||
|
/* This code stolen from pccard_event:card_removed */
|
||||||
|
if (slt->state == filled) {
|
||||||
|
int s = splhigh();
|
||||||
|
disable_slot(slt);
|
||||||
|
slt->laststate = filled;
|
||||||
|
slt->state = suspend;
|
||||||
|
splx(s);
|
||||||
|
printf("pccard: card disabled, slot %d\n", slt->slotnum);
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* Disable any pending timeouts for this slot since we're
|
||||||
|
* powering it down/disabling now.
|
||||||
|
*/
|
||||||
|
untimeout(power_off_slot, (caddr_t)slt, slt->disable_ch);
|
||||||
|
untimeout(power_off_slot, (caddr_t)slt, slt->poff_ch);
|
||||||
|
slt->ctrl->disable(slt);
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
pccard_resume(device_t dev)
|
||||||
|
{
|
||||||
|
struct slot *slt = pccard_dev2slot(dev);
|
||||||
|
|
||||||
|
if (pcic_resume_reset)
|
||||||
|
slt->ctrl->resume(slt);
|
||||||
|
/* This code stolen from pccard_event:card_inserted */
|
||||||
|
if (slt->state == suspend) {
|
||||||
|
slt->laststate = suspend;
|
||||||
|
slt->state = empty;
|
||||||
|
slt->insert_seq = 1;
|
||||||
|
untimeout(inserted, (void *)slt, slt->insert_ch);
|
||||||
|
inserted((void *) slt);
|
||||||
|
selwakeup(&slt->selp);
|
||||||
|
}
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
@ -77,6 +77,8 @@ devclass_t pccard_devclass;
|
|||||||
#define PCCARD_NIRQ 1
|
#define PCCARD_NIRQ 1
|
||||||
#define PCCARD_NDRQ 0
|
#define PCCARD_NDRQ 0
|
||||||
|
|
||||||
|
#define PCCARD_DEVINFO(d) (struct pccard_devinfo *) device_get_ivars(d)
|
||||||
|
|
||||||
static int
|
static int
|
||||||
pccard_probe(device_t dev)
|
pccard_probe(device_t dev)
|
||||||
{
|
{
|
||||||
@ -86,7 +88,7 @@ pccard_probe(device_t dev)
|
|||||||
|
|
||||||
static void
|
static void
|
||||||
pccard_print_resources(struct resource_list *rl, const char *name, int type,
|
pccard_print_resources(struct resource_list *rl, const char *name, int type,
|
||||||
int count, const char *format)
|
int count, const char *format)
|
||||||
{
|
{
|
||||||
struct resource_list_entry *rle;
|
struct resource_list_entry *rle;
|
||||||
int printed;
|
int printed;
|
||||||
@ -116,7 +118,7 @@ pccard_print_resources(struct resource_list *rl, const char *name, int type,
|
|||||||
static int
|
static int
|
||||||
pccard_print_child(device_t dev, device_t child)
|
pccard_print_child(device_t dev, device_t child)
|
||||||
{
|
{
|
||||||
struct pccard_devinfo *devi = device_get_ivars(child);
|
struct pccard_devinfo *devi = PCCARD_DEVINFO(child);
|
||||||
struct resource_list *rl = &devi->resources;
|
struct resource_list *rl = &devi->resources;
|
||||||
int retval = 0;
|
int retval = 0;
|
||||||
|
|
||||||
@ -144,7 +146,7 @@ static int
|
|||||||
pccard_set_resource(device_t dev, device_t child, int type, int rid,
|
pccard_set_resource(device_t dev, device_t child, int type, int rid,
|
||||||
u_long start, u_long count)
|
u_long start, u_long count)
|
||||||
{
|
{
|
||||||
struct pccard_devinfo *devi = device_get_ivars(child);
|
struct pccard_devinfo *devi = PCCARD_DEVINFO(child);
|
||||||
struct resource_list *rl = &devi->resources;
|
struct resource_list *rl = &devi->resources;
|
||||||
|
|
||||||
if (type != SYS_RES_IOPORT && type != SYS_RES_MEMORY
|
if (type != SYS_RES_IOPORT && type != SYS_RES_MEMORY
|
||||||
@ -170,7 +172,7 @@ static int
|
|||||||
pccard_get_resource(device_t dev, device_t child, int type, int rid,
|
pccard_get_resource(device_t dev, device_t child, int type, int rid,
|
||||||
u_long *startp, u_long *countp)
|
u_long *startp, u_long *countp)
|
||||||
{
|
{
|
||||||
struct pccard_devinfo *devi = device_get_ivars(child);
|
struct pccard_devinfo *devi = PCCARD_DEVINFO(child);
|
||||||
struct resource_list *rl = &devi->resources;
|
struct resource_list *rl = &devi->resources;
|
||||||
struct resource_list_entry *rle;
|
struct resource_list_entry *rle;
|
||||||
|
|
||||||
@ -189,7 +191,7 @@ pccard_get_resource(device_t dev, device_t child, int type, int rid,
|
|||||||
static void
|
static void
|
||||||
pccard_delete_resource(device_t dev, device_t child, int type, int rid)
|
pccard_delete_resource(device_t dev, device_t child, int type, int rid)
|
||||||
{
|
{
|
||||||
struct pccard_devinfo *devi = device_get_ivars(child);
|
struct pccard_devinfo *devi = PCCARD_DEVINFO(child);
|
||||||
struct resource_list *rl = &devi->resources;
|
struct resource_list *rl = &devi->resources;
|
||||||
resource_list_delete(rl, type, rid);
|
resource_list_delete(rl, type, rid);
|
||||||
}
|
}
|
||||||
@ -245,7 +247,7 @@ static int
|
|||||||
pccard_release_resource(device_t bus, device_t child, int type, int rid,
|
pccard_release_resource(device_t bus, device_t child, int type, int rid,
|
||||||
struct resource *r)
|
struct resource *r)
|
||||||
{
|
{
|
||||||
struct pccard_devinfo *devi = device_get_ivars(child);
|
struct pccard_devinfo *devi = PCCARD_DEVINFO(child);
|
||||||
struct resource_list *rl = &devi->resources;
|
struct resource_list *rl = &devi->resources;
|
||||||
return resource_list_release(rl, bus, child, type, rid, r);
|
return resource_list_release(rl, bus, child, type, rid, r);
|
||||||
}
|
}
|
||||||
@ -255,8 +257,8 @@ static device_method_t pccard_methods[] = {
|
|||||||
DEVMETHOD(device_probe, pccard_probe),
|
DEVMETHOD(device_probe, pccard_probe),
|
||||||
DEVMETHOD(device_attach, bus_generic_attach),
|
DEVMETHOD(device_attach, bus_generic_attach),
|
||||||
DEVMETHOD(device_shutdown, bus_generic_shutdown),
|
DEVMETHOD(device_shutdown, bus_generic_shutdown),
|
||||||
DEVMETHOD(device_suspend, bus_generic_suspend),
|
DEVMETHOD(device_suspend, pccard_suspend),
|
||||||
DEVMETHOD(device_resume, bus_generic_resume),
|
DEVMETHOD(device_resume, pccard_resume),
|
||||||
|
|
||||||
/* Bus interface */
|
/* Bus interface */
|
||||||
DEVMETHOD(bus_print_child, pccard_print_child),
|
DEVMETHOD(bus_print_child, pccard_print_child),
|
||||||
@ -271,7 +273,6 @@ static device_method_t pccard_methods[] = {
|
|||||||
DEVMETHOD(bus_get_resource, pccard_get_resource),
|
DEVMETHOD(bus_get_resource, pccard_get_resource),
|
||||||
DEVMETHOD(bus_delete_resource, pccard_delete_resource),
|
DEVMETHOD(bus_delete_resource, pccard_delete_resource),
|
||||||
|
|
||||||
|
|
||||||
{ 0, 0 }
|
{ 0, 0 }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -69,7 +69,6 @@ struct slot_ctrl {
|
|||||||
/* Map interrupt number */
|
/* Map interrupt number */
|
||||||
void (*resume) __P((struct slot *));
|
void (*resume) __P((struct slot *));
|
||||||
/* suspend/resume support */
|
/* suspend/resume support */
|
||||||
int extra; /* Controller specific size */
|
|
||||||
int maxmem; /* Number of allowed memory windows */
|
int maxmem; /* Number of allowed memory windows */
|
||||||
int maxio; /* Number of allowed I/O windows */
|
int maxio; /* Number of allowed I/O windows */
|
||||||
|
|
||||||
@ -89,7 +88,6 @@ struct slot_ctrl {
|
|||||||
*/
|
*/
|
||||||
struct pccard_devinfo {
|
struct pccard_devinfo {
|
||||||
u_char name[128];
|
u_char name[128];
|
||||||
struct isa_device isahd;
|
|
||||||
int running; /* Current state of driver */
|
int running; /* Current state of driver */
|
||||||
u_char misc[128]; /* For any random info */
|
u_char misc[128]; /* For any random info */
|
||||||
struct slot *slt; /* Back pointer to slot */
|
struct slot *slt; /* Back pointer to slot */
|
||||||
@ -128,5 +126,7 @@ enum card_event { card_removed, card_inserted };
|
|||||||
|
|
||||||
struct slot *pccard_alloc_slot(struct slot_ctrl *);
|
struct slot *pccard_alloc_slot(struct slot_ctrl *);
|
||||||
void pccard_event(struct slot *, enum card_event);
|
void pccard_event(struct slot *, enum card_event);
|
||||||
|
int pccard_suspend(device_t);
|
||||||
|
int pccard_resume(device_t);
|
||||||
|
|
||||||
#endif /* !_PCCARD_SLOT_H */
|
#endif /* !_PCCARD_SLOT_H */
|
||||||
|
Loading…
x
Reference in New Issue
Block a user