Annotation of uae/src/scsidev.c, revision 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.