|
|
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:
1.1.1.3 ! root 27: /* the new libscg should always have a scsi_close */
! 28: #ifndef SCSI_CLOSE
! 29: #define SCSI_CLOSE
1.1 root 30: #endif
31:
1.1.1.3 ! root 32: typedef int BOOL;
1.1 root 33:
1.1.1.3 ! root 34: #include "scg/scgcmd.h"
! 35: #include "scg/scsitransp.h"
! 36: #include "scg/scsireg.h"
1.1 root 37:
1.1.1.3 ! root 38: /* our configure does not have a seperate UAE_SCSIDEV_THREADS */
! 39: #if defined(UAE_FILESYS_THREADS) && !defined(SCSI_IS_NOT_THREAD_SAFE)
! 40: #define UAE_SCSIDEV_THREADS
! 41: #endif
1.1 root 42:
1.1.1.3 ! root 43: #undef DEBUGME
1.1 root 44:
45: /****************** generic SCSI stuff stolen from cdrecord and scsitransp.c ***********/
46: static int scsierr(SCSI *scgp)
47: {
48: register struct scg_cmd *cp = scgp->scmd;
49:
50: if(cp->error != SCG_NO_ERROR ||
51: cp->ux_errno != 0 || *(u_char *)&cp->scb != 0)
52: return -1;
53: return 0;
54: }
55:
56: static int inquiry (SCSI *scgp, void *bp, int cnt)
57: {
58: struct scg_cmd *scmd = scgp->scmd;
59:
1.1.1.3 ! root 60: memset(bp, cnt, '\0');
! 61: memset((caddr_t)scmd, sizeof(*scmd), '\0');
1.1 root 62: scmd->addr = bp;
63: scmd->size = cnt;
64: scmd->flags = SCG_RECV_DATA|SCG_DISRE_ENA;
65: scmd->cdb_len = SC_G0_CDBLEN;
66: scmd->sense_len = CCS_SENSE_LEN;
67: scmd->target = scgp->target;
68: scmd->cdb.g0_cdb.cmd = SC_INQUIRY;
69: scmd->cdb.g0_cdb.lun = scgp->lun;
70: scmd->cdb.g0_cdb.count = cnt;
71:
72: scgp->cmdname = "inquiry";
73:
74: if (scsicmd(scgp) < 0)
75: return (-1);
76: return (0);
77: }
78:
79: static void print_product(struct scsi_inquiry *ip)
80: {
81: write_log ("'%.8s' ", ip->info);
82: write_log ("'%.16s' ", ip->ident);
83: write_log ("'%.4s' ", ip->revision);
84: if (ip->add_len < 31) {
85: write_log ("NON CCS ");
86: }
87: }
88:
1.1.1.3 ! root 89: /* get integer value from env or return default value, if unset */
! 90: static int getenvint (const char *varname, int def)
1.1 root 91: {
1.1.1.3 ! root 92: const char *val = getenv (varname);
! 93: return val ? atoi (val) : def;
! 94: }
! 95:
! 96: /* wrapper for the underlying combination of scsi_smalloc()/scsi_open() */
! 97: static SCSI *openscsi (int scsibus, int target, int lun)
! 98: {
! 99: SCSI *scgp = scsi_smalloc ();
! 100: if (!scgp) {
1.1 root 101: return NULL;
102: }
1.1.1.3 ! root 103:
! 104: scgp->debug = getenvint ("UAE_SCSI_DEBUG", 0);
! 105: scgp->kdebug = getenvint ("UAE_SCSI_KDEBUG", 0);
! 106: scgp->silent = getenvint ("UAE_SCSI_SILENT", 1);
! 107: scgp->scsibus = scsibus;
1.1 root 108: scgp->target = target;
109: scgp->lun = lun;
1.1.1.3 ! root 110:
! 111: if (!scsi_open(scgp, NULL, scsibus, target, lun)) {
! 112: scsi_sfree (scgp);
! 113: return NULL;
! 114: } else {
! 115: return scgp;
! 116: }
1.1 root 117: }
118:
119: static void closescsi (SCSI *scgp)
120: {
121: scsi_close (scgp);
1.1.1.3 ! root 122: scsi_sfree (scgp);
1.1 root 123: }
124:
125: /********************* start of our own code ************************/
126:
127: static int opencount = 0;
128: static SCSI *scgp; /* SCSI handle which is to be used by the main thread */
129: uae_sem_t scgp_sem;
130:
131:
132: /****************** unit handling *******************/
133:
134: struct scsidevdata {
135: int bus, target, lun; /* the real values */
136: int aunit; /* Amiga unit number, by default calculated like that: */
137: #define BTL2UNIT(bus, target, lun) \
138: (2 * (bus) + (target) / 8) * 100 + \
139: (lun) * 10 + \
140: (target % 8)
141: SCSI *scgp;
142: long max_dma;
1.1.1.3 ! root 143: int isatapi;
1.1 root 144: #ifdef UAE_SCSIDEV_THREADS
145: /* Threading stuff */
146: smp_comm_pipe requests;
147: penguin_id tid;
148: int thread_running;
149: uae_sem_t sync_sem;
150: #endif
151: };
152:
153: #define MAX_DRIVES 16
154: static struct scsidevdata drives[MAX_DRIVES];
155: static int num_drives;
156: static struct scsidevdata *get_scsidev_data (int unit)
157: {
158: int i;
159:
160: for (i = 0; i < num_drives; i++) {
161: if (unit == drives[i].aunit) {
162: return &drives[i];
163: }
164: }
165: return NULL;
166: }
167:
168: static struct scsidevdata *add_scsidev_data (int bus, int target, int lun, int aunit)
169: {
170: if (num_drives + 1 < MAX_DRIVES) {
171: memset(&drives[num_drives], 0, sizeof(drives[num_drives]));
172: drives[num_drives].bus = bus;
173: drives[num_drives].target = target;
174: drives[num_drives].lun = lun;
175: drives[num_drives].aunit = aunit;
1.1.1.3 ! root 176: #if !defined(UAE_SCSIDEV_THREADS)
1.1 root 177: drives[num_drives].scgp = scgp;
1.1.1.3 ! root 178: drives[num_drives].max_dma = scsi_bufsize (scgp, 512 * 1024);
1.1 root 179: #endif
1.1.1.3 ! root 180: /* check if this drive is an ATAPI drive */
! 181: scgp->scsibus = bus;
! 182: scgp->target = target;
! 183: scgp->lun = lun;
! 184: drives[num_drives].isatapi = scsi_isatapi (scgp);
1.1 root 185: return &drives[num_drives++];
186: }
187:
188: return NULL;
189: }
190:
191: static void *scsidev_penguin(void *);
192: static int start_thread (struct scsidevdata *sdd)
193: {
194: #ifdef UAE_SCSIDEV_THREADS
195: if (sdd->thread_running)
196: return 1;
197: init_comm_pipe (&sdd->requests, 10, 1);
198: uae_sem_init (&sdd->sync_sem, 0, 0);
199: start_penguin (scsidev_penguin, sdd, &sdd->tid);
200: uae_sem_wait (&sdd->sync_sem);
201: return sdd->thread_running;
202: #else
203: return 1;
204: #endif
205: }
206:
207: /************* Exec device functions ****************/
208:
209:
210: static uae_u32 scsidev_open (void)
211: {
212: uaecptr tmp1 = m68k_areg(regs, 1); /* IOReq */
213: uae_u32 unit = m68k_dreg (regs, 0);
214: struct scsidevdata *sdd;
215:
216: #ifdef DEBUGME
217: printf("scsidev_open(0x%x, %d)\n", tmp1, unit);
218: #endif
219:
220: /* Check unit number */
221: if ((sdd = get_scsidev_data (unit)) &&
222: start_thread (sdd)) {
223: opencount++;
224: put_word (m68k_areg(regs, 6)+32, get_word (m68k_areg(regs, 6)+32) + 1);
225: put_long (tmp1 + 24, unit); /* io_Unit */
226: put_byte (tmp1 + 31, 0); /* io_Error */
227: put_byte (tmp1 + 8, 7); /* ln_type = NT_REPLYMSG */
228: return 0;
229: }
230:
231: put_long (tmp1 + 20, (uae_u32)-1);
232: put_byte (tmp1 + 31, (uae_u8)-1);
233: return (uae_u32)-1;
234: }
235:
236: static uae_u32 scsidev_close (void)
237: {
238: #ifdef DEBUGME
239: printf("scsidev_close()\n");
240: #endif
241:
242: opencount--;
243: put_word (m68k_areg(regs, 6) + 32, get_word (m68k_areg(regs, 6) + 32) - 1);
244:
245: return 0;
246: }
247:
248: static uae_u32 scsidev_expunge (void)
249: {
250: #ifdef DEBUGME
251: printf("scsidev_expunge()\n");
252: #endif
253: return 0; /* Simply ignore this one... */
254: }
255:
256: #define MODE_SELECT_6 0x15
257: #define MODE_SENSE_6 0x1A
258: #ifndef MODE_SENSE_10
259: #define MODE_SELECT_10 0x55
260: #define MODE_SENSE_10 0x5A
261: #endif
262:
263: static void scsidev_do_scsi (struct scsidevdata *sdd, uaecptr request)
264: {
265: SCSI *scgp = sdd->scgp;
266: struct scg_cmd *scmd = scgp->scmd;
267: uaecptr acmd = get_long (request + 40);
268: uaecptr scsi_data = get_long (acmd + 0);
269: uae_u32 scsi_len = get_long (acmd + 4);
270: uaecptr scsi_cmd = get_long (acmd + 12);
271: uae_u16 scsi_cmd_len = get_word (acmd + 16);
272: uae_u8 scsi_flags = get_byte (acmd + 20);
273: uaecptr scsi_sense = get_long (acmd + 22);
274: uae_u16 scsi_sense_len = get_word (acmd + 26);
275: int sactual = 0;
276: addrbank *bank_data = &get_mem_bank (scsi_data);
277: addrbank *bank_cmd = &get_mem_bank (scsi_cmd);
278:
279: /* do transfer directly to and from Amiga memory */
280: if (!bank_data || !bank_data->check (scsi_data, scsi_len) ||
281: !bank_cmd || !bank_cmd->check (scsi_cmd, scsi_cmd_len)) {
282: put_byte (request + 31, (uae_u8)-5); /* IOERR_BADADDRESS */
283: return;
284: }
285:
1.1.1.3 ! root 286: #ifdef SCSI_IS_NOT_THREAD_SAFE
1.1 root 287: uae_sem_wait (&scgp_sem);
288: #endif
289:
290: scmd->addr = bank_data->xlateaddr (scsi_data);
291: scmd->size = scsi_len;
292: scmd->flags = ((scsi_flags & 1) ? SCG_RECV_DATA : 0) | SCG_DISRE_ENA;
293: scmd->cdb_len = scsi_cmd_len;
294: memcpy(&scmd->cdb, bank_cmd->xlateaddr (scsi_cmd), scsi_cmd_len);
295: scmd->target = sdd->target;
296: scmd->sense_len = (scsi_flags & 4) ? 4 : /* SCSIF_OLDAUTOSENSE */
297: (scsi_flags & 2) ? scsi_sense_len : /* SCSIF_AUTOSENSE */
298: -1;
299: scmd->sense_count = 0;
300: *(uae_u8 *)&scmd->scb = 0;
301:
1.1.1.3 ! root 302: if (scsi_len > (unsigned int)sdd->max_dma) {
! 303: scgp->debug = 1;
! 304: } else {
! 305: scgp->debug = 0;
! 306: }
! 307:
1.1 root 308: scgp->scsibus = sdd->bus;
309: scgp->target = sdd->target;
310: scgp->lun = sdd->lun;
311:
1.1.1.3 ! root 312: /* replace MODE_SELECT/SENSE_6 if we access a ATAPI drive,
! 313: otherwise send it now */
! 314: if (sdd->isatapi &&
1.1 root 315: (scmd->cdb.g0_cdb.cmd == MODE_SELECT_6 ||
316: scmd->cdb.g0_cdb.cmd == MODE_SENSE_6)) {
317: uae_u8 buffer[256 + 2], *data = scmd->addr, *tmp;
318: int len = 0, page_len, i;
319: int do_it = 1;
320: uae_u8 sp = scmd->cdb.g0_cdb.high_addr & 1;
321: uae_u8 alloc_len = scmd->cdb.g0_cdb.count;
322: uae_u8 pcf_page_code = scmd->cdb.g0_cdb.mid_addr;
323: uae_u8 cmd = scmd->cdb.g0_cdb.cmd;
324:
325: memset (&scmd->cdb.g1_cdb, 0, sizeof(scmd->cdb.g1_cdb));
326: if (cmd == MODE_SELECT_6) {
327: /* expand parameter list */
328: tmp = data;
329: buffer[len++] = *tmp++; /* first byte, should be 0 */
330: buffer[len++] = 0; /* reserved */
331: buffer[len++] = *tmp++; /* medium type */
332: buffer[len++] = 0; *tmp++; /* ignore host application code */
333: for (i = 0; i < 4; i++) {
334: buffer[len++] = 0;
335: }
336: if (*tmp) {
337: /* skip block descriptor */
338: tmp += 8;
339: }
340: tmp++;
341: page_len = scsi_len - (tmp - data);
342: if (page_len > 0) {
343: memcpy (&buffer[len], tmp, page_len);
344: len += page_len;
345:
346: scmd->cdb.g1_cdb.cmd = MODE_SELECT_10;
347: scmd->cdb.g1_cdb.lun = sdd->lun;
348: scmd->cdb.g1_cdb.res = 1 << 3; /* PF bit */
349: scmd->cdb.g1_cdb.reladr = sp;
350: scmd->cdb.g1_cdb.count[0] = len >> 8;
351: scmd->cdb.g1_cdb.count[1] = len;
352: } else {
353: do_it = 0;
354: scmd->error = 0;
355: *(uae_u8 *)&scmd->scb = 0;
356: scmd->ux_errno = 0;
357: }
358: } else {
359: /* MODE_SENSE_6 */
360: len = alloc_len + 2;
361: scmd->cdb.g1_cdb.cmd = MODE_SENSE_10;
362: scmd->cdb.g1_cdb.lun = sdd->lun;
363: scmd->cdb.g1_cdb.addr[0] = pcf_page_code;
364: scmd->cdb.g1_cdb.count[0] = len >> 8;
365: scmd->cdb.g1_cdb.count[1] = len;
366: }
367: if (do_it) {
368: scmd->cdb_len = 10;
369: scmd->addr = buffer;
370: scmd->size = len;
371: scmd->sense_count = 0;
372: *(uae_u8 *)&scmd->scb = 0;
373:
374: scsicmd (scgp);
375:
376: if (cmd == MODE_SENSE_6 &&
377: !scmd->error &&
378: !scmd->ux_errno &&
379: !*(uae_u8 *)&scmd->scb) {
380: int req_len = len;
381:
382: /* compress result */
383: tmp = buffer;
384: len = 0;
385: tmp++; /* skip first byte of length - should better be zero */
386: data[len++] = *tmp++; /* mode data length */
387: data[len++] = *tmp++; /* medium type */
388: data[len++] = 0; /* host application type */
389: data[len++] = 0; /* block descr length */
390: tmp += 4;
391: if (*tmp) {
392: /* skip block descr - should not happen */
393: tmp += *tmp;
394: }
395: tmp++;
396: memcpy (&data[len], tmp, req_len - (tmp - buffer));
397: }
398: }
1.1.1.3 ! root 399: } else {
! 400: scsicmd (scgp);
1.1 root 401: }
402:
403: put_word (acmd + 18, scmd->error == SCG_FATAL ? 0 : scsi_cmd_len); /* fake scsi_CmdActual */
404: put_byte (acmd + 21, *(uae_u8 *)&scmd->scb); /* scsi_Status */
405: if (*(uae_u8 *)&scmd->scb) {
406: put_byte (request + 31, 45); /* HFERR_BadStatus */
407:
408: /* copy sense? */
409: for (sactual = 0;
410: scsi_sense && sactual < scsi_sense_len && sactual < scmd->sense_count;
411: sactual++) {
412: put_byte (scsi_sense + sactual, scmd->u_sense.cmd_sense[sactual]);
413: }
414: put_long (acmd + 8, 0); /* scsi_Actual */
415: } else {
416: int i;
417:
418: for (i = 0; i < scsi_sense_len; i++) {
419: put_byte (scsi_sense + i, 0);
420: }
421: sactual = 0;
422:
423: if (scmd->error != SCG_NO_ERROR ||
424: scmd->ux_errno != 0) {
1.1.1.3 ! root 425: /* we might have been limited by the hosts DMA limits,
! 426: which is usually indicated by ENOMEM */
! 427: if (scsi_len > (unsigned int)sdd->max_dma &&
! 428: scmd->ux_errno == ENOMEM) {
! 429: put_byte (request + 31, (uae_u8)-4); /* IOERR_BADLENGTH */
! 430: } else {
! 431: put_byte (request + 31, 20); /* io_Error, but not specified */
! 432: put_long (acmd + 8, 0); /* scsi_Actual */
! 433: }
1.1 root 434: } else {
435: put_byte (request + 31, 0);
436: put_long (acmd + 8, scsi_len - scmd->resid); /* scsi_Actual */
437: }
438: }
439: put_word (acmd + 28, sactual);
440:
1.1.1.3 ! root 441: #ifdef SCSI_IS_NOT_THREAD_SAFE
1.1 root 442: uae_sem_post (&scgp_sem);
443: #endif
444: }
445:
446: static void scsidev_do_io (struct scsidevdata *sdd, uaecptr request)
447: {
448: uae_u32 tmp2, dataptr, offset;
449:
450: tmp2 = get_word (request+28); /* io_Command */
451: switch (tmp2) {
452: case 28:
453: /* HD_SCSICMD */
454: scsidev_do_scsi (sdd, request);
455: break;
456: default:
457: /* Command not understood. */
458: put_byte (request+31, (uae_u8)-3); /* io_Error */
459: break;
460: }
461: #ifdef DEBUGME
462: printf ("scsidev: did io: sdd = 0x%x\n", sdd);
463: printf ("scsidev: did io: request = %08lx\n", (unsigned long)request);
464: printf ("scsidev: did io: error = %d\n", (int)get_word(request+31));
465: #endif
466: }
467:
468:
469: static uae_u32 scsidev_beginio (void)
470: {
471: uae_u32 request = m68k_areg(regs, 1);
472: int unit = get_long (request + 24);
473: struct scsidevdata *sdd = get_scsidev_data (unit);
474:
475: #ifdef DEBUGME
476: printf ("scsidev_begin_io: sdd = 0x%x\n", sdd);
477: printf ("scsidev_begin_io: request = %08lx\n", (unsigned long)request);
478: printf ("scsidev_begin_io: cmd = %d\n", (int)get_word(request+28));
479: #endif
480:
481: put_byte (request+8, NT_MESSAGE);
482: put_byte (request+31, 0); /* no error yet */
483:
484: #ifdef UAE_SCSIDEV_THREADS
485: {
486: uae_pt data;
487:
488: /* clear IOF_QUICK */
489: put_byte (request+30, get_byte (request+30) & ~1);
490: /* forward to unit thread */
491: write_comm_pipe_u32 (&sdd->requests, request, 1);
492: return 0;
493: }
494: #else
495: put_byte (request+30, get_byte (request+30) & ~1);
496: scsidev_do_io (sdd, request);
497: return get_byte (request+31); /* do we really have to return io_Error? */
498: #endif
499: }
500:
501: #ifdef UAE_SCSIDEV_THREADS
502: static void *scsidev_penguin (void *sddv)
503: {
504: struct scsidevdata *sdd = sddv;
505:
506: #ifdef DEBUGME
507: printf ("scsidev_penguin: sdd = 0x%x ready\n", sdd);
508: #endif
509: /* init SCSI */
1.1.1.3 ! root 510: if (!(sdd->scgp = openscsi (sdd->bus, sdd->target, sdd->lun)) ||
! 511: (sdd->max_dma = scsi_bufsize (sdd->scgp, 512 * 1024)) <= 0) {
1.1 root 512: sdd->thread_running = 0;
513: uae_sem_post (&sdd->sync_sem);
514: return 0;
515: }
516: sdd->thread_running = 1;
517: uae_sem_post (&sdd->sync_sem);
518:
519: for (;;) {
520: uaecptr request;
521:
522: request = (uaecptr)read_comm_pipe_u32_blocking (&sdd->requests);
523: #ifdef DEBUGME
524: printf ("scsidev_penguin: sdd = 0x%x\n", sdd);
525: printf ("scsidev_penguin: req = %08lx\n", (unsigned long)request);
526: printf ("scsidev_penguin: cmd = %d\n", (int)get_word(request+28));
527: #endif
528: if (!request) {
529: printf ("scsidev_penguin: going down with 0x%x\n", sdd->sync_sem);
530: /* Death message received. */
531: sdd->thread_running = 0;
532: uae_sem_post (&sdd->sync_sem);
533: /* Die. */
534: return 0;
535: }
536:
537: scsidev_do_io (sdd, request);
1.1.1.2 root 538: uae_ReplyMsg (request);
1.1 root 539: }
540: return 0;
541: }
542: #endif
543:
544:
545: static uae_u32 scsidev_abortio (void)
546: {
547: return (uae_u32)-3;
548: }
549:
550: static uae_u32 scsidev_init (void)
551: {
552: #ifdef DEBUGME
553: printf("scsidev_init()\n");
554: #endif
555:
556: if (scgp) {
557: /* we still have everything in place */
558: return m68k_dreg (regs, 0); /* device base */
559: }
560:
561: /* init global SCSI */
1.1.1.3 ! root 562: if (!(scgp = openscsi (-1, -1, -1))) {
1.1 root 563: return 0;
564: }
565:
566: uae_sem_init (&scgp_sem, 0, 1);
567:
568: /* add all units we find */
569: for (scgp->scsibus=0; scgp->scsibus < 8; scgp->scsibus++) {
570: if (!scsi_havebus(scgp, scgp->scsibus))
571: continue;
572: printf("scsibus%d:\n", scgp->scsibus);
573: for (scgp->target=0; scgp->target < 16; scgp->target++) {
574: struct scsi_inquiry inq;
575: scgp->lun = 0;
576: if (inquiry (scgp, &inq, sizeof(inq))) {
577: continue;
578: }
579: for (scgp->lun=0; scgp->lun < 8; scgp->lun++) {
580: if (!inquiry (scgp, &inq, sizeof(inq))) {
581: int aunit = BTL2UNIT(scgp->scsibus, scgp->target, scgp->lun);
1.1.1.3 ! root 582: struct scsidevdata *sdd;
1.1 root 583:
584: write_log (" %2.01d,%d (= %3.d): ", scgp->target, scgp->lun, aunit);
585: print_product (&inq);
1.1.1.3 ! root 586: sdd = add_scsidev_data (scgp->scsibus, scgp->target, scgp->lun, aunit);
! 587: write_log (!sdd ? " - init failed ???" : sdd->isatapi ? " - ATAPI" : " - SCSI");
1.1 root 588: write_log ("\n");
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++) {
1.1.1.3 ! root 718: if (!drives[i].thread_running) {
! 719: continue;
! 720: }
! 721: write_comm_pipe_int (&drives[i].requests, 0, 1);
! 722: uae_sem_wait (&drives[i].sync_sem);
1.1 root 723: }
724: num_drives = 0;
725: }
726: #endif
727:
728: if (scgp) {
729: closescsi (scgp);
730: scgp = NULL;
731: }
732: #endif
733:
734: opencount = 0;
735: }
736:
737: void scsidev_start_threads (void)
738: {
739: #ifdef DEBUGME
740: printf("scsidev_start_threads()\n");
741: #endif
742: }
743:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.