Change the peripheral driver list from a linker set to module driven
driver registration. This should allow things like da, sa, cd etc to be in seperate KLD's to the cam core and make them preloadable.
This commit is contained in:
parent
2b52ef3ebe
commit
d447364263
@ -63,6 +63,29 @@ static void camperiphdone(struct cam_periph *periph,
|
||||
union ccb *done_ccb);
|
||||
static void camperiphfree(struct cam_periph *periph);
|
||||
|
||||
static int nperiph_drivers;
|
||||
struct periph_driver **periph_drivers;
|
||||
|
||||
void
|
||||
periphdriver_register(void *data)
|
||||
{
|
||||
struct periph_driver **newdrivers, **old;
|
||||
int ndrivers;
|
||||
|
||||
ndrivers = nperiph_drivers + 2;
|
||||
newdrivers = malloc(sizeof(*newdrivers) * ndrivers, M_TEMP, M_WAITOK);
|
||||
if (periph_drivers)
|
||||
bcopy(periph_drivers, newdrivers,
|
||||
sizeof(*newdrivers) * ndrivers);
|
||||
newdrivers[nperiph_drivers] = (struct periph_driver *)data;
|
||||
newdrivers[nperiph_drivers + 1] = NULL;
|
||||
old = periph_drivers;
|
||||
periph_drivers = newdrivers;
|
||||
if (old)
|
||||
free(old, M_TEMP);
|
||||
nperiph_drivers++;
|
||||
}
|
||||
|
||||
cam_status
|
||||
cam_periph_alloc(periph_ctor_t *periph_ctor,
|
||||
periph_oninv_t *periph_oninvalidate,
|
||||
@ -112,8 +135,7 @@ cam_periph_alloc(periph_ctor_t *periph_ctor,
|
||||
|
||||
init_level++;
|
||||
|
||||
for (p_drv = (struct periph_driver **)periphdriver_set.ls_items;
|
||||
*p_drv != NULL; p_drv++) {
|
||||
for (p_drv = periph_drivers; *p_drv != NULL; p_drv++) {
|
||||
if (strcmp((*p_drv)->driver_name, name) == 0)
|
||||
break;
|
||||
}
|
||||
@ -201,8 +223,7 @@ cam_periph_find(struct cam_path *path, char *name)
|
||||
struct cam_periph *periph;
|
||||
int s;
|
||||
|
||||
for (p_drv = (struct periph_driver **)periphdriver_set.ls_items;
|
||||
*p_drv != NULL; p_drv++) {
|
||||
for (p_drv = periph_drivers; *p_drv != NULL; p_drv++) {
|
||||
|
||||
if (name != NULL && (strcmp((*p_drv)->driver_name, name) != 0))
|
||||
continue;
|
||||
@ -401,8 +422,7 @@ camperiphfree(struct cam_periph *periph)
|
||||
int s;
|
||||
struct periph_driver **p_drv;
|
||||
|
||||
for (p_drv = (struct periph_driver **)periphdriver_set.ls_items;
|
||||
*p_drv != NULL; p_drv++) {
|
||||
for (p_drv = periph_drivers; *p_drv != NULL; p_drv++) {
|
||||
if (strcmp((*p_drv)->driver_name, periph->periph_name) == 0)
|
||||
break;
|
||||
}
|
||||
|
@ -37,7 +37,30 @@
|
||||
|
||||
extern struct cam_periph *xpt_periph;
|
||||
|
||||
extern struct linker_set periphdriver_set;
|
||||
extern struct periph_driver **periph_drivers;
|
||||
void periphdriver_register(void *);
|
||||
|
||||
#include <sys/module.h>
|
||||
#define PERIPHDRIVER_DECLARE(name, driver) \
|
||||
static int name ## _modevent(module_t mod, int type, void *data) \
|
||||
{ \
|
||||
switch (type) { \
|
||||
case MOD_LOAD: \
|
||||
periphdriver_register(data); \
|
||||
break; \
|
||||
case MOD_UNLOAD: \
|
||||
printf(#name " module unload - not possible for this module type\n"); \
|
||||
return EINVAL; \
|
||||
} \
|
||||
return 0; \
|
||||
} \
|
||||
static moduledata_t name ## _mod = { \
|
||||
#name, \
|
||||
name ## _modevent, \
|
||||
(void *)&driver \
|
||||
}; \
|
||||
DECLARE_MODULE(name, name ## _mod, SI_SUB_DRIVERS, SI_ORDER_ANY); \
|
||||
MODULE_DEPEND(name, cam, 1, 1, 1)
|
||||
|
||||
typedef void (periph_init_t)(void); /*
|
||||
* Callback informing the peripheral driver
|
||||
|
@ -576,8 +576,8 @@ static struct periph_driver probe_driver =
|
||||
TAILQ_HEAD_INITIALIZER(probe_driver.units)
|
||||
};
|
||||
|
||||
DATA_SET(periphdriver_set, xpt_driver);
|
||||
DATA_SET(periphdriver_set, probe_driver);
|
||||
PERIPHDRIVER_DECLARE(xpt, xpt_driver);
|
||||
PERIPHDRIVER_DECLARE(probe, probe_driver);
|
||||
|
||||
#define XPT_CDEV_MAJOR 104
|
||||
|
||||
@ -1167,8 +1167,7 @@ xptioctl(dev_t dev, u_long cmd, caddr_t addr, int flag, struct proc *p)
|
||||
cur_generation = xsoftc.generation;
|
||||
|
||||
/* first find our driver in the list of drivers */
|
||||
for (p_drv = (struct periph_driver **)periphdriver_set.ls_items;
|
||||
*p_drv != NULL; p_drv++)
|
||||
for (p_drv = periph_drivers; *p_drv != NULL; p_drv++)
|
||||
if (strcmp((*p_drv)->driver_name, name) == 0)
|
||||
break;
|
||||
|
||||
@ -2342,9 +2341,7 @@ xptplistperiphfunc(struct cam_periph *periph, void *arg)
|
||||
* peripheral driver linker set entry would cost
|
||||
* more in the long run than doing this quick lookup.
|
||||
*/
|
||||
for (pdrv =
|
||||
(struct periph_driver **)periphdriver_set.ls_items;
|
||||
*pdrv != NULL; pdrv++) {
|
||||
for (pdrv = periph_drivers; *pdrv != NULL; pdrv++) {
|
||||
if (strcmp((*pdrv)->driver_name,
|
||||
periph->periph_name) == 0)
|
||||
break;
|
||||
@ -2546,8 +2543,7 @@ xptpdrvtraverse(struct periph_driver **start_pdrv,
|
||||
* change while the system is running), the list traversal should
|
||||
* be modified to work like the other traversal functions.
|
||||
*/
|
||||
for (pdrv = (start_pdrv ? start_pdrv :
|
||||
(struct periph_driver **)periphdriver_set.ls_items);
|
||||
for (pdrv = (start_pdrv ? start_pdrv : periph_drivers);
|
||||
*pdrv != NULL; pdrv++) {
|
||||
retval = tr_func(pdrv, arg);
|
||||
|
||||
@ -6210,7 +6206,7 @@ xpt_finishconfig(struct cam_periph *periph, union ccb *done_ccb)
|
||||
if (busses_to_config == 0) {
|
||||
/* Register all the peripheral drivers */
|
||||
/* XXX This will have to change when we have loadable modules */
|
||||
p_drv = (struct periph_driver **)periphdriver_set.ls_items;
|
||||
p_drv = periph_drivers;
|
||||
for (i = 0; p_drv[i] != NULL; i++) {
|
||||
(*p_drv[i]->init)();
|
||||
}
|
||||
|
@ -245,7 +245,7 @@ static struct periph_driver cddriver =
|
||||
TAILQ_HEAD_INITIALIZER(cddriver.units), /* generation */ 0
|
||||
};
|
||||
|
||||
DATA_SET(periphdriver_set, cddriver);
|
||||
PERIPHDRIVER_DECLARE(cd, cddriver);
|
||||
|
||||
/* For 2.2-stable support */
|
||||
#ifndef D_DISK
|
||||
|
@ -209,7 +209,7 @@ static struct periph_driver chdriver =
|
||||
TAILQ_HEAD_INITIALIZER(chdriver.units), /* generation */ 0
|
||||
};
|
||||
|
||||
DATA_SET(periphdriver_set, chdriver);
|
||||
PERIPHDRIVER_DECLARE(ch, chdriver);
|
||||
|
||||
static struct cdevsw ch_cdevsw = {
|
||||
/* open */ chopen,
|
||||
|
@ -299,7 +299,7 @@ static struct periph_driver dadriver =
|
||||
TAILQ_HEAD_INITIALIZER(dadriver.units), /* generation */ 0
|
||||
};
|
||||
|
||||
DATA_SET(periphdriver_set, dadriver);
|
||||
PERIPHDRIVER_DECLARE(da, dadriver);
|
||||
|
||||
#define DA_CDEV_MAJOR 13
|
||||
#define DA_BDEV_MAJOR 4
|
||||
|
@ -107,7 +107,7 @@ static struct periph_driver passdriver =
|
||||
TAILQ_HEAD_INITIALIZER(passdriver.units), /* generation */ 0
|
||||
};
|
||||
|
||||
DATA_SET(periphdriver_set, passdriver);
|
||||
PERIPHDRIVER_DECLARE(pass, passdriver);
|
||||
|
||||
static struct cdevsw pass_cdevsw = {
|
||||
/* open */ passopen,
|
||||
|
@ -114,7 +114,7 @@ static struct periph_driver ptdriver =
|
||||
TAILQ_HEAD_INITIALIZER(ptdriver.units), /* generation */ 0
|
||||
};
|
||||
|
||||
DATA_SET(periphdriver_set, ptdriver);
|
||||
PERIPHDRIVER_DECLARE(pt, ptdriver);
|
||||
|
||||
#define PT_CDEV_MAJOR 61
|
||||
|
||||
|
@ -402,7 +402,7 @@ static struct periph_driver sadriver =
|
||||
TAILQ_HEAD_INITIALIZER(sadriver.units), /* generation */ 0
|
||||
};
|
||||
|
||||
DATA_SET(periphdriver_set, sadriver);
|
||||
PERIPHDRIVER_DECLARE(sa, sadriver);
|
||||
|
||||
/* For 2.2-stable support */
|
||||
#ifndef D_TAPE
|
||||
|
@ -173,7 +173,7 @@ static struct periph_driver sesdriver = {
|
||||
TAILQ_HEAD_INITIALIZER(sesdriver.units), /* generation */ 0
|
||||
};
|
||||
|
||||
DATA_SET(periphdriver_set, sesdriver);
|
||||
PERIPHDRIVER_DECLARE(ses, sesdriver);
|
||||
|
||||
static struct cdevsw ses_cdevsw =
|
||||
{
|
||||
|
@ -149,7 +149,7 @@ static struct periph_driver targbhdriver =
|
||||
TAILQ_HEAD_INITIALIZER(targbhdriver.units), /* generation */ 0
|
||||
};
|
||||
|
||||
DATA_SET(periphdriver_set, targbhdriver);
|
||||
PERIPHDRIVER_DECLARE(targbh, targbhdriver);
|
||||
|
||||
static void
|
||||
targbhinit(void)
|
||||
|
@ -228,7 +228,7 @@ static struct periph_driver targdriver =
|
||||
TAILQ_HEAD_INITIALIZER(targdriver.units), /* generation */ 0
|
||||
};
|
||||
|
||||
DATA_SET(periphdriver_set, targdriver);
|
||||
PERIPHDRIVER_DECLARE(targ, targdriver);
|
||||
|
||||
static struct extend_array *targperiphs;
|
||||
static dev_t targ_ctl_dev;
|
||||
|
Loading…
Reference in New Issue
Block a user