symbian-qemu-0.9.1-12/qemu-symbian-svp/hw/scsi-generic.c
changeset 1 2fb8b9db1c86
equal deleted inserted replaced
0:ffa851df0825 1:2fb8b9db1c86
       
     1 /*
       
     2  * Generic SCSI Device support
       
     3  *
       
     4  * Copyright (c) 2007 Bull S.A.S.
       
     5  * Based on code by Paul Brook
       
     6  * Based on code by Fabrice Bellard
       
     7  *
       
     8  * Written by Laurent Vivier <Laurent.Vivier@bull.net>
       
     9  *
       
    10  * This code is licenced under the LGPL.
       
    11  *
       
    12  */
       
    13 
       
    14 #include "qemu-common.h"
       
    15 #include "block.h"
       
    16 #include "scsi-disk.h"
       
    17 
       
    18 #ifndef __linux__
       
    19 
       
    20 SCSIDevice *scsi_generic_init(BlockDriverState *bdrv, int tcq,
       
    21                               scsi_completionfn completion, void *opaque)
       
    22 {
       
    23     return NULL;
       
    24 }
       
    25 
       
    26 #else /* __linux__ */
       
    27 
       
    28 //#define DEBUG_SCSI
       
    29 
       
    30 #ifdef DEBUG_SCSI
       
    31 #define DPRINTF(fmt, args...) \
       
    32 do { printf("scsi-generic: " fmt , ##args); } while (0)
       
    33 #else
       
    34 #define DPRINTF(fmt, args...) do {} while(0)
       
    35 #endif
       
    36 
       
    37 #define BADF(fmt, args...) \
       
    38 do { fprintf(stderr, "scsi-generic: " fmt , ##args); } while (0)
       
    39 
       
    40 #include <stdio.h>
       
    41 #include <sys/types.h>
       
    42 #include <sys/stat.h>
       
    43 #include <unistd.h>
       
    44 #include <scsi/sg.h>
       
    45 #include <scsi/scsi.h>
       
    46 
       
    47 #define REWIND 0x01
       
    48 #define REPORT_DENSITY_SUPPORT 0x44
       
    49 #define LOAD_UNLOAD 0xa6
       
    50 #define SET_CD_SPEED 0xbb
       
    51 #define BLANK 0xa1
       
    52 
       
    53 #define SCSI_CMD_BUF_SIZE     16
       
    54 #define SCSI_SENSE_BUF_SIZE 96
       
    55 
       
    56 #define SG_ERR_DRIVER_TIMEOUT 0x06
       
    57 #define SG_ERR_DRIVER_SENSE 0x08
       
    58 
       
    59 #ifndef MAX_UINT
       
    60 #define MAX_UINT ((unsigned int)-1)
       
    61 #endif
       
    62 
       
    63 typedef struct SCSIRequest {
       
    64     BlockDriverAIOCB *aiocb;
       
    65     struct SCSIRequest *next;
       
    66     SCSIDeviceState *dev;
       
    67     uint32_t tag;
       
    68     uint8_t cmd[SCSI_CMD_BUF_SIZE];
       
    69     int cmdlen;
       
    70     uint8_t *buf;
       
    71     int buflen;
       
    72     int len;
       
    73     sg_io_hdr_t io_header;
       
    74 } SCSIRequest;
       
    75 
       
    76 struct SCSIDeviceState
       
    77 {
       
    78     SCSIRequest *requests;
       
    79     BlockDriverState *bdrv;
       
    80     int type;
       
    81     int blocksize;
       
    82     int lun;
       
    83     scsi_completionfn completion;
       
    84     void *opaque;
       
    85     int driver_status;
       
    86     uint8_t sensebuf[SCSI_SENSE_BUF_SIZE];
       
    87     uint8_t senselen;
       
    88 };
       
    89 
       
    90 /* Global pool of SCSIRequest structures.  */
       
    91 static SCSIRequest *free_requests = NULL;
       
    92 
       
    93 static SCSIRequest *scsi_new_request(SCSIDeviceState *s, uint32_t tag)
       
    94 {
       
    95     SCSIRequest *r;
       
    96 
       
    97     if (free_requests) {
       
    98         r = free_requests;
       
    99         free_requests = r->next;
       
   100     } else {
       
   101         r = qemu_malloc(sizeof(SCSIRequest));
       
   102         r->buf = NULL;
       
   103         r->buflen = 0;
       
   104     }
       
   105     r->dev = s;
       
   106     r->tag = tag;
       
   107     memset(r->cmd, 0, sizeof(r->cmd));
       
   108     memset(&r->io_header, 0, sizeof(r->io_header));
       
   109     r->cmdlen = 0;
       
   110     r->len = 0;
       
   111     r->aiocb = NULL;
       
   112 
       
   113     /* link */
       
   114 
       
   115     r->next = s->requests;
       
   116     s->requests = r;
       
   117     return r;
       
   118 }
       
   119 
       
   120 static void scsi_remove_request(SCSIRequest *r)
       
   121 {
       
   122     SCSIRequest *last;
       
   123     SCSIDeviceState *s = r->dev;
       
   124 
       
   125     if (s->requests == r) {
       
   126         s->requests = r->next;
       
   127     } else {
       
   128         last = s->requests;
       
   129         while (last && last->next != r)
       
   130             last = last->next;
       
   131         if (last) {
       
   132             last->next = r->next;
       
   133         } else {
       
   134             BADF("Orphaned request\n");
       
   135         }
       
   136     }
       
   137     r->next = free_requests;
       
   138     free_requests = r;
       
   139 }
       
   140 
       
   141 static SCSIRequest *scsi_find_request(SCSIDeviceState *s, uint32_t tag)
       
   142 {
       
   143     SCSIRequest *r;
       
   144 
       
   145     r = s->requests;
       
   146     while (r && r->tag != tag)
       
   147         r = r->next;
       
   148 
       
   149     return r;
       
   150 }
       
   151 
       
   152 /* Helper function for command completion.  */
       
   153 static void scsi_command_complete(void *opaque, int ret)
       
   154 {
       
   155     SCSIRequest *r = (SCSIRequest *)opaque;
       
   156     SCSIDeviceState *s = r->dev;
       
   157     uint32_t tag;
       
   158     int status;
       
   159 
       
   160     s->driver_status = r->io_header.driver_status;
       
   161     if (s->driver_status & SG_ERR_DRIVER_SENSE)
       
   162         s->senselen = r->io_header.sb_len_wr;
       
   163 
       
   164     if (ret != 0)
       
   165         status = BUSY << 1;
       
   166     else {
       
   167         if (s->driver_status & SG_ERR_DRIVER_TIMEOUT) {
       
   168             status = BUSY << 1;
       
   169             BADF("Driver Timeout\n");
       
   170         } else if (r->io_header.status)
       
   171             status = r->io_header.status;
       
   172         else if (s->driver_status & SG_ERR_DRIVER_SENSE)
       
   173             status = CHECK_CONDITION << 1;
       
   174         else
       
   175             status = GOOD << 1;
       
   176     }
       
   177     DPRINTF("Command complete 0x%p tag=0x%x status=%d\n",
       
   178             r, r->tag, status);
       
   179     tag = r->tag;
       
   180     scsi_remove_request(r);
       
   181     s->completion(s->opaque, SCSI_REASON_DONE, tag, status);
       
   182 }
       
   183 
       
   184 /* Cancel a pending data transfer.  */
       
   185 static void scsi_cancel_io(SCSIDevice *d, uint32_t tag)
       
   186 {
       
   187     DPRINTF("scsi_cancel_io 0x%x\n", tag);
       
   188     SCSIDeviceState *s = d->state;
       
   189     SCSIRequest *r;
       
   190     DPRINTF("Cancel tag=0x%x\n", tag);
       
   191     r = scsi_find_request(s, tag);
       
   192     if (r) {
       
   193         if (r->aiocb)
       
   194             bdrv_aio_cancel(r->aiocb);
       
   195         r->aiocb = NULL;
       
   196         scsi_remove_request(r);
       
   197     }
       
   198 }
       
   199 
       
   200 static int execute_command(BlockDriverState *bdrv,
       
   201                            SCSIRequest *r, int direction,
       
   202 			   BlockDriverCompletionFunc *complete)
       
   203 {
       
   204 
       
   205     r->io_header.interface_id = 'S';
       
   206     r->io_header.dxfer_direction = direction;
       
   207     r->io_header.dxferp = r->buf;
       
   208     r->io_header.dxfer_len = r->buflen;
       
   209     r->io_header.cmdp = r->cmd;
       
   210     r->io_header.cmd_len = r->cmdlen;
       
   211     r->io_header.mx_sb_len = sizeof(r->dev->sensebuf);
       
   212     r->io_header.sbp = r->dev->sensebuf;
       
   213     r->io_header.timeout = MAX_UINT;
       
   214     r->io_header.usr_ptr = r;
       
   215     r->io_header.flags |= SG_FLAG_DIRECT_IO;
       
   216 
       
   217     if (bdrv_pwrite(bdrv, -1, &r->io_header, sizeof(r->io_header)) == -1) {
       
   218         BADF("execute_command: write failed ! (%d)\n", errno);
       
   219         return -1;
       
   220     }
       
   221     if (complete == NULL) {
       
   222         int ret;
       
   223         r->aiocb = NULL;
       
   224         while ((ret = bdrv_pread(bdrv, -1, &r->io_header,
       
   225                                            sizeof(r->io_header))) == -1 &&
       
   226                       errno == EINTR);
       
   227         if (ret == -1) {
       
   228             BADF("execute_command: read failed !\n");
       
   229             return -1;
       
   230         }
       
   231         return 0;
       
   232     }
       
   233 
       
   234     r->aiocb = bdrv_aio_read(bdrv, 0, (uint8_t*)&r->io_header,
       
   235                           -(int64_t)sizeof(r->io_header), complete, r);
       
   236     if (r->aiocb == NULL) {
       
   237         BADF("execute_command: read failed !\n");
       
   238         return -1;
       
   239     }
       
   240 
       
   241     return 0;
       
   242 }
       
   243 
       
   244 static void scsi_read_complete(void * opaque, int ret)
       
   245 {
       
   246     SCSIRequest *r = (SCSIRequest *)opaque;
       
   247     SCSIDeviceState *s = r->dev;
       
   248     int len;
       
   249 
       
   250     if (ret) {
       
   251         DPRINTF("IO error\n");
       
   252         scsi_command_complete(r, ret);
       
   253         return;
       
   254     }
       
   255     len = r->io_header.dxfer_len - r->io_header.resid;
       
   256     DPRINTF("Data ready tag=0x%x len=%d\n", r->tag, len);
       
   257 
       
   258     r->len = -1;
       
   259     s->completion(s->opaque, SCSI_REASON_DATA, r->tag, len);
       
   260     if (len == 0)
       
   261         scsi_command_complete(r, 0);
       
   262 }
       
   263 
       
   264 /* Read more data from scsi device into buffer.  */
       
   265 static void scsi_read_data(SCSIDevice *d, uint32_t tag)
       
   266 {
       
   267     SCSIDeviceState *s = d->state;
       
   268     SCSIRequest *r;
       
   269     int ret;
       
   270 
       
   271     DPRINTF("scsi_read_data 0x%x\n", tag);
       
   272     r = scsi_find_request(s, tag);
       
   273     if (!r) {
       
   274         BADF("Bad read tag 0x%x\n", tag);
       
   275         /* ??? This is the wrong error.  */
       
   276         scsi_command_complete(r, -EINVAL);
       
   277         return;
       
   278     }
       
   279 
       
   280     if (r->len == -1) {
       
   281         scsi_command_complete(r, 0);
       
   282         return;
       
   283     }
       
   284 
       
   285     if (r->cmd[0] == REQUEST_SENSE && s->driver_status & SG_ERR_DRIVER_SENSE)
       
   286     {
       
   287         s->senselen = MIN(r->len, s->senselen);
       
   288         memcpy(r->buf, s->sensebuf, s->senselen);
       
   289         r->io_header.driver_status = 0;
       
   290         r->io_header.status = 0;
       
   291         r->io_header.dxfer_len  = s->senselen;
       
   292         r->len = -1;
       
   293         DPRINTF("Data ready tag=0x%x len=%d\n", r->tag, s->senselen);
       
   294         DPRINTF("Sense: %d %d %d %d %d %d %d %d\n",
       
   295                 r->buf[0], r->buf[1], r->buf[2], r->buf[3],
       
   296                 r->buf[4], r->buf[5], r->buf[6], r->buf[7]);
       
   297         s->completion(s->opaque, SCSI_REASON_DATA, r->tag, s->senselen);
       
   298         return;
       
   299     }
       
   300 
       
   301     ret = execute_command(s->bdrv, r, SG_DXFER_FROM_DEV, scsi_read_complete);
       
   302     if (ret == -1) {
       
   303         scsi_command_complete(r, -EINVAL);
       
   304         return;
       
   305     }
       
   306 }
       
   307 
       
   308 static void scsi_write_complete(void * opaque, int ret)
       
   309 {
       
   310     SCSIRequest *r = (SCSIRequest *)opaque;
       
   311 
       
   312     DPRINTF("scsi_write_complete() ret = %d\n", ret);
       
   313     if (ret) {
       
   314         DPRINTF("IO error\n");
       
   315         scsi_command_complete(r, ret);
       
   316         return;
       
   317     }
       
   318 
       
   319     if (r->cmd[0] == MODE_SELECT && r->cmd[4] == 12 &&
       
   320         r->dev->type == TYPE_TAPE) {
       
   321         r->dev->blocksize = (r->buf[9] << 16) | (r->buf[10] << 8) | r->buf[11];
       
   322         DPRINTF("block size %d\n", r->dev->blocksize);
       
   323     }
       
   324 
       
   325     scsi_command_complete(r, ret);
       
   326 }
       
   327 
       
   328 /* Write data to a scsi device.  Returns nonzero on failure.
       
   329    The transfer may complete asynchronously.  */
       
   330 static int scsi_write_data(SCSIDevice *d, uint32_t tag)
       
   331 {
       
   332     SCSIDeviceState *s = d->state;
       
   333     SCSIRequest *r;
       
   334     int ret;
       
   335 
       
   336     DPRINTF("scsi_write_data 0x%x\n", tag);
       
   337     r = scsi_find_request(s, tag);
       
   338     if (!r) {
       
   339         BADF("Bad write tag 0x%x\n", tag);
       
   340         /* ??? This is the wrong error.  */
       
   341         scsi_command_complete(r, -EINVAL);
       
   342         return 0;
       
   343     }
       
   344 
       
   345     if (r->len == 0) {
       
   346         r->len = r->buflen;
       
   347         s->completion(s->opaque, SCSI_REASON_DATA, r->tag, r->len);
       
   348         return 0;
       
   349     }
       
   350 
       
   351     ret = execute_command(s->bdrv, r, SG_DXFER_TO_DEV, scsi_write_complete);
       
   352     if (ret == -1) {
       
   353         scsi_command_complete(r, -EINVAL);
       
   354         return 1;
       
   355     }
       
   356 
       
   357     return 0;
       
   358 }
       
   359 
       
   360 /* Return a pointer to the data buffer.  */
       
   361 static uint8_t *scsi_get_buf(SCSIDevice *d, uint32_t tag)
       
   362 {
       
   363     SCSIDeviceState *s = d->state;
       
   364     SCSIRequest *r;
       
   365     r = scsi_find_request(s, tag);
       
   366     if (!r) {
       
   367         BADF("Bad buffer tag 0x%x\n", tag);
       
   368         return NULL;
       
   369     }
       
   370     return r->buf;
       
   371 }
       
   372 
       
   373 static int scsi_length(uint8_t *cmd, int blocksize, int *cmdlen, uint32_t *len)
       
   374 {
       
   375     switch (cmd[0] >> 5) {
       
   376     case 0:
       
   377         *len = cmd[4];
       
   378         *cmdlen = 6;
       
   379         /* length 0 means 256 blocks */
       
   380         if (*len == 0)
       
   381             *len = 256;
       
   382         break;
       
   383     case 1:
       
   384     case 2:
       
   385         *len = cmd[8] | (cmd[7] << 8);
       
   386         *cmdlen = 10;
       
   387         break;
       
   388     case 4:
       
   389         *len = cmd[13] | (cmd[12] << 8) | (cmd[11] << 16) | (cmd[10] << 24);
       
   390         *cmdlen = 16;
       
   391         break;
       
   392     case 5:
       
   393         *len = cmd[9] | (cmd[8] << 8) | (cmd[7] << 16) | (cmd[6] << 24);
       
   394         *cmdlen = 12;
       
   395         break;
       
   396     default:
       
   397         return -1;
       
   398     }
       
   399 
       
   400     switch(cmd[0]) {
       
   401     case TEST_UNIT_READY:
       
   402     case REZERO_UNIT:
       
   403     case START_STOP:
       
   404     case SEEK_6:
       
   405     case WRITE_FILEMARKS:
       
   406     case SPACE:
       
   407     case ERASE:
       
   408     case ALLOW_MEDIUM_REMOVAL:
       
   409     case VERIFY:
       
   410     case SEEK_10:
       
   411     case SYNCHRONIZE_CACHE:
       
   412     case LOCK_UNLOCK_CACHE:
       
   413     case LOAD_UNLOAD:
       
   414     case SET_CD_SPEED:
       
   415     case SET_LIMITS:
       
   416     case WRITE_LONG:
       
   417     case MOVE_MEDIUM:
       
   418     case UPDATE_BLOCK:
       
   419         *len = 0;
       
   420         break;
       
   421     case MODE_SENSE:
       
   422         break;
       
   423     case WRITE_SAME:
       
   424         *len = 1;
       
   425         break;
       
   426     case READ_CAPACITY:
       
   427         *len = 8;
       
   428         break;
       
   429     case READ_BLOCK_LIMITS:
       
   430         *len = 6;
       
   431         break;
       
   432     case READ_POSITION:
       
   433         *len = 20;
       
   434         break;
       
   435     case SEND_VOLUME_TAG:
       
   436         *len *= 40;
       
   437         break;
       
   438     case MEDIUM_SCAN:
       
   439         *len *= 8;
       
   440         break;
       
   441     case WRITE_10:
       
   442         cmd[1] &= ~0x08;	/* disable FUA */
       
   443     case WRITE_VERIFY:
       
   444     case WRITE_6:
       
   445     case WRITE_12:
       
   446     case WRITE_VERIFY_12:
       
   447         *len *= blocksize;
       
   448         break;
       
   449     case READ_10:
       
   450         cmd[1] &= ~0x08;	/* disable FUA */
       
   451     case READ_6:
       
   452     case READ_REVERSE:
       
   453     case RECOVER_BUFFERED_DATA:
       
   454     case READ_12:
       
   455         *len *= blocksize;
       
   456         break;
       
   457     case INQUIRY:
       
   458         *len = cmd[4] | (cmd[3] << 8);
       
   459         break;
       
   460     }
       
   461     return 0;
       
   462 }
       
   463 
       
   464 static int scsi_stream_length(uint8_t *cmd, int blocksize, int *cmdlen, uint32_t *len)
       
   465 {
       
   466     switch(cmd[0]) {
       
   467     /* stream commands */
       
   468     case READ_6:
       
   469     case READ_REVERSE:
       
   470     case RECOVER_BUFFERED_DATA:
       
   471     case WRITE_6:
       
   472         *cmdlen = 6;
       
   473         *len = cmd[4] | (cmd[3] << 8) | (cmd[2] << 16);
       
   474         if (cmd[1] & 0x01) /* fixed */
       
   475             *len *= blocksize;
       
   476         break;
       
   477     case REWIND:
       
   478     case START_STOP:
       
   479         *cmdlen = 6;
       
   480         *len = 0;
       
   481         cmd[1] = 0x01;	/* force IMMED, otherwise qemu waits end of command */
       
   482         break;
       
   483     /* generic commands */
       
   484     default:
       
   485         return scsi_length(cmd, blocksize, cmdlen, len);
       
   486     }
       
   487     return 0;
       
   488 }
       
   489 
       
   490 static int is_write(int command)
       
   491 {
       
   492     switch (command) {
       
   493     case COPY:
       
   494     case COPY_VERIFY:
       
   495     case COMPARE:
       
   496     case CHANGE_DEFINITION:
       
   497     case LOG_SELECT:
       
   498     case MODE_SELECT:
       
   499     case MODE_SELECT_10:
       
   500     case SEND_DIAGNOSTIC:
       
   501     case WRITE_BUFFER:
       
   502     case FORMAT_UNIT:
       
   503     case REASSIGN_BLOCKS:
       
   504     case RESERVE:
       
   505     case SEARCH_EQUAL:
       
   506     case SEARCH_HIGH:
       
   507     case SEARCH_LOW:
       
   508     case WRITE_6:
       
   509     case WRITE_10:
       
   510     case WRITE_VERIFY:
       
   511     case UPDATE_BLOCK:
       
   512     case WRITE_LONG:
       
   513     case WRITE_SAME:
       
   514     case SEARCH_HIGH_12:
       
   515     case SEARCH_EQUAL_12:
       
   516     case SEARCH_LOW_12:
       
   517     case WRITE_12:
       
   518     case WRITE_VERIFY_12:
       
   519     case SET_WINDOW:
       
   520     case MEDIUM_SCAN:
       
   521     case SEND_VOLUME_TAG:
       
   522     case WRITE_LONG_2:
       
   523         return 1;
       
   524     }
       
   525     return 0;
       
   526 }
       
   527 
       
   528 /* Execute a scsi command.  Returns the length of the data expected by the
       
   529    command.  This will be Positive for data transfers from the device
       
   530    (eg. disk reads), negative for transfers to the device (eg. disk writes),
       
   531    and zero if the command does not transfer any data.  */
       
   532 
       
   533 static int32_t scsi_send_command(SCSIDevice *d, uint32_t tag,
       
   534                                  uint8_t *cmd, int lun)
       
   535 {
       
   536     SCSIDeviceState *s = d->state;
       
   537     uint32_t len=0;
       
   538     int cmdlen=0;
       
   539     SCSIRequest *r;
       
   540     int ret;
       
   541 
       
   542     if (s->type == TYPE_TAPE) {
       
   543         if (scsi_stream_length(cmd, s->blocksize, &cmdlen, &len) == -1) {
       
   544             BADF("Unsupported command length, command %x\n", cmd[0]);
       
   545             return 0;
       
   546         }
       
   547      } else {
       
   548         if (scsi_length(cmd, s->blocksize, &cmdlen, &len) == -1) {
       
   549             BADF("Unsupported command length, command %x\n", cmd[0]);
       
   550             return 0;
       
   551         }
       
   552     }
       
   553 
       
   554     DPRINTF("Command: lun=%d tag=0x%x data=0x%02x len %d\n", lun, tag,
       
   555             cmd[0], len);
       
   556 
       
   557     if (cmd[0] != REQUEST_SENSE &&
       
   558         (lun != s->lun || (cmd[1] >> 5) != s->lun)) {
       
   559         DPRINTF("Unimplemented LUN %d\n", lun ? lun : cmd[1] >> 5);
       
   560 
       
   561         s->sensebuf[0] = 0x70;
       
   562         s->sensebuf[1] = 0x00;
       
   563         s->sensebuf[2] = ILLEGAL_REQUEST;
       
   564         s->sensebuf[3] = 0x00;
       
   565         s->sensebuf[4] = 0x00;
       
   566         s->sensebuf[5] = 0x00;
       
   567         s->sensebuf[6] = 0x00;
       
   568         s->senselen = 7;
       
   569         s->driver_status = SG_ERR_DRIVER_SENSE;
       
   570         s->completion(s->opaque, SCSI_REASON_DONE, tag, CHECK_CONDITION << 1);
       
   571         return 0;
       
   572     }
       
   573 
       
   574     r = scsi_find_request(s, tag);
       
   575     if (r) {
       
   576         BADF("Tag 0x%x already in use %p\n", tag, r);
       
   577         scsi_cancel_io(d, tag);
       
   578     }
       
   579     r = scsi_new_request(s, tag);
       
   580 
       
   581     memcpy(r->cmd, cmd, cmdlen);
       
   582     r->cmdlen = cmdlen;
       
   583 
       
   584     if (len == 0) {
       
   585         if (r->buf != NULL)
       
   586             free(r->buf);
       
   587         r->buflen = 0;
       
   588         r->buf = NULL;
       
   589         ret = execute_command(s->bdrv, r, SG_DXFER_NONE, scsi_command_complete);
       
   590         if (ret == -1) {
       
   591             scsi_command_complete(r, -EINVAL);
       
   592             return 0;
       
   593         }
       
   594         return 0;
       
   595     }
       
   596 
       
   597     if (r->buflen != len) {
       
   598         if (r->buf != NULL)
       
   599             free(r->buf);
       
   600         r->buf = qemu_malloc(len);
       
   601         r->buflen = len;
       
   602     }
       
   603 
       
   604     memset(r->buf, 0, r->buflen);
       
   605     r->len = len;
       
   606     if (is_write(cmd[0])) {
       
   607         r->len = 0;
       
   608         return -len;
       
   609     }
       
   610 
       
   611     return len;
       
   612 }
       
   613 
       
   614 static int get_blocksize(BlockDriverState *bdrv)
       
   615 {
       
   616     uint8_t cmd[10];
       
   617     uint8_t buf[8];
       
   618     uint8_t sensebuf[8];
       
   619     sg_io_hdr_t io_header;
       
   620     int ret;
       
   621 
       
   622     memset(cmd, 0, sizeof(cmd));
       
   623     memset(buf, 0, sizeof(buf));
       
   624     cmd[0] = READ_CAPACITY;
       
   625 
       
   626     memset(&io_header, 0, sizeof(io_header));
       
   627     io_header.interface_id = 'S';
       
   628     io_header.dxfer_direction = SG_DXFER_FROM_DEV;
       
   629     io_header.dxfer_len = sizeof(buf);
       
   630     io_header.dxferp = buf;
       
   631     io_header.cmdp = cmd;
       
   632     io_header.cmd_len = sizeof(cmd);
       
   633     io_header.mx_sb_len = sizeof(sensebuf);
       
   634     io_header.sbp = sensebuf;
       
   635     io_header.timeout = 6000; /* XXX */
       
   636 
       
   637     ret = bdrv_pwrite(bdrv, -1, &io_header, sizeof(io_header));
       
   638     if (ret == -1)
       
   639         return -1;
       
   640 
       
   641     while ((ret = bdrv_pread(bdrv, -1, &io_header, sizeof(io_header))) == -1 &&
       
   642            errno == EINTR);
       
   643 
       
   644     if (ret == -1)
       
   645         return -1;
       
   646 
       
   647     return (buf[4] << 24) | (buf[5] << 16) | (buf[6] << 8) | buf[7];
       
   648 }
       
   649 
       
   650 static int get_stream_blocksize(BlockDriverState *bdrv)
       
   651 {
       
   652     uint8_t cmd[6];
       
   653     uint8_t buf[12];
       
   654     uint8_t sensebuf[8];
       
   655     sg_io_hdr_t io_header;
       
   656     int ret;
       
   657 
       
   658     memset(cmd, 0, sizeof(cmd));
       
   659     memset(buf, 0, sizeof(buf));
       
   660     cmd[0] = MODE_SENSE;
       
   661     cmd[4] = sizeof(buf);
       
   662 
       
   663     memset(&io_header, 0, sizeof(io_header));
       
   664     io_header.interface_id = 'S';
       
   665     io_header.dxfer_direction = SG_DXFER_FROM_DEV;
       
   666     io_header.dxfer_len = sizeof(buf);
       
   667     io_header.dxferp = buf;
       
   668     io_header.cmdp = cmd;
       
   669     io_header.cmd_len = sizeof(cmd);
       
   670     io_header.mx_sb_len = sizeof(sensebuf);
       
   671     io_header.sbp = sensebuf;
       
   672     io_header.timeout = 6000; /* XXX */
       
   673 
       
   674     ret = bdrv_pwrite(bdrv, -1, &io_header, sizeof(io_header));
       
   675     if (ret == -1)
       
   676         return -1;
       
   677 
       
   678     while ((ret = bdrv_pread(bdrv, -1, &io_header, sizeof(io_header))) == -1 &&
       
   679            errno == EINTR);
       
   680 
       
   681     if (ret == -1)
       
   682         return -1;
       
   683 
       
   684     return (buf[9] << 16) | (buf[10] << 8) | buf[11];
       
   685 }
       
   686 
       
   687 static void scsi_destroy(SCSIDevice *d)
       
   688 {
       
   689     SCSIRequest *r, *n;
       
   690 
       
   691     r = d->state->requests;
       
   692     while (r) {
       
   693         n = r->next;
       
   694         qemu_free(r);
       
   695         r = n;
       
   696     }
       
   697 
       
   698     r = free_requests;
       
   699     while (r) {
       
   700         n = r->next;
       
   701         qemu_free(r);
       
   702         r = n;
       
   703     }
       
   704 
       
   705     qemu_free(d->state);
       
   706     qemu_free(d);
       
   707 }
       
   708 
       
   709 SCSIDevice *scsi_generic_init(BlockDriverState *bdrv, int tcq,
       
   710                               scsi_completionfn completion, void *opaque)
       
   711 {
       
   712     int sg_version;
       
   713     SCSIDevice *d;
       
   714     SCSIDeviceState *s;
       
   715     struct sg_scsi_id scsiid;
       
   716 
       
   717     /* check we are really using a /dev/sg* file */
       
   718 
       
   719     if (!bdrv_is_sg(bdrv))
       
   720         return NULL;
       
   721 
       
   722     /* check we are using a driver managing SG_IO (version 3 and after */
       
   723 
       
   724     if (bdrv_ioctl(bdrv, SG_GET_VERSION_NUM, &sg_version) < 0 ||
       
   725         sg_version < 30000)
       
   726         return NULL;
       
   727 
       
   728     /* get LUN of the /dev/sg? */
       
   729 
       
   730     if (bdrv_ioctl(bdrv, SG_GET_SCSI_ID, &scsiid))
       
   731         return NULL;
       
   732 
       
   733     /* define device state */
       
   734 
       
   735     s = (SCSIDeviceState *)qemu_mallocz(sizeof(SCSIDeviceState));
       
   736     s->bdrv = bdrv;
       
   737     s->requests = NULL;
       
   738     s->completion = completion;
       
   739     s->opaque = opaque;
       
   740     s->lun = scsiid.lun;
       
   741     DPRINTF("LUN %d\n", s->lun);
       
   742     s->type = scsiid.scsi_type;
       
   743     DPRINTF("device type %d\n", s->type);
       
   744     if (s->type == TYPE_TAPE) {
       
   745         s->blocksize = get_stream_blocksize(s->bdrv);
       
   746         if (s->blocksize == -1)
       
   747             s->blocksize = 0;
       
   748     } else {
       
   749         s->blocksize = get_blocksize(s->bdrv);
       
   750         /* removable media returns 0 if not present */
       
   751         if (s->blocksize <= 0) {
       
   752             if (s->type == TYPE_ROM || s->type  == TYPE_WORM)
       
   753                 s->blocksize = 2048;
       
   754             else
       
   755                 s->blocksize = 512;
       
   756         }
       
   757     }
       
   758     DPRINTF("block size %d\n", s->blocksize);
       
   759     s->driver_status = 0;
       
   760     memset(s->sensebuf, 0, sizeof(s->sensebuf));
       
   761 
       
   762     /* define function to manage device */
       
   763 
       
   764     d = (SCSIDevice *)qemu_mallocz(sizeof(SCSIDevice));
       
   765     d->state = s;
       
   766     d->destroy = scsi_destroy;
       
   767     d->send_command = scsi_send_command;
       
   768     d->read_data = scsi_read_data;
       
   769     d->write_data = scsi_write_data;
       
   770     d->cancel_io = scsi_cancel_io;
       
   771     d->get_buf = scsi_get_buf;
       
   772 
       
   773     return d;
       
   774 }
       
   775 #endif /* __linux__ */