summaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
authorsimokawa <simokawa@FreeBSD.org>2003-08-05 03:11:39 +0000
committersimokawa <simokawa@FreeBSD.org>2003-08-05 03:11:39 +0000
commit2e2a46ee2995da8f9ae6127ae115b29c2fab3db4 (patch)
tree81db5c0e4e301186eeff7bc59b7528f40cd8f284 /sys
parent8e8a7cd92a57f9aec2866f861b8e4a6e3a6153cb (diff)
downloadFreeBSD-src-2e2a46ee2995da8f9ae6127ae115b29c2fab3db4.zip
FreeBSD-src-2e2a46ee2995da8f9ae6127ae115b29c2fab3db4.tar.gz
Change device name notation.
- /dev/fw{,mem}X.Y represents the Y'th unit on the X'th bus. - /dev/fw{,mem}X is an alias of fw{,mem}X.0 for compatibility. - Clone devices.
Diffstat (limited to 'sys')
-rw-r--r--sys/dev/firewire/firewire.c83
-rw-r--r--sys/dev/firewire/firewire.h3
-rw-r--r--sys/dev/firewire/firewirereg.h6
-rw-r--r--sys/dev/firewire/fwdev.c103
4 files changed, 141 insertions, 54 deletions
diff --git a/sys/dev/firewire/firewire.c b/sys/dev/firewire/firewire.c
index 0d474c7..11919df 100644
--- a/sys/dev/firewire/firewire.c
+++ b/sys/dev/firewire/firewire.c
@@ -124,8 +124,6 @@ char linkspeed[7][0x10]={"S100","S200","S400","S800","S1600","S3200","Unknown"};
u_int gap_cnt[] = { 5, 5, 7, 8, 10, 13, 16, 18,
21, 24, 26, 29, 32, 35, 37, 40};
-extern struct cdevsw firewire_cdevsw;
-
static driver_t firewire_driver = {
"firewire",
firewire_methods,
@@ -356,44 +354,22 @@ firewire_watchdog(void *arg)
* The attach routine.
*/
static int
-firewire_attach( device_t dev )
+firewire_attach(device_t dev)
{
- int i, unitmask, mn;
+ int unit;
struct firewire_softc *sc = device_get_softc(dev);
device_t pa = device_get_parent(dev);
struct firewire_comm *fc;
- dev_t d;
fc = (struct firewire_comm *)device_get_softc(pa);
sc->fc = fc;
fc->status = FWBUSNOTREADY;
- unitmask = UNIT2MIN(device_get_unit(dev));
-
+ unit = device_get_unit(dev);
if( fc->nisodma > FWMAXNDMA) fc->nisodma = FWMAXNDMA;
- for ( i = 0 ; i < fc->nisodma ; i++ ){
- mn = unitmask | i;
- /* XXX device name should be improved */
- d = make_dev(&firewire_cdevsw, unit2minor(mn),
- UID_ROOT, GID_OPERATOR, 0660,
- "fw%x", mn);
-#if __FreeBSD_version >= 500000
- if (i == 0)
- sc->dev = d;
- else
- dev_depends(sc->dev, d);
-#else
- sc->dev[i] = d;
-#endif
- }
- d = make_dev(&firewire_cdevsw, unit2minor(unitmask | FWMEM_FLAG),
- UID_ROOT, GID_OPERATOR, 0660,
- "fwmem%d", device_get_unit(dev));
-#if __FreeBSD_version >= 500000
- dev_depends(sc->dev, d);
-#else
- sc->dev[i] = d;
-#endif
+
+ fwdev_makedev(sc);
+
CALLOUT_INIT(&sc->fc->timeout_callout);
CALLOUT_INIT(&sc->fc->bmr_callout);
CALLOUT_INIT(&sc->fc->retry_probe_callout);
@@ -450,30 +426,25 @@ firewire_resume(device_t dev)
* Dettach it.
*/
static int
-firewire_detach( device_t dev )
+firewire_detach(device_t dev)
{
struct firewire_softc *sc;
struct csrdir *csrd, *next;
struct fw_device *fwdev, *fwdev_next;
+ int err;
sc = (struct firewire_softc *)device_get_softc(dev);
+ if ((err = fwdev_destroydev(sc)) != 0)
+ return err;
- bus_generic_detach(dev);
+ if ((err = bus_generic_detach(dev)) != 0)
+ return err;
callout_stop(&sc->fc->timeout_callout);
callout_stop(&sc->fc->bmr_callout);
callout_stop(&sc->fc->retry_probe_callout);
callout_stop(&sc->fc->busprobe_callout);
-#if __FreeBSD_version >= 500000
- destroy_dev(sc->dev);
-#else
- {
- int j;
- for (j = 0 ; j < sc->fc->nisodma + 1; j++)
- destroy_dev(sc->dev[j]);
- }
-#endif
/* XXX xfree_free and untimeout on all xfers */
for (fwdev = STAILQ_FIRST(&sc->fc->devices); fwdev != NULL;
fwdev = fwdev_next) {
@@ -2197,5 +2168,33 @@ fw_bmr(struct firewire_comm *fc)
return 0;
}
-DRIVER_MODULE(firewire,fwohci,firewire_driver,firewire_devclass,0,0);
+static int
+fw_modevent(module_t mode, int type, void *data)
+{
+ int err = 0;
+#if __FreeBSD_version >= 500000
+ static eventhandler_tag fwdev_ehtag = NULL;
+#endif
+
+ switch (type) {
+ case MOD_LOAD:
+#if __FreeBSD_version >= 500000
+ fwdev_ehtag = EVENTHANDLER_REGISTER(dev_clone,
+ fwdev_clone, 0, 1000);
+#endif
+ break;
+ case MOD_UNLOAD:
+#if __FreeBSD_version >= 500000
+ if (fwdev_ehtag != NULL)
+ EVENTHANDLER_DEREGISTER(dev_clone, fwdev_ehtag);
+#endif
+ break;
+ case MOD_SHUTDOWN:
+ break;
+ }
+ return (err);
+}
+
+
+DRIVER_MODULE(firewire,fwohci,firewire_driver,firewire_devclass,fw_modevent,0);
MODULE_VERSION(firewire, 1);
diff --git a/sys/dev/firewire/firewire.h b/sys/dev/firewire/firewire.h
index b3ff169..b5f6573 100644
--- a/sys/dev/firewire/firewire.h
+++ b/sys/dev/firewire/firewire.h
@@ -393,7 +393,8 @@ struct fw_crom_buf {
#define unit2minor(x) (((x) & 0xff) | (((x) << 8) & ~0xffff))
#endif
-#define UNIT2MIN(x) (((x) & 0xff) << 8)
+#define MAKEMINOR(f, u, s) \
+ unit2minor((f) | (((u) & 0xff) << 8) | (s & 0xff))
#define DEV2UNIT(x) ((dev2unit(x) & 0xff00) >> 8)
#define DEV2SUB(x) (dev2unit(x) & 0xff)
diff --git a/sys/dev/firewire/firewirereg.h b/sys/dev/firewire/firewirereg.h
index 3a69e4e..e90f0c0 100644
--- a/sys/dev/firewire/firewirereg.h
+++ b/sys/dev/firewire/firewirereg.h
@@ -70,8 +70,6 @@ struct fw_device{
struct firewire_softc {
#if __FreeBSD_version >= 500000
dev_t dev;
-#else
- dev_t dev[FWMAXNDMA+1];
#endif
struct firewire_comm *fc;
};
@@ -290,7 +288,9 @@ struct fw_device *fw_noderesolve_nodeid __P((struct firewire_comm *, int));
struct fw_device *fw_noderesolve_eui64 __P((struct firewire_comm *, struct fw_eui64 *));
struct fw_bind *fw_bindlookup __P((struct firewire_comm *, u_int32_t, u_int32_t));
void fw_drain_txq __P((struct firewire_comm *));
-
+int fwdev_makedev __P((struct firewire_softc *));
+int fwdev_destroydev __P((struct firewire_softc *));
+void fwdev_clone __P((void *, char *, int, dev_t *));
extern int firewire_debug;
extern devclass_t firewire_devclass;
diff --git a/sys/dev/firewire/fwdev.c b/sys/dev/firewire/fwdev.c
index abf0e47..0d61fb7 100644
--- a/sys/dev/firewire/fwdev.c
+++ b/sys/dev/firewire/fwdev.c
@@ -46,6 +46,7 @@
#include <sys/poll.h>
#include <sys/bus.h>
+#include <sys/ctype.h>
#include <machine/bus.h>
#include <sys/ioccom.h>
@@ -82,7 +83,8 @@ struct cdevsw firewire_cdevsw =
.d_flags = D_MEM
#else
fw_open, fw_close, fw_read, fw_write, fw_ioctl,
- fw_poll, fw_mmap, nostrategy, "fw", CDEV_MAJOR, nodump, nopsize, D_MEM
+ fw_poll, fw_mmap, nostrategy, "fw", CDEV_MAJOR,
+ nodump, nopsize, D_MEM, -1
#endif
};
@@ -159,9 +161,6 @@ fwdev_freebuf(struct fw_xferq *q)
static int
fw_open (dev_t dev, int flags, int fmt, fw_proc *td)
{
- int unit = DEV2UNIT(dev);
- int sub = DEV2SUB(dev);
-
int err = 0;
if (dev->si_drv1 != NULL)
@@ -171,11 +170,15 @@ fw_open (dev_t dev, int flags, int fmt, fw_proc *td)
return fwmem_open(dev, flags, fmt, td);
#if __FreeBSD_version >= 500000
- if ((dev->si_flags & SI_NAMED) == 0)
-#endif
+ if ((dev->si_flags & SI_NAMED) == 0) {
+ int unit = DEV2UNIT(dev);
+ int sub = DEV2SUB(dev);
+
make_dev(&firewire_cdevsw, minor(dev),
UID_ROOT, GID_OPERATOR, 0660,
"fw%d.%d", unit, sub);
+ }
+#endif
dev->si_drv1 = malloc(sizeof(struct fw_drv1), M_FW, M_WAITOK | M_ZERO);
@@ -718,7 +721,7 @@ fw_mmap (dev_t dev, vm_offset_t offset, int nproto)
fw_mmap (dev_t dev, vm_offset_t offset, vm_paddr_t *paddr, int nproto)
#endif
{
- struct firewire_softc *fc;
+ struct firewire_softc *sc;
int unit = DEV2UNIT(dev);
if (DEV_FWMEM(dev))
@@ -728,7 +731,91 @@ fw_mmap (dev_t dev, vm_offset_t offset, vm_paddr_t *paddr, int nproto)
return fwmem_mmap(dev, offset, paddr, nproto);
#endif
- fc = devclass_get_softc(firewire_devclass, unit);
+ sc = devclass_get_softc(firewire_devclass, unit);
return EINVAL;
}
+
+int
+fwdev_makedev(struct firewire_softc *sc)
+{
+ int err = 0;
+
+#if __FreeBSD_version >= 500000
+ dev_t d;
+ int unit;
+
+ unit = device_get_unit(sc->fc->bdev);
+ sc->dev = make_dev(&firewire_cdevsw, MAKEMINOR(0, unit, 0),
+ UID_ROOT, GID_OPERATOR, 0660,
+ "fw%d.%d", unit, 0);
+ d = make_dev(&firewire_cdevsw,
+ MAKEMINOR(FWMEM_FLAG, unit, 0),
+ UID_ROOT, GID_OPERATOR, 0660,
+ "fwmem%d.%d", unit, 0);
+ dev_depends(sc->dev, d);
+ make_dev_alias(sc->dev, "fw%d", unit);
+ make_dev_alias(d, "fwmem%d", unit);
+#else
+ cdevsw_add(&firewire_cdevsw);
+#endif
+
+ return (err);
+}
+
+int
+fwdev_destroydev(struct firewire_softc *sc)
+{
+ int err = 0;
+
+#if __FreeBSD_version >= 500000
+ destroy_dev(sc->dev);
+#else
+ cdevsw_remove(&firewire_cdevsw);
+#endif
+ return (err);
+}
+
+#if __FreeBSD_version >= 500000
+#define NDEVTYPE 2
+void
+fwdev_clone(void *arg, char *name, int namelen, dev_t *dev)
+{
+ struct firewire_softc *sc;
+ char *devnames[NDEVTYPE] = {"fw", "fwmem"};
+ char *subp = NULL;
+ int devflag[NDEVTYPE] = {0, FWMEM_FLAG};
+ int i, unit = 0, sub = 0;
+
+ if (*dev != NODEV)
+ return;
+
+ for (i = 0; i < NDEVTYPE; i++)
+ if (dev_stdclone(name, &subp, devnames[i], &unit) != 1)
+ goto found;
+ /* not match */
+ return;
+found:
+
+ if (subp == NULL || *subp++ != '.')
+ return;
+
+ /* /dev/fwU.S */
+ while (isdigit(*subp)) {
+ sub *= 10;
+ sub += *subp++ - '0';
+ }
+ if (*subp != '\0')
+ return;
+
+ sc = devclass_get_softc(firewire_devclass, unit);
+ if (sc == NULL)
+ return;
+ *dev = make_dev(&firewire_cdevsw, MAKEMINOR(devflag[i], unit, sub),
+ UID_ROOT, GID_OPERATOR, 0660,
+ "%s%d.%d", devnames[i], unit, sub);
+ (*dev)->si_flags |= SI_CHEAPCLONE;
+ dev_depends(sc->dev, *dev);
+ return;
+}
+#endif
OpenPOWER on IntegriCloud