Powering down / 'stop'ing cards under NEWCARD?
Mark Santcroos
marks at ripe.net
Tue May 6 01:12:13 PDT 2003
On Mon, May 05, 2003 at 11:31:24PM -0700, Cliff L. Biffle wrote:
> That specific problem I'll deal with another day, but for now, is there any
> way to 'stop' a card under -current with NEWCARD?
The following patch was provided by Mitsuru IWASAKI:
(Find his original post at current@ Oct 29 2002)
Index: pccbb.c
===================================================================
RCS file: /home/ncvs/src/sys/dev/pccbb/pccbb.c,v
retrieving revision 1.59
diff -u -r1.59 pccbb.c
--- pccbb.c 11 Oct 2002 04:30:59 -0000 1.59
+++ pccbb.c 29 Oct 2002 10:55:48 -0000
@@ -86,6 +86,8 @@
#include <sys/sysctl.h>
#include <sys/kthread.h>
#include <sys/bus.h>
+#include <sys/conf.h>
+#include <sys/ioccom.h>
#include <machine/bus.h>
#include <sys/rman.h>
#include <machine/resource.h>
@@ -210,6 +212,13 @@
SYSCTL_ULONG(_hw_cbb, OID_AUTO, debug, CTLFLAG_RW, &cbb_debug, 0,
"Verbose cardbus bridge debugging");
+int cbb_boot_deactivated = 0;
+TUNABLE_INT("hw.cbb.boot_deactivated", &cbb_boot_deactivated);
+SYSCTL_INT(_hw_cbb, OID_AUTO, boot_deactivated, CTLFLAG_RD,
+ &cbb_boot_deactivated, 0,
+ "Override the automatic powering up of pccards at boot.");
+
+
static int cbb_chipset(uint32_t pci_id, const char **namep);
static int cbb_probe(device_t brdev);
static void cbb_chipinit(struct cbb_softc *sc);
@@ -264,6 +273,93 @@
static void cbb_write_config(device_t brdev, int b, int s, int f,
int reg, uint32_t val, int width);
+static d_open_t crdopen;
+static d_close_t crdclose;
+static d_ioctl_t crdioctl;
+
+#define CDEV_MAJOR 50
+static struct cdevsw crd_cdevsw = {
+ /* open */ crdopen,
+ /* close */ crdclose,
+ /* read */ noread,
+ /* write */ nowrite,
+ /* ioctl */ crdioctl,
+ /* poll */ nopoll,
+ /* mmap */ nommap,
+ /* strategy */ nostrategy,
+ /* name */ "crd",
+ /* maj */ CDEV_MAJOR,
+ /* dump */ nodump,
+ /* psize */ nopsize,
+ /* flags */ 0,
+};
+
+#define PIOCSVIR _IOW('P', 10, int) /* Virtual insert/remove */
+
+static int
+crdopen(dev_t dev, int oflags, int devtype, d_thread_t *td)
+{
+ if (dev == NULL || dev->si_drv1 == NULL) {
+ return (ENXIO);
+ }
+
+ return (0);
+}
+
+static int
+crdclose(dev_t dev, int fflag, int devtype, d_thread_t *td)
+{
+ return (0);
+}
+
+static int
+crdioctl(dev_t dev, u_long cmd, caddr_t data, int fflag, d_thread_t *td)
+{
+ struct cbb_softc *sc;
+ int error;
+ int pwval;
+
+ sc = dev->si_drv1;
+ error = 0;
+
+ switch(cmd) {
+ /*
+ * Set power values.
+ */
+ case PIOCSVIR:
+ pwval = *(int *)data;
+
+ switch (pwval) {
+ case 0:
+ if (!(sc->flags & CBB_CARD_OK)) {
+ error = EINVAL;
+ break;
+ }
+
+ sc->flags |= CBB_INACTIVATE;
+ cbb_removal(sc);
+ break;
+
+ case 1:
+ if (sc->flags & CBB_CARD_OK) {
+ error = EINVAL;
+ break;
+ }
+
+ sc->flags &= ~CBB_INACTIVATE;
+ cbb_insert(sc);
+ break;
+ }
+
+ break;
+
+ default:
+ error = ENOTTY;
+ }
+
+ return (error);
+}
+
/*
*/
static __inline void
@@ -560,6 +656,8 @@
{
struct cbb_softc *sc = (struct cbb_softc *)device_get_softc(brdev);
int rid;
+ int unit;
+ dev_t cbb_dev_t;
mtx_init(&sc->mtx, device_get_nameunit(brdev), "cbb", MTX_DEF);
cv_init(&sc->cv, "cbb cv");
@@ -680,6 +778,10 @@
/* reset interrupt */
cbb_set(sc, CBB_SOCKET_EVENT, cbb_get(sc, CBB_SOCKET_EVENT));
+ if (cbb_boot_deactivated) {
+ sc->flags |= CBB_INACTIVATE;
+ }
+
/* Start the thread */
if (kthread_create(cbb_event_thread, sc, &sc->event_thread, 0, 0,
"%s%d", device_get_name(sc->dev), device_get_unit(sc->dev))) {
@@ -687,6 +789,10 @@
panic ("cbb_create_event_thread");
}
+ unit = device_get_unit(sc->dev);
+ cbb_dev_t = make_dev(&crd_cdevsw, unit, 0, 0, 0664, "card%d", unit);
+ cbb_dev_t->si_drv1 = sc;
+
return (0);
err:
if (sc->irq_res)
@@ -913,10 +1019,14 @@
status = cbb_get(sc, CBB_SOCKET_STATE);
mtx_lock(&Giant);
- if ((status & CBB_SOCKET_STAT_CD) == 0)
- cbb_insert(sc);
- else
+ if ((status & CBB_SOCKET_STAT_CD) == 0) {
+ if (!(sc->flags & CBB_INACTIVATE)) {
+ cbb_insert(sc);
+ }
+ } else {
+ sc->flags &= ~CBB_INACTIVATE;
cbb_removal(sc);
+ }
mtx_unlock(&Giant);
/*
@@ -995,6 +1105,7 @@
else if ((!(sc->flags & CBB_16BIT_CARD)) && sc->cbdev != NULL)
CARD_DETACH_CARD(sc->cbdev, DETACH_FORCE);
cbb_destroy_res(sc);
+ sc->flags &= ~CBB_CARD_OK;
}
/************************************************************************/
@@ -1918,7 +2029,10 @@
cbb_setb(sc, CBB_SOCKET_MASK, CBB_SOCKET_MASK_CD);
/* Force us to go query the socket state */
- cbb_setb(sc, CBB_SOCKET_FORCE, CBB_SOCKET_EVENT_CD);
+ mtx_lock(&sc->mtx);
+ sc->flags &= ~CBB_CARD_OK;
+ cv_signal(&sc->cv);
+ mtx_unlock(&sc->mtx);
error = bus_generic_resume(self);
Index: pccbbvar.h
===================================================================
RCS file: /home/ncvs/src/sys/dev/pccbb/pccbbvar.h,v
retrieving revision 1.15
diff -u -r1.15 pccbbvar.h
--- pccbbvar.h 7 Oct 2002 23:11:29 -0000 1.15
+++ pccbbvar.h 28 Oct 2002 15:31:17 -0000
@@ -65,6 +65,7 @@
struct mtx mtx;
struct cv cv;
u_int32_t flags;
+#define CBB_INACTIVATE 0x04000000
#define CBB_CARD_OK 0x08000000
#define CBB_KLUDGE_ALLOC 0x10000000
#define CBB_16BIT_CARD 0x20000000
--
Mark Santcroos RIPE Network Coordination Centre
http://www.ripe.net/home/mark/ New Projects Group/TTM
More information about the freebsd-mobile
mailing list