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

📄 ueagle-atm.c

📁 linux 内核源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
	struct intr_pkt *intr;	uea_enters(INS_TO_USBDEV(sc));	if (UEA_CHIP_VERSION(sc) == EAGLE_IV) {		size = E4_INTR_PKT_SIZE;		sc->dispatch_cmv = uea_dispatch_cmv_e4;		sc->schedule_load_page = uea_schedule_load_page_e4;		sc->stat = uea_stat_e4;		sc->send_cmvs = uea_send_cmvs_e4;		INIT_WORK(&sc->task, uea_load_page_e4);	} else {		size = E1_INTR_PKT_SIZE;		sc->dispatch_cmv = uea_dispatch_cmv_e1;		sc->schedule_load_page = uea_schedule_load_page_e1;		sc->stat = uea_stat_e1;		sc->send_cmvs = uea_send_cmvs_e1;		INIT_WORK(&sc->task, uea_load_page_e1);	}	init_waitqueue_head(&sc->sync_q);	sc->work_q = create_workqueue("ueagle-dsp");	if (!sc->work_q) {		uea_err(INS_TO_USBDEV(sc), "cannot allocate workqueue\n");		uea_leaves(INS_TO_USBDEV(sc));		return -ENOMEM;	}	if (UEA_CHIP_VERSION(sc) == ADI930)		load_XILINX_firmware(sc);	intr = kmalloc(size, GFP_KERNEL);	if (!intr) {		uea_err(INS_TO_USBDEV(sc),		       "cannot allocate interrupt package\n");		goto err0;	}	sc->urb_int = usb_alloc_urb(0, GFP_KERNEL);	if (!sc->urb_int) {		uea_err(INS_TO_USBDEV(sc), "cannot allocate interrupt URB\n");		goto err1;	}	usb_fill_int_urb(sc->urb_int, sc->usb_dev,			 usb_rcvintpipe(sc->usb_dev, UEA_INTR_PIPE),			 intr, size, uea_intr, sc,			 sc->usb_dev->actconfig->interface[0]->altsetting[0].			 endpoint[0].desc.bInterval);	ret = usb_submit_urb(sc->urb_int, GFP_KERNEL);	if (ret < 0) {		uea_err(INS_TO_USBDEV(sc),		       "urb submition failed with error %d\n", ret);		goto err1;	}	sc->kthread = kthread_run(uea_kthread, sc, "ueagle-atm");	if (sc->kthread == ERR_PTR(-ENOMEM)) {		uea_err(INS_TO_USBDEV(sc), "failed to create thread\n");		goto err2;	}	uea_leaves(INS_TO_USBDEV(sc));	return 0;err2:	usb_kill_urb(sc->urb_int);err1:	usb_free_urb(sc->urb_int);	sc->urb_int = NULL;	kfree(intr);err0:	destroy_workqueue(sc->work_q);	uea_leaves(INS_TO_USBDEV(sc));	return -ENOMEM;}/* * Stop the modem : kill kernel thread and free data */static void uea_stop(struct uea_softc *sc){	int ret;	uea_enters(INS_TO_USBDEV(sc));	ret = kthread_stop(sc->kthread);	uea_dbg(INS_TO_USBDEV(sc), "kthread finish with status %d\n", ret);	uea_request(sc, UEA_SET_MODE, UEA_LOOPBACK_ON, 0, NULL);	usb_kill_urb(sc->urb_int);	kfree(sc->urb_int->transfer_buffer);	usb_free_urb(sc->urb_int);	/* stop any pending boot process, when no one can schedule work */	destroy_workqueue(sc->work_q);	if (sc->dsp_firm)		release_firmware(sc->dsp_firm);	uea_leaves(INS_TO_USBDEV(sc));}/* syfs interface */static struct uea_softc *dev_to_uea(struct device *dev){	struct usb_interface *intf;	struct usbatm_data *usbatm;	intf = to_usb_interface(dev);	if (!intf)		return NULL;	usbatm = usb_get_intfdata(intf);	if (!usbatm)		return NULL;	return usbatm->driver_data;}static ssize_t read_status(struct device *dev, struct device_attribute *attr,		char *buf){	int ret = -ENODEV;	struct uea_softc *sc;	mutex_lock(&uea_mutex);	sc = dev_to_uea(dev);	if (!sc)		goto out;	ret = snprintf(buf, 10, "%08x\n", sc->stats.phy.state);out:	mutex_unlock(&uea_mutex);	return ret;}static ssize_t reboot(struct device *dev, struct device_attribute *attr,		const char *buf, size_t count){	int ret = -ENODEV;	struct uea_softc *sc;	mutex_lock(&uea_mutex);	sc = dev_to_uea(dev);	if (!sc)		goto out;	sc->reset = 1;	ret = count;out:	mutex_unlock(&uea_mutex);	return ret;}static DEVICE_ATTR(stat_status, S_IWUGO | S_IRUGO, read_status, reboot);static ssize_t read_human_status(struct device *dev, struct device_attribute *attr,		char *buf){	int ret = -ENODEV;	int modem_state;	struct uea_softc *sc;	mutex_lock(&uea_mutex);	sc = dev_to_uea(dev);	if (!sc)		goto out;	if (UEA_CHIP_VERSION(sc) == EAGLE_IV) {		switch (sc->stats.phy.state) {		case 0x0:	/* not yet synchronized */		case 0x1:		case 0x3:		case 0x4:			modem_state = 0;			break;		case 0x5:	/* initialization */		case 0x6:		case 0x9:		case 0xa:			modem_state = 1;			break;		case 0x7: 	/* operational */			modem_state = 2;			break;		case 0x2:	/* fail ... */			modem_state = 3;			break;		default:	/* unknown */			modem_state = 4;			break;		}	} else		modem_state = GET_STATUS(sc->stats.phy.state);	switch (modem_state) {	case 0:		ret = sprintf(buf, "Modem is booting\n");		break;	case 1:		ret = sprintf(buf, "Modem is initializing\n");		break;	case 2:		ret = sprintf(buf, "Modem is operational\n");		break;	case 3:		ret = sprintf(buf, "Modem synchronization failed\n");		break;	default:		ret = sprintf(buf, "Modem state is unknown\n");		break;	}out:	mutex_unlock(&uea_mutex);	return ret;}static DEVICE_ATTR(stat_human_status, S_IWUGO | S_IRUGO, read_human_status, NULL);static ssize_t read_delin(struct device *dev, struct device_attribute *attr,		char *buf){	int ret = -ENODEV;	struct uea_softc *sc;	char *delin = "GOOD";	mutex_lock(&uea_mutex);	sc = dev_to_uea(dev);	if (!sc)		goto out;	if (UEA_CHIP_VERSION(sc) == EAGLE_IV) {		if (sc->stats.phy.flags & 0x4000)			delin = "RESET";		else if (sc->stats.phy.flags & 0x0001)			delin = "LOSS";	} else {		if (sc->stats.phy.flags & 0x0C00)			delin = "ERROR";		else if (sc->stats.phy.flags & 0x0030)			delin = "LOSS";	}	ret = sprintf(buf, "%s\n", delin);out:	mutex_unlock(&uea_mutex);	return ret;}static DEVICE_ATTR(stat_delin, S_IWUGO | S_IRUGO, read_delin, NULL);#define UEA_ATTR(name, reset) 					\								\static ssize_t read_##name(struct device *dev, 			\		struct device_attribute *attr, char *buf)	\{ 								\	int ret = -ENODEV; 					\	struct uea_softc *sc; 					\ 								\	mutex_lock(&uea_mutex); 				\	sc = dev_to_uea(dev);					\	if (!sc) 						\		goto out; 					\	ret = snprintf(buf, 10, "%08x\n", sc->stats.phy.name);	\	if (reset)						\		sc->stats.phy.name = 0;				\out: 								\	mutex_unlock(&uea_mutex); 				\	return ret; 						\} 								\								\static DEVICE_ATTR(stat_##name, S_IRUGO, read_##name, NULL)UEA_ATTR(mflags, 1);UEA_ATTR(vidcpe, 0);UEA_ATTR(usrate, 0);UEA_ATTR(dsrate, 0);UEA_ATTR(usattenuation, 0);UEA_ATTR(dsattenuation, 0);UEA_ATTR(usmargin, 0);UEA_ATTR(dsmargin, 0);UEA_ATTR(txflow, 0);UEA_ATTR(rxflow, 0);UEA_ATTR(uscorr, 0);UEA_ATTR(dscorr, 0);UEA_ATTR(usunc, 0);UEA_ATTR(dsunc, 0);UEA_ATTR(firmid, 0);/* Retrieve the device End System Identifier (MAC) */#define htoi(x) (isdigit(x) ? x-'0' : toupper(x)-'A'+10)static int uea_getesi(struct uea_softc *sc, u_char * esi){	unsigned char mac_str[2 * ETH_ALEN + 1];	int i;	if (usb_string	    (sc->usb_dev, sc->usb_dev->descriptor.iSerialNumber, mac_str,	     sizeof(mac_str)) != 2 * ETH_ALEN)		return 1;	for (i = 0; i < ETH_ALEN; i++)		esi[i] = htoi(mac_str[2 * i]) * 16 + htoi(mac_str[2 * i + 1]);	return 0;}/* ATM stuff */static int uea_atm_open(struct usbatm_data *usbatm, struct atm_dev *atm_dev){	struct uea_softc *sc = usbatm->driver_data;	return uea_getesi(sc, atm_dev->esi);}static int uea_heavy(struct usbatm_data *usbatm, struct usb_interface *intf){	struct uea_softc *sc = usbatm->driver_data;	wait_event_interruptible(sc->sync_q, IS_OPERATIONAL(sc));	return 0;}static int claim_interface(struct usb_device *usb_dev,			   struct usbatm_data *usbatm, int ifnum){	int ret;	struct usb_interface *intf = usb_ifnum_to_if(usb_dev, ifnum);	if (!intf) {		uea_err(usb_dev, "interface %d not found\n", ifnum);		return -ENODEV;	}	ret = usb_driver_claim_interface(&uea_driver, intf, usbatm);	if (ret != 0)		uea_err(usb_dev, "can't claim interface %d, error %d\n", ifnum,		       ret);	return ret;}static struct attribute *attrs[] = {	&dev_attr_stat_status.attr,	&dev_attr_stat_mflags.attr,	&dev_attr_stat_human_status.attr,	&dev_attr_stat_delin.attr,	&dev_attr_stat_vidcpe.attr,	&dev_attr_stat_usrate.attr,	&dev_attr_stat_dsrate.attr,	&dev_attr_stat_usattenuation.attr,	&dev_attr_stat_dsattenuation.attr,	&dev_attr_stat_usmargin.attr,	&dev_attr_stat_dsmargin.attr,	&dev_attr_stat_txflow.attr,	&dev_attr_stat_rxflow.attr,	&dev_attr_stat_uscorr.attr,	&dev_attr_stat_dscorr.attr,	&dev_attr_stat_usunc.attr,	&dev_attr_stat_dsunc.attr,	&dev_attr_stat_firmid.attr,	NULL,};static struct attribute_group attr_grp = {	.attrs = attrs,};static int uea_bind(struct usbatm_data *usbatm, struct usb_interface *intf,		   const struct usb_device_id *id){	struct usb_device *usb = interface_to_usbdev(intf);	struct uea_softc *sc;	int ret, ifnum = intf->altsetting->desc.bInterfaceNumber;	unsigned int alt;	uea_enters(usb);	/* interface 0 is for firmware/monitoring */	if (ifnum != UEA_INTR_IFACE_NO)		return -ENODEV;	usbatm->flags = (sync_wait[modem_index] ? 0 : UDSL_SKIP_HEAVY_INIT);	/* interface 1 is for outbound traffic */	ret = claim_interface(usb, usbatm, UEA_US_IFACE_NO);	if (ret < 0)		return ret;	/* ADI930 has only 2 interfaces and inbound traffic is on interface 1 */	if (UEA_CHIP_VERSION(id) != ADI930) {		/* interface 2 is for inbound traffic */		ret = claim_interface(usb, usbatm, UEA_DS_IFACE_NO);		if (ret < 0)			return ret;	}	sc = kzalloc(sizeof(struct uea_softc), GFP_KERNEL);	if (!sc) {		uea_err(usb, "uea_init: not enough memory !\n");		return -ENOMEM;	}	sc->usb_dev = usb;	usbatm->driver_data = sc;	sc->usbatm = usbatm;	sc->modem_index = (modem_index < NB_MODEM) ? modem_index++ : 0;	sc->driver_info = id->driver_info;	/* first try to use module parameter */	if (annex[sc->modem_index] == 1)		sc->annex = ANNEXA;	else if (annex[sc->modem_index] == 2)		sc->annex = ANNEXB;	/* try to autodetect annex */	else if (sc->driver_info & AUTO_ANNEX_A)		sc->annex = ANNEXA;	else if (sc->driver_info & AUTO_ANNEX_B)		sc->annex = ANNEXB;	else		sc->annex = (le16_to_cpu(sc->usb_dev->descriptor.bcdDevice) & 0x80)?ANNEXB:ANNEXA;	alt = altsetting[sc->modem_index];	/* ADI930 don't support iso */	if (UEA_CHIP_VERSION(id) != ADI930 && alt > 0) {		if (alt <= 8 && usb_set_interface(usb, UEA_DS_IFACE_NO, alt) == 0) {			uea_dbg(usb, "set alternate %u for 2 interface\n", alt);			uea_info(usb, "using iso mode\n");			usbatm->flags |= UDSL_USE_ISOC | UDSL_IGNORE_EILSEQ;		} else {			uea_err(usb, "setting alternate %u failed for "					"2 interface, using bulk mode\n", alt);		}	}	ret = sysfs_create_group(&intf->dev.kobj, &attr_grp);	if (ret < 0)		goto error;	ret = uea_boot(sc);	if (ret < 0)		goto error_rm_grp;	return 0;error_rm_grp:	sysfs_remove_group(&intf->dev.kobj, &attr_grp);error:	kfree(sc);	return ret;}static void uea_unbind(struct usbatm_data *usbatm, struct usb_interface *intf){	struct uea_softc *sc = usbatm->driver_data;	sysfs_remove_group(&intf->dev.kobj, &attr_grp);	uea_stop(sc);	kfree(sc);}static struct usbatm_driver uea_usbatm_driver = {	.driver_name = "ueagle-atm",	.bind = uea_bind,	.atm_start = uea_atm_open,	.unbind = uea_unbind,	.heavy_init = uea_heavy,	.bulk_in = UEA_BULK_DATA_PIPE,	.bulk_out = UEA_BULK_DATA_PIPE,	.isoc_in = UEA_ISO_DATA_PIPE,};static int uea_probe(struct usb_interface *intf, const struct usb_device_id *id){	struct usb_device *usb = interface_to_usbdev(intf);	uea_enters(usb);	uea_info(usb, "ADSL device founded vid (%#X) pid (%#X) Rev (%#X): %s\n",		le16_to_cpu(usb->descriptor.idVendor),		le16_to_cpu(usb->descriptor.idProduct),		le16_to_cpu(usb->descriptor.bcdDevice),		chip_name[UEA_CHIP_VERSION(id)]);	usb_reset_device(usb);	if (UEA_IS_PREFIRM(id))		return uea_load_firmware(usb, UEA_CHIP_VERSION(id));	return usbatm_usb_probe(intf, id, &uea_usbatm_driver);}static void uea_disconnect(struct usb_interface *intf){	struct usb_device *usb = interface_to_usbdev(intf);	int ifnum = intf->altsetting->desc.bInterfaceNumber;	uea_enters(usb);	/* ADI930 has 2 interfaces and eagle 3 interfaces.	 * Pre-firmware device has one interface	 */	if (usb->config->desc.bNumInterfaces != 1 && ifnum == 0) {		mutex_lock(&uea_mutex);		usbatm_usb_disconnect(intf);		mutex_unlock(&uea_mutex);		uea_info(usb, "ADSL device removed\n");	}	uea_leaves(usb);}/* * List of supported VID/PID */static const struct usb_device_id uea_ids[] = {	{USB_DEVICE(ANALOG_VID,	ADI930_PID_PREFIRM),	.driver_info = ADI930 | PREFIRM},	{USB_DEVICE(ANALOG_VID,	ADI930_PID_PSTFIRM),	.driver_info = ADI930 | PSTFIRM},	{USB_DEVICE(ANALOG_VID,	EAGLE_I_PID_PREFIRM),	.driver_info = EAGLE_I | PREFIRM},	{USB_DEVICE(ANALOG_VID,	EAGLE_I_PID_PSTFIRM),	.driver_info = EAGLE_I | PSTFIRM},	{USB_DEVICE(ANALOG_VID,	EAGLE_II_PID_PREFIRM),	.driver_info = EAGLE_II | PREFIRM},	{USB_DEVICE(ANALOG_VID,	EAGLE_II_PID_PSTFIRM),	.driver_info = EAGLE_II | PSTFIRM},	{USB_DEVICE(ANALOG_VID,	EAGLE_IIC_PID_PREFIRM),	.driver_info = EAGLE_II | PREFIRM},	{USB_DEVICE(ANALOG_VID,	EAGLE_IIC_PID_PSTFIRM),	.driver_info = EAGLE_II | PSTFIRM},	{USB_DEVICE(ANALOG_VID,	EAGLE_III_PID_PREFIRM),	.driver_info = EAGLE_III | PREFIRM},	{USB_DEVICE(ANALOG_VID,	EAGLE_III_PID_PSTFIRM),	.driver_info = EAGLE_III | PSTFIRM},	{USB_D

⌨️ 快捷键说明

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