scsi_cmds.c revision 677833bc953b6cb418c701facbdcf4aa18d6c44e
#ifdef USB_DISK
/*******************************************************************************
*
*
* Copyright 2003 Steven James <pyro@linuxlabs.com> and
* LinuxLabs http://www.linuxlabs.com
*
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
******************************************************************************/
#include <etherboot.h>
#include <pci.h>
#include <timer.h>
#include <lib.h>
#define DEBUG_THIS DEBUG_USB
#include <debug.h>
#include "scsi.h"
#include "usb_scsi_low.h"
#ifndef NULL
#define NULL (void *) 0x0
#endif
#include "scsi_cmds.h"
typedef struct sense_data {
typedef struct fixed_sense_data {
unsigned int info;
typedef struct additional_fixed_data {
unsigned int info;
{
int i;
DPRINTF( "sense data ");
for(i=0;i<len; i++) {
}
DPRINTF("\n\n");
int dlen;
DPRINTF("code = %02x, key = %1x, additional = %02x, qual = %02x\n", sd->code, sd->sense_key, sd->additional_code, sd->qualifier);
while(remaining) {
pos+=2;
remaining -=2;
for(i=0; i<dlen; i++)
DPRINTF("\n");
pos+=i;
remaining -=i;
}
} else {
DPRINTF("filemark ");
}
DPRINTF(" End Of Media ");
}
DPRINTF("Illegal instruction");
}
DPRINTF("\n");
DPRINTF( "(valid) ");
}
// while(remaining) {
if(remaining) {
DPRINTF("sense key data = %02x:%02x:%02x\n\n", afd->specific[2], afd->specific[1], afd->specific[0]);
afd++;
remaining -= sizeof(additional_fixed_data_t);
}
}
}
typedef struct query_response {
char vendor[8];
char product[16];
char revision[4];
char vendor_data[20];
unsigned short version_desc[8];
char reserved4[21];
typedef struct ReadBlockCMD {
unsigned int block_address;
unsigned short block_count;
{
int ret;
char sensedat[32];
ret = scsi_command( sgd, (uint8_t *)&rb, sizeof(rb), SG_DXFER_FROM_DEV, buffer, count * 512, sensedat, sizeof(sensedat));
if(ret<0) {
}
return(ret);
}
{
int ret;
char sensedat[32];
ret = scsi_command( sgd, (uint8_t *)&rb, sizeof(rb), SG_DXFER_TO_DEV, buffer, count * 512, sensedat, sizeof(sensedat));
return(ret);
}
typedef struct ReadLongCMD {
unsigned int block_address;
unsigned short length;
{
int ret;
char sensedat[32];
ret = scsi_command( sgd, (uint8_t *)&rb, sizeof(rb), SG_DXFER_FROM_DEV, buffer, size, sensedat, sizeof(sensedat));
return(ret);
}
struct ReadCapacityResponse {
unsigned int block_address;
unsigned int block_length;
};
{
int ret;
struct ReadCapacityResponse response;
char sensedat[32];
ret = scsi_command(sgd, ReadCapacityCMD, sizeof(ReadCapacityCMD), SG_DXFER_FROM_DEV, (uint8_t *)&response, sizeof(response), sensedat, sizeof(sensedat) );
if(ret<0) {
}
return(ret);
}
#define INQ_REP_LEN 96
{
int ret;
char sensedat[32];
ret = scsi_command(sgd, InquiryCMD, sizeof(InquiryCMD), SG_DXFER_FROM_DEV, (uint8_t *)qr, sizeof(query_response_t), sensedat, sizeof(sensedat) );
if(ret<0){
DPRINTF("query: IOCTL");
}
return(ret);
}
typedef struct lun_list {
unsigned int list_length;
unsigned int reserved;
unsigned long long lun[16];
} lun_list_t;
#define REPORT_LUNS 0xa0
{
int ret;
char sensedat[32];
ret = scsi_command(sgd, ReportLunsCMD, sizeof(ReportLunsCMD), SG_DXFER_FROM_DEV, (uint8_t *)list, sizeof(lun_list_t), sensedat, sizeof(sensedat) );
if(ret<0) {
DPRINTF("Report Luns: IOCTL");
}
return(ret);
}
typedef struct command_descriptor {
unsigned short service_action;
unsigned short cdb_len;
typedef struct report_opcodes_result {
unsigned long length;
#define REPORT_OPCODES 0xa3
typedef struct report_opcodes_cmd {
unsigned int reply_len;
//ReportOpcodesCMD_t ReportOpcodesCMD = { cmd : REPORT_OPCODES, reply_len: htonl(sizeof(report_opcode_result_t)) };
{
int ret;
char sensedat[32];
ret = scsi_command(sgd, (uint8_t *)&ReportOpcodesCMD, sizeof(ReportOpcodesCMD_t), SG_DXFER_FROM_DEV, (uint8_t *)list, sizeof(report_opcode_result_t), sensedat, sizeof(sensedat) );
if(ret<0) {
DPRINTF("Report Luns: IOCTL");
}
return(ret);
}
#define READ_ATTRIBUTE 0x8c
#define VOLUME_LIST 2
#define PARTITION_LIST 3
typedef struct read_attribute_cmd {
unsigned int reply_len;
{
int ret;
ret = scsi_command(sgd, (uint8_t *)&cmd, sizeof(cmd), SG_DXFER_FROM_DEV, reply, sizeof(reply), sensedat, sizeof(sensedat) );
if(ret<0) {
DPRINTF("Report Volumes: IOCTL");
return(-1);
}
return(0);
return(reply[3]);
}
{
int ret;
ret = scsi_command(sgd, (uint8_t *)&cmd, sizeof(cmd), SG_DXFER_FROM_DEV, reply, sizeof(reply), sensedat, sizeof(sensedat) );
if(ret<0) {
DPRINTF("Report PARTITIONVolumes: IOCTL");
return(-1);
}
return(0);
return(reply[3]);
}
{
int ret;
ret = scsi_command(sgd, &cmd, sizeof(cmd), SG_DXFER_FROM_DEV, NULL, 0, sensedat, sizeof(sensedat) );
if(ret<0) {
DPRINTF("UnitReady :");
return(0);
}
return(1);
}
#endif