|
|
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);
1.1.1.2 ! root 540: uae_ReplyMsg (request);
1.1 root 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.