Commit 17d5363b authored by Christoph Hellwig's avatar Christoph Hellwig Committed by Jens Axboe
Browse files

scsi: introduce a result field in struct scsi_request



This passes on the scsi_cmnd result field to users of passthrough
requests.  Currently we abuse req->errors for this purpose, but that
field will go away in its current form.

Note that the old IDE code abuses the errors field in very creative
ways and stores all kinds of different values in it.  I didn't dare
to touch this magic, so the abuses are brought forward 1:1.

Signed-off-by: default avatarChristoph Hellwig <hch@lst.de>
Reviewed-by: default avatarMartin K. Petersen <martin.petersen@oracle.com>
Reviewed-by: default avatarBart Van Assche <Bart.VanAssche@sandisk.com>
Signed-off-by: default avatarJens Axboe <axboe@fb.com>
parent d19633d5
Loading
Loading
Loading
Loading
+4 −4
Original line number Diff line number Diff line
@@ -37,7 +37,7 @@ static void bsg_destroy_job(struct kref *kref)
	struct bsg_job *job = container_of(kref, struct bsg_job, kref);
	struct request *rq = job->req;

	blk_end_request_all(rq, rq->errors);
	blk_end_request_all(rq, scsi_req(rq)->result);

	put_device(job->dev);	/* release reference for the request */

@@ -74,7 +74,7 @@ void bsg_job_done(struct bsg_job *job, int result,
	struct scsi_request *rq = scsi_req(req);
	int err;

	err = job->req->errors = result;
	err = scsi_req(job->req)->result = result;
	if (err < 0)
		/* we're only returning the result field in the reply */
		rq->sense_len = sizeof(u32);
@@ -177,7 +177,7 @@ failjob_rls_job:
 * @q: request queue to manage
 *
 * On error the create_bsg_job function should return a -Exyz error value
 * that will be set to the req->errors.
 * that will be set to ->result.
 *
 * Drivers/subsys should pass this to the queue init function.
 */
@@ -201,7 +201,7 @@ static void bsg_request_fn(struct request_queue *q)

		ret = bsg_create_job(dev, req);
		if (ret) {
			req->errors = ret;
			scsi_req(req)->result = ret;
			blk_end_request_all(req, ret);
			spin_lock_irq(q->queue_lock);
			continue;
+6 −6
Original line number Diff line number Diff line
@@ -391,13 +391,13 @@ static int blk_complete_sgv4_hdr_rq(struct request *rq, struct sg_io_v4 *hdr,
	struct scsi_request *req = scsi_req(rq);
	int ret = 0;

	dprintk("rq %p bio %p 0x%x\n", rq, bio, rq->errors);
	dprintk("rq %p bio %p 0x%x\n", rq, bio, req->result);
	/*
	 * fill in all the output members
	 */
	hdr->device_status = rq->errors & 0xff;
	hdr->transport_status = host_byte(rq->errors);
	hdr->driver_status = driver_byte(rq->errors);
	hdr->device_status = req->result & 0xff;
	hdr->transport_status = host_byte(req->result);
	hdr->driver_status = driver_byte(req->result);
	hdr->info = 0;
	if (hdr->device_status || hdr->transport_status || hdr->driver_status)
		hdr->info |= SG_INFO_CHECK;
@@ -431,8 +431,8 @@ static int blk_complete_sgv4_hdr_rq(struct request *rq, struct sg_io_v4 *hdr,
	 * just a protocol response (i.e. non negative), that gets
	 * processed above.
	 */
	if (!ret && rq->errors < 0)
		ret = rq->errors;
	if (!ret && req->result < 0)
		ret = req->result;

	blk_rq_unmap_user(bio);
	scsi_req_free_cmd(req);
+7 −7
Original line number Diff line number Diff line
@@ -262,11 +262,11 @@ static int blk_complete_sghdr_rq(struct request *rq, struct sg_io_hdr *hdr,
	/*
	 * fill in all the output members
	 */
	hdr->status = rq->errors & 0xff;
	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->status = req->result & 0xff;
	hdr->masked_status = status_byte(req->result);
	hdr->msg_status = msg_byte(req->result);
	hdr->host_status = host_byte(req->result);
	hdr->driver_status = driver_byte(req->result);
	hdr->info = 0;
	if (hdr->masked_status || hdr->host_status || hdr->driver_status)
		hdr->info |= SG_INFO_CHECK;
@@ -509,7 +509,7 @@ int sg_scsi_ioctl(struct request_queue *q, struct gendisk *disk, fmode_t mode,

	blk_execute_rq(q, disk, rq, 0);

	err = rq->errors & 0xff;	/* only 8 bit SCSI status */
	err = req->result & 0xff;	/* only 8 bit SCSI status */
	if (err) {
		if (req->sense_len && req->sense) {
			bytes = (OMAX_SB_LEN > req->sense_len) ?
@@ -548,7 +548,7 @@ static int __blk_send_generic(struct request_queue *q, struct gendisk *bd_disk,
	scsi_req(rq)->cmd[4] = data;
	scsi_req(rq)->cmd_len = 6;
	blk_execute_rq(q, bd_disk, rq, 0);
	err = rq->errors ? -EIO : 0;
	err = scsi_req(rq)->result ? -EIO : 0;
	blk_put_request(rq);

	return err;
+21 −21
Original line number Diff line number Diff line
@@ -1864,8 +1864,7 @@ static void cciss_softirq_done(struct request *rq)
	/* set the residual count for pc requests */
	if (blk_rq_is_passthrough(rq))
		scsi_req(rq)->resid_len = c->err_info->ResidualCnt;

	blk_end_request_all(rq, (rq->errors == 0) ? 0 : -EIO);
	blk_end_request_all(rq, scsi_req(rq)->result ? -EIO : 0);

	spin_lock_irqsave(&h->lock, flags);
	cmd_free(h, c);
@@ -3140,18 +3139,19 @@ static inline void complete_command(ctlr_info_t *h, CommandList_struct *cmd,
{
	int retry_cmd = 0;
	struct request *rq = cmd->rq;
	struct scsi_request *sreq = scsi_req(rq);

	rq->errors = 0;
	sreq->result = 0;

	if (timeout)
		rq->errors = make_status_bytes(0, 0, 0, DRIVER_TIMEOUT);
		sreq->result = make_status_bytes(0, 0, 0, DRIVER_TIMEOUT);

	if (cmd->err_info->CommandStatus == 0)	/* no error has occurred */
		goto after_error_processing;

	switch (cmd->err_info->CommandStatus) {
	case CMD_TARGET_STATUS:
		rq->errors = evaluate_target_status(h, cmd, &retry_cmd);
		sreq->result = evaluate_target_status(h, cmd, &retry_cmd);
		break;
	case CMD_DATA_UNDERRUN:
		if (!blk_rq_is_passthrough(cmd->rq)) {
@@ -3169,7 +3169,7 @@ static inline void complete_command(ctlr_info_t *h, CommandList_struct *cmd,
	case CMD_INVALID:
		dev_warn(&h->pdev->dev, "cciss: cmd %p is "
		       "reported invalid\n", cmd);
		rq->errors = make_status_bytes(SAM_STAT_GOOD,
		sreq->result = make_status_bytes(SAM_STAT_GOOD,
			cmd->err_info->CommandStatus, DRIVER_OK,
			blk_rq_is_passthrough(cmd->rq) ?
				DID_PASSTHROUGH : DID_ERROR);
@@ -3177,7 +3177,7 @@ static inline void complete_command(ctlr_info_t *h, CommandList_struct *cmd,
	case CMD_PROTOCOL_ERR:
		dev_warn(&h->pdev->dev, "cciss: cmd %p has "
		       "protocol error\n", cmd);
		rq->errors = make_status_bytes(SAM_STAT_GOOD,
		sreq->result = make_status_bytes(SAM_STAT_GOOD,
			cmd->err_info->CommandStatus, DRIVER_OK,
			blk_rq_is_passthrough(cmd->rq) ?
				DID_PASSTHROUGH : DID_ERROR);
@@ -3185,7 +3185,7 @@ static inline void complete_command(ctlr_info_t *h, CommandList_struct *cmd,
	case CMD_HARDWARE_ERR:
		dev_warn(&h->pdev->dev, "cciss: cmd %p had "
		       " hardware error\n", cmd);
		rq->errors = make_status_bytes(SAM_STAT_GOOD,
		sreq->result = make_status_bytes(SAM_STAT_GOOD,
			cmd->err_info->CommandStatus, DRIVER_OK,
			blk_rq_is_passthrough(cmd->rq) ?
				DID_PASSTHROUGH : DID_ERROR);
@@ -3193,7 +3193,7 @@ static inline void complete_command(ctlr_info_t *h, CommandList_struct *cmd,
	case CMD_CONNECTION_LOST:
		dev_warn(&h->pdev->dev, "cciss: cmd %p had "
		       "connection lost\n", cmd);
		rq->errors = make_status_bytes(SAM_STAT_GOOD,
		sreq->result = make_status_bytes(SAM_STAT_GOOD,
			cmd->err_info->CommandStatus, DRIVER_OK,
			blk_rq_is_passthrough(cmd->rq) ?
				DID_PASSTHROUGH : DID_ERROR);
@@ -3201,7 +3201,7 @@ static inline void complete_command(ctlr_info_t *h, CommandList_struct *cmd,
	case CMD_ABORTED:
		dev_warn(&h->pdev->dev, "cciss: cmd %p was "
		       "aborted\n", cmd);
		rq->errors = make_status_bytes(SAM_STAT_GOOD,
		sreq->result = make_status_bytes(SAM_STAT_GOOD,
			cmd->err_info->CommandStatus, DRIVER_OK,
			blk_rq_is_passthrough(cmd->rq) ?
				DID_PASSTHROUGH : DID_ABORT);
@@ -3209,7 +3209,7 @@ static inline void complete_command(ctlr_info_t *h, CommandList_struct *cmd,
	case CMD_ABORT_FAILED:
		dev_warn(&h->pdev->dev, "cciss: cmd %p reports "
		       "abort failed\n", cmd);
		rq->errors = make_status_bytes(SAM_STAT_GOOD,
		sreq->result = make_status_bytes(SAM_STAT_GOOD,
			cmd->err_info->CommandStatus, DRIVER_OK,
			blk_rq_is_passthrough(cmd->rq) ?
				DID_PASSTHROUGH : DID_ERROR);
@@ -3224,21 +3224,21 @@ static inline void complete_command(ctlr_info_t *h, CommandList_struct *cmd,
		} else
			dev_warn(&h->pdev->dev,
				"%p retried too many times\n", cmd);
		rq->errors = make_status_bytes(SAM_STAT_GOOD,
		sreq->result = make_status_bytes(SAM_STAT_GOOD,
			cmd->err_info->CommandStatus, DRIVER_OK,
			blk_rq_is_passthrough(cmd->rq) ?
				DID_PASSTHROUGH : DID_ABORT);
		break;
	case CMD_TIMEOUT:
		dev_warn(&h->pdev->dev, "cmd %p timedout\n", cmd);
		rq->errors = make_status_bytes(SAM_STAT_GOOD,
		sreq->result = make_status_bytes(SAM_STAT_GOOD,
			cmd->err_info->CommandStatus, DRIVER_OK,
			blk_rq_is_passthrough(cmd->rq) ?
				DID_PASSTHROUGH : DID_ERROR);
		break;
	case CMD_UNABORTABLE:
		dev_warn(&h->pdev->dev, "cmd %p unabortable\n", cmd);
		rq->errors = make_status_bytes(SAM_STAT_GOOD,
		sreq->result = make_status_bytes(SAM_STAT_GOOD,
			cmd->err_info->CommandStatus, DRIVER_OK,
			blk_rq_is_passthrough(cmd->rq) ?
				DID_PASSTHROUGH : DID_ERROR);
@@ -3247,7 +3247,7 @@ static inline void complete_command(ctlr_info_t *h, CommandList_struct *cmd,
		dev_warn(&h->pdev->dev, "cmd %p returned "
		       "unknown status %x\n", cmd,
		       cmd->err_info->CommandStatus);
		rq->errors = make_status_bytes(SAM_STAT_GOOD,
		sreq->result = make_status_bytes(SAM_STAT_GOOD,
			cmd->err_info->CommandStatus, DRIVER_OK,
			blk_rq_is_passthrough(cmd->rq) ?
				DID_PASSTHROUGH : DID_ERROR);
@@ -3380,8 +3380,8 @@ static void do_cciss_request(struct request_queue *q)
		if (dma_mapping_error(&h->pdev->dev, temp64.val)) {
			dev_warn(&h->pdev->dev,
				"%s: error mapping page for DMA\n", __func__);
			creq->errors = make_status_bytes(SAM_STAT_GOOD,
							0, DRIVER_OK,
			scsi_req(creq)->result =
				make_status_bytes(SAM_STAT_GOOD, 0, DRIVER_OK,
						  DID_SOFT_ERROR);
			cmd_free(h, c);
			return;
@@ -3395,8 +3395,8 @@ static void do_cciss_request(struct request_queue *q)
		if (cciss_map_sg_chain_block(h, c, h->cmd_sg_list[c->cmdindex],
			(seg - (h->max_cmd_sgentries - 1)) *
				sizeof(SGDescriptor_struct))) {
			creq->errors = make_status_bytes(SAM_STAT_GOOD,
							0, DRIVER_OK,
			scsi_req(creq)->result =
				make_status_bytes(SAM_STAT_GOOD, 0, DRIVER_OK,
						  DID_SOFT_ERROR);
			cmd_free(h, c);
			return;
+1 −1
Original line number Diff line number Diff line
@@ -724,7 +724,7 @@ static int pkt_generic_packet(struct pktcdvd_device *pd, struct packet_command *
		rq->rq_flags |= RQF_QUIET;

	blk_execute_rq(rq->q, pd->bdev->bd_disk, rq, 0);
	if (rq->errors)
	if (scsi_req(rq)->result)
		ret = -EIO;
out:
	blk_put_request(rq);
Loading