Exemplo n.º 1
0
void usb_stor_transparent_scsi_command(Scsi_Cmnd *srb, struct us_data *us)
{
	/* send the command to the transport layer */
	usb_stor_invoke_transport(srb, us);

	if (srb->result == SAM_STAT_GOOD) {
		/* Fix the INQUIRY data if necessary */
		fix_inquiry_data(srb);

		/* Fix the READ CAPACITY result if necessary */
		if (us->flags & US_FL_FIX_CAPACITY)
			fix_read_capacity(srb);
	}
}
Exemplo n.º 2
0
void usb_stor_ufi_command(Scsi_Cmnd *srb, struct us_data *us)
{
	/* 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_Cmnd struct field contains
	 * a unsigned char cmnd[16], 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 (this affects the transport layer) */
	srb->cmd_len = 12;

	/* XXX We should be constantly re-evaluating the need for these */

	/* determine the correct 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;

		/* 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;
	} /* end switch on cmnd[0] */

	/* send the command to the transport layer */
	usb_stor_invoke_transport(srb, us);

	if (srb->result == SAM_STAT_GOOD) {
		/* Fix the data for an INQUIRY, if necessary */
		fix_inquiry_data(srb);
	}
}
Exemplo n.º 3
0
/***********************************************************************
 * Protocol routines
 ***********************************************************************/
void  UMAS_Qic157Command(SCSI_CMD_T *srb, UMAS_DATA_T *umas)
{
    /*
     *  Pad the ATAPI command with zeros
     *  NOTE: This only works because a SCSI_CMD_T struct field contains
     *  a uint8_t cmnd[12], so we know we have storage available
     */
    for(; srb->cmd_len < 12; srb->cmd_len++)
        srb->cmnd[srb->cmd_len] = 0;

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

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

    /* fix the INQUIRY data if necessary */
    fix_inquiry_data(srb);
}
Exemplo n.º 4
0
void usb_stor_qic157_command(Scsi_Cmnd *srb, struct us_data *us)
{
	/* Pad the ATAPI command with zeros 
	 *
	 * NOTE: This only works because a Scsi_Cmnd struct field contains
	 * a unsigned char cmnd[16], so we know we have storage available
	 */
	for (; srb->cmd_len<12; srb->cmd_len++)
		srb->cmnd[srb->cmd_len] = 0;

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

	/* send the command to the transport layer */
	usb_stor_invoke_transport(srb, us);
	if (srb->result == SAM_STAT_GOOD) {
		/* fix the INQUIRY data if necessary */
		fix_inquiry_data(srb);
	}
}
Exemplo n.º 5
0
void  UMAS_TransparentScsiCommand(SCSI_CMD_T *srb, UMAS_DATA_T *umas)
{
    /*
     * This code supports devices which do not support {READ|WRITE}_6
     * Apparently, neither Windows or MacOS will use these commands,
     * so some devices do not support them
     */
    if(umas->flags & UMAS_FL_MODE_XLATE)
    {
        /* translate READ_6 to READ_10 */
        if(srb->cmnd[0] == READ_6)
        {
            /* get the control */
            srb->cmnd[9] = umas->srb.cmnd[5];

            /* get the length */
            srb->cmnd[8] = umas->srb.cmnd[6];
            srb->cmnd[7] = 0;

            /* set the reserved area to 0 */
            srb->cmnd[6] = 0;

            /* get LBA */
            srb->cmnd[5] = umas->srb.cmnd[3];
            srb->cmnd[4] = umas->srb.cmnd[2];
            srb->cmnd[3] = 0;
            srb->cmnd[2] = 0;

            /* LUN and other info in cmnd[1] can stay */

            /* fix command code */
            srb->cmnd[0] = 0x28;

            UMAS_DEBUG("Changing READ_6 to READ_10\n");
            UMAS_DEBUG_ShowCommand(srb);
        }

        /* translate WRITE_6 to WRITE_10 */
        if(srb->cmnd[0] == WRITE_6)
        {
            /* get the control */
            srb->cmnd[9] = umas->srb.cmnd[5];

            /* get the length */
            srb->cmnd[8] = umas->srb.cmnd[4];
            srb->cmnd[7] = 0;

            /* set the reserved area to 0 */
            srb->cmnd[6] = 0;

            /* get LBA */
            srb->cmnd[5] = umas->srb.cmnd[3];
            srb->cmnd[4] = umas->srb.cmnd[2];
            srb->cmnd[3] = 0;
            srb->cmnd[2] = 0;

            /* LUN and other info in cmnd[1] can stay */

            /* fix command code */
            srb->cmnd[0] = 0x2A;

            UMAS_DEBUG("Changing WRITE_6 to WRITE_10\n");
            UMAS_DEBUG_ShowCommand(&umas->srb);
        }
    }   /* if (umas->flags & UMAS_FL_MODE_XLATE) */

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

    /* fix the INQUIRY data if necessary */
    fix_inquiry_data(srb);
}
Exemplo 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);
}
Exemplo 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);
}