rq = blk_rq_map_user(q, writing ? WRITE : READ, hdr->dxferp, hdr->dxfer_len); 
rq = blk_get_request(q, writing ? WRITE : READ, GFP_KERNEL); if (!rq) return -ENOMEM; 
static int sg_io(struct file *file, request_queue_t *q,		struct gendisk *bd_disk, struct sg_io_hdr *hdr){	unsigned long start_time;	int reading, writing;	struct request *rq;	struct bio *bio;	char sense[SCSI_SENSE_BUFFERSIZE];	unsigned char cmd[BLK_MAX_CDB];	if (hdr->interface_id != 'S')		return -EINVAL;	if (hdr->cmd_len > BLK_MAX_CDB)		return -EINVAL;	if (copy_from_user(cmd, hdr->cmdp, hdr->cmd_len))		return -EFAULT;	if (verify_command(file, cmd))		return -EPERM;	/*	 * we'll do that later	 */	if (hdr->iovec_count)		return -EOPNOTSUPP;	if (hdr->dxfer_len > (q->max_sectors << 9))		return -EIO;	reading = writing = 0;	if (hdr->dxfer_len) {		switch (hdr->dxfer_direction) {		default:			return -EINVAL;		case SG_DXFER_TO_FROM_DEV:			reading = 1;			/* fall through */		case SG_DXFER_TO_DEV:			writing = 1;			break;		case SG_DXFER_FROM_DEV:			reading = 1;			break;		}		rq = blk_rq_map_user(q, writing ? WRITE : READ, hdr->dxferp,				     hdr->dxfer_len);		if (IS_ERR(rq))			return PTR_ERR(rq);	} else		rq = blk_get_request(q, READ, __GFP_WAIT);	/*	 * fill in request structure	 */	rq->cmd_len = hdr->cmd_len;	memcpy(rq->cmd, cmd, hdr->cmd_len);	if (sizeof(rq->cmd) != hdr->cmd_len)		memset(rq->cmd + hdr->cmd_len, 0, sizeof(rq->cmd) - hdr->cmd_len);	memset(sense, 0, sizeof(sense));	rq->sense = sense;	rq->sense_len = 0;	rq->flags |= REQ_BLOCK_PC;	bio = rq->bio;	/*	 * bounce this after holding a reference to the original bio, it's	 * needed for proper unmapping	 */	if (rq->bio)		blk_queue_bounce(q, &rq->bio);	rq->timeout = (hdr->timeout * HZ) / 1000;	if (!rq->timeout)		rq->timeout = q->sg_timeout;	if (!rq->timeout)		rq->timeout = BLK_DEFAULT_TIMEOUT;	start_time = jiffies;	/* ignore return value. All information is passed back to caller	 * (if he doesn't check that is his problem).	 * N.B. a non-zero SCSI status is _not_ necessarily an error.	 */	blk_execute_rq(q, bd_disk, rq);	/* write to all output members */	hdr->status = 0xff & rq->errors;	hdr->masked_status = status_byte(rq->errors);	hdr->msg_status = msg_byte(rq->errors);	hdr->host_status = host_byte(rq->errors);	hdr->driver_status = driver_byte(rq->errors);	hdr->info = 0;	if (hdr->masked_status || hdr->host_status || hdr->driver_status)		hdr->info |= SG_INFO_CHECK;	hdr->resid = rq->data_len;	hdr->duration = ((jiffies - start_time) * 1000) / HZ;	hdr->sb_len_wr = 0;	if (rq->sense_len && hdr->sbp) {		int len = min((unsigned int) hdr->mx_sb_len, rq->sense_len);		if (!copy_to_user(hdr->sbp, rq->sense, len))			hdr->sb_len_wr = len;	}	if (blk_rq_unmap_user(rq, bio, hdr->dxfer_len))		return -EFAULT;	/* may not have succeeded, but output values written to control	 * structure (struct sg_io_hdr).  */	return 0;}
10457	/local/tlutelli/issta_data/temp/c/2005_temp/2005/10457/dd1cab95f356f1395278633565f198463cf6bd24/scsi_ioctl.c/buggy/drivers/block/scsi_ioctl.c