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

📄 ib-pcmcia.c

📁 linux下的无线宽带驱动
💻 C
📖 第 1 页 / 共 2 页
字号:
			local->rx_nbuf = nbuf;			continue;		}		if (local->rx_echunk < nchunk)			nchunk = local->rx_echunk;		ib_pcmcia_blit(modem->rx_buf + local->rx_ibuf,				mem + ((rx_ichunk + irx) << 5), nchunk);		local->irx += nchunk;		if (2 * rx_nchunk <= local->irx)			local->irx -= 2 * rx_nchunk;		mem[OFFSET_PC_IRX] = local->irx;		local->rx_echunk -= nchunk;		local->rx_ibuf += nchunk << 5;		if (local->rx_echunk == 0)			ib_net_rx_parse(modem, local->rx_nbuf);	}	while (1) {		if (local->tx_echunk == 0) {			nbuf = ib_net_tx_prepare(modem);			if (nbuf == 0)				break;			modem->stats.tx_bytes += nbuf;			modem->stats.tx_packets += 1;			local->tx_echunk = (nbuf + 31) >> 5;			local->tx_jbuf = 0;		}		itx = mem[OFFSET_UT_ITX];		if (2 * tx_nchunk <= itx)			goto failed;		jtx = local->jtx;		if (mem[OFFSET_PC_JTX] != jtx)			goto failed;		if (jtx < itx)			nchunk = itx - jtx - tx_nchunk;		else			nchunk = itx - jtx + tx_nchunk;		if (nchunk < 0)			goto failed;		if (nchunk == 0)			break;		if (tx_nchunk <= jtx)			jtx -= tx_nchunk;		if (tx_nchunk - jtx < nchunk)			nchunk = tx_nchunk - jtx;		if (local->tx_echunk < nchunk)			nchunk = local->tx_echunk;		ib_pcmcia_blit(mem + ((tx_jchunk + jtx) << 5),				modem->tx_buf + local->tx_jbuf, nchunk);		local->tx_echunk -= nchunk;		local->tx_jbuf += nchunk << 5;		local->jtx += nchunk;		if (2 * tx_nchunk <= local->jtx)			local->jtx -= 2 * tx_nchunk;		mem[OFFSET_PC_JTX] = local->jtx;	}	return;failed:	DEBUG(1, "ib-pcmcia: normal failed\n");	ib_pcmcia_reset(local);}/** * ib_pcmcia_wait - hardware reset wait; get hardware address. *     called under ib_lock * @local: device private state. */static void ib_pcmcia_wait(struct ib_pcmcia_local_t *local){	struct ib_net_modem_t *modem = local->modem;	unsigned char *mem = local->mem;	if (ib_pcmcia_check(local))		return;	local->feedback = mem[OFFSET_UT_SEQUENCE];	mem[OFFSET_PC_FEEDBACK] = local->feedback;	local->rx_echunk = 0;	local->tx_echunk = 0;	mem[OFFSET_PC_IRX] = local->irx = 0;	mem[OFFSET_PC_JTX] = local->jtx = 0;	if (mem[OFFSET_UT_MAGIC1] != 0xac || mem[OFFSET_UT_MAGIC2] != 0x02			|| mem[OFFSET_UT_FEEDBACK] != local->sequence) {		DEBUG(8, "ib-pcmcia: wait %02X %02X %02X %02X\n",				mem[OFFSET_UT_MAGIC1], mem[OFFSET_UT_MAGIC2],				mem[OFFSET_UT_FEEDBACK], local->sequence);		return;	}	ib_net_addr(modem, mem + OFFSET_UT_ETHERNET);	local->ifstate = IFSTATE_NORMAL;	ib_pcmcia_normal(local);}/** * ib_pcmcia_poll - poll hardware according to protocol. *     called under ib_lock * @_local: device private state. */static void ib_pcmcia_poll(void *_local){	struct ib_pcmcia_local_t *local = _local;	switch (local->ifstate) {	case IFSTATE_RESET:		ib_pcmcia_reset(local);		break;	case IFSTATE_WAIT:		ib_pcmcia_wait(local);		break;	case IFSTATE_NORMAL:		ib_pcmcia_normal(local);		break;	}}/** * ib_pcmcia_open - open device. *     called under ib_lock * @_local: device private state. */static int ib_pcmcia_open(void *_local){	struct ib_pcmcia_local_t *local = _local;	struct ib_net_modem_t *modem = local->modem;	unsigned char *mem = local->mem;	DEBUG(9, "ib-pcmcia: +open\n");	mem[OFFSET_PC_STATUS] = (modem->pc_status |= STATUS_READY);	mem[OFFSET_PC_PACKET] = modem->stats.tx_packets & 0xff;	DEBUG(9, "ib-pcmcia: -open\n");	return 0;}/** * ib_pcmcia_rx_parse - *     called under ib_lock * @_local: device private state. */static void ib_pcmcia_rx_parse(void *_local){	struct ib_pcmcia_local_t *local = _local;	struct ib_net_modem_t *modem = local->modem;	unsigned char *mem = local->mem;	ib_net_ut_status(modem, mem[OFFSET_UT_STATUS]);	mem[OFFSET_PC_STATUS] = modem->pc_status;	mem[OFFSET_PC_PACKET] = modem->stats.tx_packets & 0xff;}/** * ib_pcmcia_close - close device; release in a momemt. *     called under ib_lock * @_local: device private state. */static int ib_pcmcia_close(void *_local){	struct ib_pcmcia_local_t *local = _local;	struct ib_net_modem_t *modem = local->modem;	unsigned char *mem = local->mem;	if (pcmcia_dev_present(local->dev)) {		mem[OFFSET_PC_STATUS] = (modem->pc_status &= ~STATUS_READY);		mem[OFFSET_PC_PACKET] = modem->stats.tx_packets & 0xff;	}	return 0;}/** * ib_pcmcia_net_driver - PCMCIA driver callback functions. */static struct ib_net_driver_t ib_pcmcia_net_driver = {	.poll = ib_pcmcia_poll,	.tx_timeout = NULL,	.open = ib_pcmcia_open,	.rx_parse = ib_pcmcia_rx_parse,	.close = ib_pcmcia_close,};/** * ib_pcmcia_config - PCMCIA config. * @link: device state. */static int ib_pcmcia_config(struct pcmcia_device *link){	struct ib_pcmcia_local_t *local = link->priv;	struct net_device *netdev;	struct ib_net_modem_t *modem;	struct tuple_t tuple;	union cisparse_t parse;	unsigned char buf[64];	int version;	struct config_info_t conf;	struct cistpl_cftable_entry_t *cfg;	struct cistpl_cftable_entry_t dflt = { 0 };	struct win_req_t req;	int err;	tuple.DesiredTuple = CISTPL_MANFID;	tuple.Attributes = 0;	tuple.TupleData = buf;	tuple.TupleDataMax = sizeof(buf);	tuple.TupleOffset = 0;	err = pcmcia_get_first_tuple(link, &tuple);	if (err)		goto failed1;	err = pcmcia_get_tuple_data(link, &tuple);	if (err)		goto failed1;	err = pcmcia_parse_tuple(&tuple, &parse);	if (err)		goto failed1;	version = parse.manfid.card;	DEBUG(1, "ib-pcmcia: card version %d\n", version);	tuple.DesiredTuple = CISTPL_CONFIG;	tuple.Attributes = 0;	tuple.TupleData = buf;	tuple.TupleDataMax = sizeof(buf);	tuple.TupleOffset = 0;	err = pcmcia_get_first_tuple(link, &tuple);	if (err)		goto failed1;	err = pcmcia_get_tuple_data(link, &tuple);	if (err)		goto failed1;	err = pcmcia_parse_tuple(&tuple, &parse);	if (err)		goto failed1;	link->conf.ConfigBase = parse.config.base;	link->conf.Present = parse.config.rmask[0];	//err = pcmcia_get_configuration_info(link, &conf);	//if (err)	//	goto failed1;	// NTJ: quick fix to get things working with 2.6.28.	// will reorg code to use pcmcia_loop_config()	conf.Vcc = link->socket->socket.Vcc;	tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;	err = pcmcia_get_first_tuple(link, &tuple);	if (err)		goto failed1;	while (1) {		if (pcmcia_get_tuple_data(link, &tuple))			goto next_entry;		if (pcmcia_parse_tuple(&tuple, &parse))			goto next_entry;		cfg = &parse.cftable_entry;		if (cfg->flags & CISTPL_CFTABLE_DEFAULT)			dflt = *cfg;		if (cfg->index == 0)			goto next_entry;		link->conf.ConfigIndex = cfg->index;		if (cfg->flags & CISTPL_CFTABLE_AUDIO) {			link->conf.Attributes |= CONF_ENABLE_SPKR;			link->conf.Status = CCSR_AUDIO_ENA;		}		if (cfg->vcc.present & (1 << CISTPL_POWER_VNOM)) {			if (conf.Vcc != cfg->vcc.param[CISTPL_POWER_VNOM]					/ 10000)				goto next_entry;		} else if (dflt.vcc.present & (1 << CISTPL_POWER_VNOM)) {			if (conf.Vcc != dflt.vcc.param[CISTPL_POWER_VNOM]					/ 10000)				goto next_entry;		}		if (cfg->vpp1.present & (1 << CISTPL_POWER_VNOM))			link->conf.Vpp = cfg->vpp1.param[CISTPL_POWER_VNOM]					/ 10000;		else if (dflt.vpp1.present & (1 << CISTPL_POWER_VNOM))			link->conf.Vpp = dflt.vpp1.param[CISTPL_POWER_VNOM]					/ 10000;		break;next_entry:		err = pcmcia_get_next_tuple(link, &tuple);		if (err)			goto failed1;	}	err = pcmcia_request_configuration(link, &link->conf);	if (err) {		DEBUG(1, "ib-pcmcia: pcmcia_request_configuration failed\n");		goto failed1;	}	req.AccessSpeed = 0;	req.Attributes = WIN_MEMORY_TYPE_CM | WIN_DATA_WIDTH_16 | WIN_ENABLE;	req.Base = 0;	req.Size = version < 2 ? 0x1000 : 0x2000;	link->win = NULL;	err = pcmcia_request_window(&link, &req, &link->win);	if (err) {		DEBUG(1, "ib-pcmcia: pcmcia_request_window failed\n");		goto failed2;	}	local->mem = (unsigned char*) ioremap(req.Base, req.Size);	if (local->mem == NULL) {		DEBUG(1, "ib-pcmcia: ioremap failed\n");		err = -EIO;		goto failed3;	}	err = ib_net_register(&netdev);	if (err)		goto failed4;	modem = netdev->priv;	strcpy(local->node.dev_name, netdev->name);	ib_net_addr(modem, local->mem + OFFSET_UT_ETHERNET);	modem->driver = &ib_pcmcia_net_driver;	modem->pdriver = local;	local->modem = modem;	local->ifstate = IFSTATE_RESET;	local->nreset = 0;	init_timer(&local->timer);	local->timer.expires = jiffies + HZ / 4;	local->timer.function = ib_pcmcia_timer;	local->timer.data = (unsigned long) local;	add_timer(&local->timer);	local->node.major = local->node.minor = 0;	local->node.next = NULL;	return 0;failed4:	iounmap(local->mem);failed3:failed2:	pcmcia_disable_device(link);failed1:	DEBUG(1, "ib-pcmcia: config failed\n");	return err;}/** * ib_pcmcia_probe - probe device. * @dev: device state. */static int ib_pcmcia_probe(struct pcmcia_device *link){	struct ib_pcmcia_local_t *local;	local = kmalloc(sizeof(struct ib_pcmcia_local_t), GFP_KERNEL);	if (local == NULL)		return -ENOMEM;	local->dev = link;	link->priv = local;	link->conf.Attributes = 0;	link->conf.IntType = INT_MEMORY_AND_IO;	link->conf.Status = 0;	link->conf.Vpp = 0;	init_timer(&local->release);	local->release.function = &ib_pcmcia_release;	local->release.data = (unsigned long) local;	local->modem = NULL;	return ib_pcmcia_config(link);}static struct pcmcia_device_id ib_pcmcia_table[] = {	PCMCIA_DEVICE_MANF_CARD(0x02e3, 0x0001),	PCMCIA_DEVICE_MANF_CARD(0x02e3, 0x0002),	PCMCIA_DEVICE_PROD_ID12("Kyocera Corporation", "Access Card",			0xaba79a14, 0xd66618ce),	PCMCIA_DEVICE_NULL,};MODULE_DEVICE_TABLE(pcmcia, ib_pcmcia_table);/** * ib_pcmcia_driver - PCMCIA driver struct. */static struct pcmcia_driver ib_pcmcia_driver = {	.owner = THIS_MODULE,	.drv = {		.name = ib_pcmcia_dev_info,	},	.probe = ib_pcmcia_probe,	.remove = ib_pcmcia_detach,	.id_table = ib_pcmcia_table,};/** * ib_pcmcia_init - ib-pcmcia module init. */static int __init ib_pcmcia_init(void){	if (io16)		ib_pcmcia_blit = ib_pcmcia_blit16;	else		ib_pcmcia_blit = ib_pcmcia_blit32;	pcmcia_register_driver(&ib_pcmcia_driver);	return 0;}/** * ib_pcmcia_exit - ib-pcmcia module exit. */static void __exit ib_pcmcia_exit(void){	pcmcia_unregister_driver(&ib_pcmcia_driver);}module_init(ib_pcmcia_init);module_exit(ib_pcmcia_exit);MODULE_DESCRIPTION("iBurst compatible PCMCIA driver");MODULE_LICENSE("GPL");

⌨️ 快捷键说明

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