/* BLKPREP_KILL return also releases the command */ 
static int scsi_prep_fn(struct request_queue *q, struct request *req){	struct scsi_device *sdev = q->queuedata;	struct scsi_cmnd *cmd;	int specials_only = 0;	/*	 * Just check to see if the device is online.  If it isn't, we	 * refuse to process any commands.  The device must be brought	 * online before trying any recovery commands	 */	if (unlikely(!scsi_device_online(sdev))) {		printk(KERN_ERR "scsi%d (%d:%d): rejecting I/O to offline device\n",		       sdev->host->host_no, sdev->id, sdev->lun);		goto kill;	}	if (unlikely(sdev->sdev_state != SDEV_RUNNING)) {		/* OK, we're not in a running state don't prep		 * user commands */		if (sdev->sdev_state == SDEV_DEL) {			/* Device is fully deleted, no commands			 * at all allowed down */			printk(KERN_ERR "scsi%d (%d:%d): rejecting I/O to dead device\n",			       sdev->host->host_no, sdev->id, sdev->lun);			goto kill;		}		/* OK, we only allow special commands (i.e. not		 * user initiated ones */		specials_only = sdev->sdev_state;	}	/*	 * Find the actual device driver associated with this command.	 * The SPECIAL requests are things like character device or	 * ioctls, which did not originate from ll_rw_blk.  Note that	 * the special field is also used to indicate the cmd for	 * the remainder of a partially fulfilled request that can 	 * come up when there is a medium error.  We have to treat	 * these two cases differently.  We differentiate by looking	 * at request->cmd, as this tells us the real story.	 */	if (req->flags & REQ_SPECIAL && req->special) {		struct scsi_request *sreq = req->special;		if (sreq->sr_magic == SCSI_REQ_MAGIC) {			cmd = scsi_get_command(sreq->sr_device, GFP_ATOMIC);			if (unlikely(!cmd))				goto defer;			scsi_init_cmd_from_req(cmd, sreq);		} else			cmd = req->special;	} else if (req->flags & (REQ_CMD | REQ_BLOCK_PC)) {		if(unlikely(specials_only) && !(req->flags & REQ_SPECIAL)) {			if(specials_only == SDEV_QUIESCE ||					specials_only == SDEV_BLOCK)				goto defer;						printk(KERN_ERR "scsi%d (%d:%d): rejecting I/O to device being removed\n",			       sdev->host->host_no, sdev->id, sdev->lun);			goto kill;		}								/*		 * Now try and find a command block that we can use.		 */		if (!req->special) {			cmd = scsi_get_command(sdev, GFP_ATOMIC);			if (unlikely(!cmd))				goto defer;		} else			cmd = req->special;				/* pull a tag out of the request if we have one */		cmd->tag = req->tag;	} else {		blk_dump_rq_flags(req, "SCSI bad req");		goto kill;	}		/* note the overloading of req->special.  When the tag	 * is active it always means cmd.  If the tag goes	 * back for re-queueing, it may be reset */	req->special = cmd;	cmd->request = req;		/*	 * FIXME: drop the lock here because the functions below	 * expect to be called without the queue lock held.  Also,	 * previously, we dequeued the request before dropping the	 * lock.  We hope REQ_STARTED prevents anything untoward from	 * happening now.	 */	if (req->flags & (REQ_CMD | REQ_BLOCK_PC)) {		struct scsi_driver *drv;		int ret;		/*		 * This will do a couple of things:		 *  1) Fill in the actual SCSI command.		 *  2) Fill in any other upper-level specific fields		 * (timeout).		 *		 * If this returns 0, it means that the request failed		 * (reading past end of disk, reading offline device,		 * etc).   This won't actually talk to the device, but		 * some kinds of consistency checking may cause the			 * request to be rejected immediately.		 */		/* 		 * This sets up the scatter-gather table (allocating if		 * required).		 */		ret = scsi_init_io(cmd);		switch(ret) {		case BLKPREP_KILL:			/* BLKPREP_KILL return also releases the command */			goto kill;		case BLKPREP_DEFER:			goto defer;		}				/*		 * Initialize the actual SCSI command for this request.		 */		if (req->rq_disk) {			drv = *(struct scsi_driver **)req->rq_disk->private_data;			if (unlikely(!drv->init_command(cmd))) {				scsi_release_buffers(cmd);				scsi_put_command(cmd);				goto kill;			}		} else {			memcpy(cmd->cmnd, req->cmd, sizeof(cmd->cmnd));			cmd->cmd_len = req->cmd_len;			if (rq_data_dir(req) == WRITE)				cmd->sc_data_direction = DMA_TO_DEVICE;			else if (req->data_len)				cmd->sc_data_direction = DMA_FROM_DEVICE;			else				cmd->sc_data_direction = DMA_NONE;						cmd->transfersize = req->data_len;			cmd->allowed = 3;			cmd->timeout_per_command = req->timeout;			cmd->done = scsi_generic_done;		}	}	/*	 * The request is now prepped, no need to come back here	 */	req->flags |= REQ_DONTPREP;	return BLKPREP_OK; defer:	/* If we defer, the elv_next_request() returns NULL, but the	 * queue must be restarted, so we plug here if no returning	 * command will automatically do that. */	if (sdev->device_busy == 0)		blk_plug_device(q);	return BLKPREP_DEFER; kill:	req->errors = DID_NO_CONNECT << 16;	return BLKPREP_KILL;}
4520	/local/tlutelli/issta_data/temp/c/2005_temp/2005/4520/7c72ce81870ded9365f4bc5caa98ef1591dd18dd/scsi_lib.c/clean/drivers/scsi/scsi_lib.c