Adds the APM hooks into the generic pccard kernel files. With this code
in place device drivers can now register power-down/power-up routines so that we can use common routines to power-up/power-down cards for insert/removals, suspend/resume, etc.. Reviewed by: phk Submitted by: the 'Nomads'
This commit is contained in:
parent
ceb677462b
commit
298d7dcd87
@ -14,7 +14,7 @@
|
|||||||
*
|
*
|
||||||
* Sep, 1994 Implemented on FreeBSD 1.1.5.1R (Toshiba AVS001WD)
|
* Sep, 1994 Implemented on FreeBSD 1.1.5.1R (Toshiba AVS001WD)
|
||||||
*
|
*
|
||||||
* $Id: apm.c,v 1.38 1996/04/18 19:21:47 nate Exp $
|
* $Id: apm.c,v 1.39 1996/04/22 19:40:18 nate Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "apm.h"
|
#include "apm.h"
|
||||||
@ -356,7 +356,6 @@ apm_hook_establish(int apmh, struct apmhook *ah)
|
|||||||
return apm_add_hook(&hook[apmh], ah);
|
return apm_add_hook(&hook[apmh], ah);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef notused
|
|
||||||
/* disestablish an apm hook */
|
/* disestablish an apm hook */
|
||||||
void
|
void
|
||||||
apm_hook_disestablish(int apmh, struct apmhook *ah)
|
apm_hook_disestablish(int apmh, struct apmhook *ah)
|
||||||
@ -366,7 +365,6 @@ apm_hook_disestablish(int apmh, struct apmhook *ah)
|
|||||||
|
|
||||||
apm_del_hook(&hook[apmh], ah);
|
apm_del_hook(&hook[apmh], ah);
|
||||||
}
|
}
|
||||||
#endif /* notused */
|
|
||||||
|
|
||||||
|
|
||||||
static struct timeval suspend_time;
|
static struct timeval suspend_time;
|
||||||
|
@ -14,7 +14,7 @@
|
|||||||
*
|
*
|
||||||
* Sep, 1994 Implemented on FreeBSD 1.1.5.1R (Toshiba AVS001WD)
|
* Sep, 1994 Implemented on FreeBSD 1.1.5.1R (Toshiba AVS001WD)
|
||||||
*
|
*
|
||||||
* $Id: apm.c,v 1.38 1996/04/18 19:21:47 nate Exp $
|
* $Id: apm.c,v 1.39 1996/04/22 19:40:18 nate Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "apm.h"
|
#include "apm.h"
|
||||||
@ -356,7 +356,6 @@ apm_hook_establish(int apmh, struct apmhook *ah)
|
|||||||
return apm_add_hook(&hook[apmh], ah);
|
return apm_add_hook(&hook[apmh], ah);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef notused
|
|
||||||
/* disestablish an apm hook */
|
/* disestablish an apm hook */
|
||||||
void
|
void
|
||||||
apm_hook_disestablish(int apmh, struct apmhook *ah)
|
apm_hook_disestablish(int apmh, struct apmhook *ah)
|
||||||
@ -366,7 +365,6 @@ apm_hook_disestablish(int apmh, struct apmhook *ah)
|
|||||||
|
|
||||||
apm_del_hook(&hook[apmh], ah);
|
apm_del_hook(&hook[apmh], ah);
|
||||||
}
|
}
|
||||||
#endif /* notused */
|
|
||||||
|
|
||||||
|
|
||||||
static struct timeval suspend_time;
|
static struct timeval suspend_time;
|
||||||
|
@ -12,7 +12,7 @@
|
|||||||
*
|
*
|
||||||
* Aug, 1994 Implemented on FreeBSD 1.1.5.1R (Toshiba AVS001WD)
|
* Aug, 1994 Implemented on FreeBSD 1.1.5.1R (Toshiba AVS001WD)
|
||||||
*
|
*
|
||||||
* $Id: apm_bios.h,v 1.8 1996/03/12 05:51:35 nate Exp $
|
* $Id: apm_bios.h,v 1.9 1996/03/13 00:41:45 nate Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef _MACHINE_APM_BIOS_H_
|
#ifndef _MACHINE_APM_BIOS_H_
|
||||||
@ -135,9 +135,7 @@ struct apmhook {
|
|||||||
|
|
||||||
void apm_suspend(void);
|
void apm_suspend(void);
|
||||||
struct apmhook *apm_hook_establish (int apmh, struct apmhook *);
|
struct apmhook *apm_hook_establish (int apmh, struct apmhook *);
|
||||||
#ifdef notused
|
|
||||||
void apm_hook_disestablish (int apmh, struct apmhook *);
|
void apm_hook_disestablish (int apmh, struct apmhook *);
|
||||||
#endif
|
|
||||||
void apm_cpu_idle(void);
|
void apm_cpu_idle(void);
|
||||||
void apm_cpu_busy(void);
|
void apm_cpu_busy(void);
|
||||||
|
|
||||||
|
@ -54,6 +54,11 @@
|
|||||||
#include <i386/isa/isa_device.h>
|
#include <i386/isa/isa_device.h>
|
||||||
#include <i386/isa/icu.h>
|
#include <i386/isa/icu.h>
|
||||||
|
|
||||||
|
#include "apm.h"
|
||||||
|
#if NAPM > 0
|
||||||
|
#include <machine/apm_bios.h>
|
||||||
|
#endif /* NAPM > 0 */
|
||||||
|
|
||||||
#include <pccard/card.h>
|
#include <pccard/card.h>
|
||||||
#include <pccard/driver.h>
|
#include <pccard/driver.h>
|
||||||
#include <pccard/slot.h>
|
#include <pccard/slot.h>
|
||||||
@ -82,6 +87,20 @@ static int invalid_io_memory(unsigned long, int);
|
|||||||
static struct pccard_drv *find_driver(char *);
|
static struct pccard_drv *find_driver(char *);
|
||||||
static void remove_device(struct pccard_dev *);
|
static void remove_device(struct pccard_dev *);
|
||||||
static void slot_irq_handler(int);
|
static void slot_irq_handler(int);
|
||||||
|
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 */
|
||||||
static struct slot *slot_list;
|
static struct slot *slot_list;
|
||||||
@ -221,6 +240,12 @@ pccard_remove_controller(struct slot_ctrl *cp)
|
|||||||
last->next = next;
|
last->next = next;
|
||||||
else
|
else
|
||||||
slot_list = next;
|
slot_list = next;
|
||||||
|
#if NAPM > 0
|
||||||
|
apm_hook_disestablish(APM_HOOK_SUSPEND,
|
||||||
|
&s_hook[sp->slot]);
|
||||||
|
apm_hook_disestablish(APM_HOOK_RESUME,
|
||||||
|
&r_hook[sp->slot]);
|
||||||
|
#endif
|
||||||
if (cp->extra && sp->cdata)
|
if (cp->extra && sp->cdata)
|
||||||
FREE(sp->cdata, M_DEVBUF);
|
FREE(sp->cdata, M_DEVBUF);
|
||||||
FREE(sp, M_DEVBUF);
|
FREE(sp, M_DEVBUF);
|
||||||
@ -244,6 +269,21 @@ pccard_remove_controller(struct slot_ctrl *cp)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Power off the slot.
|
||||||
|
* (doing it immediately makes the removal of some cards unstable)
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
power_off_slot(void *arg)
|
||||||
|
{
|
||||||
|
struct slot *sp = (struct slot *)arg;
|
||||||
|
|
||||||
|
sp->pwr_off_pending = 0;
|
||||||
|
|
||||||
|
/* Power off the slot. */
|
||||||
|
sp->ctrl->disable(sp);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* disable_slot - Disables the slot by removing
|
* disable_slot - Disables the slot by removing
|
||||||
* the power and unmapping the I/O
|
* the power and unmapping the I/O
|
||||||
@ -282,7 +322,8 @@ disable_slot(struct slot *sp)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* Power off the slot. */
|
/* Power off the slot. */
|
||||||
sp->ctrl->disable(sp);
|
timeout(power_off_slot, (caddr_t)sp, hz / 4);
|
||||||
|
sp->pwr_off_pending = 1;
|
||||||
|
|
||||||
/* De-activate all contexts. */
|
/* De-activate all contexts. */
|
||||||
for (i = 0; i < sp->ctrl->maxmem; i++)
|
for (i = 0; i < sp->ctrl->maxmem; i++)
|
||||||
@ -297,6 +338,40 @@ disable_slot(struct slot *sp)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* APM hooks for suspending and resuming.
|
||||||
|
*/
|
||||||
|
#if NAPM > 0
|
||||||
|
static int
|
||||||
|
slot_suspend(void *arg)
|
||||||
|
{
|
||||||
|
struct slot *sp = arg;
|
||||||
|
struct pccard_dev *dp;
|
||||||
|
|
||||||
|
for (dp = sp->devices; dp; dp = dp->next)
|
||||||
|
(void) dp->drv->suspend(dp);
|
||||||
|
if (!sp->suspend_power)
|
||||||
|
sp->ctrl->disable(sp);
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
slot_resume(void *arg)
|
||||||
|
{
|
||||||
|
struct slot *sp = arg;
|
||||||
|
struct pccard_dev *dp;
|
||||||
|
|
||||||
|
if (!sp->suspend_power)
|
||||||
|
sp->ctrl->power(sp);
|
||||||
|
if (sp->irq)
|
||||||
|
sp->ctrl->mapirq(sp, sp->irq);
|
||||||
|
for (dp = sp->devices; dp; dp = dp->next)
|
||||||
|
(void) dp->drv->init(dp, 0);
|
||||||
|
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
|
||||||
@ -345,6 +420,24 @@ pccard_alloc_slot(struct slot_ctrl *cp)
|
|||||||
printf("PC-Card %s (%d mem & %d I/O windows)\n",
|
printf("PC-Card %s (%d mem & %d I/O windows)\n",
|
||||||
cp->name, cp->maxmem, cp->maxio);
|
cp->name, cp->maxmem, cp->maxio);
|
||||||
}
|
}
|
||||||
|
#if NAPM > 0
|
||||||
|
{
|
||||||
|
struct apmhook *ap;
|
||||||
|
|
||||||
|
ap = &s_hook[sp->slot];
|
||||||
|
ap->ah_fun = slot_suspend;
|
||||||
|
ap->ah_arg = (void *)sp;
|
||||||
|
ap->ah_name = cp->name;
|
||||||
|
ap->ah_order = APM_MID_ORDER;
|
||||||
|
apm_hook_establish(APM_HOOK_SUSPEND, ap);
|
||||||
|
ap = &r_hook[sp->slot];
|
||||||
|
ap->ah_fun = slot_resume;
|
||||||
|
ap->ah_arg = (void *)sp;
|
||||||
|
ap->ah_name = cp->name;
|
||||||
|
ap->ah_order = APM_MID_ORDER;
|
||||||
|
apm_hook_establish(APM_HOOK_RESUME, ap);
|
||||||
|
}
|
||||||
|
#endif /* NAPM > 0 */
|
||||||
return(sp);
|
return(sp);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -528,19 +621,26 @@ inserted(void *arg)
|
|||||||
*/
|
*/
|
||||||
sp->pwr.vcc = 50;
|
sp->pwr.vcc = 50;
|
||||||
sp->pwr.vpp = 0;
|
sp->pwr.vpp = 0;
|
||||||
|
untimeout(power_off_slot, (caddr_t)sp);
|
||||||
|
if (sp->pwr_off_pending)
|
||||||
|
sp->ctrl->disable(sp);
|
||||||
|
sp->pwr_off_pending = 0;
|
||||||
sp->ctrl->power(sp);
|
sp->ctrl->power(sp);
|
||||||
printf("Card inserted, slot %d\n", sp->slot);
|
printf("Card inserted, slot %d\n", sp->slot);
|
||||||
/*
|
/*
|
||||||
* Now start resetting the card.
|
* Now start resetting the card.
|
||||||
*/
|
*/
|
||||||
sp->ctrl->reset(sp);
|
sp->ctrl->reset(sp);
|
||||||
|
#if NAPM > 0
|
||||||
|
sp->suspend_power = 0;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Insert/Remove beep
|
* Insert/Remove beep
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static int beepok = 1;
|
static int beepok = 0;
|
||||||
|
|
||||||
static void enable_beep(void *dummy)
|
static void enable_beep(void *dummy)
|
||||||
{
|
{
|
||||||
@ -572,8 +672,10 @@ int s;
|
|||||||
sp->state = empty;
|
sp->state = empty;
|
||||||
splx(s);
|
splx(s);
|
||||||
printf("Card removed, slot %d\n", sp->slot);
|
printf("Card removed, slot %d\n", sp->slot);
|
||||||
sysbeep(PCCARD_BEEP_PITCH0, PCCARD_BEEP_DURATION0);
|
if (beepok) {
|
||||||
beepok = 0;
|
sysbeep(PCCARD_BEEP_PITCH0, PCCARD_BEEP_DURATION0);
|
||||||
|
beepok = 0;
|
||||||
|
}
|
||||||
timeout(enable_beep, (void *)NULL, hz/5);
|
timeout(enable_beep, (void *)NULL, hz/5);
|
||||||
selwakeup(&sp->selp);
|
selwakeup(&sp->selp);
|
||||||
}
|
}
|
||||||
@ -581,8 +683,10 @@ int s;
|
|||||||
case card_inserted:
|
case card_inserted:
|
||||||
sp->insert_seq = 1;
|
sp->insert_seq = 1;
|
||||||
timeout(inserted, (void *)sp, hz/4);
|
timeout(inserted, (void *)sp, hz/4);
|
||||||
sysbeep(PCCARD_BEEP_PITCH0, PCCARD_BEEP_DURATION0);
|
if (beepok) {
|
||||||
beepok = 0;
|
sysbeep(PCCARD_BEEP_PITCH0, PCCARD_BEEP_DURATION0);
|
||||||
|
beepok = 0;
|
||||||
|
}
|
||||||
timeout(enable_beep, (void *)NULL, hz/5);
|
timeout(enable_beep, (void *)NULL, hz/5);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -750,6 +854,9 @@ crdioctl(dev_t dev, int cmd, caddr_t data, int fflag, struct proc *p)
|
|||||||
struct mem_desc *mp;
|
struct mem_desc *mp;
|
||||||
struct io_desc *ip;
|
struct io_desc *ip;
|
||||||
|
|
||||||
|
/* beep is disabled until the 1st call of crdioctl() */
|
||||||
|
enable_beep(NULL);
|
||||||
|
|
||||||
if (sp == 0 && cmd != PIOCRWMEM)
|
if (sp == 0 && cmd != PIOCRWMEM)
|
||||||
return(ENXIO);
|
return(ENXIO);
|
||||||
switch(cmd) {
|
switch(cmd) {
|
||||||
|
@ -630,6 +630,8 @@ pcic_probe ()
|
|||||||
pcicintr, 0, &pcic_imask);
|
pcicintr, 0, &pcic_imask);
|
||||||
if (pcic_irq < 0)
|
if (pcic_irq < 0)
|
||||||
printf("pcic: failed to allocate IRQ\n");
|
printf("pcic: failed to allocate IRQ\n");
|
||||||
|
else
|
||||||
|
printf("pcic: controller irq %d\n", pcic_irq);
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
* Check for a card in this slot.
|
* Check for a card in this slot.
|
||||||
@ -800,7 +802,7 @@ pcic_reset(void *chan)
|
|||||||
putb(sp, PCIC_TIME_CMD0, 0x6);
|
putb(sp, PCIC_TIME_CMD0, 0x6);
|
||||||
putb(sp, PCIC_TIME_RECOV0, 0x0);
|
putb(sp, PCIC_TIME_RECOV0, 0x0);
|
||||||
putb(sp, PCIC_TIME_SETUP1, 1);
|
putb(sp, PCIC_TIME_SETUP1, 1);
|
||||||
putb(sp, PCIC_TIME_CMD1, 0x5F);
|
putb(sp, PCIC_TIME_CMD1, 0xf);
|
||||||
putb(sp, PCIC_TIME_RECOV1, 0);
|
putb(sp, PCIC_TIME_RECOV1, 0);
|
||||||
}
|
}
|
||||||
selwakeup(&slotp->selp);
|
selwakeup(&slotp->selp);
|
||||||
|
@ -125,6 +125,8 @@ struct slot {
|
|||||||
struct power pwr; /* Power values */
|
struct power pwr; /* Power values */
|
||||||
struct slot_ctrl *ctrl; /* Per-controller data */
|
struct slot_ctrl *ctrl; /* Per-controller data */
|
||||||
void *cdata; /* Controller specific data */
|
void *cdata; /* Controller specific data */
|
||||||
|
int suspend_power; /* Leave powered on during suspend */
|
||||||
|
int pwr_off_pending;/* Power status of slot */
|
||||||
#ifdef DEVFS
|
#ifdef DEVFS
|
||||||
void *devfs_token;
|
void *devfs_token;
|
||||||
#endif /* DEVFS*/
|
#endif /* DEVFS*/
|
||||||
|
Loading…
x
Reference in New Issue
Block a user