static int ub_probe(struct usb_interface *intf,    const struct usb_device_id *dev_id){	struct ub_dev *sc;	request_queue_t *q;	struct gendisk *disk;	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);	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... */	rc = -ENOSR;	if ((sc->id = ub_id_get()) == -1)		goto err_id;	snprintf(sc->name, 8, DRV_NAME "%c", sc->id + 'a');	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? */	/* 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.	 */	ub_probe_clear_stall(sc, sc->recv_bulk_pipe);	ub_probe_clear_stall(sc, sc->send_bulk_pipe);	/*	 * 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)) <= 0) break;		if (rc != 0x6) break;		msleep(10);	}	sc->removable = 1;		/* XXX Query this from the device */	sc->changed = 1;		/* ub_revalidate clears only */	sc->first_open = 1;	ub_revalidate(sc);	/* This is pretty much a long term P3 */	printk(KERN_INFO "%s: device %u capacity nsec %ld bsize %u\n",	    sc->name, sc->dev->devnum, sc->capacity.nsec, sc->capacity.bsize);	/*	 * Just one disk per sc currently, but maybe more.	 */	rc = -ENOMEM;	if ((disk = alloc_disk(UB_MINORS_PER_MAJOR)) == NULL)		goto err_diskalloc;	sc->disk = disk;	sprintf(disk->disk_name, DRV_NAME "%c", sc->id + 'a');	sprintf(disk->devfs_name, DEVFS_NAME "/%c", sc->id + 'a');	disk->major = UB_MAJOR;	disk->first_minor = sc->id * UB_MINORS_PER_MAJOR;	disk->fops = &ub_bd_fops;	disk->private_data = sc;	disk->driverfs_dev = &intf->dev;	rc = -ENOMEM;	if ((q = blk_init_queue(ub_bd_rq_fn, &sc->lock)) == NULL)		goto err_blkqinit;	disk->queue = q;        // blk_queue_bounce_limit(q, hba[i]->pdev->dma_mask);	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, CARM_SG_BOUNDARY);	blk_queue_max_sectors(q, UB_MAX_SECTORS);	blk_queue_hardsect_size(q, sc->capacity.bsize);	/*	 * This is a serious infraction, caused by a deficiency in the	 * USB sg interface (usb_sg_wait()). We plan to remove this once	 * we get mileage on the driver and can justify a change to USB API.	 * See blk_queue_bounce_limit() to understand this part.	 *	 * XXX And I still need to be aware of the DMA mask in the HC.	 */	q->bounce_pfn = blk_max_low_pfn;	q->bounce_gfp = GFP_NOIO;	q->queuedata = sc;	set_capacity(disk, sc->capacity.nsec);	if (sc->removable)		disk->flags |= GENHD_FL_REMOVABLE;	add_disk(disk);	return 0;err_blkqinit:	put_disk(disk);err_diskalloc:	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);	ub_id_put(sc->id);err_id:	kfree(sc);err_core:	return rc;}
4520	/local/tlutelli/issta_data/temp/c/2005_temp/2005/4520/f4800078d9ed4bd20b1b27f56e7b68cfa0d73038/ub.c/clean/drivers/block/ub.c