Annotation of uae/src/scsidev.c, revision 1.1.1.1

1.1       root        1:  /*
                      2:   * UAE - The Un*x Amiga Emulator
                      3:   *
                      4:   * a SCSI device
                      5:   *
                      6:   * Copyright 1995 Bernd Schmidt
                      7:   * Copyright 1999 Patrick Ohly
                      8:   */
                      9: 
                     10: #include "sysconfig.h"
                     11: #include "sysdeps.h"
                     12: 
                     13: #include "config.h"
                     14: #include "threaddep/penguin.h"
                     15: #include "options.h"
                     16: #include "memory.h"
                     17: #include "custom.h"
                     18: #include "readcpu.h"
                     19: #include "newcpu.h"
                     20: #include "disk.h"
                     21: #include "autoconf.h"
                     22: #include "filesys.h"
                     23: #include "execlib.h"
                     24: #include "native2amiga.h"
                     25: #include "scsidev.h"
                     26: #include "scg/scsireg.h"
                     27: 
                     28: /* our configure does not distinguish that */
                     29: #ifdef UAE_FILESYS_THREADS
                     30: #define UAE_SCSIDEV_THREADS
                     31: #endif
                     32: 
                     33: #undef DEBUGME
                     34: 
                     35: /* follow the cdrecord style by including the correct code */
                     36: #include "scsi-support.c"
                     37: 
                     38: 
                     39: 
                     40: /****************** generic SCSI stuff stolen from cdrecord and scsitransp.c ***********/
                     41: static int scsierr(SCSI *scgp)
                     42: {
                     43:     register struct scg_cmd *cp = scgp->scmd;
                     44: 
                     45:     if(cp->error != SCG_NO_ERROR ||
                     46:        cp->ux_errno != 0 || *(u_char *)&cp->scb != 0)
                     47:         return -1;
                     48:     return 0;
                     49: }
                     50: 
                     51: int scsicmd(SCSI *scgp)
                     52: {
                     53:     int f;
                     54:     int ret;
                     55:     register struct scg_cmd *scmd = scgp->scmd;
                     56: 
                     57:     f = scsi_fileno(scgp, scgp->scsibus, scgp->target, scgp->lun);
                     58:     scmd->kdebug = scgp->kdebug;
                     59:     if (scmd->timeout == 0 || scmd->timeout < scgp->deftimeout)
                     60:         scmd->timeout = scgp->deftimeout;
                     61:     if (scgp->disre_disable)
                     62:         scmd->flags &= ~SCG_DISRE_ENA;
                     63:     if (scgp->noparity)
                     64:         scmd->flags |= SCG_NOPARITY;
                     65: 
                     66:     gettimeofday(scgp->cmdstart, (struct timezone *)0);
                     67:     errno = 0;
                     68:     ret = scsi_send(scgp, f, scmd);
                     69:     scsitimes(scgp);
                     70:     if (ret < 0 && errno && !scgp->scmd->ux_errno) {
                     71:         scgp->scmd->ux_errno = errno;
                     72:     }        
                     73:     ret = scsierr(scgp);
                     74:     return (ret);
                     75: }
                     76: 
                     77: static int inquiry (SCSI *scgp, void *bp, int cnt)
                     78: {
                     79:     struct scg_cmd *scmd = scgp->scmd;
                     80: 
                     81:     fillbytes(bp, cnt, '\0');
                     82:     fillbytes((caddr_t)scmd, sizeof(*scmd), '\0');
                     83:     scmd->addr = bp;
                     84:     scmd->size = cnt;
                     85:     scmd->flags = SCG_RECV_DATA|SCG_DISRE_ENA;
                     86:     scmd->cdb_len = SC_G0_CDBLEN;
                     87:     scmd->sense_len = CCS_SENSE_LEN;
                     88:     scmd->target = scgp->target;
                     89:     scmd->cdb.g0_cdb.cmd = SC_INQUIRY;
                     90:     scmd->cdb.g0_cdb.lun = scgp->lun;
                     91:     scmd->cdb.g0_cdb.count = cnt;
                     92:        
                     93:     scgp->cmdname = "inquiry";
                     94: 
                     95:     if (scsicmd(scgp) < 0)
                     96:         return (-1);
                     97:     return (0);
                     98: }
                     99: 
                    100: static void print_product(struct scsi_inquiry *ip)
                    101: {
                    102:     write_log ("'%.8s' ", ip->info);
                    103:     write_log ("'%.16s' ", ip->ident);
                    104:     write_log ("'%.4s' ", ip->revision);
                    105:     if (ip->add_len < 31) {
                    106:         write_log ("NON CCS ");
                    107:     }
                    108: }
                    109: 
                    110: static SCSI *openscsi (char *dev, int bus, int target, int lun)
                    111: {
                    112:     SCSI *scgp;
                    113:     
                    114:     if(!(scgp = calloc(1, sizeof (*scgp))) ||
                    115:        !(scgp->scmd = calloc(1, sizeof (*scgp->scmd))) ||
                    116:        !(scgp->cmdstart = malloc(sizeof (*scgp->cmdstart))) ||
                    117:        !(scgp->cmdstop = malloc(sizeof (*scgp->cmdstop)))) {
                    118:         return NULL;
                    119:     }
                    120:     /* we don't really know the timeout - should better
                    121:        disable it, if possible */
                    122:     scgp->deftimeout = 80 * 60; /* 80min */
                    123:     scgp->scsibus = bus;
                    124:     scgp->target = target;
                    125:     scgp->lun = lun;
                    126:     return scsi_open (scgp, dev, bus, target, lun) >= 0 ? scgp : NULL;
                    127: }
                    128: 
                    129: #ifdef SCSI_CLOSE
                    130: /* if there is no scsi_close, then we have to keep everything */
                    131: static void closescsi (SCSI *scgp)
                    132: {
                    133:     scsi_close (scgp);
                    134:     free (scgp->scmd);
                    135:     free (scgp->cmdstart);
                    136:     free (scgp->cmdstop);
                    137: }
                    138: #endif
                    139: 
                    140: /********************* start of our own code ************************/
                    141: 
                    142: static int opencount = 0;
                    143: static SCSI *scgp; /* SCSI handle which is to be used by the main thread */
                    144: uae_sem_t scgp_sem;
                    145: 
                    146: 
                    147: /****************** unit handling *******************/
                    148: 
                    149: struct scsidevdata {
                    150:     int bus, target, lun; /* the real values */
                    151:     int aunit;            /* Amiga unit number, by default calculated like that: */
                    152: #define BTL2UNIT(bus, target, lun) \
                    153:       (2 * (bus) + (target) / 8) * 100 + \
                    154:       (lun) * 10 + \
                    155:       (target % 8)
                    156:     SCSI *scgp;
                    157:     long max_dma;
                    158: #ifdef UAE_SCSIDEV_THREADS
                    159:     /* Threading stuff */
                    160:     smp_comm_pipe requests;
                    161:     penguin_id tid;
                    162:     int thread_running;
                    163:     uae_sem_t sync_sem;
                    164: #endif
                    165: };
                    166: 
                    167: #define MAX_DRIVES 16
                    168: static struct scsidevdata drives[MAX_DRIVES];
                    169: static int num_drives;
                    170: static struct scsidevdata *get_scsidev_data (int unit)
                    171: {
                    172:     int i;
                    173: 
                    174:     for (i = 0; i < num_drives; i++) {
                    175:         if (unit == drives[i].aunit) {
                    176:             return &drives[i];
                    177:         }
                    178:     }
                    179:     return NULL;
                    180: }
                    181: 
                    182: static struct scsidevdata *add_scsidev_data (int bus, int target, int lun, int aunit)
                    183: {
                    184:     if (num_drives + 1 < MAX_DRIVES) {
                    185:         memset(&drives[num_drives], 0, sizeof(drives[num_drives]));
                    186:         drives[num_drives].bus = bus;
                    187:         drives[num_drives].target = target;
                    188:         drives[num_drives].lun = lun;
                    189:         drives[num_drives].aunit = aunit;
                    190: #if !defined(UAE_SCSIDEV_THREADS) || !defined(SCSI_IS_THREAD_SAFE)
                    191:         drives[num_drives].scgp = scgp;
                    192:         drives[num_drives].max_dma = scsi_maxdma (scgp);
                    193: #endif
                    194:         return &drives[num_drives++];
                    195:     }
                    196: 
                    197:     return NULL;
                    198: }
                    199: 
                    200: static void *scsidev_penguin(void *);
                    201: static int start_thread (struct scsidevdata *sdd)
                    202: {
                    203: #ifdef UAE_SCSIDEV_THREADS
                    204:     if (sdd->thread_running)
                    205:         return 1;
                    206:     init_comm_pipe (&sdd->requests, 10, 1);
                    207:     uae_sem_init (&sdd->sync_sem, 0, 0);
                    208:     start_penguin (scsidev_penguin, sdd, &sdd->tid);
                    209:     uae_sem_wait (&sdd->sync_sem);
                    210:     return sdd->thread_running;
                    211: #else
                    212:     return 1;
                    213: #endif
                    214: }
                    215:     
                    216: /************* Exec device functions ****************/
                    217: 
                    218: 
                    219: static uae_u32 scsidev_open (void)
                    220: {
                    221:     uaecptr tmp1 = m68k_areg(regs, 1); /* IOReq */
                    222:     uae_u32 unit = m68k_dreg (regs, 0);
                    223:     struct scsidevdata *sdd;
                    224: 
                    225: #ifdef DEBUGME
                    226:     printf("scsidev_open(0x%x, %d)\n", tmp1, unit);
                    227: #endif
                    228: 
                    229:     /* Check unit number */
                    230:     if ((sdd = get_scsidev_data (unit)) &&
                    231:         start_thread (sdd)) {
                    232:        opencount++;
                    233:        put_word (m68k_areg(regs, 6)+32, get_word (m68k_areg(regs, 6)+32) + 1);
                    234:        put_long (tmp1 + 24, unit); /* io_Unit */
                    235:        put_byte (tmp1 + 31, 0); /* io_Error */
                    236:        put_byte (tmp1 + 8, 7); /* ln_type = NT_REPLYMSG */
                    237:        return 0;
                    238:     }
                    239: 
                    240:     put_long (tmp1 + 20, (uae_u32)-1);
                    241:     put_byte (tmp1 + 31, (uae_u8)-1);
                    242:     return (uae_u32)-1;
                    243: }
                    244: 
                    245: static uae_u32 scsidev_close (void)
                    246: {
                    247: #ifdef DEBUGME
                    248:     printf("scsidev_close()\n");
                    249: #endif
                    250: 
                    251:     opencount--;
                    252:     put_word (m68k_areg(regs, 6) + 32, get_word (m68k_areg(regs, 6) + 32) - 1);
                    253: 
                    254:     return 0;
                    255: }
                    256: 
                    257: static uae_u32 scsidev_expunge (void)
                    258: {
                    259:  #ifdef DEBUGME
                    260:     printf("scsidev_expunge()\n");
                    261: #endif
                    262:     return 0; /* Simply ignore this one... */
                    263: }
                    264: 
                    265: #define MODE_SELECT_6  0x15
                    266: #define MODE_SENSE_6   0x1A
                    267: #ifndef MODE_SENSE_10
                    268: #define MODE_SELECT_10 0x55
                    269: #define MODE_SENSE_10  0x5A
                    270: #endif
                    271: 
                    272: static void scsidev_do_scsi (struct scsidevdata *sdd, uaecptr request)
                    273: {
                    274:     SCSI *scgp = sdd->scgp;
                    275:     struct scg_cmd *scmd = scgp->scmd;
                    276:     uaecptr acmd = get_long (request + 40);
                    277:     uaecptr scsi_data = get_long (acmd + 0);
                    278:     uae_u32 scsi_len = get_long (acmd + 4);
                    279:     uaecptr scsi_cmd = get_long (acmd + 12);
                    280:     uae_u16 scsi_cmd_len = get_word (acmd + 16);
                    281:     uae_u8 scsi_flags = get_byte (acmd + 20);
                    282:     uaecptr scsi_sense = get_long (acmd + 22);
                    283:     uae_u16 scsi_sense_len = get_word (acmd + 26);
                    284:     int sactual = 0;
                    285:     addrbank *bank_data = &get_mem_bank (scsi_data);
                    286:     addrbank *bank_cmd  = &get_mem_bank (scsi_cmd);
                    287: 
                    288:     /* do transfer directly to and from Amiga memory */
                    289:     if (!bank_data || !bank_data->check (scsi_data, scsi_len) ||
                    290:         !bank_cmd  || !bank_cmd->check (scsi_cmd, scsi_cmd_len)) {
                    291:         put_byte (request + 31, (uae_u8)-5); /* IOERR_BADADDRESS */
                    292:         return;
                    293:     }
                    294: 
                    295:     /* we are limited by the hosts DMA limits */
                    296:     if (scsi_len > sdd->max_dma) {
                    297:         put_byte (request + 31, (uae_u8)-4); /* IOERR_BADLENGTH */
                    298:         return;
                    299:     }
                    300: 
                    301: #ifndef SCSI_IS_THREAD_SAFE
                    302:     uae_sem_wait (&scgp_sem);
                    303: #endif
                    304: 
                    305:     scmd->addr = bank_data->xlateaddr (scsi_data);
                    306:     scmd->size = scsi_len;
                    307:     scmd->flags = ((scsi_flags & 1) ? SCG_RECV_DATA : 0) | SCG_DISRE_ENA;
                    308:     scmd->cdb_len = scsi_cmd_len;
                    309:     memcpy(&scmd->cdb, bank_cmd->xlateaddr (scsi_cmd), scsi_cmd_len);
                    310:     scmd->target = sdd->target;
                    311:     scmd->sense_len = (scsi_flags & 4) ? 4 : /* SCSIF_OLDAUTOSENSE */
                    312:         (scsi_flags & 2) ? scsi_sense_len : /* SCSIF_AUTOSENSE */
                    313:         -1;
                    314:     scmd->sense_count = 0;
                    315:     *(uae_u8 *)&scmd->scb = 0;
                    316: 
                    317:     scgp->scsibus = sdd->bus;
                    318:     scgp->target  = sdd->target;
                    319:     scgp->lun     = sdd->lun;
                    320:     scsicmd (scgp);
                    321: 
                    322:     /* replace MODE_SELECT/SENSE_6 if they are not supported */
                    323:     if (scmd->scb.chk &&
                    324:         ((struct scsi_ext_sense *)&scmd->sense)->key == 0x5 &&
                    325:         ((struct scsi_ext_sense *)&scmd->sense)->sense_code == 0x20 && /* INVALID_COMMAND */
                    326:         (scmd->cdb.g0_cdb.cmd == MODE_SELECT_6 ||
                    327:          scmd->cdb.g0_cdb.cmd == MODE_SENSE_6)) {
                    328:         uae_u8 buffer[256 + 2], *data = scmd->addr, *tmp;
                    329:         int len = 0, page_len, i;
                    330:         int do_it = 1;
                    331:         uae_u8 sp = scmd->cdb.g0_cdb.high_addr & 1;
                    332:         uae_u8 alloc_len = scmd->cdb.g0_cdb.count;
                    333:         uae_u8 pcf_page_code = scmd->cdb.g0_cdb.mid_addr;
                    334:         uae_u8 cmd = scmd->cdb.g0_cdb.cmd;
                    335: 
                    336:         memset (&scmd->cdb.g1_cdb, 0, sizeof(scmd->cdb.g1_cdb));
                    337:         if (cmd == MODE_SELECT_6) {
                    338:             /* expand parameter list */
                    339:             tmp = data;
                    340:             buffer[len++] = *tmp++;      /* first byte, should be 0 */
                    341:             buffer[len++] = 0;           /* reserved */
                    342:             buffer[len++] = *tmp++;      /* medium type */
                    343:             buffer[len++] = 0; *tmp++;   /* ignore host application code */
                    344:             for (i = 0; i < 4; i++) {
                    345:                 buffer[len++] = 0;
                    346:             }
                    347:             if (*tmp) {
                    348:                 /* skip block descriptor */
                    349:                 tmp += 8;
                    350:             }
                    351:             tmp++;
                    352:             page_len = scsi_len - (tmp - data);
                    353:             if (page_len > 0) {
                    354:                 memcpy (&buffer[len], tmp, page_len);
                    355:                 len += page_len;
                    356: 
                    357:                 scmd->cdb.g1_cdb.cmd = MODE_SELECT_10;
                    358:                 scmd->cdb.g1_cdb.lun = sdd->lun;
                    359:                 scmd->cdb.g1_cdb.res = 1 << 3; /* PF bit */
                    360:                 scmd->cdb.g1_cdb.reladr = sp;
                    361:                 scmd->cdb.g1_cdb.count[0] = len >> 8;
                    362:                 scmd->cdb.g1_cdb.count[1] = len;
                    363:             } else {
                    364:                 do_it = 0;
                    365:                 scmd->error = 0;
                    366:                 *(uae_u8 *)&scmd->scb = 0;
                    367:                 scmd->ux_errno = 0;
                    368:             }
                    369:         } else {
                    370:             /* MODE_SENSE_6 */
                    371:             len = alloc_len + 2;
                    372:             scmd->cdb.g1_cdb.cmd = MODE_SENSE_10;
                    373:             scmd->cdb.g1_cdb.lun = sdd->lun;
                    374:             scmd->cdb.g1_cdb.addr[0] = pcf_page_code;
                    375:             scmd->cdb.g1_cdb.count[0] = len >> 8;
                    376:             scmd->cdb.g1_cdb.count[1] = len;
                    377:         }
                    378:         if (do_it) {
                    379:             scmd->cdb_len = 10;
                    380:             scmd->addr = buffer;
                    381:             scmd->size = len;
                    382:             scmd->sense_count = 0;
                    383:             *(uae_u8 *)&scmd->scb = 0;
                    384:             
                    385:             scsicmd (scgp);
                    386: 
                    387:             if (cmd == MODE_SENSE_6 &&
                    388:                 !scmd->error &&
                    389:                 !scmd->ux_errno &&
                    390:                 !*(uae_u8 *)&scmd->scb) {
                    391:                 int req_len = len;
                    392:                 
                    393:                 /* compress result */
                    394:                 tmp = buffer;
                    395:                 len = 0;
                    396:                 tmp++;                 /* skip first byte of length - should better be zero */
                    397:                 data[len++] = *tmp++;  /* mode data length */
                    398:                 data[len++] = *tmp++;  /* medium type */
                    399:                 data[len++] = 0;       /* host application type */
                    400:                 data[len++] = 0;       /* block descr length */
                    401:                 tmp += 4;
                    402:                 if (*tmp) {
                    403:                     /* skip block descr - should not happen */
                    404:                     tmp += *tmp;
                    405:                 }
                    406:                 tmp++;
                    407:                 memcpy (&data[len], tmp, req_len - (tmp - buffer));
                    408:             }
                    409:         }
                    410:     }
                    411:     
                    412:     put_word (acmd + 18, scmd->error == SCG_FATAL ? 0 : scsi_cmd_len); /* fake scsi_CmdActual */
                    413:     put_byte (acmd + 21, *(uae_u8 *)&scmd->scb); /* scsi_Status */
                    414:     if (*(uae_u8 *)&scmd->scb) {
                    415:         put_byte (request + 31, 45); /* HFERR_BadStatus */
                    416: 
                    417:         /* copy sense? */
                    418:         for (sactual = 0;
                    419:              scsi_sense && sactual < scsi_sense_len && sactual < scmd->sense_count;
                    420:              sactual++) {
                    421:             put_byte (scsi_sense + sactual, scmd->u_sense.cmd_sense[sactual]);
                    422:         }
                    423:         put_long (acmd + 8, 0); /* scsi_Actual */
                    424:     } else {
                    425:         int i;
                    426:         
                    427:         for (i = 0; i < scsi_sense_len; i++) {
                    428:             put_byte (scsi_sense + i, 0);
                    429:         }
                    430:         sactual = 0;
                    431: 
                    432:         if (scmd->error != SCG_NO_ERROR ||
                    433:             scmd->ux_errno != 0) {
                    434:             put_byte (request + 31, 20); /* io_Error, but not specified */
                    435:             put_long (acmd + 8, 0); /* scsi_Actual */
                    436:         } else {
                    437:             put_byte (request + 31, 0);
                    438:             put_long (acmd + 8, scsi_len - scmd->resid); /* scsi_Actual */
                    439:         }
                    440:     }
                    441:     put_word (acmd + 28, sactual);
                    442: 
                    443: #ifndef SCSI_IS_THREAD_SAFE
                    444:     uae_sem_post (&scgp_sem);
                    445: #endif
                    446: }
                    447: 
                    448: static void scsidev_do_io (struct scsidevdata *sdd, uaecptr request)
                    449: {
                    450:     uae_u32 tmp2, dataptr, offset;
                    451:     
                    452:     tmp2 = get_word (request+28); /* io_Command */
                    453:     switch (tmp2) {
                    454:      case 28:
                    455:         /* HD_SCSICMD */
                    456:         scsidev_do_scsi (sdd, request);
                    457:         break;
                    458:      default:
                    459:        /* Command not understood. */
                    460:        put_byte (request+31, (uae_u8)-3); /* io_Error */
                    461:        break;
                    462:     }
                    463: #ifdef DEBUGME
                    464:     printf ("scsidev: did io: sdd     = 0x%x\n", sdd);
                    465:     printf ("scsidev: did io: request = %08lx\n", (unsigned long)request);
                    466:     printf ("scsidev: did io: error   = %d\n", (int)get_word(request+31));
                    467: #endif
                    468: }
                    469: 
                    470: 
                    471: static uae_u32 scsidev_beginio (void)
                    472: {
                    473:     uae_u32 request = m68k_areg(regs, 1);
                    474:     int unit = get_long (request + 24);
                    475:     struct scsidevdata *sdd = get_scsidev_data (unit);
                    476: 
                    477: #ifdef DEBUGME
                    478:     printf ("scsidev_begin_io: sdd     = 0x%x\n", sdd);
                    479:     printf ("scsidev_begin_io: request = %08lx\n", (unsigned long)request);
                    480:     printf ("scsidev_begin_io: cmd     = %d\n", (int)get_word(request+28));
                    481: #endif
                    482: 
                    483:     put_byte (request+8, NT_MESSAGE);
                    484:     put_byte (request+31, 0); /* no error yet */
                    485: 
                    486: #ifdef UAE_SCSIDEV_THREADS
                    487:     {
                    488:         uae_pt data;
                    489: 
                    490:         /* clear IOF_QUICK */
                    491:         put_byte (request+30, get_byte (request+30) & ~1);
                    492:         /* forward to unit thread */
                    493:         write_comm_pipe_u32 (&sdd->requests, request, 1);
                    494:         return 0;
                    495:     }
                    496: #else
                    497:     put_byte (request+30, get_byte (request+30) & ~1);
                    498:     scsidev_do_io (sdd, request);
                    499:     return get_byte (request+31); /* do we really have to return io_Error? */
                    500: #endif
                    501: }
                    502: 
                    503: #ifdef UAE_SCSIDEV_THREADS
                    504: static void *scsidev_penguin (void *sddv)
                    505: {
                    506:     struct scsidevdata *sdd = sddv;
                    507: 
                    508: #ifdef DEBUGME
                    509:     printf ("scsidev_penguin: sdd  = 0x%x ready\n", sdd);
                    510: #endif    
                    511:     /* init SCSI */
                    512:     if (!(sdd->scgp = openscsi (NULL, sdd->bus, sdd->target, sdd->lun)) ||
                    513:         (sdd->max_dma = scsi_maxdma (sdd->scgp)) <= 0) {
                    514:         sdd->thread_running = 0;
                    515:         uae_sem_post (&sdd->sync_sem);
                    516:         return 0;
                    517:     }
                    518:     sdd->thread_running = 1;
                    519:     uae_sem_post (&sdd->sync_sem);
                    520: 
                    521:     for (;;) {
                    522:        uaecptr request;
                    523: 
                    524:        request = (uaecptr)read_comm_pipe_u32_blocking (&sdd->requests);
                    525: #ifdef DEBUGME
                    526:         printf ("scsidev_penguin: sdd  = 0x%x\n", sdd);
                    527:         printf ("scsidev_penguin: req  = %08lx\n", (unsigned long)request);
                    528:         printf ("scsidev_penguin: cmd  = %d\n", (int)get_word(request+28));
                    529: #endif
                    530:         if (!request) {
                    531:             printf ("scsidev_penguin: going down with 0x%x\n", sdd->sync_sem);
                    532:            /* Death message received. */
                    533:             sdd->thread_running = 0;
                    534:            uae_sem_post (&sdd->sync_sem);
                    535:            /* Die.  */
                    536:            return 0;
                    537:        }
                    538: 
                    539:         scsidev_do_io (sdd, request);
                    540:         ReplyMsg (request);
                    541:     }
                    542:     return 0;
                    543: }
                    544: #endif
                    545: 
                    546: 
                    547: static uae_u32 scsidev_abortio (void)
                    548: {
                    549:     return (uae_u32)-3;
                    550: }
                    551: 
                    552: static uae_u32 scsidev_init (void)
                    553: {
                    554: #ifdef DEBUGME
                    555:     printf("scsidev_init()\n");
                    556: #endif
                    557:     
                    558:     if (scgp) {
                    559:         /* we still have everything in place */
                    560:         return m68k_dreg (regs, 0); /* device base */
                    561:     }
                    562:     
                    563:     /* init global SCSI */
                    564:     if (!(scgp = openscsi (NULL, -1, -1, -1))) {
                    565:         return 0;
                    566:     }
                    567: 
                    568:     uae_sem_init (&scgp_sem, 0, 1);
                    569: 
                    570:     /* add all units we find */
                    571:     for (scgp->scsibus=0; scgp->scsibus < 8; scgp->scsibus++) {
                    572:         if (!scsi_havebus(scgp, scgp->scsibus))
                    573:             continue;
                    574:         printf("scsibus%d:\n", scgp->scsibus);
                    575:         for (scgp->target=0; scgp->target < 16; scgp->target++) {
                    576:             struct scsi_inquiry inq;
                    577:             scgp->lun = 0;
                    578:             if (inquiry (scgp, &inq, sizeof(inq))) {
                    579:                 continue;
                    580:             }
                    581:             for (scgp->lun=0; scgp->lun < 8; scgp->lun++) {
                    582:                 if (!inquiry (scgp, &inq, sizeof(inq))) {
                    583:                     int aunit = BTL2UNIT(scgp->scsibus, scgp->target, scgp->lun);
                    584:                     
                    585:                     write_log ("   %2.01d,%d (= %3.d): ", scgp->target, scgp->lun, aunit);
                    586:                     print_product (&inq);
                    587:                     write_log ("\n");
                    588:                     add_scsidev_data (scgp->scsibus, scgp->target, scgp->lun, aunit);
                    589:                }
                    590:             }
                    591:         }
                    592:     }
                    593:     return m68k_dreg (regs, 0); /* device base */
                    594: }
                    595: 
                    596: static uaecptr ROM_scsidev_resname = 0,
                    597:     ROM_scsidev_resid = 0,
                    598:     ROM_scsidev_init = 0;
                    599: 
                    600: uaecptr scsidev_startup (uaecptr resaddr)
                    601: {
                    602: #ifdef DEBUGME
                    603:     printf("scsidev_startup(0x%x)\n", resaddr);
                    604: #endif
                    605:     /* Build a struct Resident. This will set up and initialize
                    606:      * the uaescsi.device */
                    607:     put_word(resaddr + 0x0, 0x4AFC);
                    608:     put_long(resaddr + 0x2, resaddr);
                    609:     put_long(resaddr + 0x6, resaddr + 0x1A); /* Continue scan here */
                    610:     put_word(resaddr + 0xA, 0x8101); /* RTF_AUTOINIT|RTF_COLDSTART; Version 1 */
                    611:     put_word(resaddr + 0xC, 0x0305); /* NT_DEVICE; pri 05 */
                    612:     put_long(resaddr + 0xE, ROM_scsidev_resname);
                    613:     put_long(resaddr + 0x12, ROM_scsidev_resid);
                    614:     put_long(resaddr + 0x16, ROM_scsidev_init); /* calls scsidev_init */
                    615:     resaddr += 0x1A;
                    616: 
                    617:     return resaddr;
                    618: }
                    619: 
                    620: void scsidev_install (void)
                    621: {
                    622:     uae_u32 functable, datatable;
                    623:     uae_u32 initcode, openfunc, closefunc, expungefunc;
                    624:     uae_u32 beginiofunc, abortiofunc;
                    625: 
                    626: #ifdef DEBUGME
                    627:     printf("scsidev_install(): 0x%x\n", here ());
                    628: #endif
                    629: 
                    630:     ROM_scsidev_resname = ds ("uaescsi.device");
                    631:     ROM_scsidev_resid = ds ("UAE scsi.device 0.1");
                    632: 
                    633:     /* initcode */
                    634:     initcode = here ();
                    635:     calltrap (deftrap (scsidev_init)); dw (RTS);
                    636:     
                    637:     /* Open */
                    638:     openfunc = here ();
                    639:     calltrap (deftrap (scsidev_open)); dw (RTS);
                    640: 
                    641:     /* Close */
                    642:     closefunc = here ();
                    643:     calltrap (deftrap (scsidev_close)); dw (RTS);
                    644: 
                    645:     /* Expunge */
                    646:     expungefunc = here ();
                    647:     calltrap (deftrap (scsidev_expunge)); dw (RTS);
                    648: 
                    649:     /* BeginIO */
                    650:     beginiofunc = here ();
                    651:     calltrap (deftrap (scsidev_beginio));
                    652: #ifndef UAE_SCSIDEV_THREADS
                    653:     /* don't reply when using threads - native2amiga's Reply() does that */
                    654:     dw (0x48E7); dw (0x8002); /* movem.l d0/a6,-(a7) */
                    655:     dw (0x0829); dw (0); dw (30); /* btst #0,30(a1) */
                    656:     dw (0x6608); /* bne.b +8 */
                    657:     dw (0x2C78); dw (0x0004); /* move.l 4,a6 */
                    658:     dw (0x4EAE); dw (-378); /* jsr ReplyMsg(a6) */
                    659:     dw (0x4CDF); dw (0x4001); /* movem.l (a7)+,d0/a6 */
                    660: #endif
                    661:     dw (RTS);
                    662: 
                    663:     /* AbortIO */
                    664:     abortiofunc = here ();
                    665:     calltrap (deftrap (scsidev_abortio)); dw (RTS);
                    666: 
                    667:     /* FuncTable */
                    668:     functable = here ();
                    669:     dl (openfunc); /* Open */
                    670:     dl (closefunc); /* Close */
                    671:     dl (expungefunc); /* Expunge */
                    672:     dl (EXPANSION_nullfunc); /* Null */
                    673:     dl (beginiofunc); /* BeginIO */
                    674:     dl (abortiofunc); /* AbortIO */
                    675:     dl (0xFFFFFFFFul); /* end of table */
                    676: 
                    677:     /* DataTable */
                    678:     datatable = here ();
                    679:     dw (0xE000); /* INITBYTE */
                    680:     dw (0x0008); /* LN_TYPE */
                    681:     dw (0x0300); /* NT_DEVICE */
                    682:     dw (0xC000); /* INITLONG */
                    683:     dw (0x000A); /* LN_NAME */
                    684:     dl (ROM_scsidev_resname);
                    685:     dw (0xE000); /* INITBYTE */
                    686:     dw (0x000E); /* LIB_FLAGS */
                    687:     dw (0x0600); /* LIBF_SUMUSED | LIBF_CHANGED */
                    688:     dw (0xD000); /* INITWORD */
                    689:     dw (0x0014); /* LIB_VERSION */
                    690:     dw (0x0004); /* 0.4 */
                    691:     dw (0xD000); /* INITWORD */
                    692:     dw (0x0016); /* LIB_REVISION */
                    693:     dw (0x0000); /* end of table already ??? */
                    694:     dw (0xC000); /* INITLONG */
                    695:     dw (0x0018); /* LIB_IDSTRING */
                    696:     dl (ROM_scsidev_resid);
                    697:     dw (0x0000); /* end of table */
                    698: 
                    699:     ROM_scsidev_init = here ();
                    700:     dl (0x00000100); /* size of device base */
                    701:     dl (functable);
                    702:     dl (datatable);
                    703:     dl (initcode);
                    704: }
                    705: 
                    706: void scsidev_reset (void)
                    707: {
                    708: #ifdef DEBUGME
                    709:     printf("scsidev_reset()\n");
                    710: #endif
                    711: 
                    712: #ifdef SCSI_CLOSE
                    713: #ifdef UAE_SCSIDEV_THREADS
                    714:     {
                    715:         int i;
                    716: 
                    717:         for (i = 0; i < num_drives; i++) {
                    718:             write_comm_pipe (&drives[i].requests, 0, 1);
                    719:             uae_sem_wait (&drives[i].sync);
                    720:         }
                    721:         num_drives = 0;
                    722:     }
                    723: #endif
                    724:     
                    725:     if (scgp) {
                    726:         closescsi (scgp);
                    727:         scgp = NULL;
                    728:     }
                    729: #endif
                    730:     
                    731:     opencount = 0;
                    732: }
                    733: 
                    734: void scsidev_start_threads (void)
                    735: {
                    736: #ifdef DEBUGME
                    737:     printf("scsidev_start_threads()\n");
                    738: #endif
                    739: }
                    740: 

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.