⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cardmgr.c

📁 pcmcia source code
💻 C
📖 第 1 页 / 共 3 页
字号:
			break;	    }	} else {	    /* this is a 2.4 kernel; hotplug handles these cards */	    s->state |= SOCKET_HOTPLUG;	    syslog(LOG_INFO, "socket %d: CardBus hotplug device", ns);	    //beep(BEEP_TIME, BEEP_OK);	    return NULL;	}    }    /* Try for a FUNCID match */    if (!card && (funcid.func != 0xff)) {	for (card = root_func; card; card = card->next)	    if (card->id.func.funcid == funcid.func)		break;    }    if (card) {	syslog(LOG_INFO, "socket %d: %s", ns, card->name);	beep(BEEP_TIME, BEEP_OK);	if (verbose) log_card_info(vers, &manfid, &funcid, &pci_id);	return card;    }    if (!blank_card || (status.CardState & CS_EVENT_CB_DETECT) ||	manfid.manf || manfid.card || pci_id.vendor || vers) {	syslog(LOG_INFO, "unsupported card in socket %d", ns);	if (one_pass) return NULL;	beep(BEEP_TIME, BEEP_ERR);	log_card_info(vers, &manfid, &funcid, &pci_id);	write_stab();	return NULL;    } else {	card = blank_card;	syslog(LOG_INFO, "socket %d: %s", ns, card->name);	beep(BEEP_TIME, BEEP_WARN);	return card;    }}/*====================================================================*/static void load_config(void){    if (chdir(configpath) != 0) {	syslog(LOG_ERR, "chdir to %s failed: %m", configpath);	exit(EXIT_FAILURE);    }    if (parse_configfile("config") != 0)	exit(EXIT_FAILURE);    if (root_device == NULL)	syslog(LOG_WARNING, "no device drivers defined");    if ((root_card == NULL) && (root_func == NULL))	syslog(LOG_WARNING, "no cards defined");}/*====================================================================*/static void free_card(card_info_t *card){    if (card && (--card->refs == 0)) {	int i;	free(card->name);	switch(card->ident_type) {	case VERS_1_IDENT:	    for (i = 0; i < card->id.vers.ns; i++)		free(card->id.vers.pi[i]);	break;	case TUPLE_IDENT:	    free(card->id.tuple.info);	    break;	default:	    break;	}	free(card);    }}static void free_device(device_info_t *dev){    if (dev && (--dev->refs == 0)) {	int i;	for (i = 0; i < dev->modules; i++) {	    free(dev->module[i]);	    if (dev->opts[i]) free(dev->opts[i]);	}	if (dev->class) free(dev->class);	free(dev);    }}static void free_mtd(mtd_ident_t *mtd){    if (mtd && (--mtd->refs == 0)) {	free(mtd->name);	free(mtd->module);	free(mtd);    }}static void free_config(void){    while (root_adjust != NULL) {	adjust_list_t *adj = root_adjust;	root_adjust = root_adjust->next;	free(adj);    }        while (root_device != NULL) {	device_info_t *dev = root_device;	root_device = root_device->next;	free_device(dev);    }    while (root_card != NULL) {	card_info_t *card = root_card;	root_card = root_card->next;	free_card(card);    }        while (root_func != NULL) {	card_info_t *card = root_func;	root_func = root_func->next;	free_card(card);    }    blank_card = NULL;        while (root_mtd != NULL) {	mtd_ident_t *mtd = root_mtd;	root_mtd = root_mtd->next;	free_mtd(mtd);    }    default_mtd = NULL;}/*====================================================================*/static int execute(char *msg, char *cmd){    int ret;    FILE *f;    char line[256];    syslog(LOG_INFO, "executing: '%s'", cmd);    strcat(cmd, " 2>&1");    f = popen(cmd, "r");    while (fgets(line, 255, f)) {	line[strlen(line)-1] = '\0';	syslog(LOG_INFO, "+ %s", line);    }    ret = pclose(f);    if (WIFEXITED(ret)) {	if (WEXITSTATUS(ret))	    syslog(LOG_INFO, "%s exited with status %d",		   msg, WEXITSTATUS(ret));	return WEXITSTATUS(ret);    } else	syslog(LOG_INFO, "%s exited on signal %d",	       msg, WTERMSIG(ret));    return -1;}/*====================================================================*/static int execute_on_dev(char *action, char *class, char *dev){    /* Fixed length strings are ok here */    char msg[128], cmd[128];    sprintf(msg, "%s cmd", action);    sprintf(cmd, "./%s %s %s", class, action, dev);    return execute(msg, cmd);}static int execute_on_all(char *cmd, char *class, int sn, int fn){    socket_info_t *s = &socket[sn];    bind_info_t *bind;    int ret = 0;    for (bind = s->bind[fn]; bind != NULL; bind = bind->next)	if (bind->name[0] && (bind->name[2] != '#'))	    ret |= execute_on_dev(cmd, class, bind->name);    return ret;}/*====================================================================*/typedef struct module_list_t {    char *mod;    int usage;    struct module_list_t *next;} module_list_t;static module_list_t *module_list = NULL;static int try_insmod(char *mod, char *opts){    char *cmd = malloc(strlen(mod) + strlen(modpath) +		       (opts ? strlen(opts) : 0) + 30);    int ret;    strcpy(cmd, "insmod ");    if (strchr(mod, '/') != NULL)	sprintf(cmd+7, "%s/%s.o", modpath, mod);    else	sprintf(cmd+7, "%s/pcmcia/%s.o", modpath, mod);    if (access(cmd+7, R_OK) != 0) {	syslog(LOG_INFO, "module %s not available", cmd+7);	free(cmd);	return -1;    }    if (opts) {	strcat(cmd, " ");	strcat(cmd, opts);    }    ret = execute("insmod", cmd);    free(cmd);    return ret;}static int try_modprobe(char *mod, char *opts){    char *cmd = malloc(strlen(mod) + (opts ? strlen(opts) : 0) + 20);    char *s = strrchr(mod, '/');    int ret;    sprintf(cmd, "modprobe %s", (s) ? s+1 : mod);    if (opts) {	strcat(cmd, " ");	strcat(cmd, opts);    }    ret = execute("modprobe", cmd);    free(cmd);    return ret;}static void install_module(char *mod, char *opts){    module_list_t *ml;    for (ml = module_list; ml != NULL; ml = ml->next)	if (strcmp(mod, ml->mod) == 0) break;    if (ml == NULL) {	ml = (module_list_t *)malloc(sizeof(struct module_list_t));	ml->mod = mod;	ml->usage = 0;	ml->next = module_list;	module_list = ml;    }    ml->usage++;    if (ml->usage != 1)	return;    if (access("/proc/bus/pccard/drivers", R_OK) == 0) {	FILE *f = fopen("/proc/bus/pccard/drivers", "r");	if (f) {	    char a[61], s[33];	    while (fgets(a, 60, f)) {		int is_kernel;		sscanf(a, "%s %d", s, &is_kernel);		if (strcmp(s, mod) != 0) continue;		/* If it isn't a module, we won't try to rmmod */		ml->usage += is_kernel;		fclose(f);		return;	    }	    fclose(f);	}    }    if (do_modprobe) {	if (try_modprobe(mod, opts) != 0)	    try_insmod(mod, opts);    } else {	if (try_insmod(mod, opts) != 0)	    try_modprobe(mod, opts);    }}static void remove_module(char *mod){    char *s, cmd[128];    module_list_t *ml;    for (ml = module_list; ml != NULL; ml = ml->next)	if (strcmp(mod, ml->mod) == 0) break;    if (ml != NULL) {	ml->usage--;	if (ml->usage == 0) {	    /* Strip off leading path names */	    s = strrchr(mod, '/');	    s = (s) ? s+1 : mod;	    sprintf(cmd, do_modprobe ? "modprobe -r %s" : "rmmod %s", s);	    execute(do_modprobe ? "modprobe" : "rmmod", cmd);	}    }}/*====================================================================*/static mtd_ident_t *lookup_mtd(region_info_t *region){    mtd_ident_t *mtd;    int match = 0;        for (mtd = root_mtd; mtd; mtd = mtd->next) {	switch (mtd->mtd_type) {	case JEDEC_MTD:	    if ((mtd->jedec_mfr == region->JedecMfr) &&		(mtd->jedec_info == region->JedecInfo)) {		match = 1;		break;	    }	case DTYPE_MTD:	    break;	default:	    break;	}	if (match) break;    }    if (mtd)	return mtd;    else	return default_mtd;}/*====================================================================*/static void bind_mtd(int sn){    socket_info_t *s = &socket[sn];    region_info_t region;    bind_info_t bind;    mtd_info_t mtd_info;    mtd_ident_t *mtd;    int i, attr, ret, nr;    nr = 0;    for (attr = 0; attr < 2; attr++) {	region.Attributes = attr;	ret = ioctl(s->fd, DS_GET_FIRST_REGION, &region);	while (ret == 0) {	    mtd = lookup_mtd(&region);	    if (mtd) {		/* Have we seen this MTD before? */		for (i = 0; i < nr; i++)		    if (s->mtd[i] == mtd) break;		if (i == nr) {		    install_module(mtd->module, mtd->opts);		    s->mtd[nr] = mtd;		    mtd->refs++;		    nr++;		}		syslog(LOG_INFO, "  %s memory region at 0x%x: %s",		       attr ? "Attribute" : "Common", region.CardOffset,		       mtd->name);		/* Bind MTD to this region */		strcpy(mtd_info.dev_info, s->mtd[i]->module);		mtd_info.Attributes = region.Attributes;		mtd_info.CardOffset = region.CardOffset;		if (ioctl(s->fd, DS_BIND_MTD, &mtd_info) != 0) {		    syslog(LOG_INFO,			   "bind MTD '%s' to region at 0x%x failed: %m",			   (char *)mtd_info.dev_info, region.CardOffset);		}	    }	    ret = ioctl(s->fd, DS_GET_NEXT_REGION, &region);	}    }    s->mtd[nr] = NULL;        /* Now bind each unique MTD as a normal client of this socket */    for (i = 0; i < nr; i++) {	strcpy(bind.dev_info, s->mtd[i]->module);	bind.function = 0;	if (ioctl(s->fd, DS_BIND_REQUEST, &bind) != 0)	    syslog(LOG_INFO, "bind MTD '%s' to socket %d failed: %m",		   (char *)bind.dev_info, sn);    }}/*====================================================================*/static void update_cis(socket_info_t *s){    cisdump_t cis;    FILE *f = fopen(s->card->cis_file, "r");    if (f == NULL)	syslog(LOG_ERR, "could not open '%s': %m", s->card->cis_file);    else {	cis.Length = fread(cis.Data, 1, CISTPL_MAX_CIS_SIZE, f);	fclose(f);	if (ioctl(s->fd, DS_REPLACE_CIS, &cis) != 0)	    syslog(LOG_ERR, "could not replace CIS: %m");    }}/*====================================================================*/static void do_insert(int sn){    socket_info_t *s = &socket[sn];    card_info_t *card;    device_info_t **dev;    bind_info_t *bind, **tail;    int i, j, ret;    /* Already identified? */    if ((s->card != NULL) && (s->card != blank_card))	return;    if (verbose) syslog(LOG_INFO, "initializing socket %d", sn);    card = lookup_card(sn);    if (s->state & SOCKET_HOTPLUG) {	write_stab();	return;    }    /* Make sure we've learned something new before continuing */    if (card == s->card)	return;    s->card = card;    card->refs++;    if (card->cis_file) update_cis(s);    dev = card->device;    /* Set up MTD's */    for (i = 0; i < card->bindings; i++)	if (dev[i]->needs_mtd)	    break;    if (i < card->bindings)	bind_mtd(sn);    /* Install kernel modules */    for (i = 0; i < card->bindings; i++) {	dev[i]->refs++;	for (j = 0; j < dev[i]->modules; j++)	    install_module(dev[i]->module[j], dev[i]->opts[j]);    }        /* Bind drivers by their dev_info identifiers */    for (i = 0; i < card->bindings; i++) {	bind = calloc(1, sizeof(bind_info_t));	strcpy((char *)bind->dev_info, (char *)dev[i]->dev_info);	if (strcmp(bind->dev_info, "cb_enabler") == 0)	    bind->function = BIND_FN_ALL;	else	    bind->function = card->dev_fn[i];	if (ioctl(s->fd, DS_BIND_REQUEST, bind) != 0) {	    if (errno == EBUSY) {		syslog(LOG_INFO, "'%s' already bound to socket %d",		       (char *)bind->dev_info, sn);	    } else {		syslog(LOG_INFO, "bind '%s' to socket %d failed: %m",		       (char *)bind->dev_info, sn);		beep(BEEP_TIME, BEEP_ERR);		write_stab();		return;	    }	}	for (ret = j = 0; j < 10; j++) {	    ret = ioctl(s->fd, DS_GET_DEVICE_INFO, bind);	    if ((ret == 0) || (errno != EAGAIN))		break;	    usleep(100000);	}	if (ret != 0) {	    syslog(LOG_INFO, "get dev info on socket %d failed: %m",		   sn);	    if ((errno == EAGAIN) &&		(strcmp(dev[i]->module[dev[i]->modules-1],			(char *)bind->dev_info) != 0))		syslog(LOG_INFO, "wrong module '%s' for device '%s'?",		       dev[i]->module[dev[i]->modules-1],		       (char *)bind->dev_info);	    ioctl(s->fd, DS_UNBIND_REQUEST, bind);	    beep(BEEP_TIME, BEEP_ERR);	    write_stab();	    return;	}	tail = &s->bind[i];	while (ret == 0) {	    bind_info_t *old;	    if ((strlen(bind->name) > 3) && (bind->name[2] == '#'))		xlate_scsi_name(bind);	    old = *tail = bind; tail = (bind_info_t **)&bind->next;	    bind = (bind_info_t *)malloc(sizeof(bind_info_t));	    memcpy(bind, old, sizeof(bind_info_t));	    ret = ioctl(s->fd, DS_GET_NEXT_DEVICE, bind);	}	*tail = NULL; free(bind);	write_stab();    }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -