patch-2.3.4 linux/drivers/usb/acm.c

Next file: linux/drivers/usb/audio.c
Previous file: linux/drivers/usb/Makefile
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v2.3.3/linux/drivers/usb/acm.c linux/drivers/usb/acm.c
@@ -3,9 +3,19 @@
  *
  * Armin Fuerst 5/8/1999
  *
- * version 0.0: Driver sets up configuration, setus up data pipes, opens misc
+ * version 0.2: Improved Bulk transfer. TX led now flashes every time data is
+ * sent. Send Encapsulated Data is not needed, nor does it do anything.
+ * Why's that ?!? Thanks to Thomas Sailer for his close look at the bulk code.
+ * He told me about some importand bugs. (5/21/99)
+ *
+ * version 0.1: Bulk transfer for uhci seems to work now, no dangling tds any
+ * more. TX led of the ISDN TA flashed the first time. Does this mean it works?
+ * The interrupt of the ctrl endpoint crashes the kernel => no read possible
+ * (5/19/99)
+ *
+ * version 0.0: Driver sets up configuration, sets up data pipes, opens misc
  * device. No actual data transfer is done, since we don't have bulk transfer,
- * yet. Purely skeleton for now.
+ * yet. Purely skeleton for now. (5/8/99)
  */
 
 #include <linux/kernel.h>
@@ -13,10 +23,11 @@
 #include <linux/signal.h>
 #include <linux/errno.h>
 #include <linux/miscdevice.h>
-#include <linux/random.h>
 #include <linux/poll.h>
 #include <linux/init.h>
 #include <linux/malloc.h>
+#include <linux/config.h>
+#include <linux/module.h>
 
 #include <asm/spinlock.h>
 
@@ -27,8 +38,12 @@
 struct acm_state {
 	int present; /* this acm is plugged in */
 	int active; /* someone is has this acm's device open */
+	int serstate; /* Status of the serial port (rate, handshakelines,...) */
 	struct usb_device *dev;
-	unsigned int readpipe,writepipe;
+	unsigned ctrlbuffer;	/*buffer for control messages*/
+	unsigned int readendp,writeendp,ctrlendp;
+	unsigned int readpipe,writepipe,ctrlpipe;
+	char buffer;
 };
 
 static struct acm_state static_acm_state;
@@ -37,16 +52,44 @@
 
 static int acm_irq(int state, void *__buffer, void *dev_id)
 {
-/*
-	signed char *data = __buffer;
+//	unsigned char *data = __buffer;
         struct acm_state *acm = &static_acm_state; 
+        devrequest *dr;
+
+        dr=__buffer;
+	printk("ACM_USB_IRQ\n");
+        printk("reqtype: %02X\n",dr->requesttype);
+        printk("request: %02X\n",dr->request);
+	printk("wValue: %02X\n",dr->value);
+	printk("wIndex: %02X\n",dr->index);
+	printk("wLength: %02X\n",dr->length);
+	
+	switch(dr->request) {
+	  //Network connection 
+	  case 0x00:
+	    printk("Network connection: ");
+	    if (dr->request==0) printk("disconnected\n");
+	    if (dr->request==1) printk("connected\n");
+	    break;
+
+    	  //Response available
+	  case 0x01:
+	    printk("Response available\n");
+	    acm->buffer=1;
+	    break;
+	
+	  //Set serial line state
+	  case 0x20:
+	    if ((dr->index==1)&&(dr->length==2)) {
+	      acm->serstate=acm->ctrlbuffer;
+	      printk("Serstate: %02X\n",acm->ctrlbuffer);
+	    }
+	    break;
+	}
+/*
 	if(!acm->active)
 		return 1;
 */
-
-	/*We should so something useful here*/
-	printk("ACM_USB_IRQ\n");
-
 	return 1;
 }
 
@@ -76,22 +119,48 @@
 static ssize_t write_acm(struct file * file,
        const char * buffer, size_t count, loff_t *ppos)
 {
-        char * buffer="ABCDEFGHIJKLMNOPQRSTUVWXYZ";
+        devrequest dr;
 	struct acm_state *acm = &static_acm_state;
+	unsigned long retval;	        
+
 	printk("USB_FILE_WRITE\n");
-		printk("writing:>%s<\n",buffer);
-		acm->dev->bus->op->bulk_msg(acm->dev,acm->writepipe,buffer, 26);
-		printk("done:>%s<\n",buffer);
-		printk("reading:>%s<\n",buffer);
-		acm->dev->bus->op->bulk_msg(acm->dev,acm->readpipe,buffer, 26);
-		printk("done:>%s<\n",buffer);
+//Huh, i seem to got that wrong, we don't need this ?!?
+/*
+	dr.requesttype = USB_TYPE_CLASS | USB_RT_ENDPOINT;
+	dr.request = 0;
+	dr.value = 0;
+	dr.index = acm->writeendp;
+	dr.length = count;
+	acm->dev->bus->op->control_msg(acm->dev, usb_sndctrlpipe(acm->dev, 0), &dr, NULL, 0);
+*/	
+
+	acm->dev->bus->op->bulk_msg(acm->dev,&acm->writepipe,buffer, count, &retval);
 	return -EINVAL;
 }
 
-static ssize_t read_acm(struct file * file, char * buffer, size_t count, loff_t *ppos)
+
+static ssize_t read_acm(struct file * file, const char * buffer, size_t count, loff_t *ppos)
 {
+	devrequest dr;
+        struct acm_state *acm = &static_acm_state;
+	unsigned long retval;
 	printk("USB_FILE_READ\n");
-	return -EINVAL;
+//        if (!acm->buffer) return -1;
+     	acm->buffer=0;
+//We don't need this
+/*
+	printk("writing control msg\n");
+	dr.requesttype = USB_TYPE_CLASS | USB_RT_ENDPOINT | 0x80;
+	dr.request = 1;
+	dr.value = 0;
+	dr.index = acm->readendp;
+	dr.length = 0;
+	acm->dev->bus->op->control_msg(acm->dev, usb_sndctrlpipe(acm->dev, 0), &dr, NULL, 0);
+*/
+	printk("reading:>%s<\n",buffer);
+	acm->dev->bus->op->bulk_msg(acm->dev,&acm->readpipe,buffer, 1,&retval);
+	printk("done:>%s<\n",buffer);
+	return 1;
 }
 
 struct file_operations usb_acm_fops = {
@@ -165,10 +234,14 @@
 		printk("USB ACM found\n");
 		usb_set_configuration(dev, dev->config[cfgnum].bConfigurationValue);
 		acm->dev=dev;
-		acm->readpipe=__create_pipe(dev,&dev->config[cfgnum].interface[1].endpoint[0]);
-		acm->writepipe=__create_pipe(dev,&dev->config[cfgnum].interface[1].endpoint[1]);
-		usb_request_irq(dev, usb_rcvctrlpipe(dev,&dev->config[cfgnum].interface[0].endpoint[0]), acm_irq, endpoint->bInterval, NULL);
+		acm->readendp=dev->config[cfgnum].interface[1].endpoint[0].bEndpointAddress;
+		acm->writeendp=dev->config[cfgnum].interface[1].endpoint[1].bEndpointAddress;
+		acm->ctrlendp=dev->config[cfgnum].interface[0].endpoint[0].bEndpointAddress;
+		acm->readpipe=usb_rcvbulkpipe(dev,acm->readendp);
+		acm->writepipe=usb_sndbulkpipe(dev,acm->writeendp);
+		usb_request_irq(dev,acm->ctrlpipe=usb_rcvctrlpipe(dev,acm->ctrlendp), acm_irq, dev->config[cfgnum].interface[0].endpoint[0].bInterval, &acm->ctrlbuffer);
 		acm->present = 1;
+		acm->buffer=0;
 		return 0;
 	}
 
@@ -203,7 +276,7 @@
 	return 0;
 }
 
-#if 0
+#ifdef MODULE
 
 int init_module(void)
 {

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)