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.
This commit is contained in:
Hidetoshi Shimokawa 2003-08-05 03:11:39 +00:00
parent c357858ad7
commit a160e00e41
4 changed files with 141 additions and 54 deletions

View File

@ -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);

View File

@ -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)

View File

@ -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;

View File

@ -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