コード例 #1
0
ファイル: printer.c プロジェクト: Antares84/asuswrt-merlin
static int usblp_set_protocol(struct usblp *usblp, int protocol)
{
	int r, alts;

	if (protocol < USBLP_FIRST_PROTOCOL || protocol > USBLP_LAST_PROTOCOL)
		return -EINVAL;

	alts = usblp->protocol[protocol].alt_setting;
	if (alts < 0) return -EINVAL;
	r = usb_set_interface(usblp->dev, usblp->ifnum, alts);
	if (r < 0) {
		err("can't set desired altsetting %d on interface %d",
			alts, usblp->ifnum);
		return r;
	}

	FILL_BULK_URB(&usblp->writeurb, usblp->dev,
		usb_sndbulkpipe(usblp->dev,
		 usblp->protocol[protocol].epwrite->bEndpointAddress),
		usblp->buf, 0,
		usblp_bulk, usblp);

	usblp->bidir = (usblp->protocol[protocol].epread != 0);
	if (usblp->bidir)
		FILL_BULK_URB(&usblp->readurb, usblp->dev,
			usb_rcvbulkpipe(usblp->dev,
			 usblp->protocol[protocol].epread->bEndpointAddress),
			usblp->buf + USBLP_BUF_SIZE, USBLP_BUF_SIZE,
			usblp_bulk, usblp);

	usblp->current_protocol = protocol;
	dbg("usblp%d set protocol %d", usblp->minor, protocol);
	return 0;
}
コード例 #2
0
ファイル: rtl8150.c プロジェクト: JBTech/ralink_rt5350
static int rtl8150_start_xmit(struct sk_buff *skb, struct net_device *netdev)
{
	rtl8150_t *dev;
	int count, res;

	netif_stop_queue(netdev);
	dev = netdev->priv;
	count = (skb->len < 60) ? 60 : skb->len;
	count = (count & 0x3f) ? count : count + 1;
	memcpy(dev->tx_buff, skb->data, skb->len);
	FILL_BULK_URB(dev->tx_urb, dev->udev, usb_sndbulkpipe(dev->udev, 2),
		      dev->tx_buff, count, write_bulk_callback, dev);
	dev->tx_urb->transfer_buffer_length = count;

	if ((res = usb_submit_urb(dev->tx_urb))) {
		warn("failed tx_urb %d\n", res);
		dev->stats.tx_errors++;
		netif_start_queue(netdev);
	} else {
		dev->stats.tx_packets++;
		dev->stats.tx_bytes += skb->len;
		netdev->trans_start = jiffies;
	}
	dev_kfree_skb(skb);

	return 0;
}
コード例 #3
0
ファイル: rtl8150.c プロジェクト: JBTech/ralink_rt5350
static int rtl8150_open(struct net_device *netdev)
{
	rtl8150_t *dev;
	int res;

	dev = netdev->priv;
	if (dev == NULL) {
		return -ENODEV;
	}

	down(&dev->sem);

	set_registers(dev, IDR, 6, netdev->dev_addr);
	
	FILL_BULK_URB(dev->rx_urb, dev->udev, usb_rcvbulkpipe(dev->udev, 1),
		      dev->rx_buff, RTL8150_MAX_MTU, read_bulk_callback, dev);
	if ((res = usb_submit_urb(dev->rx_urb)))
		warn("%s: rx_urb submit failed: %d", __FUNCTION__, res);
	FILL_INT_URB(dev->intr_urb, dev->udev, usb_rcvintpipe(dev->udev, 3),
		     dev->intr_buff, sizeof(dev->intr_buff), intr_callback,
		     dev, dev->intr_interval);
	if ((res = usb_submit_urb(dev->intr_urb)))
		warn("%s: intr_urb submit failed: %d", __FUNCTION__, res);
	netif_start_queue(netdev);
	enable_net_traffic(dev);
	up(&dev->sem);

	return res;
}
コード例 #4
0
ファイル: pcan_usb_core.c プロジェクト: ESE519/LemonAid
//****************************************************************************
// start and stop functions for CAN data IN and OUT
static int pcan_usb_start(struct pcandev *dev)
{
	int err = 0;
	USB_PORT *u = &dev->port.usb;
	struct pcan_usb_interface *usb_if = u->usb_if;

	DPRINTK(KERN_DEBUG "%s: %s(CAN#%d), minor = %d.\n", 
	        DEVICE_NAME, __FUNCTION__, u->dev_ctrl_index, dev->nMinor);

	/* if not, wait for packet on the interface */
	if (!atomic_read(&usb_if->read_data.use_count))
	{
		FILL_BULK_URB(&usb_if->read_data, usb_if->usb_dev,
		              usb_rcvbulkpipe(usb_if->usb_dev, 
		                              usb_if->pipe_read.ucNumber),
		              usb_if->read_buffer_addr[0], usb_if->read_buffer_size, 
		              pcan_usb_read_notify, usb_if);

		// submit urb
		if ((err = __usb_submit_urb(&usb_if->read_data)))
			printk(KERN_ERR "%s: %s() can't submit! (%d)\n", 
		          DEVICE_NAME, __FUNCTION__, err);
		else
			atomic_inc(&usb_if->active_urbs);
	}

	return err;
}
コード例 #5
0
ファイル: microtek.c プロジェクト: fgeraci/cs518-sched
inline static
void mts_int_submit_urb (struct urb* transfer,
			int pipe,
			void* data,
			unsigned length,
			mts_usb_urb_callback callback )
/* Interrupt context! */

/* Holding transfer->context->lock! */
{
	int res;

	MTS_INT_INIT();

	FILL_BULK_URB(transfer,
		      context->instance->usb_dev,
		      pipe,
		      data,
		      length,
		      callback,
		      context
		);

	transfer->status = 0;

	res = usb_submit_urb( transfer );
	if ( res ) {
		MTS_INT_ERROR( "could not submit URB! Error was %d\n",(int)res );
		context->srb->result = DID_ERROR << 16;
		mts_transfer_cleanup(transfer);
	}
	return;
}
コード例 #6
0
ファイル: CDCEther.c プロジェクト: liexusong/Linux-2.4.16
static int CDCEther_start_xmit( struct sk_buff *skb, struct net_device *net )
{
	ether_dev_t	*ether_dev = net->priv;
	int 	count;
	int 	res;

	// If we are told to transmit an ethernet frame that fits EXACTLY 
	// into an integer number of USB packets, we force it to send one 
	// more byte so the device will get a runt USB packet signalling the 
	// end of the ethernet frame
	if ( (skb->len) ^ (ether_dev->data_ep_out_size) ) {
		// It was not an exact multiple
		// no need to add anything extra
		count = skb->len;
	} else {
		// Add one to make it NOT an exact multiple
		count = skb->len + 1;
	}

	// Tell the kernel, "No more frames 'til we are done
	// with this one.'
	netif_stop_queue( net );

	// Copy it from kernel memory to OUR memory
	memcpy(ether_dev->tx_buff, skb->data, skb->len);

	// Fill in the URB for shipping it out.
	FILL_BULK_URB( &ether_dev->tx_urb, ether_dev->usb,
			usb_sndbulkpipe(ether_dev->usb, ether_dev->data_ep_out),
			ether_dev->tx_buff, ether_dev->wMaxSegmentSize, 
			write_bulk_callback, ether_dev );

	// Tell the URB how much it will be transporting today
	ether_dev->tx_urb.transfer_buffer_length = count;
	
	// Send the URB on its merry way.
	if ((res = usb_submit_urb(&ether_dev->tx_urb)))  {
		// Hmm...  It didn't go. Tell someone...
		warn("failed tx_urb %d", res);
		// update some stats...
		ether_dev->stats.tx_errors++;
		// and tell the kernel to give us another.
		// Maybe we'll get it right next time.
		netif_start_queue( net );
	} else {
		// Okay, it went out.
		// Update statistics
		ether_dev->stats.tx_packets++;
		ether_dev->stats.tx_bytes += skb->len;
		// And tell the kernel when the last transmit occurred.
		net->trans_start = jiffies;
	}

	// We are done with the kernel's memory
	dev_kfree_skb(skb);

	// We are done here.
	return 0;
}
コード例 #7
0
ファイル: ir-usb.c プロジェクト: liexusong/Linux-2.4.16
static int ir_open (struct usb_serial_port *port, struct file *filp)
{
	struct usb_serial *serial = port->serial;
	char *buffer;
	int result = 0;

	if (port_paranoia_check (port, __FUNCTION__))
		return -ENODEV;
	
	dbg(__FUNCTION__ " - port %d", port->number);

	down (&port->sem);
	
	++port->open_count;
	MOD_INC_USE_COUNT;
	
	if (!port->active) {
		port->active = 1;

		if (buffer_size) {
			/* override the default buffer sizes */
			buffer = kmalloc (buffer_size, GFP_KERNEL);
			if (!buffer) {
				err (__FUNCTION__ " - out of memory.");
				return -ENOMEM;
			}
			kfree (port->read_urb->transfer_buffer);
			port->read_urb->transfer_buffer = buffer;
			port->read_urb->transfer_buffer_length = buffer_size;

			buffer = kmalloc (buffer_size, GFP_KERNEL);
			if (!buffer) {
				err (__FUNCTION__ " - out of memory.");
				return -ENOMEM;
			}
			kfree (port->write_urb->transfer_buffer);
			port->write_urb->transfer_buffer = buffer;
			port->write_urb->transfer_buffer_length = buffer_size;
			port->bulk_out_size = buffer_size;
		}

		/* Start reading from the device */
		FILL_BULK_URB(port->read_urb, serial->dev, 
			      usb_rcvbulkpipe(serial->dev, port->bulk_in_endpointAddress),
			      port->read_urb->transfer_buffer, port->read_urb->transfer_buffer_length,
			      ir_read_bulk_callback, port);
		result = usb_submit_urb(port->read_urb);
		if (result)
			err(__FUNCTION__ " - failed submitting read urb, error %d", result);
	}
	
	up (&port->sem);
	
	return result;
}
コード例 #8
0
ファイル: usbserial.c プロジェクト: nhanh0/hah
static int generic_write (struct usb_serial_port *port, int from_user, const unsigned char *buf, int count)
{
	struct usb_serial *serial = port->serial;
	int result;

	dbg(__FUNCTION__ " - port %d", port->number);

	if (count == 0) {
		dbg(__FUNCTION__ " - write request of 0 bytes");
		return (0);
	}

	/* only do something if we have a bulk out endpoint */
	if (serial->num_bulk_out) {
		if (port->write_urb->status == -EINPROGRESS) {
			dbg (__FUNCTION__ " - already writing");
			return (0);
		}

		count = (count > port->bulk_out_size) ? port->bulk_out_size : count;

		if (from_user) {
			if (copy_from_user(port->write_urb->transfer_buffer, buf, count))
				return -EFAULT;
		}
		else {
			memcpy (port->write_urb->transfer_buffer, buf, count);
		}  

		usb_serial_debug_data (__FILE__, __FUNCTION__, count, port->write_urb->transfer_buffer);

		/* set up our urb */
		FILL_BULK_URB(port->write_urb, serial->dev, 
			      usb_sndbulkpipe(serial->dev, port->bulk_out_endpointAddress),
			      port->write_urb->transfer_buffer, count,
			      ((serial->type->write_bulk_callback) ? 
			       serial->type->write_bulk_callback : 
			       generic_write_bulk_callback), 
			      port);

		/* send the data out the bulk port */
		result = usb_submit_urb(port->write_urb);
		if (result)
			err(__FUNCTION__ " - failed submitting write urb, error %d", result);
		else
			result = count;

		return result;
	}
	
	/* no bulk out, so return 0 bytes written */
	return (0);
} 
コード例 #9
0
ファイル: microtek.c プロジェクト: fgeraci/cs518-sched
static
int mts_scsi_queuecommand( Scsi_Cmnd *srb, mts_scsi_cmnd_callback callback )
{
	struct mts_desc* desc = (struct mts_desc*)(srb->host->hostdata[0]);
	int err = 0;
	int res;

	MTS_DEBUG_GOT_HERE();
	mts_show_command(srb);
	mts_debug_dump(desc);

	if ( srb->device->lun || srb->device->id || srb->device->channel ) {

		MTS_DEBUG("Command to LUN=%d ID=%d CHANNEL=%d from SCSI layer\n",(int)srb->device->lun,(int)srb->device->id, (int)srb->device->channel );

		MTS_DEBUG("this device doesn't exist\n");

		srb->result = DID_BAD_TARGET << 16;

		if(callback)
			callback(srb);

		goto out;
	}

	
	FILL_BULK_URB(&desc->urb,
		      desc->usb_dev,
		      usb_sndbulkpipe(desc->usb_dev,desc->ep_out),
		      srb->cmnd,
		      srb->cmd_len,
		      mts_command_done,
		      &desc->context
		      );


	mts_build_transfer_context( srb, desc );
	desc->context.final_callback = callback;
	
	res=usb_submit_urb(&desc->urb);

	if(res){
		MTS_ERROR("error %d submitting URB\n",(int)res);
		srb->result = DID_ERROR << 16;

		if(callback)
			callback(srb);

	}

out:
	return err;
}
コード例 #10
0
ファイル: rtl8150.c プロジェクト: JBTech/ralink_rt5350
static void read_bulk_callback(struct urb *urb)
{
	rtl8150_t *dev;
	int pkt_len, res;
	struct sk_buff *skb;
	struct net_device *netdev;
	u16 rx_stat;

	dev = urb->context;
	if (!dev) {
		warn("!dev");
		return;
	}
	netdev = dev->netdev;
	if (!netif_device_present(netdev)) {
		warn("netdev is not present");
		return;
	}
	switch (urb->status) {
	case 0:
		break;
	case -ENOENT:
		return;
	case -ETIMEDOUT:
		warn("need a device reset?..");
		goto goon;
	default:
		warn("Rx status %d", urb->status);
		goto goon;
	}

	pkt_len = urb->actual_length - 4;
	rx_stat = le16_to_cpu(*(u16 *) (dev->rx_buff + pkt_len));

	if (!(skb = dev_alloc_skb(pkt_len + 2)))
		goto goon;
	skb->dev = netdev;
	skb_reserve(skb, 2);
	eth_copy_and_sum(skb, dev->rx_buff, pkt_len, 0);
	skb_put(skb, pkt_len);
	skb->protocol = eth_type_trans(skb, netdev);
	netif_rx(skb);
	dev->stats.rx_packets++;
	dev->stats.rx_bytes += pkt_len;
goon:
	FILL_BULK_URB(dev->rx_urb, dev->udev, usb_rcvbulkpipe(dev->udev, 1),
		      dev->rx_buff, RTL8150_MAX_MTU, read_bulk_callback, dev);
	if ((res = usb_submit_urb(dev->rx_urb)))
		warn("%s: Rx urb submission failed %d", netdev->name, res);
}
コード例 #11
0
ファイル: usbserial.c プロジェクト: nhanh0/hah
static void generic_read_bulk_callback (struct urb *urb)
{
	struct usb_serial_port *port = (struct usb_serial_port *)urb->context;
	struct usb_serial *serial = get_usb_serial (port, __FUNCTION__);
	struct tty_struct *tty;
	unsigned char *data = urb->transfer_buffer;
	int i;
	int result;

	dbg(__FUNCTION__ " - port %d", port->number);
	
	if (!serial) {
		dbg(__FUNCTION__ " - bad serial pointer, exiting");
		return;
	}

	if (urb->status) {
		dbg(__FUNCTION__ " - nonzero read bulk status received: %d", urb->status);
		return;
	}

	usb_serial_debug_data (__FILE__, __FUNCTION__, urb->actual_length, data);

	tty = port->tty;
	if (urb->actual_length) {
		for (i = 0; i < urb->actual_length ; ++i) {
			/* if we insert more than TTY_FLIPBUF_SIZE characters, we drop them. */
			if(tty->flip.count >= TTY_FLIPBUF_SIZE) {
				tty_flip_buffer_push(tty);
			}
			/* this doesn't actually push the data through unless tty->low_latency is set */
			tty_insert_flip_char(tty, data[i], 0);
		}
	  	tty_flip_buffer_push(tty);
	}

	/* Continue trying to always read  */
	FILL_BULK_URB(port->read_urb, serial->dev, 
		      usb_rcvbulkpipe(serial->dev, port->bulk_in_endpointAddress),
		      port->read_urb->transfer_buffer, port->read_urb->transfer_buffer_length,
		      ((serial->type->read_bulk_callback) ?
		       serial->type->read_bulk_callback :
		       generic_read_bulk_callback), 
		      port);
	result = usb_submit_urb(port->read_urb);
	if (result)
		err(__FUNCTION__ " - failed resubmitting read urb, error %d", result);
}
コード例 #12
0
ファイル: rtusb_bulk.c プロジェクト: AxelLin/Drv
void RTusb_fill_bulk_urb (struct urb *pUrb,
	struct usb_device *pUsb_Dev,
	unsigned int bulkpipe,
	void *pTransferBuf,
	int BufSize,
	usb_complete_t Complete,
	void *pContext)
{

#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
	usb_fill_bulk_urb(pUrb, pUsb_Dev, bulkpipe, pTransferBuf, BufSize, Complete, pContext);	
#else
	FILL_BULK_URB(pUrb, pUsb_Dev, bulkpipe, pTransferBuf, BufSize, Complete, pContext);
#endif

}
コード例 #13
0
ファイル: UmasTransport.c プロジェクト: brucetsao/Nuvoton
/*
 *  This is our function to emulate usb_bulk_msg() but give us enough
 *  access to make aborts/resets work
 */
static int  usb_stor_bulk_msg(UMAS_DATA_T *umas, void *data, int pipe,
                              uint32_t len, uint32_t *act_len)
{
    URB_T   *urb = umas->current_urb;
    volatile int  t0;
    int     status;

    /* fill the URB */
    FILL_BULK_URB(urb, umas->pusb_dev, pipe, data, len,
                  usb_stor_blocking_completion, NULL);
    urb->actual_length = 0;
    urb->error_count = 0;
    urb->transfer_flags = USB_ASYNC_UNLINK;

    _UmasUrbComplete = 0;

    /* submit the URB */
    status = USBH_SubmitUrb(urb);
    if(status)
        return status;

#if 1
    for(t0 = 0; t0 < 0x1000000; t0++)
    {
        if(is_urb_completed())
            break;
    }
    if(t0 >= 0x8000000)
#else
    t0 = umas_get_ticks();
    while(umas_get_ticks() - t0 < 500)
    {
        if(is_urb_completed())
            break;
    }
    if(umas_get_ticks() - t0 >= 500)
#endif
    {
        UMAS_DEBUG("usb_stor_bulk_msg time-out failed!\n");
        return USB_ERR_TIMEOUT;
    }

    /* return the actual length of the data transferred */
    *act_len = urb->actual_length;

    return urb->status;
}
コード例 #14
0
ファイル: usbserial.c プロジェクト: nhanh0/hah
/*****************************************************************************
 * generic devices specific driver functions
 *****************************************************************************/
static int generic_open (struct usb_serial_port *port, struct file *filp)
{
	struct usb_serial *serial = port->serial;
	int result = 0;

	if (port_paranoia_check (port, __FUNCTION__))
		return -ENODEV;

	/* only increment our usage count, if this device is _really_ a generic device */
	if_generic_do(MOD_INC_USE_COUNT);

	dbg(__FUNCTION__ " - port %d", port->number);

	down (&port->sem);
	
	++port->open_count;
	
	if (!port->active) {
		port->active = 1;

		/* force low_latency on so that our tty_push actually forces the data through, 
		   otherwise it is scheduled, and with high data rates (like with OHCI) data
		   can get lost. */
		port->tty->low_latency = 1;
		
		/* if we have a bulk interrupt, start reading from it */
		if (serial->num_bulk_in) {
			/* Start reading from the device */
			FILL_BULK_URB(port->read_urb, serial->dev, 
				      usb_rcvbulkpipe(serial->dev, port->bulk_in_endpointAddress),
				      port->read_urb->transfer_buffer, port->read_urb->transfer_buffer_length,
				      ((serial->type->read_bulk_callback) ?
				       serial->type->read_bulk_callback :
				       generic_read_bulk_callback), 
				      port);
			result = usb_submit_urb(port->read_urb);
			if (result)
				err(__FUNCTION__ " - failed resubmitting read urb, error %d", result);
		}
	}
	
	up (&port->sem);
	
	return result;
}
コード例 #15
0
ファイル: rtl8150.c プロジェクト: iwangv/edimax-br-6528n
static int rtl8150_open(struct net_device *netdev)
{
	rtl8150_t *dev;
	int res;

	dev = netdev->priv;
	if (dev == NULL) {
		return -ENODEV;
	}

	down(&dev->sem);

	set_registers(dev, IDR, 6, netdev->dev_addr);
	
	FILL_BULK_URB(dev->rx_urb, dev->udev, usb_rcvbulkpipe(dev->udev, 1),
		      dev->rx_buff, RTL8150_MAX_MTU, read_bulk_callback, dev);
	if ((res = usb_submit_urb(dev->rx_urb)))
		warn("%s: rx_urb submit failed: %d", __FUNCTION__, res);
	FILL_INT_URB(dev->intr_urb, dev->udev, usb_rcvintpipe(dev->udev, 3),
		     dev->intr_buff, sizeof(dev->intr_buff), intr_callback,
		     dev, dev->intr_interval);
	if ((res = usb_submit_urb(dev->intr_urb)))
		warn("%s: intr_urb submit failed: %d", __FUNCTION__, res);
	netif_start_queue(netdev);
	enable_net_traffic(dev);
	up(&dev->sem);

#ifdef CONFIG_RTL865XB_3G
	{

		if (0!=reCore_registerWANDevice(netdev))
			printk("XXX Can't register wan device\n");	

		if(0!=devglue_regExtDevice(netdev->name, 8, CONFIG_RTL865XB_3G_PORT, &myLinkID2))
			printk("XXX Can't register a link ID for device %s on extPort 0x%x!!!\n", netdev->name,CONFIG_RTL865XB_3G_PORT );
		else
			printk("Device %s on vlan ID %d using Link ID %d. Loopback/Ext port is %d\n", netdev->name, 8,  myLinkID2, CONFIG_RTL865XB_3G_PORT);
	}
#endif	

	return res;
}
コード例 #16
0
ファイル: transport.c プロジェクト: niubl/camera_project
/* This is our function to emulate usb_bulk_msg() but give us enough
 * access to make aborts/resets work
 */
int usb_stor_bulk_msg(struct us_data *us, void *data, int pipe,
		      unsigned int len, unsigned int *act_len)
{
	struct completion urb_done;
	int status;

	/* set up data structures for the wakeup system */
	init_completion(&urb_done);

	/* lock the URB */
	down(&(us->current_urb_sem));

	/* fill the URB */
	FILL_BULK_URB(us->current_urb, us->pusb_dev, pipe, data, len,
		      usb_stor_blocking_completion, &urb_done);
		      

		      
	us->current_urb->actual_length = 0;
	us->current_urb->error_count = 0;
	us->current_urb->transfer_flags = USB_ASYNC_UNLINK;

	/* submit the URB */
	status = usb_submit_urb(us->current_urb);
	if (status) {
		/* something went wrong */
		up(&(us->current_urb_sem));
		return status;
	}

	/* wait for the completion of the URB */
	up(&(us->current_urb_sem));
	wait_for_completion(&urb_done);
	down(&(us->current_urb_sem));

	/* return the actual length of the data transferred */
	*act_len = us->current_urb->actual_length;

	/* release the lock and return status */
	up(&(us->current_urb_sem));
	return us->current_urb->status;
}
コード例 #17
0
ファイル: hci_usb.c プロジェクト: TitaniumBoy/lin
static int hci_usb_write_msg(struct hci_usb *husb, struct sk_buff *skb)
{
	struct urb *urb = husb->write_urb;
	int pipe, status;

	DBG("%s len %d", husb->hdev.name, skb->len);

	pipe = usb_sndbulkpipe(husb->udev, husb->bulk_out_ep_addr);

	FILL_BULK_URB(urb, husb->udev, pipe, skb->data, skb->len,
	              hci_usb_bulk_write, skb);
	urb->transfer_flags |= USB_QUEUE_BULK;

	if ((status = usb_submit_urb(urb))) {
		DBG("%s write URB submit failed %d", husb->hdev.name, status);
		return status;
	}

	return 0;
}
コード例 #18
0
ファイル: ir-usb.c プロジェクト: liexusong/Linux-2.4.16
static void ir_read_bulk_callback (struct urb *urb)
{
	struct usb_serial_port *port = (struct usb_serial_port *)urb->context;
	struct usb_serial *serial = get_usb_serial (port, __FUNCTION__);
	struct tty_struct *tty;
	unsigned char *data = urb->transfer_buffer;
	int result;

	if (port_paranoia_check (port, __FUNCTION__))
		return;

	dbg(__FUNCTION__ " - port %d", port->number);

	if (!serial) {
		dbg(__FUNCTION__ " - bad serial pointer, exiting");
		return;
	}

	if (urb->status) {
		dbg(__FUNCTION__ " - nonzero read bulk status received: %d", urb->status);
		return;
	}

	usb_serial_debug_data (__FILE__, __FUNCTION__, urb->actual_length, data);

	/* Bypass flip-buffers, and feed the ldisc directly due to our 
	 * potentally large buffer size.  Since we used to set low_latency,
	 * this is exactly what the tty layer did anyway :) */
	tty = port->tty;
	tty->ldisc.receive_buf(tty, data+1, NULL, urb->actual_length-1);

	/* Continue trying to always read  */
	FILL_BULK_URB(port->read_urb, serial->dev, 
		      usb_rcvbulkpipe(serial->dev, port->bulk_in_endpointAddress),
		      port->read_urb->transfer_buffer, port->read_urb->transfer_buffer_length,
		      ir_read_bulk_callback, port);
	result = usb_submit_urb(port->read_urb);
	if (result)
		err(__FUNCTION__ " - failed resubmitting read urb, error %d", result);
	return;
}
コード例 #19
0
ファイル: microtek.c プロジェクト: davidbau/davej
inline static
void mts_int_submit_urb (struct urb* transfer,
			int pipe,
			void* data,
			unsigned length,
			mts_usb_urb_callback callback )
/* Interrupt context! */

/* Holding transfer->context->lock! */
{
	int res;
	struct mts_transfer_context* context;
	
	MTS_INT_INIT();
	
	FILL_BULK_URB(transfer,
		      context->instance->usb_dev,
		      pipe,
		      data,
		      length,
		      callback,
		      context
		);

/*	transfer->transfer_flags = USB_DISABLE_SPD;*/
	transfer->transfer_flags = USB_ASYNC_UNLINK;
	transfer->status = 0;
	transfer->timeout = 100;

	res = usb_submit_urb( transfer );
	if ( res ) {
		MTS_INT_ERROR( "could not submit URB! Error was %d\n",(int)res );
		context->srb->result = DID_ERROR << 16;
		context->state = mts_con_error;
		mts_transfer_cleanup(transfer);
	}
	return;
}
コード例 #20
0
ファイル: CDCEther.c プロジェクト: liexusong/Linux-2.4.16
static int CDCEther_open(struct net_device *net)
{
	ether_dev_t *ether_dev = (ether_dev_t *)net->priv;
	int	res;

	// We are finally getting used!
	MOD_INC_USE_COUNT;

	// Turn on the USB and let the packets flow!!!
	if ( (res = enable_net_traffic( ether_dev )) ) {
		err( __FUNCTION__ "can't enable_net_traffic() - %d", res );
		MOD_DEC_USE_COUNT;
		return -EIO;
	}

	// Prep a receive URB
	FILL_BULK_URB( &ether_dev->rx_urb, ether_dev->usb,
			usb_rcvbulkpipe(ether_dev->usb, ether_dev->data_ep_in),
			ether_dev->rx_buff, ether_dev->wMaxSegmentSize, 
			read_bulk_callback, ether_dev );

	// Put it out there so the device can send us stuff
	if ( (res = usb_submit_urb(&ether_dev->rx_urb)) )
	{
		// Hmm...  Okay...
		warn( __FUNCTION__ " failed rx_urb %d", res );
	}

	// Tell the kernel we are ready to start receiving from it
	netif_start_queue( net );
	
	// We are up and running.
	ether_dev->flags |= CDC_ETHER_RUNNING;

	// Let's get ready to move frames!!!
	return 0;
}
コード例 #21
0
ファイル: empeg.c プロジェクト: JBTech/ralink_rt5350
/******************************************************************************
 * Empeg specific driver functions
 ******************************************************************************/
static int empeg_open (struct usb_serial_port *port, struct file *filp)
{
	struct usb_serial *serial = port->serial;
	int result = 0;;

	if (port_paranoia_check (port, __FUNCTION__))
		return -ENODEV;

	dbg("%s - port %d", __FUNCTION__, port->number);

	/* Force default termio settings */
	empeg_set_termios (port, NULL) ;

	bytes_in = 0;
	bytes_out = 0;

	/* Start reading from the device */
	FILL_BULK_URB(
		port->read_urb,
		serial->dev, 
		usb_rcvbulkpipe(serial->dev,
			port->bulk_in_endpointAddress),
		port->read_urb->transfer_buffer,
		port->read_urb->transfer_buffer_length,
		empeg_read_bulk_callback,
		port);

	port->read_urb->transfer_flags |= USB_QUEUE_BULK;

	result = usb_submit_urb(port->read_urb);

	if (result)
		err("%s - failed submitting read urb, error %d", __FUNCTION__, result);

	return result;
}
コード例 #22
0
static void *usblp_probe(struct usb_device *dev, unsigned int ifnum)
{
    struct usb_interface_descriptor *interface;
    struct usb_endpoint_descriptor *epread, *epwrite;
    struct usblp *usblp;
    int minor, i, alts = -1, bidir = 0;
    int length, err;
    char *buf;

    for (i = 0; i < dev->actconfig->interface[ifnum].num_altsetting; i++) {

        interface = &dev->actconfig->interface[ifnum].altsetting[i];

        if (interface->bInterfaceClass != 7 || interface->bInterfaceSubClass != 1 ||
                interface->bInterfaceProtocol < 1 || interface->bInterfaceProtocol > 3 ||
                (interface->bInterfaceProtocol > 1 && interface->bNumEndpoints < 2))
            continue;

        if (alts == -1)
            alts = i;

        if (!bidir && interface->bInterfaceProtocol > 1) {
            bidir = 1;
            alts = i;
        }
    }

    if (alts == -1)
        return NULL;

    interface = &dev->actconfig->interface[ifnum].altsetting[alts];
    if (usb_set_interface(dev, ifnum, alts))
        err("can't set desired altsetting %d on interface %d", alts, ifnum);

    epwrite = interface->endpoint + 0;
    epread = bidir ? interface->endpoint + 1 : NULL;

    if ((epwrite->bEndpointAddress & 0x80) == 0x80) {
        if (interface->bNumEndpoints == 1)
            return NULL;
        epwrite = interface->endpoint + 1;
        epread = bidir ? interface->endpoint + 0 : NULL;
    }

    if ((epwrite->bEndpointAddress & 0x80) == 0x80)
        return NULL;

    if (bidir && (epread->bEndpointAddress & 0x80) != 0x80)
        return NULL;

    for (minor = 0; minor < USBLP_MINORS && usblp_table[minor]; minor++);
    if (usblp_table[minor]) {
        err("no more free usblp devices");
        return NULL;
    }

    if (!(usblp = kmalloc(sizeof(struct usblp), GFP_KERNEL))) {
        err("out of memory");
        return NULL;
    }
    memset(usblp, 0, sizeof(struct usblp));

    usblp->dev = dev;
    usblp->ifnum = ifnum;
    usblp->minor = minor;
    usblp->bidir = bidir;

    init_waitqueue_head(&usblp->wait);

    if (!(buf = kmalloc(USBLP_BUF_SIZE * (bidir ? 2 : 1), GFP_KERNEL))) {
        err("out of memory");
        kfree(usblp);
        return NULL;
    }

    if (!(usblp->device_id_string = kmalloc(DEVICE_ID_SIZE, GFP_KERNEL))) {
        err("out of memory");
        kfree(usblp);
        kfree(buf);
        return NULL;
    }

    FILL_BULK_URB(&usblp->writeurb, dev, usb_sndbulkpipe(dev, epwrite->bEndpointAddress),
                  buf, 0, usblp_bulk, usblp);

    if (bidir)
        FILL_BULK_URB(&usblp->readurb, dev, usb_rcvbulkpipe(dev, epread->bEndpointAddress),
                      buf + USBLP_BUF_SIZE, USBLP_BUF_SIZE, usblp_bulk, usblp);

    /* Get the device_id string if possible. FIXME: Could make this kmalloc(length). */
    err = usblp_get_id(usblp, 0, usblp->device_id_string, DEVICE_ID_SIZE - 1);
    if (err >= 0) {
        length = (usblp->device_id_string[0] << 8) + usblp->device_id_string[1]; /* big-endian */
        if (length < DEVICE_ID_SIZE)
            usblp->device_id_string[length] = '\0';
        else
            usblp->device_id_string[DEVICE_ID_SIZE - 1] = '\0';
        dbg ("usblp%d Device ID string [%d]=%s",
             minor, length, &usblp->device_id_string[2]);
    }
    else {
        err ("usblp%d: error = %d reading IEEE-1284 Device ID string",
             minor, err);
        usblp->device_id_string[0] = usblp->device_id_string[1] = '\0';
    }

#ifdef DEBUG
    usblp_check_status(usblp);
#endif

    info("usblp%d: USB %sdirectional printer dev %d if %d alt %d",
         minor, bidir ? "Bi" : "Uni", dev->devnum, ifnum, alts);

    return usblp_table[minor] = usblp;
}
コード例 #23
0
static void * usb_hpna_probe( struct usb_device *dev, unsigned int ifnum )
{
//	struct net_device 		*net_dev;
	struct device 		*net_dev;
	usb_hpna_t			*hpna = &usb_dev_hpna;
#ifdef PEGASUS_PRINT_PRODUCT_NAME
	int dev_index;
#endif

	spinlock_t xxx = { };

#ifdef PEGASUS_PRINT_PRODUCT_NAME /* XXX */
	if ( (dev_index = match_product(dev->descriptor.idVendor,
				dev->descriptor.idProduct)) == -1 ) {
		return NULL;
	}

	printk("USB Ethernet(Pegasus) %s found\n",
					product_list[dev_index].name);
#else
	if ( dev->descriptor.idVendor != ADMTEK_VENDOR_ID ||
	     dev->descriptor.idProduct != ADMTEK_HPNA_PEGASUS ) {
		return	NULL;
	}

	printk("USB HPNA Pegasus found\n");
#endif

	if ( usb_set_configuration(dev, dev->config[0].bConfigurationValue)) {
		err("usb_set_configuration() failed");
		return NULL;
	}

	hpna->usb_dev = dev;

	hpna->rx_pipe = usb_rcvbulkpipe(hpna->usb_dev, 1);
	hpna->tx_pipe = usb_sndbulkpipe(hpna->usb_dev, 2);
	hpna->intr_pipe = usb_rcvintpipe(hpna->usb_dev, 0);

	if ( reset_mac(dev) ) {
		err("can't reset MAC");
	}

	hpna->present = 1;

	if(!(hpna->rx_buff=kmalloc(MAX_MTU, GFP_KERNEL))) {
		err("not enough mem for out buff");
		return	NULL;
	}
	if(!(hpna->tx_buff=kmalloc(MAX_MTU, GFP_KERNEL))) {
		kfree_s(hpna->rx_buff, MAX_MTU);
		err("not enough mem for out buff");
		return	NULL;
	}

	net_dev = init_etherdev( 0, 0 );
	hpna->net_dev = net_dev;
	net_dev->priv = hpna;
	net_dev->open = hpna_open;
	net_dev->stop = hpna_close;
//	net_dev->watchdog_timeo = TX_TIMEOUT;
//	net_dev->tx_timeout = tx_timeout;
	net_dev->do_ioctl = hpna_ioctl; 
	net_dev->hard_start_xmit = hpna_start_xmit;
	net_dev->set_multicast_list = set_rx_mode;
	net_dev->get_stats = hpna_netdev_stats; 
	net_dev->mtu = HPNA_MTU;
#if 1
{
/*
 * to support dhcp client daemon(dhcpcd), it needs to get HW address
 * in probe routine.
 */
	struct usb_device *usb_dev = hpna->usb_dev;
	__u8	node_id[6];
	
	if ( get_node_id(usb_dev, node_id) ) {
		printk("USB Pegasus can't get HW address in probe routine.\n");
		printk("But Pegasus will re-try in open routine.\n");
		goto next;
	}
	hpna_set_registers(usb_dev, 0x10, 6, node_id);
	memcpy(net_dev->dev_addr, node_id, 6);
}
next:
#endif
	hpna->hpna_lock = xxx;	//SPIN_LOCK_UNLOCKED;
	
	FILL_BULK_URB( &hpna->rx_urb, hpna->usb_dev, hpna->rx_pipe, 
			hpna->rx_buff, MAX_MTU, hpna_read_irq, net_dev );
	FILL_BULK_URB( &hpna->tx_urb, hpna->usb_dev, hpna->tx_pipe, 
			hpna->tx_buff, MAX_MTU, hpna_write_irq, net_dev );
	FILL_INT_URB( &hpna->intr_urb, hpna->usb_dev, hpna->intr_pipe,
			hpna->intr_buff, 8, hpna_irq, net_dev, 250 );
	
/*	list_add( &hpna->list, &hpna_list );*/
	
	return	net_dev; 
}
コード例 #24
0
ファイル: visor.c プロジェクト: iwangv/edimax-br-6528n
static int visor_write (struct usb_serial_port *port, int from_user, const unsigned char *buf, int count)
{
	struct usb_serial *serial = port->serial;
	struct urb *urb;
	const unsigned char *current_position = buf;
	unsigned long flags;
	int status;
	int i;
	int bytes_sent = 0;
	int transfer_size;

	dbg("%s - port %d", __FUNCTION__, port->number);

	while (count > 0) {
		/* try to find a free urb in our list of them */
		urb = NULL;
		spin_lock_irqsave (&write_urb_pool_lock, flags);
		for (i = 0; i < NUM_URBS; ++i) {
			if (write_urb_pool[i]->status != -EINPROGRESS) {
				urb = write_urb_pool[i];
				break;
			}
		}
		spin_unlock_irqrestore (&write_urb_pool_lock, flags);
		if (urb == NULL) {
			dbg("%s - no more free urbs", __FUNCTION__);
			goto exit;
		}
		if (urb->transfer_buffer == NULL) {
			urb->transfer_buffer = kmalloc (URB_TRANSFER_BUFFER_SIZE, GFP_KERNEL);
			if (urb->transfer_buffer == NULL) {
				err("%s no more kernel memory...", __FUNCTION__);
				goto exit;
			}
		}
		
		transfer_size = min (count, URB_TRANSFER_BUFFER_SIZE);
		if (from_user) {
			if (copy_from_user (urb->transfer_buffer, current_position, transfer_size)) {
				bytes_sent = -EFAULT;
				break;
			}
		} else {
			memcpy (urb->transfer_buffer, current_position, transfer_size);
		}

		usb_serial_debug_data (__FILE__, __FUNCTION__, transfer_size, urb->transfer_buffer);

		/* build up our urb */
		FILL_BULK_URB (urb, serial->dev, usb_sndbulkpipe(serial->dev, port->bulk_out_endpointAddress), 
				urb->transfer_buffer, transfer_size, visor_write_bulk_callback, port);
		urb->transfer_flags |= USB_QUEUE_BULK;

		/* send it down the pipe */
		status = usb_submit_urb(urb);
		if (status) {
			err("%s - usb_submit_urb(write bulk) failed with status = %d", __FUNCTION__, status);
			bytes_sent = status;
			break;
		}

		current_position += transfer_size;
		bytes_sent += transfer_size;
		count -= transfer_size;
		bytes_out += transfer_size;
	}

exit:
	return bytes_sent;
} 
コード例 #25
0
ファイル: CDCEther.c プロジェクト: liexusong/Linux-2.4.16
static void read_bulk_callback( struct urb *urb )
{
	ether_dev_t *ether_dev = urb->context;
	struct net_device *net;
	int count = urb->actual_length, res;
	struct sk_buff	*skb;

	// Sanity check 
	if ( !ether_dev || !(ether_dev->flags & CDC_ETHER_RUNNING) ) {
		dbg("BULK IN callback but driver is not active!");
		return;
	}

	net = ether_dev->net;
	if ( !netif_device_present(net) ) {
		// Somebody killed our network interface...
		return;
	}

	if ( ether_dev->flags & CDC_ETHER_RX_BUSY ) {
		// Are we already trying to receive a frame???
		ether_dev->stats.rx_errors++;
		dbg("ether_dev Rx busy");
		return;
	}

	// We are busy, leave us alone!
	ether_dev->flags |= CDC_ETHER_RX_BUSY;

	switch ( urb->status ) {
		case USB_ST_NOERROR:
			break;
		case USB_ST_NORESPONSE:
			dbg( "no repsonse in BULK IN" );
			ether_dev->flags &= ~CDC_ETHER_RX_BUSY;
			break;
		default:
			dbg( "%s: RX status %d", net->name, urb->status );
			goto goon;
	}

	// Check to make sure we got some data...
	if ( !count ) {
		// We got no data!!!
		goto goon;
	}

	// Tell the kernel we want some memory
	if ( !(skb = dev_alloc_skb(count)) ) {
		// We got no receive buffer.
		goto goon;
	}

	// Here's where it came from
	skb->dev = net;
	
	// Now we copy it over
	eth_copy_and_sum(skb, ether_dev->rx_buff, count, 0);
	
	// Not sure
	skb_put(skb, count);
	// Not sure here either
	skb->protocol = eth_type_trans(skb, net);
	
	// Ship it off to the kernel
	netif_rx(skb);
	
	// update out statistics
	ether_dev->stats.rx_packets++;
	ether_dev->stats.rx_bytes += count;

goon:
	// Prep the USB to wait for another frame
	FILL_BULK_URB( &ether_dev->rx_urb, ether_dev->usb,
			usb_rcvbulkpipe(ether_dev->usb, ether_dev->data_ep_in),
			ether_dev->rx_buff, ether_dev->wMaxSegmentSize, 
			read_bulk_callback, ether_dev );
			
	// Give this to the USB subsystem so it can tell us 
	// when more data arrives.
	if ( (res = usb_submit_urb(&ether_dev->rx_urb)) ) {
		warn( __FUNCTION__ " failed submint rx_urb %d", res);
	}
	
	// We are no longer busy, show us the frames!!!
	ether_dev->flags &= ~CDC_ETHER_RX_BUSY;
}
コード例 #26
0
/**
 *	skel_write
 */
static ssize_t skel_write (struct file *file, const char *buffer, size_t count, loff_t *ppos)
{
	struct usb_skel *dev;
	ssize_t bytes_written = 0;
	int retval = 0;

	dev = (struct usb_skel *)file->private_data;

	dbg(__FUNCTION__ " - minor %d, count = %d", dev->minor, count);

	/* lock this object */
	down (&dev->sem);

	/* verify that the device wasn't unplugged */
	if (dev->udev == NULL) {
		retval = -ENODEV;
		goto exit;
	}

	/* verify that we actually have some data to write */
	if (count == 0) {
		dbg(__FUNCTION__ " - write request of 0 bytes");
		goto exit;
	}

	/* see if we are already in the middle of a write */
	if (dev->write_urb->status == -EINPROGRESS) {
		dbg (__FUNCTION__ " - already writing");
		goto exit;
	}

	/* we can only write as much as 1 urb will hold */
	bytes_written = (count > dev->bulk_out_size) ? 
				dev->bulk_out_size : count;

	/* copy the data from userspace into our urb */
	if (copy_from_user(dev->write_urb->transfer_buffer, buffer, 
			   bytes_written)) {
		retval = -EFAULT;
		goto exit;
	}

	usb_skel_debug_data (__FUNCTION__, bytes_written, 
			     dev->write_urb->transfer_buffer);

	/* set up our urb */
	FILL_BULK_URB(dev->write_urb, dev->udev, 
		      usb_sndbulkpipe(dev->udev, dev->bulk_out_endpointAddr),
		      dev->write_urb->transfer_buffer, bytes_written,
		      skel_write_bulk_callback, dev);

	/* send the data out the bulk port */
	retval = usb_submit_urb(dev->write_urb);
	if (retval) {
		err(__FUNCTION__ " - failed submitting write urb, error %d",
		    retval);
	} else {
		retval = bytes_written;
	}

exit:
	/* unlock the device */
	up (&dev->sem);

	return retval;
}
コード例 #27
0
ファイル: hci_usb.c プロジェクト: TitaniumBoy/lin
static void * hci_usb_probe(struct usb_device *udev, unsigned int ifnum, const struct usb_device_id *id)
{
	struct usb_endpoint_descriptor *bulk_out_ep, *intr_in_ep, *bulk_in_ep;
	struct usb_interface_descriptor *uif;
	struct usb_endpoint_descriptor *ep;
	struct hci_usb *husb;
	struct hci_dev *hdev;
	int i, size, pipe;
	__u8 * buf;

	DBG("udev %p ifnum %d", udev, ifnum);

	/* Check device signature */
	if ((udev->descriptor.bDeviceClass    != HCI_DEV_CLASS)   ||
	    (udev->descriptor.bDeviceSubClass != HCI_DEV_SUBCLASS)||
	    (udev->descriptor.bDeviceProtocol != HCI_DEV_PROTOCOL) )
		return NULL;

	MOD_INC_USE_COUNT;

	uif = &udev->actconfig->interface[ifnum].altsetting[0];

	if (uif->bNumEndpoints != 3) {
		DBG("Wrong number of endpoints %d", uif->bNumEndpoints);
		MOD_DEC_USE_COUNT;
		return NULL;
	}

	bulk_out_ep = intr_in_ep = bulk_in_ep = NULL;

	/* Find endpoints that we need */
	for ( i = 0; i < uif->bNumEndpoints; ++i) {
		ep = &uif->endpoint[i];

		switch (ep->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) {
			case USB_ENDPOINT_XFER_BULK:
				if (ep->bEndpointAddress & USB_DIR_IN)
					bulk_in_ep  = ep;
				else
					bulk_out_ep = ep;
				break;

			case USB_ENDPOINT_XFER_INT:
				intr_in_ep = ep;
				break;
		};
	}

	if (!bulk_in_ep || !bulk_out_ep || !intr_in_ep) {
		DBG("Endpoints not found: %p %p %p", bulk_in_ep, bulk_out_ep, intr_in_ep);
		MOD_DEC_USE_COUNT;
		return NULL;
	}

	if (!(husb = kmalloc(sizeof(struct hci_usb), GFP_KERNEL))) {
		ERR("Can't allocate: control structure");
		MOD_DEC_USE_COUNT;
		return NULL;
	}

	memset(husb, 0, sizeof(struct hci_usb));

	husb->udev = udev;
	husb->bulk_out_ep_addr = bulk_out_ep->bEndpointAddress;

	if (!(husb->ctrl_urb = usb_alloc_urb(0))) {
		ERR("Can't allocate: control URB");
		goto probe_error;
	}

	if (!(husb->write_urb = usb_alloc_urb(0))) {
		ERR("Can't allocate: write URB");
		goto probe_error;
	}

	if (!(husb->read_urb = usb_alloc_urb(0))) {
		ERR("Can't allocate: read URB");
		goto probe_error;
	}

	ep = bulk_in_ep;
	pipe = usb_rcvbulkpipe(udev, ep->bEndpointAddress);
	size = HCI_MAX_FRAME_SIZE;

	if (!(buf = kmalloc(size, GFP_KERNEL))) {
		ERR("Can't allocate: read buffer");
		goto probe_error;
	}

	FILL_BULK_URB(husb->read_urb, udev, pipe, buf, size, hci_usb_bulk_read, husb);
	husb->read_urb->transfer_flags |= USB_QUEUE_BULK;

	ep = intr_in_ep;
	pipe = usb_rcvintpipe(udev, ep->bEndpointAddress);
	size = usb_maxpacket(udev, pipe, usb_pipeout(pipe));

	if (!(husb->intr_urb = usb_alloc_urb(0))) {
		ERR("Can't allocate: interrupt URB");
		goto probe_error;
	}

	if (!(buf = kmalloc(size, GFP_KERNEL))) {
		ERR("Can't allocate: interrupt buffer");
		goto probe_error;
	}

	FILL_INT_URB(husb->intr_urb, udev, pipe, buf, size, hci_usb_intr, husb, ep->bInterval);

	skb_queue_head_init(&husb->tx_ctrl_q);
	skb_queue_head_init(&husb->tx_write_q);

	/* Initialize and register HCI device */
	hdev = &husb->hdev;

	hdev->type = HCI_USB;
	hdev->driver_data = husb;

	hdev->open  = hci_usb_open;
	hdev->close = hci_usb_close;
	hdev->flush = hci_usb_flush;
	hdev->send	= hci_usb_send_frame;

	if (hci_register_dev(hdev) < 0) {
		ERR("Can't register HCI device %s", hdev->name);
		goto probe_error;
	}

	return husb;

probe_error:
	hci_usb_free_bufs(husb);
	kfree(husb);
	MOD_DEC_USE_COUNT;
	return NULL;
}
コード例 #28
0
ファイル: mdc800.c プロジェクト: NieHao/Tomato-RAF
/*
 * Callback to search the Mustek MDC800 on the USB Bus
 */
static void* mdc800_usb_probe (struct usb_device *dev ,unsigned int ifnum,
			       const struct usb_device_id *id)
{
	int i,j;
	struct usb_interface_descriptor	*intf_desc;
	int irq_interval=0;

	dbg ("(mdc800_usb_probe) called.");


	if (mdc800->dev != 0)
	{
		warn ("only one Mustek MDC800 is supported.");
		return 0;
	}

	if (dev->descriptor.bNumConfigurations != 1)
	{
		err ("probe fails -> wrong Number of Configuration");
		return 0;
	}
	intf_desc=&dev->actconfig->interface[ifnum].altsetting[0];

	if (
			( intf_desc->bInterfaceClass != 0xff )
		||	( intf_desc->bInterfaceSubClass != 0 )
		|| ( intf_desc->bInterfaceProtocol != 0 )
		|| ( intf_desc->bNumEndpoints != 4)
	)
	{
		err ("probe fails -> wrong Interface");
		return 0;
	}

	/* Check the Endpoints */
	for (i=0; i<4; i++)
	{
		mdc800->endpoint[i]=-1;
		for (j=0; j<4; j++)
		{
			if (mdc800_endpoint_equals (&intf_desc->endpoint [j],&mdc800_ed [i]))
			{
				mdc800->endpoint[i]=intf_desc->endpoint [j].bEndpointAddress ;
				if (i==1)
				{
					irq_interval=intf_desc->endpoint [j].bInterval;
				}

				continue;
			}
		}
		if (mdc800->endpoint[i] == -1)
		{
			err ("probe fails -> Wrong Endpoints.");
			return 0;
		}
	}


	usb_driver_claim_interface (&mdc800_usb_driver, &dev->actconfig->interface[ifnum], mdc800);
	if (usb_set_interface (dev, ifnum, 0) < 0)
	{
		err ("MDC800 Configuration fails.");
		return 0;
	}

	info ("Found Mustek MDC800 on USB.");

	down (&mdc800->io_lock);

	mdc800->dev=dev;
	mdc800->open=0;

	/* Setup URB Structs */
	FILL_INT_URB (
		mdc800->irq_urb,
		mdc800->dev,
		usb_rcvintpipe (mdc800->dev,mdc800->endpoint [1]),
		mdc800->irq_urb_buffer,
		8,
		mdc800_usb_irq,
		mdc800,
		irq_interval
	);

	FILL_BULK_URB (
		mdc800->write_urb,
		mdc800->dev,
		usb_sndbulkpipe (mdc800->dev, mdc800->endpoint[0]),
		mdc800->write_urb_buffer,
		8,
		mdc800_usb_write_notify,
		mdc800
	);

	FILL_BULK_URB (
		mdc800->download_urb,
		mdc800->dev,
		usb_rcvbulkpipe (mdc800->dev, mdc800->endpoint [3]),
		mdc800->download_urb_buffer,
		64,
		mdc800_usb_download_notify,
		mdc800
	);

	mdc800->state=READY;

	up (&mdc800->io_lock);
	
	return mdc800;
}
コード例 #29
0
/**
 *	skel_probe
 *
 *	Called by the usb core when a new device is connected that it thinks
 *	this driver might be interested in.
 */
static void * skel_probe(struct usb_device *udev, unsigned int ifnum, const struct usb_device_id *id)
{
	struct usb_skel *dev = NULL;
	struct usb_interface *interface;
	struct usb_interface_descriptor *iface_desc;
	struct usb_endpoint_descriptor *endpoint;
	int minor;
	int buffer_size;
	int i;
	char name[10];

	
	/* See if the device offered us matches what we can accept */
	if ((udev->descriptor.idVendor != USB_SKEL_VENDOR_ID) ||
	    (udev->descriptor.idProduct != USB_SKEL_PRODUCT_ID)) {
		return NULL;
	}

	/* select a "subminor" number (part of a minor number) */
	down (&minor_table_mutex);
	for (minor = 0; minor < MAX_DEVICES; ++minor) {
		if (minor_table[minor] == NULL)
			break;
	}
	if (minor >= MAX_DEVICES) {
		info ("Too many devices plugged in, can not handle this device.");
		goto exit;
	}

	/* allocate memory for our device state and intialize it */
	dev = kmalloc (sizeof(struct usb_skel), GFP_KERNEL);
	if (dev == NULL) {
		err ("Out of memory");
		goto exit;
	}
	memset (dev, 0x00, sizeof (*dev));
	minor_table[minor] = dev;

	interface = &udev->actconfig->interface[ifnum];

	init_MUTEX (&dev->sem);
	dev->udev = udev;
	dev->interface = interface;
	dev->minor = minor;

	/* set up the endpoint information */
	/* check out the endpoints */
	iface_desc = &interface->altsetting[0];
	for (i = 0; i < iface_desc->bNumEndpoints; ++i) {
		endpoint = &iface_desc->endpoint[i];

		if ((endpoint->bEndpointAddress & 0x80) &&
		    ((endpoint->bmAttributes & 3) == 0x02)) {
			/* we found a bulk in endpoint */
			buffer_size = endpoint->wMaxPacketSize;
			dev->bulk_in_size = buffer_size;
			dev->bulk_in_endpointAddr = endpoint->bEndpointAddress;
			dev->bulk_in_buffer = kmalloc (buffer_size, GFP_KERNEL);
			if (!dev->bulk_in_buffer) {
				err("Couldn't allocate bulk_in_buffer");
				goto error;
			}
		}
		
		if (((endpoint->bEndpointAddress & 0x80) == 0x00) &&
		    ((endpoint->bmAttributes & 3) == 0x02)) {
			/* we found a bulk out endpoint */
			dev->write_urb = usb_alloc_urb(0);
			if (!dev->write_urb) {
				err("No free urbs available");
				goto error;
			}
			buffer_size = endpoint->wMaxPacketSize;
			dev->bulk_out_size = buffer_size;
			dev->bulk_out_endpointAddr = endpoint->bEndpointAddress;
			dev->bulk_out_buffer = kmalloc (buffer_size, GFP_KERNEL);
			if (!dev->bulk_out_buffer) {
				err("Couldn't allocate bulk_out_buffer");
				goto error;
			}
			FILL_BULK_URB(dev->write_urb, udev, 
				      usb_sndbulkpipe(udev, 
						      endpoint->bEndpointAddress),
				      dev->bulk_out_buffer, buffer_size,
				      skel_write_bulk_callback, dev);
		}
	}

	/* initialize the devfs node for this device and register it */
	sprintf(name, "skel%d", dev->minor);
	
	dev->devfs = devfs_register (usb_devfs_handle, name,
				     DEVFS_FL_DEFAULT, USB_MAJOR,
				     USB_SKEL_MINOR_BASE + dev->minor,
				     S_IFCHR | S_IRUSR | S_IWUSR | 
				     S_IRGRP | S_IWGRP | S_IROTH, 
				     &skel_fops, NULL);

	/* let the user know what node this device is now attached to */
	info ("USB Skeleton device now attached to USBSkel%d", dev->minor);
	goto exit;
	
error:
	skel_delete (dev);
	dev = NULL;

exit:
	up (&minor_table_mutex);
	return dev;
}
コード例 #30
0
ファイル: printer.c プロジェクト: liexusong/Linux-2.4.16
static void *usblp_probe(struct usb_device *dev, unsigned int ifnum,
			 const struct usb_device_id *id)
{
	struct usb_interface_descriptor *interface;
	struct usb_endpoint_descriptor *epread, *epwrite;
	struct usblp *usblp;
	int minor, i, bidir = 0, quirks;
	int alts = dev->actconfig->interface[ifnum].act_altsetting;
	int length, err;
	char *buf;
	char name[6];

	/* If a bidirectional interface exists, use it. */
	for (i = 0; i < dev->actconfig->interface[ifnum].num_altsetting; i++) {

		interface = &dev->actconfig->interface[ifnum].altsetting[i];

		if (interface->bInterfaceClass != 7 || interface->bInterfaceSubClass != 1 ||
		    interface->bInterfaceProtocol < 1 || interface->bInterfaceProtocol > 3 ||
		   (interface->bInterfaceProtocol > 1 && interface->bNumEndpoints < 2))
			continue;

		if (interface->bInterfaceProtocol > 1) {
			bidir = 1;
			alts = i;
			break;
		}
	}

	interface = &dev->actconfig->interface[ifnum].altsetting[alts];
	if (usb_set_interface(dev, ifnum, alts))
		err("can't set desired altsetting %d on interface %d", alts, ifnum);

	epwrite = interface->endpoint + 0;
	epread = bidir ? interface->endpoint + 1 : NULL;

	if ((epwrite->bEndpointAddress & 0x80) == 0x80) {
		if (interface->bNumEndpoints == 1)
			return NULL;
		epwrite = interface->endpoint + 1;
		epread = bidir ? interface->endpoint + 0 : NULL;
	}

	if ((epwrite->bEndpointAddress & 0x80) == 0x80)
		return NULL;

	if (bidir && (epread->bEndpointAddress & 0x80) != 0x80)
		return NULL;

	for (minor = 0; minor < USBLP_MINORS && usblp_table[minor]; minor++);
	if (usblp_table[minor]) {
		err("no more free usblp devices");
		return NULL;
	}

	if (!(usblp = kmalloc(sizeof(struct usblp), GFP_KERNEL))) {
		err("out of memory");
		return NULL;
	}
	memset(usblp, 0, sizeof(struct usblp));
	init_MUTEX (&usblp->sem);

	/* lookup quirks for this printer */
	quirks = usblp_quirks(dev->descriptor.idVendor, dev->descriptor.idProduct);

	if (bidir && (quirks & USBLP_QUIRK_BIDIR)) {
		bidir = 0;
		epread = NULL;
		info ("Disabling reads from problem bidirectional printer on usblp%d",
			minor);
	}

	usblp->dev = dev;
	usblp->ifnum = ifnum;
	usblp->minor = minor;
	usblp->bidir = bidir;
	usblp->quirks = quirks;

	init_waitqueue_head(&usblp->wait);

	if (!(buf = kmalloc(USBLP_BUF_SIZE * (bidir ? 2 : 1), GFP_KERNEL))) {
		err("out of memory");
		kfree(usblp);
		return NULL;
	}

	if (!(usblp->device_id_string = kmalloc(DEVICE_ID_SIZE, GFP_KERNEL))) {
		err("out of memory");
		kfree(usblp);
		kfree(buf);
		return NULL;
	}

	FILL_BULK_URB(&usblp->writeurb, dev, usb_sndbulkpipe(dev, epwrite->bEndpointAddress),
		buf, 0, usblp_bulk, usblp);

	if (bidir)
		FILL_BULK_URB(&usblp->readurb, dev, usb_rcvbulkpipe(dev, epread->bEndpointAddress),
			buf + USBLP_BUF_SIZE, USBLP_BUF_SIZE, usblp_bulk, usblp);

	/* Get the device_id string if possible. FIXME: Could make this kmalloc(length). */
	err = usblp_get_id(usblp, 0, usblp->device_id_string, DEVICE_ID_SIZE - 1);
	if (err >= 0) {
		length = (usblp->device_id_string[0] << 8) + usblp->device_id_string[1]; /* big-endian */
		if (length < DEVICE_ID_SIZE)
			usblp->device_id_string[length] = '\0';
		else
			usblp->device_id_string[DEVICE_ID_SIZE - 1] = '\0';
		dbg ("usblp%d Device ID string [%d]=%s",
			minor, length, &usblp->device_id_string[2]);
	}
	else {
		err ("usblp%d: error = %d reading IEEE-1284 Device ID string",
			minor, err);
		usblp->device_id_string[0] = usblp->device_id_string[1] = '\0';
	}

#ifdef DEBUG
	usblp_check_status(usblp, 0);
#endif

	sprintf(name, "lp%d", minor);

	/* if we have devfs, create with perms=660 */
	usblp->devfs = devfs_register(usb_devfs_handle, name,
				      DEVFS_FL_DEFAULT, USB_MAJOR,
				      USBLP_MINOR_BASE + minor,
				      S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP |
				      S_IWGRP, &usblp_fops, NULL);

	info("usblp%d: USB %sdirectional printer dev %d if %d alt %d",
		minor, bidir ? "Bi" : "Uni", dev->devnum, ifnum, alts);

	return usblp_table[minor] = usblp;
}