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

📄 ub.c

📁 Linux块设备驱动源码
💻 C
📖 第 1 页 / 共 5 页
字号:
			printk(KERN_NOTICE			     "%s: Unable to submit GetMaxLUN (%d)\n",			     sc->name, rc);		}		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) {		if (rc == -EPIPE) {			printk("%s: Stall at GetMaxLUN, using 1 LUN\n",			     sc->name); /* P3 */		} else {			printk(KERN_NOTICE			     "%s: Error at GetMaxLUN (%d)\n",			     sc->name, rc);		}		goto err_io;	}	if (sc->work_urb.actual_length != 1) {		printk("%s: GetMaxLUN returned %d bytes\n", sc->name,		    sc->work_urb.actual_length); /* P3 */		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;		}		printk("%s: GetMaxLUN returned %d, using %d LUNs\n", sc->name,		    *p, nluns); /* P3 */	}	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)				ep_in = ep;			else				ep_out = ep;		}	}	if (ep_in == NULL || ep_out == NULL) {		printk(KERN_NOTICE "%s: failed endpoint check\n",		    sc->name);		return -EIO;	}	/* 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;	rc = -ENOMEM;	if ((sc = kmalloc(sizeof(struct ub_dev), GFP_KERNEL)) == NULL)		goto err_core;	memset(sc, 0, sizeof(struct ub_dev));	spin_lock_init(&sc->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_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);	// usb_get_intf(sc->intf);	/* Do we need this? */	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) */	ub_get_pipes(sc, sc->dev, intf);	if (device_create_file(&sc->intf->dev, &dev_attr_diag) != 0)		goto err_diag;	/*	 * 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 benh's key */		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) {			/* 			 * This segment is taken from usb-storage. They say			 * that ZIP-100 needs this, but my own ZIP-100 works			 * fine without this.			 * Still, it does not seem to hurt anything.			 */			if (rc == -EPIPE) {				ub_probe_clear_stall(sc, sc->recv_bulk_pipe);				ub_probe_clear_stall(sc, sc->send_bulk_pipe);			}			break;		}		if (rc != 0) {			nluns = rc;			break;		}		msleep(100);	}	for (i = 0; i < nluns; i++) {		ub_probe_lun(sc, i);	}	return 0;	/* device_remove_file(&sc->intf->dev, &dev_attr_diag); */err_diag:	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;	request_queue_t *q;	struct gendisk *disk;	int rc;	rc = -ENOMEM;	if ((lun = kmalloc(sizeof(struct ub_lun), GFP_KERNEL)) == NULL)		goto err_alloc;	memset(lun, 0, sizeof(struct ub_lun));	lun->num = lnum;	rc = -ENOSR;	if ((lun->id = ub_id_get()) == -1)		goto err_id;	lun->udev = sc;	list_add(&lun->link, &sc->luns);	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 */	lun->first_open = 1;	ub_revalidate(sc, lun);	rc = -ENOMEM;	if ((disk = alloc_disk(UB_MINORS_PER_MAJOR)) == NULL)		goto err_diskalloc;	lun->disk = disk;	sprintf(disk->disk_name, DRV_NAME "%c", lun->id + 'a');	sprintf(disk->devfs_name, DEVFS_NAME "/%c", lun->id + 'a');	disk->major = UB_MAJOR;	disk->first_minor = lun->id * UB_MINORS_PER_MAJOR;	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);	q->queuedata = lun;	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:	list_del(&lun->link);	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 list_head *p;	struct ub_lun *lun;	struct gendisk *disk;	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);	/*	 * 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_pop(sc)) != NULL) {			cmd->error = -ENOTCONN;			cmd->state = UB_CMDST_DONE;			ub_cmdtr_state(sc, cmd);			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 (p, &sc->luns) {		lun = list_entry(p, struct ub_lun, link);		disk = lun->disk;		if (disk->flags & GENHD_FL_UP)			del_gendisk(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.		 */	}	/*	 * Taking a lock on a structure which is about to be freed	 * is very nonsensual. Here it is largely a way to do a debug freeze,	 * and a bracket which shows where the nonsensual code segment ends.	 *	 * 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.	 */	device_remove_file(&sc->intf->dev, &dev_attr_diag);	usb_set_intfdata(intf, NULL);	// usb_put_intf(sc->intf);	sc->intf = NULL;	usb_put_dev(sc->dev);	sc->dev = NULL;	ub_put(sc);}static struct usb_driver ub_driver = {	.owner =	THIS_MODULE,	.name =		"ub",	.probe =	ub_probe,	.disconnect =	ub_disconnect,	.id_table =	ub_usb_ids,};static int __init ub_init(void){	int rc;	if ((rc = register_blkdev(UB_MAJOR, DRV_NAME)) != 0)		goto err_regblkdev;	devfs_mk_dir(DEVFS_NAME);	if ((rc = usb_register(&ub_driver)) != 0)		goto err_register;	return 0;err_register:	devfs_remove(DEVFS_NAME);	unregister_blkdev(UB_MAJOR, DRV_NAME);err_regblkdev:	return rc;}static void __exit ub_exit(void){	usb_deregister(&ub_driver);	devfs_remove(DEVFS_NAME);	unregister_blkdev(UB_MAJOR, DRV_NAME);}module_init(ub_init);module_exit(ub_exit);MODULE_LICENSE("GPL");

⌨️ 快捷键说明

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