|
|
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:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.