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

📄 ub.c

📁 linux 内核源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
	int ifnum = sc->intf->cur_altsetting->desc.bInterfaceNumber;	unsigned char *p;	enum { ALLOC_SIZE = 1 };	struct usb_ctrlrequest *cr;	struct completion compl;	struct timer_list timer;	int nluns;	int rc;	init_completion(&compl);	rc = -ENOMEM;	if ((p = kmalloc(ALLOC_SIZE, GFP_KERNEL)) == NULL)		goto err_alloc;	*p = 55;	cr = &sc->work_cr;	cr->bRequestType = USB_DIR_IN | USB_TYPE_CLASS | USB_RECIP_INTERFACE;	cr->bRequest = US_BULK_GET_MAX_LUN;	cr->wValue = cpu_to_le16(0);	cr->wIndex = cpu_to_le16(ifnum);	cr->wLength = cpu_to_le16(1);	usb_fill_control_urb(&sc->work_urb, sc->dev, sc->recv_ctrl_pipe,	    (unsigned char*) cr, p, 1, ub_probe_urb_complete, &compl);	sc->work_urb.actual_length = 0;	sc->work_urb.error_count = 0;	sc->work_urb.status = 0;	if ((rc = usb_submit_urb(&sc->work_urb, GFP_KERNEL)) != 0)		goto err_submit;	init_timer(&timer);	timer.function = ub_probe_timeout;	timer.data = (unsigned long) &compl;	timer.expires = jiffies + UB_CTRL_TIMEOUT;	add_timer(&timer);	wait_for_completion(&compl);	del_timer_sync(&timer);	usb_kill_urb(&sc->work_urb);	if ((rc = sc->work_urb.status) < 0)		goto err_io;	if (sc->work_urb.actual_length != 1) {		nluns = 0;	} else {		if ((nluns = *p) == 55) {			nluns = 0;		} else {  			/* GetMaxLUN returns the maximum LUN number */			nluns += 1;			if (nluns > UB_MAX_LUNS)				nluns = UB_MAX_LUNS;		}	}	kfree(p);	return nluns;err_io:err_submit:	kfree(p);err_alloc:	return rc;}/* * Clear initial stalls. */static int ub_probe_clear_stall(struct ub_dev *sc, int stalled_pipe){	int endp;	struct usb_ctrlrequest *cr;	struct completion compl;	struct timer_list timer;	int rc;	init_completion(&compl);	endp = usb_pipeendpoint(stalled_pipe);	if (usb_pipein (stalled_pipe))		endp |= USB_DIR_IN;	cr = &sc->work_cr;	cr->bRequestType = USB_RECIP_ENDPOINT;	cr->bRequest = USB_REQ_CLEAR_FEATURE;	cr->wValue = cpu_to_le16(USB_ENDPOINT_HALT);	cr->wIndex = cpu_to_le16(endp);	cr->wLength = cpu_to_le16(0);	usb_fill_control_urb(&sc->work_urb, sc->dev, sc->send_ctrl_pipe,	    (unsigned char*) cr, NULL, 0, ub_probe_urb_complete, &compl);	sc->work_urb.actual_length = 0;	sc->work_urb.error_count = 0;	sc->work_urb.status = 0;	if ((rc = usb_submit_urb(&sc->work_urb, GFP_KERNEL)) != 0) {		printk(KERN_WARNING		     "%s: Unable to submit a probe clear (%d)\n", sc->name, rc);		return rc;	}	init_timer(&timer);	timer.function = ub_probe_timeout;	timer.data = (unsigned long) &compl;	timer.expires = jiffies + UB_CTRL_TIMEOUT;	add_timer(&timer);	wait_for_completion(&compl);	del_timer_sync(&timer);	usb_kill_urb(&sc->work_urb);	/* reset the endpoint toggle */	usb_settoggle(sc->dev, endp, usb_pipeout(sc->last_pipe), 0);	return 0;}/* * Get the pipe settings. */static int ub_get_pipes(struct ub_dev *sc, struct usb_device *dev,    struct usb_interface *intf){	struct usb_host_interface *altsetting = intf->cur_altsetting;	struct usb_endpoint_descriptor *ep_in = NULL;	struct usb_endpoint_descriptor *ep_out = NULL;	struct usb_endpoint_descriptor *ep;	int i;	/*	 * Find the endpoints we need.	 * We are expecting a minimum of 2 endpoints - in and out (bulk).	 * We will ignore any others.	 */	for (i = 0; i < altsetting->desc.bNumEndpoints; i++) {		ep = &altsetting->endpoint[i].desc;		/* Is it a BULK endpoint? */		if ((ep->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK)				== USB_ENDPOINT_XFER_BULK) {			/* BULK in or out? */			if (ep->bEndpointAddress & USB_DIR_IN) {				if (ep_in == NULL)					ep_in = ep;			} else {				if (ep_out == NULL)					ep_out = ep;			}		}	}	if (ep_in == NULL || ep_out == NULL) {		printk(KERN_NOTICE "%s: failed endpoint check\n",		    sc->name);		return -ENODEV;	}	/* Calculate and store the pipe values */	sc->send_ctrl_pipe = usb_sndctrlpipe(dev, 0);	sc->recv_ctrl_pipe = usb_rcvctrlpipe(dev, 0);	sc->send_bulk_pipe = usb_sndbulkpipe(dev,		ep_out->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK);	sc->recv_bulk_pipe = usb_rcvbulkpipe(dev, 		ep_in->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK);	return 0;}/* * Probing is done in the process context, which allows us to cheat * and not to build a state machine for the discovery. */static int ub_probe(struct usb_interface *intf,    const struct usb_device_id *dev_id){	struct ub_dev *sc;	int nluns;	int rc;	int i;	if (usb_usual_check_type(dev_id, USB_US_TYPE_UB))		return -ENXIO;	rc = -ENOMEM;	if ((sc = kzalloc(sizeof(struct ub_dev), GFP_KERNEL)) == NULL)		goto err_core;	sc->lock = ub_next_lock();	INIT_LIST_HEAD(&sc->luns);	usb_init_urb(&sc->work_urb);	tasklet_init(&sc->tasklet, ub_scsi_action, (unsigned long)sc);	atomic_set(&sc->poison, 0);	INIT_WORK(&sc->reset_work, ub_reset_task);	init_waitqueue_head(&sc->reset_wait);	init_timer(&sc->work_timer);	sc->work_timer.data = (unsigned long) sc;	sc->work_timer.function = ub_urb_timeout;	ub_init_completion(&sc->work_done);	sc->work_done.done = 1;		/* A little yuk, but oh well... */	sc->dev = interface_to_usbdev(intf);	sc->intf = intf;	// sc->ifnum = intf->cur_altsetting->desc.bInterfaceNumber;	usb_set_intfdata(intf, sc);	usb_get_dev(sc->dev);	/*	 * Since we give the interface struct to the block level through	 * disk->driverfs_dev, we have to pin it. Otherwise, block_uevent	 * oopses on close after a disconnect (kernels 2.6.16 and up).	 */	usb_get_intf(sc->intf);	snprintf(sc->name, 12, DRV_NAME "(%d.%d)",	    sc->dev->bus->busnum, sc->dev->devnum);	/* XXX Verify that we can handle the device (from descriptors) */	if (ub_get_pipes(sc, sc->dev, intf) != 0)		goto err_dev_desc;	/*	 * At this point, all USB initialization is done, do upper layer.	 * We really hate halfway initialized structures, so from the	 * invariants perspective, this ub_dev is fully constructed at	 * this point.	 */	/*	 * This is needed to clear toggles. It is a problem only if we do	 * `rmmod ub && modprobe ub` without disconnects, but we like that.	 */#if 0 /* iPod Mini fails if we do this (big white iPod works) */	ub_probe_clear_stall(sc, sc->recv_bulk_pipe);	ub_probe_clear_stall(sc, sc->send_bulk_pipe);#endif	/*	 * The way this is used by the startup code is a little specific.	 * A SCSI check causes a USB stall. Our common case code sees it	 * and clears the check, after which the device is ready for use.	 * But if a check was not present, any command other than	 * TEST_UNIT_READY ends with a lockup (including REQUEST_SENSE).	 *	 * If we neglect to clear the SCSI check, the first real command fails	 * (which is the capacity readout). We clear that and retry, but why	 * causing spurious retries for no reason.	 *	 * Revalidation may start with its own TEST_UNIT_READY, but that one	 * has to succeed, so we clear checks with an additional one here.	 * In any case it's not our business how revaliadation is implemented.	 */	for (i = 0; i < 3; i++) {  /* Retries for the schwag key from KS'04 */		if ((rc = ub_sync_tur(sc, NULL)) <= 0) break;		if (rc != 0x6) break;		msleep(10);	}	nluns = 1;	for (i = 0; i < 3; i++) {		if ((rc = ub_sync_getmaxlun(sc)) < 0)			break;		if (rc != 0) {			nluns = rc;			break;		}		msleep(100);	}	for (i = 0; i < nluns; i++) {		ub_probe_lun(sc, i);	}	return 0;err_dev_desc:	usb_set_intfdata(intf, NULL);	usb_put_intf(sc->intf);	usb_put_dev(sc->dev);	kfree(sc);err_core:	return rc;}static int ub_probe_lun(struct ub_dev *sc, int lnum){	struct ub_lun *lun;	struct request_queue *q;	struct gendisk *disk;	int rc;	rc = -ENOMEM;	if ((lun = kzalloc(sizeof(struct ub_lun), GFP_KERNEL)) == NULL)		goto err_alloc;	lun->num = lnum;	rc = -ENOSR;	if ((lun->id = ub_id_get()) == -1)		goto err_id;	lun->udev = sc;	snprintf(lun->name, 16, DRV_NAME "%c(%d.%d.%d)",	    lun->id + 'a', sc->dev->bus->busnum, sc->dev->devnum, lun->num);	lun->removable = 1;		/* XXX Query this from the device */	lun->changed = 1;		/* ub_revalidate clears only */	ub_revalidate(sc, lun);	rc = -ENOMEM;	if ((disk = alloc_disk(UB_PARTS_PER_LUN)) == NULL)		goto err_diskalloc;	sprintf(disk->disk_name, DRV_NAME "%c", lun->id + 'a');	disk->major = UB_MAJOR;	disk->first_minor = lun->id * UB_PARTS_PER_LUN;	disk->fops = &ub_bd_fops;	disk->private_data = lun;	disk->driverfs_dev = &sc->intf->dev;	rc = -ENOMEM;	if ((q = blk_init_queue(ub_request_fn, sc->lock)) == NULL)		goto err_blkqinit;	disk->queue = q;	blk_queue_bounce_limit(q, BLK_BOUNCE_HIGH);	blk_queue_max_hw_segments(q, UB_MAX_REQ_SG);	blk_queue_max_phys_segments(q, UB_MAX_REQ_SG);	blk_queue_segment_boundary(q, 0xffffffff);	/* Dubious. */	blk_queue_max_sectors(q, UB_MAX_SECTORS);	blk_queue_hardsect_size(q, lun->capacity.bsize);	lun->disk = disk;	q->queuedata = lun;	list_add(&lun->link, &sc->luns);	set_capacity(disk, lun->capacity.nsec);	if (lun->removable)		disk->flags |= GENHD_FL_REMOVABLE;	add_disk(disk);	return 0;err_blkqinit:	put_disk(disk);err_diskalloc:	ub_id_put(lun->id);err_id:	kfree(lun);err_alloc:	return rc;}static void ub_disconnect(struct usb_interface *intf){	struct ub_dev *sc = usb_get_intfdata(intf);	struct ub_lun *lun;	unsigned long flags;	/*	 * Prevent ub_bd_release from pulling the rug from under us.	 * XXX This is starting to look like a kref.	 * XXX Why not to take this ref at probe time?	 */	spin_lock_irqsave(&ub_lock, flags);	sc->openc++;	spin_unlock_irqrestore(&ub_lock, flags);	/*	 * Fence stall clearnings, operations triggered by unlinkings and so on.	 * We do not attempt to unlink any URBs, because we do not trust the	 * unlink paths in HC drivers. Also, we get -84 upon disconnect anyway.	 */	atomic_set(&sc->poison, 1);	/*	 * Wait for reset to end, if any.	 */	wait_event(sc->reset_wait, !sc->reset);	/*	 * Blow away queued commands.	 *	 * Actually, this never works, because before we get here	 * the HCD terminates outstanding URB(s). It causes our	 * SCSI command queue to advance, commands fail to submit,	 * and the whole queue drains. So, we just use this code to	 * print warnings.	 */	spin_lock_irqsave(sc->lock, flags);	{		struct ub_scsi_cmd *cmd;		int cnt = 0;		while ((cmd = ub_cmdq_peek(sc)) != NULL) {			cmd->error = -ENOTCONN;			cmd->state = UB_CMDST_DONE;			ub_cmdq_pop(sc);			(*cmd->done)(sc, cmd);			cnt++;		}		if (cnt != 0) {			printk(KERN_WARNING "%s: "			    "%d was queued after shutdown\n", sc->name, cnt);		}	}	spin_unlock_irqrestore(sc->lock, flags);	/*	 * Unregister the upper layer.	 */	list_for_each_entry(lun, &sc->luns, link) {		del_gendisk(lun->disk);		/*		 * I wish I could do:		 *    set_bit(QUEUE_FLAG_DEAD, &q->queue_flags);		 * As it is, we rely on our internal poisoning and let		 * the upper levels to spin furiously failing all the I/O.		 */	}	/*	 * Testing for -EINPROGRESS is always a bug, so we are bending	 * the rules a little.	 */	spin_lock_irqsave(sc->lock, flags);	if (sc->work_urb.status == -EINPROGRESS) {	/* janitors: ignore */		printk(KERN_WARNING "%s: "		    "URB is active after disconnect\n", sc->name);	}	spin_unlock_irqrestore(sc->lock, flags);	/*	 * There is virtually no chance that other CPU runs times so long	 * after ub_urb_complete should have called del_timer, but only if HCD	 * didn't forget to deliver a callback on unlink.	 */	del_timer_sync(&sc->work_timer);	/*	 * At this point there must be no commands coming from anyone	 * and no URBs left in transit.	 */	ub_put(sc);}static struct usb_driver ub_driver = {	.name =		"ub",	.probe =	ub_probe,	.disconnect =	ub_disconnect,	.id_table =	ub_usb_ids,};static int __init ub_init(void){	int rc;	int i;	for (i = 0; i < UB_QLOCK_NUM; i++)		spin_lock_init(&ub_qlockv[i]);	if ((rc = register_blkdev(UB_MAJOR, DRV_NAME)) != 0)		goto err_regblkdev;	if ((rc = usb_register(&ub_driver)) != 0)		goto err_register;	usb_usual_set_present(USB_US_TYPE_UB);	return 0;err_register:	unregister_blkdev(UB_MAJOR, DRV_NAME);err_regblkdev:	return rc;}static void __exit ub_exit(void){	usb_deregister(&ub_driver);	unregister_blkdev(UB_MAJOR, DRV_NAME);	usb_usual_clear_present(USB_US_TYPE_UB);}module_init(ub_init);module_exit(ub_exit);MODULE_LICENSE("GPL");

⌨️ 快捷键说明

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