diff options
Diffstat (limited to 'drivers/usb/atm/ueagle-atm.c')
| -rw-r--r-- | drivers/usb/atm/ueagle-atm.c | 222 | 
1 files changed, 123 insertions, 99 deletions
diff --git a/drivers/usb/atm/ueagle-atm.c b/drivers/usb/atm/ueagle-atm.c index ea071a5b6ee..5a459377574 100644 --- a/drivers/usb/atm/ueagle-atm.c +++ b/drivers/usb/atm/ueagle-atm.c @@ -57,7 +57,6 @@  #include <linux/module.h>  #include <linux/moduleparam.h> -#include <linux/init.h>  #include <linux/crc32.h>  #include <linux/usb.h>  #include <linux/firmware.h> @@ -116,14 +115,14 @@ struct uea_cmvs_v1 {  	u32 address;  	u16 offset;  	u32 data; -} __attribute__ ((packed)); +} __packed;  struct uea_cmvs_v2 {  	u32 group;  	u32 address;  	u32 offset;  	u32 data; -} __attribute__ ((packed)); +} __packed;  /* information about currently processed cmv */  struct cmv_dsc_e1 { @@ -168,7 +167,6 @@ struct uea_softc {  	union cmv_dsc cmv_dsc;  	struct work_struct task; -	struct workqueue_struct *work_q;  	u16 pageno;  	u16 ovl; @@ -308,6 +306,34 @@ enum {  #define FW_GET_BYTE(p) (*((__u8 *) (p)))  #define FW_DIR "ueagle-atm/" +#define EAGLE_FIRMWARE FW_DIR "eagle.fw" +#define ADI930_FIRMWARE FW_DIR "adi930.fw" +#define EAGLE_I_FIRMWARE FW_DIR "eagleI.fw" +#define EAGLE_II_FIRMWARE FW_DIR "eagleII.fw" +#define EAGLE_III_FIRMWARE FW_DIR "eagleIII.fw" +#define EAGLE_IV_FIRMWARE FW_DIR "eagleIV.fw" + +#define DSP4I_FIRMWARE FW_DIR "DSP4i.bin" +#define DSP4P_FIRMWARE FW_DIR "DSP4p.bin" +#define DSP9I_FIRMWARE FW_DIR "DSP9i.bin" +#define DSP9P_FIRMWARE FW_DIR "DSP9p.bin" +#define DSPEI_FIRMWARE FW_DIR "DSPei.bin" +#define DSPEP_FIRMWARE FW_DIR "DSPep.bin" +#define FPGA930_FIRMWARE FW_DIR "930-fpga.bin" + +#define CMV4P_FIRMWARE FW_DIR "CMV4p.bin" +#define CMV4PV2_FIRMWARE FW_DIR "CMV4p.bin.v2" +#define CMV4I_FIRMWARE FW_DIR "CMV4i.bin" +#define CMV4IV2_FIRMWARE FW_DIR "CMV4i.bin.v2" +#define CMV9P_FIRMWARE FW_DIR "CMV9p.bin" +#define CMV9PV2_FIRMWARE FW_DIR "CMV9p.bin.v2" +#define CMV9I_FIRMWARE FW_DIR "CMV9i.bin" +#define CMV9IV2_FIRMWARE FW_DIR "CMV9i.bin.v2" +#define CMVEP_FIRMWARE FW_DIR "CMVep.bin" +#define CMVEPV2_FIRMWARE FW_DIR "CMVep.bin.v2" +#define CMVEI_FIRMWARE FW_DIR "CMVei.bin" +#define CMVEIV2_FIRMWARE FW_DIR "CMVei.bin.v2" +  #define UEA_FW_NAME_MAX 30  #define NB_MODEM 4 @@ -353,7 +379,7 @@ struct block_index {  	__le32 PageAddress;  	__le16 dummy1;  	__le16 PageNumber; -} __attribute__ ((packed)); +} __packed;  #define E4_IS_BOOT_PAGE(PageSize) ((le32_to_cpu(PageSize)) & 0x80000000)  #define E4_PAGE_BYTES(PageSize) ((le32_to_cpu(PageSize) & 0x7fffffff) * 4) @@ -368,7 +394,7 @@ struct l1_code {  	u8 page_number_to_block_index[E4_MAX_PAGE_NUMBER];  	struct block_index page_header[E4_NO_SWAPPAGE_HEADERS];  	u8 code[0]; -} __attribute__ ((packed)); +} __packed;  /* structures describing a block within a DSP page */  struct block_info_e1 { @@ -378,7 +404,7 @@ struct block_info_e1 {  	__le16 wOvlOffset;  	__le16 wOvl;		/* overlay */  	__le16 wLast; -} __attribute__ ((packed)); +} __packed;  #define E1_BLOCK_INFO_SIZE 12  struct block_info_e4 { @@ -388,7 +414,7 @@ struct block_info_e4 {  	__be32 dwSize;  	__be32 dwAddress;  	__be16 wReserved; -} __attribute__ ((packed)); +} __packed;  #define E4_BLOCK_INFO_SIZE 14  #define UEA_BIHDR 0xabcd @@ -468,7 +494,7 @@ struct cmv_e1 {  	__le32 dwSymbolicAddress;  	__le16 wOffsetAddress;  	__le32 dwData; -} __attribute__ ((packed)); +} __packed;  struct cmv_e4 {  	__be16 wGroup; @@ -476,17 +502,17 @@ struct cmv_e4 {  	__be16 wOffset;  	__be16 wAddress;  	__be32 dwData[6]; -} __attribute__ ((packed)); +} __packed;  /* structures representing swap information */  struct swap_info_e1 {  	__u8 bSwapPageNo;  	__u8 bOvl;		/* overlay */ -} __attribute__ ((packed)); +} __packed;  struct swap_info_e4 {  	__u8 bSwapPageNo; -} __attribute__ ((packed)); +} __packed;  /* structures representing interrupt data */  #define e1_bSwapPageNo	u.e1.s1.swapinfo.bSwapPageNo @@ -500,23 +526,23 @@ union intr_data_e1 {  	struct {  		struct swap_info_e1 swapinfo;  		__le16 wDataSize; -	} __attribute__ ((packed)) s1; +	} __packed s1;  	struct {  		struct cmv_e1 cmv;  		__le16 wDataSize; -	} __attribute__ ((packed)) s2; -} __attribute__ ((packed)); +	} __packed s2; +} __packed;  union intr_data_e4 {  	struct {  		struct swap_info_e4 swapinfo;  		__le16 wDataSize; -	} __attribute__ ((packed)) s1; +	} __packed s1;  	struct {  		struct cmv_e4 cmv;  		__le16 wDataSize; -	} __attribute__ ((packed)) s2; -} __attribute__ ((packed)); +	} __packed s2; +} __packed;  struct intr_pkt {  	__u8 bType; @@ -529,21 +555,21 @@ struct intr_pkt {  		union intr_data_e1 e1;  		union intr_data_e4 e4;  	} u; -} __attribute__ ((packed)); +} __packed;  #define E1_INTR_PKT_SIZE 28  #define E4_INTR_PKT_SIZE 64  static struct usb_driver uea_driver;  static DEFINE_MUTEX(uea_mutex); -static const char *chip_name[] = {"ADI930", "Eagle I", "Eagle II", "Eagle III", -								"Eagle IV"}; +static const char * const chip_name[] = { +	"ADI930", "Eagle I", "Eagle II", "Eagle III", "Eagle IV"};  static int modem_index;  static unsigned int debug;  static unsigned int altsetting[NB_MODEM] = {  				[0 ... (NB_MODEM - 1)] = FASTEST_ISO_INTF}; -static int sync_wait[NB_MODEM]; +static bool sync_wait[NB_MODEM];  static char *cmv_file[NB_MODEM];  static int annex[NB_MODEM]; @@ -695,26 +721,26 @@ err:  static int uea_load_firmware(struct usb_device *usb, unsigned int ver)  {  	int ret; -	char *fw_name = FW_DIR "eagle.fw"; +	char *fw_name = EAGLE_FIRMWARE;  	uea_enters(usb);  	uea_info(usb, "pre-firmware device, uploading firmware\n");  	switch (ver) {  	case ADI930: -		fw_name = FW_DIR "adi930.fw"; +		fw_name = ADI930_FIRMWARE;  		break;  	case EAGLE_I: -		fw_name = FW_DIR "eagleI.fw"; +		fw_name = EAGLE_I_FIRMWARE;  		break;  	case EAGLE_II: -		fw_name = FW_DIR "eagleII.fw"; +		fw_name = EAGLE_II_FIRMWARE;  		break;  	case EAGLE_III: -		fw_name = FW_DIR "eagleIII.fw"; +		fw_name = EAGLE_III_FIRMWARE;  		break;  	case EAGLE_IV: -		fw_name = FW_DIR "eagleIV.fw"; +		fw_name = EAGLE_IV_FIRMWARE;  		break;  	} @@ -870,19 +896,19 @@ static int request_dsp(struct uea_softc *sc)  	if (UEA_CHIP_VERSION(sc) == EAGLE_IV) {  		if (IS_ISDN(sc)) -			dsp_name = FW_DIR "DSP4i.bin"; +			dsp_name = DSP4I_FIRMWARE;  		else -			dsp_name = FW_DIR "DSP4p.bin"; +			dsp_name = DSP4P_FIRMWARE;  	} else if (UEA_CHIP_VERSION(sc) == ADI930) {  		if (IS_ISDN(sc)) -			dsp_name = FW_DIR "DSP9i.bin"; +			dsp_name = DSP9I_FIRMWARE;  		else -			dsp_name = FW_DIR "DSP9p.bin"; +			dsp_name = DSP9P_FIRMWARE;  	} else {  		if (IS_ISDN(sc)) -			dsp_name = FW_DIR "DSPei.bin"; +			dsp_name = DSPEI_FIRMWARE;  		else -			dsp_name = FW_DIR "DSPep.bin"; +			dsp_name = DSPEP_FIRMWARE;  	}  	ret = request_firmware(&sc->dsp_firm, dsp_name, &sc->usb_dev->dev); @@ -1284,7 +1310,7 @@ static void uea_set_bulk_timeout(struct uea_softc *sc, u32 dsrate)  	/* in bulk mode the modem have problem with high rate  	 * changing internal timing could improve things, but the -	 * value is misterious. +	 * value is mysterious.  	 * ADI930 don't support it (-EPIPE error).  	 */ @@ -1358,10 +1384,8 @@ static int uea_stat_e1(struct uea_softc *sc)  		/* release the dsp firmware as it is not needed until  		 * the next failure  		 */ -		if (sc->dsp_firm) { -			release_firmware(sc->dsp_firm); -			sc->dsp_firm = NULL; -		} +		release_firmware(sc->dsp_firm); +		sc->dsp_firm = NULL;  	}  	/* always update it as atm layer could not be init when we switch to @@ -1497,10 +1521,8 @@ static int uea_stat_e4(struct uea_softc *sc)  		/* release the dsp firmware as it is not needed until  		 * the next failure  		 */ -		if (sc->dsp_firm) { -			release_firmware(sc->dsp_firm); -			sc->dsp_firm = NULL; -		} +		release_firmware(sc->dsp_firm); +		sc->dsp_firm = NULL;  	}  	/* always update it as atm layer could not be init when we switch to @@ -1744,7 +1766,7 @@ static int uea_send_cmvs_e1(struct uea_softc *sc)  				goto out;  		}  	} else { -		/* This realy should not happen */ +		/* This really should not happen */  		uea_err(INS_TO_USBDEV(sc), "bad cmvs version %d\n", ver);  		goto out;  	} @@ -1799,7 +1821,7 @@ static int uea_send_cmvs_e4(struct uea_softc *sc)  				goto out;  		}  	} else { -		/* This realy should not happen */ +		/* This really should not happen */  		uea_err(INS_TO_USBDEV(sc), "bad cmvs version %d\n", ver);  		goto out;  	} @@ -1830,7 +1852,7 @@ static int uea_start_reset(struct uea_softc *sc)  	/* mask interrupt */  	sc->booting = 1; -	/* We need to set this here because, a ack timeout could have occured, +	/* We need to set this here because, a ack timeout could have occurred,  	 * but before we start the reboot, the ack occurs and set this to 1.  	 * So we will failed to wait Ready CMV.  	 */ @@ -1879,7 +1901,7 @@ static int uea_start_reset(struct uea_softc *sc)  	/* start loading DSP */  	sc->pageno = 0;  	sc->ovl = 0; -	queue_work(sc->work_q, &sc->task); +	schedule_work(&sc->task);  	/* wait for modem ready CMV */  	ret = wait_cmv_ack(sc); @@ -1930,7 +1952,7 @@ static int load_XILINX_firmware(struct uea_softc *sc)  	int ret, size, u, ln;  	const u8 *pfw;  	u8 value; -	char *fw_name = FW_DIR "930-fpga.bin"; +	char *fw_name = FPGA930_FIRMWARE;  	uea_enters(INS_TO_USBDEV(sc)); @@ -2091,14 +2113,14 @@ static void uea_schedule_load_page_e1(struct uea_softc *sc,  {  	sc->pageno = intr->e1_bSwapPageNo;  	sc->ovl = intr->e1_bOvl >> 4 | intr->e1_bOvl << 4; -	queue_work(sc->work_q, &sc->task); +	schedule_work(&sc->task);  }  static void uea_schedule_load_page_e4(struct uea_softc *sc,  						struct intr_pkt *intr)  {  	sc->pageno = intr->e4_bSwapPageNo; -	queue_work(sc->work_q, &sc->task); +	schedule_work(&sc->task);  }  /* @@ -2170,13 +2192,6 @@ static int uea_boot(struct uea_softc *sc)  	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); @@ -2206,8 +2221,11 @@ static int uea_boot(struct uea_softc *sc)  		goto err1;  	} -	sc->kthread = kthread_run(uea_kthread, sc, "ueagle-atm"); -	if (sc->kthread == ERR_PTR(-ENOMEM)) { +	/* Create worker thread, but don't start it here.  Start it after +	 * all usbatm generic initialization is done. +	 */ +	sc->kthread = kthread_create(uea_kthread, sc, "ueagle-atm"); +	if (IS_ERR(sc->kthread)) {  		uea_err(INS_TO_USBDEV(sc), "failed to create thread\n");  		goto err2;  	} @@ -2222,7 +2240,6 @@ err1:  	sc->urb_int = NULL;  	kfree(intr);  err0: -	destroy_workqueue(sc->work_q);  	uea_leaves(INS_TO_USBDEV(sc));  	return -ENOMEM;  } @@ -2243,11 +2260,10 @@ static void uea_stop(struct uea_softc *sc)  	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); +	/* flush the work item, when no one can schedule it */ +	flush_work(&sc->task); -	if (sc->dsp_firm) -		release_firmware(sc->dsp_firm); +	release_firmware(sc->dsp_firm);  	uea_leaves(INS_TO_USBDEV(sc));  } @@ -2301,7 +2317,7 @@ out:  	return ret;  } -static DEVICE_ATTR(stat_status, S_IWUGO | S_IRUGO, read_status, reboot); +static DEVICE_ATTR(stat_status, S_IWUSR | S_IRUGO, read_status, reboot);  static ssize_t read_human_status(struct device *dev,  			struct device_attribute *attr, char *buf) @@ -2364,8 +2380,7 @@ out:  	return ret;  } -static DEVICE_ATTR(stat_human_status, S_IWUGO | S_IRUGO, -				read_human_status, NULL); +static DEVICE_ATTR(stat_human_status, S_IRUGO, read_human_status, NULL);  static ssize_t read_delin(struct device *dev, struct device_attribute *attr,  		char *buf) @@ -2397,7 +2412,7 @@ out:  	return ret;  } -static DEVICE_ATTR(stat_delin, S_IWUGO | S_IRUGO, read_delin, NULL); +static DEVICE_ATTR(stat_delin, S_IRUGO, read_delin, NULL);  #define UEA_ATTR(name, reset)					\  								\ @@ -2625,6 +2640,7 @@ static struct usbatm_driver uea_usbatm_driver = {  static int uea_probe(struct usb_interface *intf, const struct usb_device_id *id)  {  	struct usb_device *usb = interface_to_usbdev(intf); +	int ret;  	uea_enters(usb);  	uea_info(usb, "ADSL device founded vid (%#X) pid (%#X) Rev (%#X): %s\n", @@ -2638,7 +2654,19 @@ static int uea_probe(struct usb_interface *intf, const struct usb_device_id *id)  	if (UEA_IS_PREFIRM(id))  		return uea_load_firmware(usb, UEA_CHIP_VERSION(id)); -	return usbatm_usb_probe(intf, id, &uea_usbatm_driver); +	ret = usbatm_usb_probe(intf, id, &uea_usbatm_driver); +	if (ret == 0) { +		struct usbatm_data *usbatm = usb_get_intfdata(intf); +		struct uea_softc *sc = usbatm->driver_data; + +		/* Ensure carrier is initialized to off as early as possible */ +		UPDATE_ATM_SIGNAL(ATM_PHY_SIG_LOST); + +		/* Only start the worker thread when all init is done */ +		wake_up_process(sc->kthread); +	} + +	return ret;  }  static void uea_disconnect(struct usb_interface *intf) @@ -2747,37 +2775,33 @@ static struct usb_driver uea_driver = {  MODULE_DEVICE_TABLE(usb, uea_ids); -/** - * uea_init - Initialize the module. - *      Register to USB subsystem - */ -static int __init uea_init(void) -{ -	printk(KERN_INFO "[ueagle-atm] driver " EAGLEUSBVERSION " loaded\n"); - -	usb_register(&uea_driver); - -	return 0; -} - -module_init(uea_init); - -/** - * uea_exit  -  Destroy module - *    Deregister with USB subsystem - */ -static void __exit uea_exit(void) -{ -	/* -	 * This calls automatically the uea_disconnect method if necessary: -	 */ -	usb_deregister(&uea_driver); - -	printk(KERN_INFO "[ueagle-atm] driver unloaded\n"); -} - -module_exit(uea_exit); +module_usb_driver(uea_driver);  MODULE_AUTHOR("Damien Bergamini/Matthieu Castet/Stanislaw W. Gruszka");  MODULE_DESCRIPTION("ADI 930/Eagle USB ADSL Modem driver");  MODULE_LICENSE("Dual BSD/GPL"); +MODULE_FIRMWARE(EAGLE_FIRMWARE); +MODULE_FIRMWARE(ADI930_FIRMWARE); +MODULE_FIRMWARE(EAGLE_I_FIRMWARE); +MODULE_FIRMWARE(EAGLE_II_FIRMWARE); +MODULE_FIRMWARE(EAGLE_III_FIRMWARE); +MODULE_FIRMWARE(EAGLE_IV_FIRMWARE); +MODULE_FIRMWARE(DSP4I_FIRMWARE); +MODULE_FIRMWARE(DSP4P_FIRMWARE); +MODULE_FIRMWARE(DSP9I_FIRMWARE); +MODULE_FIRMWARE(DSP9P_FIRMWARE); +MODULE_FIRMWARE(DSPEI_FIRMWARE); +MODULE_FIRMWARE(DSPEP_FIRMWARE); +MODULE_FIRMWARE(FPGA930_FIRMWARE); +MODULE_FIRMWARE(CMV4P_FIRMWARE); +MODULE_FIRMWARE(CMV4PV2_FIRMWARE); +MODULE_FIRMWARE(CMV4I_FIRMWARE); +MODULE_FIRMWARE(CMV4IV2_FIRMWARE); +MODULE_FIRMWARE(CMV9P_FIRMWARE); +MODULE_FIRMWARE(CMV9PV2_FIRMWARE); +MODULE_FIRMWARE(CMV9I_FIRMWARE); +MODULE_FIRMWARE(CMV9IV2_FIRMWARE); +MODULE_FIRMWARE(CMVEP_FIRMWARE); +MODULE_FIRMWARE(CMVEPV2_FIRMWARE); +MODULE_FIRMWARE(CMVEI_FIRMWARE); +MODULE_FIRMWARE(CMVEIV2_FIRMWARE);  | 
