static int blk_complete_sghdr_rq(struct request *rq, struct sg_io_hdr *hdr,
				 struct bio *bio)
{
	int r, ret = 0;

	/*
	 * 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->info = 0;
	if (hdr->masked_status || hdr->host_status || hdr->driver_status)
		hdr->info |= SG_INFO_CHECK;
	hdr->resid = rq->resid_len;
	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;
		else
			ret = -EFAULT;
	}

	r = blk_rq_unmap_user(bio);
	if (!ret)
		ret = r;
	blk_put_request(rq);

	return ret;
}
Ejemplo n.º 2
0
/*
 * This function is called by the interrupt handler when we
 * actually have a command that is complete.  Change the
 * flags to indicate that we have a result.
 */
static void sg_command_done(Scsi_Cmnd * SCpnt)
{
    int dev = MINOR(SCpnt->request.rq_dev);
    struct scsi_generic *device = &scsi_generics[dev];
    if (!device->pending)
    {
        printk("unexpected done for sg %d\n",dev);
        scsi_release_command(SCpnt);
        SCpnt = NULL;
        return;
    }

    /*
     * See if the command completed normally, or whether something went
     * wrong.
     */
    memcpy(device->header.sense_buffer, SCpnt->sense_buffer,
           sizeof(SCpnt->sense_buffer));
    switch (host_byte(SCpnt->result)) {
    case DID_OK:
        device->header.result = 0;
        break;
    case DID_NO_CONNECT:
    case DID_BUS_BUSY:
    case DID_TIME_OUT:
        device->header.result = EBUSY;
        break;
    case DID_BAD_TARGET:
    case DID_ABORT:
    case DID_PARITY:
    case DID_RESET:
    case DID_BAD_INTR:
        device->header.result = EIO;
        break;
    case DID_ERROR:
        /*
         * There really should be DID_UNDERRUN and DID_OVERRUN error values,
         * and a means for callers of scsi_do_cmd to indicate whether an
         * underrun or overrun should signal an error.  Until that can be
         * implemented, this kludge allows for returning useful error values
         * except in cases that return DID_ERROR that might be due to an
         * underrun.
         */
        if (SCpnt->sense_buffer[0] == 0 &&
                status_byte(SCpnt->result) == GOOD)
            device->header.result = 0;
        else device->header.result = EIO;
        break;
    }

    /*
     * Now wake up the process that is waiting for the
     * result.
     */
    device->complete=1;
    scsi_release_command(SCpnt);
    SCpnt = NULL;
    wake_up(&scsi_generics[dev].read_wait);
}
Ejemplo n.º 3
0
/*
 * hp_sw_error_is_retryable - Is an HP-specific check condition retryable?
 * @req: path activation request
 *
 * Examine error codes of request and determine whether the error is retryable.
 * Some error codes are already retried by scsi-ml (see
 * scsi_decide_disposition), but some HP specific codes are not.
 * The intent of this routine is to supply the logic for the HP specific
 * check conditions.
 *
 * Returns:
 *  1 - command completed with retryable error
 *  0 - command completed with non-retryable error
 *
 * Possible optimizations
 * 1. More hardware-specific error codes
 */
static int hp_sw_error_is_retryable(struct request *req)
{
    /*
     * NOT_READY is known to be retryable
     * For now we just dump out the sense data and call it retryable
     */
    if (status_byte(req->errors) == CHECK_CONDITION)
        __scsi_print_sense(DM_HP_HWH_NAME, req->sense, req->sense_len);

    /*
     * At this point we don't have complete information about all the error
     * codes from this hardware, so we are just conservative and retry
     * when in doubt.
     */
    return 1;
}
Ejemplo n.º 4
0
/*
 * Parse MODE_SELECT cmd reply.
 */
static int trespass_endio(struct scsi_device *sdev, int result)
{
	int err = SCSI_DH_OK;
	struct scsi_sense_hdr sshdr;
	struct clariion_dh_data *csdev = get_clariion_data(sdev);
	char *sense = csdev->sense;

	if (status_byte(result) == CHECK_CONDITION &&
	    scsi_normalize_sense(sense, SCSI_SENSE_BUFFERSIZE, &sshdr)) {
		sdev_printk(KERN_ERR, sdev, "Found valid sense data 0x%2x, "
			    "0x%2x, 0x%2x while sending CLARiiON trespass "
			    "command.\n", sshdr.sense_key, sshdr.asc,
			     sshdr.ascq);

		if ((sshdr.sense_key == 0x05) && (sshdr.asc == 0x04) &&
		     (sshdr.ascq == 0x00)) {
			/*
			 * Array based copy in progress -- do not send
			 * mode_select or copy will be aborted mid-stream.
			 */
			sdev_printk(KERN_INFO, sdev, "Array Based Copy in "
				    "progress while sending CLARiiON trespass "
				    "command.\n");
			err = SCSI_DH_DEV_TEMP_BUSY;
		} else if ((sshdr.sense_key == 0x02) && (sshdr.asc == 0x04) &&
			    (sshdr.ascq == 0x03)) {
			/*
			 * LUN Not Ready - Manual Intervention Required
			 * indicates in-progress ucode upgrade (NDU).
			 */
			sdev_printk(KERN_INFO, sdev, "Detected in-progress "
				    "ucode upgrade NDU operation while sending "
				    "CLARiiON trespass command.\n");
			err = SCSI_DH_DEV_TEMP_BUSY;
		} else
			err = SCSI_DH_DEV_FAILED;
	} else if (result) {
		sdev_printk(KERN_ERR, sdev, "Error 0x%x while sending "
			    "CLARiiON trespass command.\n", result);
		err = SCSI_DH_IO;
	}

	return err;
}
Ejemplo n.º 5
0
static int sg_io(struct file *file, request_queue_t *q,
		struct gendisk *bd_disk, struct sg_io_hdr *hdr)
{
	unsigned long start_time, timeout;
	int writing = 0, ret = 0;
	struct request *rq;
	char sense[SCSI_SENSE_BUFFERSIZE];
	unsigned char cmd[BLK_MAX_CDB];
	struct bio *bio;

	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;

	if (hdr->dxfer_len > (q->max_hw_sectors << 9))
		return -EIO;

	if (hdr->dxfer_len)
		switch (hdr->dxfer_direction) {
		default:
			return -EINVAL;
		case SG_DXFER_TO_DEV:
			writing = 1;
			break;
		case SG_DXFER_TO_FROM_DEV:
		case SG_DXFER_FROM_DEV:
			break;
		}

	rq = blk_get_request(q, writing ? WRITE : READ, GFP_KERNEL);
	if (!rq)
		return -ENOMEM;

	/*
	 * fill in request structure
	 */
	rq->cmd_len = hdr->cmd_len;
	memset(rq->cmd, 0, BLK_MAX_CDB); /* ATAPI hates garbage after CDB */
	memcpy(rq->cmd, cmd, hdr->cmd_len);

	memset(sense, 0, sizeof(sense));
	rq->sense = sense;
	rq->sense_len = 0;

	rq->cmd_type = REQ_TYPE_BLOCK_PC;

	timeout = msecs_to_jiffies(hdr->timeout);
	rq->timeout = (timeout < INT_MAX) ? timeout : INT_MAX;
	if (!rq->timeout)
		rq->timeout = q->sg_timeout;
	if (!rq->timeout)
		rq->timeout = BLK_DEFAULT_TIMEOUT;

	if (hdr->iovec_count) {
		const int size = sizeof(struct sg_iovec) * hdr->iovec_count;
		struct sg_iovec *iov;

		iov = kmalloc(size, GFP_KERNEL);
		if (!iov) {
			ret = -ENOMEM;
			goto out;
		}

		if (copy_from_user(iov, hdr->dxferp, size)) {
			kfree(iov);
			ret = -EFAULT;
			goto out;
		}

		ret = blk_rq_map_user_iov(q, rq, iov, hdr->iovec_count,
					  hdr->dxfer_len);
		kfree(iov);
	} else if (hdr->dxfer_len)
		ret = blk_rq_map_user(q, rq, hdr->dxferp, hdr->dxfer_len);

	if (ret)
		goto out;

	bio = rq->bio;
	rq->retries = 0;

	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, 0);

	/* 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(bio))
		ret = -EFAULT;

	/* may not have succeeded, but output values written to control
	 * structure (struct sg_io_hdr).  */
out:
	blk_put_request(rq);
	return ret;
}
Ejemplo n.º 6
0
void  UMAS_UfiCommand(SCSI_CMD_T *srb, UMAS_DATA_T *umas)
{
    int old_cmnd = 0;

    /*
     *  fix some commands -- this is a form of mode translation
     *  UFI devices only accept 12 byte long commands
     *
     *  NOTE: This only works because a SCSI_CMD_T struct field contains
     *  a uint8_t cmnd[12], so we know we have storage available
     */

    /* set command length to 12 bytes (this affects the transport layer) */
    srb->cmd_len = 12;

    /* determine the correct (or minimum) data length for these commands */
    switch(srb->cmnd[0])
    {
        /* for INQUIRY, UFI devices only ever return 36 bytes */
        case INQUIRY:
            srb->cmnd[4] = 36;
            break;

        /* change MODE_SENSE/MODE_SELECT from 6 to 10 byte commands */
        case MODE_SENSE:
        case MODE_SELECT:
            /* save the command so we can tell what it was */
            old_cmnd = srb->cmnd[0];

            srb->cmnd[11] = 0;
            srb->cmnd[10] = 0;
            srb->cmnd[9] = 0;

            /*
             * If we're sending data, we send all.  If getting data,
             * get the minimum
             */
            if(srb->cmnd[0] == MODE_SELECT)
                srb->cmnd[8] = srb->cmnd[4];
            else
                srb->cmnd[8] = 8;

            srb->cmnd[7] = 0;
            srb->cmnd[6] = 0;
            srb->cmnd[5] = 0;
            srb->cmnd[4] = 0;
            srb->cmnd[3] = 0;
            srb->cmnd[2] = srb->cmnd[2];
            srb->cmnd[1] = srb->cmnd[1];
            srb->cmnd[0] = srb->cmnd[0] | 0x40;
            break;

        /* again, for MODE_SENSE_10, we get the minimum (8) */
        case MODE_SENSE_10:
            srb->cmnd[7] = 0;
            srb->cmnd[8] = 8;
            break;

        /* for REQUEST_SENSE, UFI devices only ever return 18 bytes */
        case REQUEST_SENSE:
            srb->cmnd[4] = 18;
            break;

        /* change READ_6/WRITE_6 to READ_10/WRITE_10, which are UFI commands */
        case WRITE_6:
        case READ_6:
            srb->cmnd[11] = 0;
            srb->cmnd[10] = 0;
            srb->cmnd[9] = 0;
            srb->cmnd[8] = srb->cmnd[4];
            srb->cmnd[7] = 0;
            srb->cmnd[6] = 0;
            srb->cmnd[5] = srb->cmnd[3];
            srb->cmnd[4] = srb->cmnd[2];
            srb->cmnd[3] = srb->cmnd[1] & 0x1F;
            srb->cmnd[2] = 0;
            srb->cmnd[1] = srb->cmnd[1] & 0xE0;
            srb->cmnd[0] = srb->cmnd[0] | 0x20;
            break;
    } /* end switch on cmnd[0] */

    /* convert MODE_SELECT data here */
    if(old_cmnd == MODE_SELECT)
        usb_stor_scsiSense6to10(srb);

    /* send the command to the transport layer */
    UMAS_InvokeTransport(srb, umas);

    /* Fix the MODE_SENSE data if we translated the command */
    if((old_cmnd == MODE_SENSE) && (status_byte(srb->result) == GOOD))
        usb_stor_scsiSense10to6(srb);

    /* Fix the data for an INQUIRY, if necessary */
    fix_inquiry_data(srb);
}
Ejemplo n.º 7
0
void  UMAS_AtapiCommand(SCSI_CMD_T *srb, UMAS_DATA_T *umas)
{
    int   old_cmnd = 0;

    /*
     *  Fix some commands -- this is a form of mode translation
     *  ATAPI devices only accept 12 byte long commands
     *
     *  NOTE: This only works because a SCSI_CMD_T struct field contains
     *  a uint8_t cmnd[12], so we know we have storage available
     */

    /* Pad the ATAPI command with zeros */
    for(; srb->cmd_len < 12; srb->cmd_len++)
        srb->cmnd[srb->cmd_len] = 0;

    /* set command length to 12 bytes */
    srb->cmd_len = 12;

    /* determine the correct (or minimum) data length for these commands */
    switch(srb->cmnd[0])
    {
        /* change MODE_SENSE/MODE_SELECT from 6 to 10 byte commands */
        case MODE_SENSE:
        case MODE_SELECT:
            /* save the command so we can tell what it was */
            old_cmnd = srb->cmnd[0];

            srb->cmnd[11] = 0;
            srb->cmnd[10] = 0;
            srb->cmnd[9] = 0;
            srb->cmnd[8] = srb->cmnd[4];
            srb->cmnd[7] = 0;
            srb->cmnd[6] = 0;
            srb->cmnd[5] = 0;
            srb->cmnd[4] = 0;
            srb->cmnd[3] = 0;
            srb->cmnd[2] = srb->cmnd[2];
            srb->cmnd[1] = srb->cmnd[1];
            srb->cmnd[0] = srb->cmnd[0] | 0x40;
            break;

        /* change READ_6/WRITE_6 to READ_10/WRITE_10, which are ATAPI commands */
        case WRITE_6:
        case READ_6:
            srb->cmnd[11] = 0;
            srb->cmnd[10] = 0;
            srb->cmnd[9] = 0;
            srb->cmnd[8] = srb->cmnd[4];
            srb->cmnd[7] = 0;
            srb->cmnd[6] = 0;
            srb->cmnd[5] = srb->cmnd[3];
            srb->cmnd[4] = srb->cmnd[2];
            srb->cmnd[3] = srb->cmnd[1] & 0x1F;
            srb->cmnd[2] = 0;
            srb->cmnd[1] = srb->cmnd[1] & 0xE0;
            srb->cmnd[0] = srb->cmnd[0] | 0x20;
            break;
    }  /* end switch on cmnd[0] */

    /* convert MODE_SELECT data here */
    if(old_cmnd == MODE_SELECT)
        usb_stor_scsiSense6to10(srb);

    /* send the command to the transport layer */
    UMAS_InvokeTransport(srb, umas);

    /* Fix the MODE_SENSE data if we translated the command */
    if((old_cmnd == MODE_SENSE) && (status_byte(srb->result) == GOOD))
        usb_stor_scsiSense10to6(srb);

    /* fix the INQUIRY data if necessary */
    fix_inquiry_data(srb);
}