usbatm cxacru.c,1.3,1.4

kagan at infradead.org kagan at infradead.org
Sun Jan 16 19:33:44 EST 2005


Update of /home/cvs/usbatm
In directory phoenix.infradead.org:/tmp/cvs-serv25526

Modified Files:
	cxacru.c 
Log Message:
Modified initialisation logic to set up udsl_instance (and thus the ATM device)
only when the modem is ready (see
http://lists.infradead.org/pipermail/usbatm/2005-January/000006.html).  This
simplifies the interaction with usb_atm and provides for the ATM device hotplug
support once the ATM layer is incorporated into the driver model.

TODO: correspoding cleanup of usb_atm and adjustment of speedtch.


Index: cxacru.c
===================================================================
RCS file: /home/cvs/usbatm/cxacru.c,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -r1.3 -r1.4
--- cxacru.c	14 Jan 2005 08:32:00 -0000	1.3
+++ cxacru.c	17 Jan 2005 00:33:41 -0000	1.4
@@ -162,6 +162,11 @@
 struct cxacru_instance_data {
 	struct udsl_instance_data u;
 
+	struct semaphore start_serialize;
+#ifdef USE_FW_LOADER
+	int firmware_start_run;
+#endif
+
 	int line_status; 
 	struct work_struct poll_work;
 	struct timer_list poll_timer;
@@ -353,59 +358,67 @@
 	cxacru_do_timer_poll((struct cxacru_instance_data *)data);
 }
 
-static void cxacru_got_firmware(struct cxacru_instance_data *instance,
-				int got_it)
+#ifdef USE_FW_LOADER
+static void cxacru_firmware_start(struct cxacru_instance_data *instance);
+#endif
+
+static void cxacru_adsl_start(struct cxacru_instance_data *instance)
 {
 	int ret;
 
-	dbg("got_firmware %d", got_it);
-	down(&instance->u.serialize);	/* vs self, cxacru_firmware_start */
-	if (instance->u.status == UDSL_LOADED_FIRMWARE)
-		goto out;
-	if (!got_it) {
-		instance->u.status = UDSL_NO_FIRMWARE;
-		goto out;
-	}
+	dbg("cxacru_adsl_start");
+	down(&instance->start_serialize);
 
-	ret = cxacru_cm(instance, CM_REQUEST_CARD_GET_STATUS, NULL, 0, NULL, 0);
-	if (ret < 0) {
-		err("cxacru_got_firmware: CARD_GET_STATUS returned %d", ret);
-		instance->u.status = UDSL_NO_FIRMWARE;
-		goto out;
-	}
+	if (!instance->u.atm_dev) {	/* ! fully initialised */
+		u8 esi[sizeof(instance->u.atm_dev->esi)] = {};
 
-	/* Read MAC address */
-	memset(instance->u.atm_dev->esi, 0, sizeof(instance->u.atm_dev->esi));
-	ret = cxacru_cm(instance, CM_REQUEST_CARD_GET_MAC_ADDRESS, NULL, 0, 
-			instance->u.atm_dev->esi, sizeof(instance->u.atm_dev->esi));
-	if (ret < 0) {
-		err("cxacru_got_firmware: CARD_GET_MAC_ADDRESS returned %d", ret);
-		instance->u.status = UDSL_NO_FIRMWARE;
-		goto out;
-	}
+		ret = cxacru_cm(instance, CM_REQUEST_CARD_GET_STATUS, NULL, 0, NULL, 0);
+		if (ret < 0) {		/* firmware not loaded */
+			dbg("cxacru_adsl_start: CARD_GET_STATUS returned %d", ret);
+#ifdef USE_FW_LOADER
+			if (!instance->firmware_start_run) {
+				instance->firmware_start_run = 1;
+				cxacru_firmware_start(instance);
+			}
+#endif /* USE_FW_LOADER */
+			goto out;
+		}
 
-	dev_info(&instance->u.usb_dev->dev,
-		 "cxacru: MAC = %02x", instance->u.atm_dev->esi[0]);
-	for (ret = 1; ret < sizeof(instance->u.atm_dev->esi); ret++)
-		printk(":%02x", instance->u.atm_dev->esi[ret]);
-	printk("\n");
+		/* Read MAC address */
+		ret = cxacru_cm(instance, CM_REQUEST_CARD_GET_MAC_ADDRESS, NULL, 0, 
+				esi, sizeof(esi));
+		if (ret < 0) {
+			err("cxacru_adsl_start: CARD_GET_MAC_ADDRESS returned %d", ret);
+			goto out;
+		}
+
+		/* FIXME: remove dev from args; should have been set in probe */
+		ret = udsl_instance_setup(instance->u.usb_dev, &instance->u);
+		if (ret)
+			goto out;
+		memcpy(instance->u.atm_dev->esi, esi, sizeof(esi));
+		/* FIXME: remove */
+		instance->u.status = UDSL_LOADED_FIRMWARE;
+
+		dev_info(&instance->u.usb_dev->dev, "cxacru: MAC = %02x", esi[0]);
+		for (ret = 1; ret < sizeof(esi); ret++)
+			printk(":%02x", esi[ret]);
+		printk("\n");
+	}
 
 	/* start ADSL */
 	ret = cxacru_cm(instance, CM_REQUEST_CHIP_ADSL_LINE_START, NULL, 0, NULL, 0);
 	if (ret < 0) {
-		err("cxacru_got_firmware: CHIP_ADSL_LINE_START returned %d", ret);
-		instance->u.status = UDSL_NO_FIRMWARE;
+		err("cxacru_adst_start: CHIP_ADSL_LINE_START returned %d", ret);
 		goto out;
 	}
 	
 	/* Start status polling */
 	cxacru_do_timer_poll(instance);
 
-	instance->u.status = UDSL_LOADED_FIRMWARE;
 	tasklet_schedule(&instance->u.receive_tasklet);
- out:
-	up(&instance->u.serialize);
-	wake_up_interruptible(&instance->u.firmware_waiters);
+out:
+	up(&instance->start_serialize);
 }
 
 static void cxacru_poll_status(struct cxacru_instance_data *instance)
@@ -543,7 +556,7 @@
 	ret = cxacru_fw(instance, FW_WRITE_MEM, 0x2, 0x0, PLLFCLK_ADDR, (u8 *) &val, 4);
 	if (ret) {
 		err("FirmwarePllFClkValue failed: %d", ret);
-		goto fail;
+		return;
 	}
 
 	/* FirmwarePllBClkValue */
@@ -551,7 +564,7 @@
 	ret = cxacru_fw(instance, FW_WRITE_MEM, 0x2, 0x0, PLLBCLK_ADDR, (u8 *) &val, 4);
 	if (ret) {
 		err("FirmwarePllBClkValue failed: %d", ret);
-		goto fail;
+		return;
 	}
 
 	/* Enable SDRAM */
@@ -559,14 +572,14 @@
 	ret = cxacru_fw(instance, FW_WRITE_MEM, 0x2, 0x0, SDRAMEN_ADDR, (u8 *) &val, 4);
 	if (ret) {
 		err("Enable SDRAM failed: %d", ret);
-		goto fail;
+		return;
 	}
 
 	/* Firmware */
 	ret = cxacru_fw(instance, FW_WRITE_MEM, 0x2, 0x0, FW_ADDR, fw->data, fw->size);
 	if (ret) {
 		err("Firmware upload failed: %d", ret);
-		goto fail;
+		return;
 	}
 
 	/* Boot ROM patch */
@@ -574,7 +587,7 @@
 		ret = cxacru_fw(instance, FW_WRITE_MEM, 0x2, 0x0, BR_ADDR, br->data, br->size);
 		if (ret) {
 			err("Boot ROM patching failed: %d", ret);
-			goto fail;
+			return;
 		}
 	}
 
@@ -583,7 +596,7 @@
 	ret = cxacru_fw(instance, FW_WRITE_MEM, 0x2, 0x0, SIG_ADDR, (u8 *) &val, 4);
 	if (ret) {
 		err("Signature storing failed: %d", ret);
-		goto fail;
+		return;
 	}
 
 	if (br) {
@@ -595,7 +608,7 @@
 	}
 	if (ret) {
 		err("Passing control to firmware failed: %d", ret);
-		goto fail;
+		return;
 	}
 
 	/* Delay to allow firmware to start up. We can do this here
@@ -610,7 +623,7 @@
 	ret = cxacru_cm(instance, CM_REQUEST_CARD_GET_STATUS, NULL, 0, NULL, 0);
 	if (ret < 0) {
 		err("modem failed to initialize: %d", ret);
-		goto fail;
+		return;
 	}
 	
 	/* Load config data (le32), doing one packet at a time */
@@ -626,7 +639,7 @@
 				(u8 *) buf, len, NULL, 0);
 		if (ret < 0) {
 			err("load config data failed: %d", ret);
-			goto fail;
+			return;
 		}
 	}
 
@@ -634,11 +647,7 @@
 
 	dbg("done setting up the modem");
 
-	cxacru_got_firmware(instance, 1);
-	return;
-
- fail:
-	cxacru_got_firmware(instance, 0);
+	cxacru_adsl_start(instance);
 }
 
 static int cxacru_find_firmware(struct cxacru_instance_data *instance,
@@ -679,38 +688,14 @@
 		release_firmware(fw);
 	}
 
-	/* In case we failed, set state back to NO_FIRMWARE so that
-	   another later attempt may work. Otherwise, we never actually
-	   manage to recover if, for example, the firmware is on /usr and
-	   we look for it too early. */
-	cxacru_got_firmware(instance, 0);
-
 	module_put(THIS_MODULE);
-	udsl_put_instance(&instance->u);
 	return 0;
 }
-#endif /* USE_FW_LOADER */
 
 static void cxacru_firmware_start(struct cxacru_instance_data *instance)
 {
-#ifdef USE_FW_LOADER
 	int ret;
-#endif
-
-	dbg("cxacru_firmware_start");
-
-	down(&instance->u.serialize);	/* vs self, cxacru_got_firmware */
-
-	if (instance->u.status >= UDSL_LOADING_FIRMWARE) {
-		up(&instance->u.serialize);
-		return;
-	}
-
-	instance->u.status = UDSL_LOADING_FIRMWARE;
-	up(&instance->u.serialize);
 
-#ifdef USE_FW_LOADER
-	udsl_get_instance(&instance->u);
 	try_module_get(THIS_MODULE);
 
 	ret = kernel_thread(cxacru_load_firmware, instance,
@@ -722,23 +707,8 @@
 	dbg("cxacru_firmware_start: kernel_thread failed (%d)!", ret);
 
 	module_put(THIS_MODULE);
-	udsl_put_instance(&instance->u);
-	/* Just pretend it never happened... hope modem_run happens */
-#endif				/* USE_FW_LOADER */
-
-	cxacru_got_firmware(instance, 0);
-}
-
-static int cxacru_firmware_wait(struct udsl_instance_data *instance)
-{
-	cxacru_firmware_start((void *)instance);
-
-	if (wait_event_interruptible(instance->firmware_waiters,
-				instance->status != UDSL_LOADING_FIRMWARE) < 0)
-		return -ERESTARTSYS;
-
-	return (instance->status == UDSL_LOADED_FIRMWARE) ? 0 : -EAGAIN;
 }
+#endif /* USE_FW_LOADER */
 
 static int cxacru_usb_ioctl(struct usb_interface *intf, unsigned int code,
 			      void *user_data)
@@ -754,7 +724,7 @@
 
 	switch (code) {
 	case UDSL_IOCTL_LINE_UP:
-		cxacru_got_firmware(instance, 1);
+		cxacru_adsl_start(instance);
 		return (instance->u.status == UDSL_LOADED_FIRMWARE) ? 0 : -EIO;
 	case UDSL_IOCTL_LINE_DOWN:
 		cxacru_cm(instance, CM_REQUEST_CHIP_ADSL_LINE_STOP, NULL, 0, NULL, 0);
@@ -810,14 +780,10 @@
 	}
 
 	instance->u.data_endpoint = CXACRU_EP_DATA;
-	instance->u.firmware_wait = cxacru_firmware_wait;
 	instance->u.snd_padding = 11;
 	instance->u.rcv_padding = 3;
 	instance->u.driver_name = cxacru_driver_name;
-
-	ret = udsl_instance_setup(dev, &instance->u);
-	if (ret)
-		goto fail;
+	instance->u.usb_dev = dev;
 
 	usb_fill_int_urb(instance->rcv_urb, dev, usb_rcvintpipe(dev, CXACRU_EP_CMD),
 			 instance->rcv_buf, PAGE_SIZE,
@@ -829,6 +795,7 @@
 			 cxacru_blocking_completion, &instance->snd_done, 4);
 	instance->snd_urb->transfer_flags |= URB_ASYNC_UNLINK;
 
+	init_MUTEX(&instance->start_serialize);
 	init_MUTEX(&instance->cm_serialize);
 
 	init_timer(&instance->poll_timer);
@@ -837,22 +804,10 @@
 
 	INIT_WORK(&instance->poll_work, (void *)cxacru_poll_status, instance);
 
-	/* First check whether the modem already seems to be alive */
-	/*
-	ret = cxacru_cm(instance, CM_REQUEST_CARD_GET_STATUS, NULL, 0, NULL, 0);
-	if (ret < 0)
-	*/
-		cxacru_firmware_start(instance);
-	/*
-	else {
-		dbg("firmware appears to be already loaded");
-		cxacru_got_firmware(instance, 1);
-		cxacru_poll_status(instance);
-	}
-	*/
-
 	usb_set_intfdata(intf, instance);
 
+	cxacru_adsl_start(instance);
+
 	return 0;
 
  fail:
@@ -896,6 +851,7 @@
 
 	/* clean up */
 	usb_set_intfdata(intf, NULL);
+	/* FIXME: do we need this refcount? */
 	udsl_put_instance(&instance->u);
 }
 




More information about the Usbatm-commits mailing list