version 1.1, 2008/03/04 16:05:17 |
version 1.2, 2008/05/11 10:26:11 |
|
|
#include <sys/param.h> |
#include <sys/param.h> |
#include <sys/systm.h> |
#include <sys/systm.h> |
#include <sys/device.h> |
#include <sys/device.h> |
#include <sys/callout.h> |
//#include <sys/callout.h> |
#include <sys/kernel.h> |
#include <sys/kernel.h> |
#include <sys/kthread.h> |
#include <sys/kthread.h> |
#include <sys/malloc.h> |
#include <sys/malloc.h> |
#include <sys/bus.h> |
|
#include <sys/intr.h> |
|
|
|
|
#include <sys/mutex.h> |
|
#include <machine/bus.h> |
|
#include <machine/intr.h> |
|
|
#include <uvm/uvm.h> |
#include <uvm/uvm.h> |
|
|
#include <dev/pcmcia/pcmciareg.h> |
#include <dev/pcmcia/pcmciareg.h> |
|
|
static void sapcic_io_unmap(pcmcia_chipset_handle_t, int); |
static void sapcic_io_unmap(pcmcia_chipset_handle_t, int); |
static void *sapcic_intr_establish(pcmcia_chipset_handle_t, |
static void *sapcic_intr_establish(pcmcia_chipset_handle_t, |
struct pcmcia_function *, int, |
struct pcmcia_function *, int, |
int (*)(void *), void *); |
int (*)(void *), void *, char *); |
static void sapcic_intr_disestablish(pcmcia_chipset_handle_t, |
static void sapcic_intr_disestablish(pcmcia_chipset_handle_t, |
void *); |
void *); |
static void sapcic_socket_enable(pcmcia_chipset_handle_t); |
static void sapcic_socket_enable(pcmcia_chipset_handle_t); |
static void sapcic_socket_disable(pcmcia_chipset_handle_t); |
static void sapcic_socket_disable(pcmcia_chipset_handle_t); |
static void sapcic_socket_settype(pcmcia_chipset_handle_t, int); |
//static void sapcic_socket_settype(pcmcia_chipset_handle_t, int); |
|
//int sapcic_socket_detect(pcmcia_chipset_handle_t); |
|
const char *sapcic_intr_string(pcmcia_chipset_handle_t pch, void *ih); |
|
|
|
|
static void sapcic_event_thread(void *); |
static void sapcic_event_thread(void *); |
|
|
static void sapcic_delay(int, const char *); |
static void sapcic_delay(int, const char *); |
|
|
#ifdef DEBUG |
#if (defined DEBUG) || (defined PCMCIADEBUG) |
#define DPRINTF(arg) printf arg |
#define DPRINTF(arg) printf arg |
#else |
#else |
#define DPRINTF(arg) |
#define DPRINTF(arg) |
|
|
|
|
sapcic_intr_establish, |
sapcic_intr_establish, |
sapcic_intr_disestablish, |
sapcic_intr_disestablish, |
|
sapcic_intr_string, |
|
|
sapcic_socket_enable, |
sapcic_socket_enable, |
sapcic_socket_disable, |
sapcic_socket_disable |
sapcic_socket_settype, |
|
}; |
}; |
|
|
|
|
|
|
|
|
/* XXX attach card if already present */ |
/* XXX attach card if already present */ |
|
|
mutex_init(&so->sc->sc_lock, MUTEX_DEFAULT, IPL_NONE); |
mtx_init(&so->sc->sc_lock, IPL_NONE); |
|
|
so->laststatus = (so->pcictag->read)(so, SAPCIC_STATUS_CARD); |
so->laststatus = (so->pcictag->read)(so, SAPCIC_STATUS_CARD); |
if (so->laststatus == SAPCIC_CARD_VALID) { |
if (so->laststatus == SAPCIC_CARD_VALID) { |
|
|
pcmcia_card_attach(so->pcmcia); |
pcmcia_card_attach(so->pcmcia); |
} |
} |
|
|
|
#if 0 |
if (kthread_create(PRI_NONE, 0, NULL, sapcic_event_thread, so, |
if (kthread_create(PRI_NONE, 0, NULL, sapcic_event_thread, so, |
&so->event_thread, "%s,%d", so->sc->sc_dev.dv_xname, so->socket)) { |
&so->event_thread, "%s,%d", so->sc->sc_dev.dv_xname, so->socket)) { |
printf("%s: unable to create event thread for socket %d\n", |
printf("%s: unable to create event thread for socket %d\n", |
so->sc->sc_dev.dv_xname, so->socket); |
so->sc->sc_dev.dv_xname, so->socket); |
panic("sapcic_kthread_create"); |
panic("sapcic_kthread_create"); |
} |
} |
|
#endif |
|
|
|
kthread_create_deferred(sapcic_event_thread, so); |
|
|
} |
} |
|
|
static void |
static void |
|
|
* Serialize event processing on the PCIC. We may |
* Serialize event processing on the PCIC. We may |
* sleep while we hold this lock. |
* sleep while we hold this lock. |
*/ |
*/ |
mutex_enter(&so->sc->sc_lock); |
mtx_enter(&so->sc->sc_lock); |
|
|
/* sleep .25s to be enqueued chatterling interrupts */ |
/* sleep .25s to be enqueued chatterling interrupts */ |
(void) tsleep(sapcic_event_thread, PWAIT, "pcicss", hz / 4); |
(void) tsleep(sapcic_event_thread, PWAIT, "pcicss", hz / 4); |
|
|
/* |
/* |
* No events to process; release the PCIC lock. |
* No events to process; release the PCIC lock. |
*/ |
*/ |
mutex_exit(&so->sc->sc_lock); |
mtx_leave(&so->sc->sc_lock); |
(void) tsleep(&so->event, PWAIT, "pcicev", hz); |
(void) tsleep(&so->event, PWAIT, "pcicev", hz); |
continue; |
continue; |
} |
} |
|
|
newstatus); |
newstatus); |
} |
} |
|
|
mutex_exit(&so->sc->sc_lock); |
mtx_leave(&so->sc->sc_lock); |
} |
} |
|
|
so->event_thread = NULL; |
//so->event_thread = NULL; |
|
|
/* In case parent is waiting for us to exit. */ |
/* In case parent is waiting for us to exit. */ |
wakeup(so->sc); |
wakeup(so->sc); |
|
|
static void |
static void |
sapcic_delay(int timo, const char *wmesg) |
sapcic_delay(int timo, const char *wmesg) |
{ |
{ |
#ifdef DIAGNOSTIC |
// tsleep(sapcic_delay, PWAIT, wmesg, roundup(timo * hz, 1000) / 1000); |
if (curlwp == NULL) |
delay(timo * 10); |
panic("sapcic_delay: called in interrupt context"); |
|
#endif |
|
|
|
tsleep(sapcic_delay, PWAIT, wmesg, roundup(timo * hz, 1000) / 1000); |
|
} |
} |
|
|
int |
int |
|
|
|
|
static void * |
static void * |
sapcic_intr_establish(pcmcia_chipset_handle_t pch, struct pcmcia_function *pf, |
sapcic_intr_establish(pcmcia_chipset_handle_t pch, struct pcmcia_function *pf, |
int ipl, int (*fct)(void *), void *arg) |
int ipl, int (*fct)(void *), void *arg, char *str) |
{ |
{ |
struct sapcic_socket *so = pch; |
struct sapcic_socket *so = pch; |
|
|
|
|
* we are changing Vcc (Toff). |
* we are changing Vcc (Toff). |
*/ |
*/ |
sapcic_delay(300 + 100, "pccen0"); |
sapcic_delay(300 + 100, "pccen0"); |
|
printf("sapcic_socket_enable: sapcic_delay\n"); |
|
|
/* power up the socket */ |
/* power up the socket */ |
/* XXX voltage selection should be done in PCMCIA code */ |
/* XXX voltage selection should be done in PCMCIA code */ |
|
|
(so->pcictag->write)(so, SAPCIC_CONTROL_LINEENABLE, 0); |
(so->pcictag->write)(so, SAPCIC_CONTROL_LINEENABLE, 0); |
} |
} |
|
|
|
#if 0 |
static void |
static void |
sapcic_socket_settype(pcmcia_chipset_handle_t pch, int type) |
sapcic_socket_settype(pcmcia_chipset_handle_t pch, int type) |
{ |
{ |
|
|
/* XXX nothing to do */ |
/* XXX nothing to do */ |
} |
} |
|
#endif |
|
|
|
#if 0 |
|
int |
|
sapcic_socket_detect(pcmcia_chipset_handle_t pch) |
|
{ |
|
/* TODO */ |
|
return (0); |
|
} |
|
#endif |
|
|
|
const char * |
|
sapcic_intr_string(pcmcia_chipset_handle_t pch, void *ih) |
|
{ |
|
// return (sa11x0_gpio_intr_string(ih)); |
|
return ("(sapcic_intr_string)"); |
|
} |
|
|
|
|