--- uae/src/scsidev.c 2018/04/24 16:47:25 1.1.1.1 +++ uae/src/scsidev.c 2018/04/24 17:16:35 1.1.1.9 @@ -10,12 +10,10 @@ #include "sysconfig.h" #include "sysdeps.h" -#include "config.h" -#include "threaddep/penguin.h" +#include "threaddep/thread.h" #include "options.h" #include "memory.h" #include "custom.h" -#include "readcpu.h" #include "newcpu.h" #include "disk.h" #include "autoconf.h" @@ -23,19 +21,26 @@ #include "execlib.h" #include "native2amiga.h" #include "scsidev.h" -#include "scg/scsireg.h" -/* our configure does not distinguish that */ -#ifdef UAE_FILESYS_THREADS -#define UAE_SCSIDEV_THREADS +#include + +/* the new libscg should always have a scsi_close */ +#ifndef SCSI_CLOSE +#define SCSI_CLOSE #endif -#undef DEBUGME +typedef int BOOL; -/* follow the cdrecord style by including the correct code */ -#include "scsi-support.c" +#include "scg/scgcmd.h" +#include "scg/scsitransp.h" +#include "scg/scsireg.h" +/* our configure does not have a seperate UAE_SCSIDEV_THREADS */ +#if defined(UAE_FILESYS_THREADS) && !defined(SCSI_IS_NOT_THREAD_SAFE) +#define UAE_SCSIDEV_THREADS +#endif +#undef DEBUGME /****************** generic SCSI stuff stolen from cdrecord and scsitransp.c ***********/ static int scsierr(SCSI *scgp) @@ -44,42 +49,16 @@ static int scsierr(SCSI *scgp) if(cp->error != SCG_NO_ERROR || cp->ux_errno != 0 || *(u_char *)&cp->scb != 0) - return -1; + return -1; return 0; } -int scsicmd(SCSI *scgp) -{ - int f; - int ret; - register struct scg_cmd *scmd = scgp->scmd; - - f = scsi_fileno(scgp, scgp->scsibus, scgp->target, scgp->lun); - scmd->kdebug = scgp->kdebug; - if (scmd->timeout == 0 || scmd->timeout < scgp->deftimeout) - scmd->timeout = scgp->deftimeout; - if (scgp->disre_disable) - scmd->flags &= ~SCG_DISRE_ENA; - if (scgp->noparity) - scmd->flags |= SCG_NOPARITY; - - gettimeofday(scgp->cmdstart, (struct timezone *)0); - errno = 0; - ret = scsi_send(scgp, f, scmd); - scsitimes(scgp); - if (ret < 0 && errno && !scgp->scmd->ux_errno) { - scgp->scmd->ux_errno = errno; - } - ret = scsierr(scgp); - return (ret); -} - static int inquiry (SCSI *scgp, void *bp, int cnt) { struct scg_cmd *scmd = scgp->scmd; - fillbytes(bp, cnt, '\0'); - fillbytes((caddr_t)scmd, sizeof(*scmd), '\0'); + memset(bp, cnt, '\0'); + memset((caddr_t)scmd, sizeof(*scmd), '\0'); scmd->addr = bp; scmd->size = cnt; scmd->flags = SCG_RECV_DATA|SCG_DISRE_ENA; @@ -89,11 +68,11 @@ static int inquiry (SCSI *scgp, void *bp scmd->cdb.g0_cdb.cmd = SC_INQUIRY; scmd->cdb.g0_cdb.lun = scgp->lun; scmd->cdb.g0_cdb.count = cnt; - + scgp->cmdname = "inquiry"; if (scsicmd(scgp) < 0) - return (-1); + return (-1); return (0); } @@ -103,39 +82,46 @@ static void print_product(struct scsi_in write_log ("'%.16s' ", ip->ident); write_log ("'%.4s' ", ip->revision); if (ip->add_len < 31) { - write_log ("NON CCS "); + write_log ("NON CCS "); } } -static SCSI *openscsi (char *dev, int bus, int target, int lun) +/* get integer value from env or return default value, if unset */ +static int getenvint (const char *varname, int def) { - SCSI *scgp; - - if(!(scgp = calloc(1, sizeof (*scgp))) || - !(scgp->scmd = calloc(1, sizeof (*scgp->scmd))) || - !(scgp->cmdstart = malloc(sizeof (*scgp->cmdstart))) || - !(scgp->cmdstop = malloc(sizeof (*scgp->cmdstop)))) { - return NULL; - } - /* we don't really know the timeout - should better - disable it, if possible */ - scgp->deftimeout = 80 * 60; /* 80min */ - scgp->scsibus = bus; + const char *val = getenv (varname); + return val ? atoi (val) : def; +} + +/* wrapper for the underlying combination of scsi_smalloc()/scsi_open() */ +static SCSI *openscsi (int scsibus, int target, int lun) +{ + SCSI *scgp = scsi_smalloc (); + if (!scgp) { + return NULL; + } + + scgp->debug = getenvint ("UAE_SCSI_DEBUG", 0); + scgp->kdebug = getenvint ("UAE_SCSI_KDEBUG", 0); + scgp->silent = getenvint ("UAE_SCSI_SILENT", 1); + scgp->verbose = getenvint ("UAE_SCSI_VERBOSE", 0); + scgp->scsibus = scsibus; scgp->target = target; scgp->lun = lun; - return scsi_open (scgp, dev, bus, target, lun) >= 0 ? scgp : NULL; + + if (!scsi_open(scgp, NULL, scsibus, target, lun)) { + scsi_sfree (scgp); + return NULL; + } else { + return scgp; + } } -#ifdef SCSI_CLOSE -/* if there is no scsi_close, then we have to keep everything */ static void closescsi (SCSI *scgp) { scsi_close (scgp); - free (scgp->scmd); - free (scgp->cmdstart); - free (scgp->cmdstop); + scsi_sfree (scgp); } -#endif /********************* start of our own code ************************/ @@ -155,10 +141,11 @@ struct scsidevdata { (target % 8) SCSI *scgp; long max_dma; + int isatapi; #ifdef UAE_SCSIDEV_THREADS /* Threading stuff */ smp_comm_pipe requests; - penguin_id tid; + uae_thread_id tid; int thread_running; uae_sem_t sync_sem; #endif @@ -172,9 +159,9 @@ static struct scsidevdata *get_scsidev_d int i; for (i = 0; i < num_drives; i++) { - if (unit == drives[i].aunit) { - return &drives[i]; - } + if (unit == drives[i].aunit) { + return &drives[i]; + } } return NULL; } @@ -182,37 +169,42 @@ static struct scsidevdata *get_scsidev_d static struct scsidevdata *add_scsidev_data (int bus, int target, int lun, int aunit) { if (num_drives + 1 < MAX_DRIVES) { - memset(&drives[num_drives], 0, sizeof(drives[num_drives])); - drives[num_drives].bus = bus; - drives[num_drives].target = target; - drives[num_drives].lun = lun; - drives[num_drives].aunit = aunit; -#if !defined(UAE_SCSIDEV_THREADS) || !defined(SCSI_IS_THREAD_SAFE) - drives[num_drives].scgp = scgp; - drives[num_drives].max_dma = scsi_maxdma (scgp); -#endif - return &drives[num_drives++]; + memset(&drives[num_drives], 0, sizeof(drives[num_drives])); + drives[num_drives].bus = bus; + drives[num_drives].target = target; + drives[num_drives].lun = lun; + drives[num_drives].aunit = aunit; +#if !defined(UAE_SCSIDEV_THREADS) + drives[num_drives].scgp = scgp; + drives[num_drives].max_dma = scsi_bufsize (scgp, 512 * 1024); +#endif + /* check if this drive is an ATAPI drive */ + scgp->scsibus = bus; + scgp->target = target; + scgp->lun = lun; + drives[num_drives].isatapi = scsi_isatapi (scgp); + return &drives[num_drives++]; } return NULL; } -static void *scsidev_penguin(void *); +static void *scsidev_thread(void *); static int start_thread (struct scsidevdata *sdd) { #ifdef UAE_SCSIDEV_THREADS if (sdd->thread_running) - return 1; + return 1; init_comm_pipe (&sdd->requests, 10, 1); uae_sem_init (&sdd->sync_sem, 0, 0); - start_penguin (scsidev_penguin, sdd, &sdd->tid); + uae_start_thread (scsidev_thread, sdd, &sdd->tid); uae_sem_wait (&sdd->sync_sem); return sdd->thread_running; #else return 1; #endif } - + /************* Exec device functions ****************/ @@ -228,7 +220,7 @@ static uae_u32 scsidev_open (void) /* Check unit number */ if ((sdd = get_scsidev_data (unit)) && - start_thread (sdd)) { + start_thread (sdd)) { opencount++; put_word (m68k_areg(regs, 6)+32, get_word (m68k_areg(regs, 6)+32) + 1); put_long (tmp1 + 24, unit); /* io_Unit */ @@ -269,6 +261,48 @@ static uae_u32 scsidev_expunge (void) #define MODE_SENSE_10 0x5A #endif + +#ifdef DEBUG_CDR +/* please ignore this code - it can be used to debug raw CD-R writing... */ + +/* +** convert time in (BCD) min:sec:frame to block address +*/ +typedef signed char BYTE; +typedef unsigned char UBYTE; +typedef long LONG; +typedef BYTE BCD; +typedef BYTE WORD[2]; +#define BCD_DEC(x) (((x) >> 4) * 10 + ((x) & 0xF)) +static LONG TestNegativeTime(LONG block) +{ + /* block -151 == 99:59:74 + -150 == 100:00:00 = 00:00:00 */ + if (block > (97 * 60 * 75)) + { + /* must be a negative block */ + block -= 100 * 60 * 75; + } + return block; +} +static LONG BCDTime2Block(UBYTE min, UBYTE sec, UBYTE frame) +{ + return(TestNegativeTime((LONG)((BCD_DEC(min) * 60 + BCD_DEC(sec)) * 75 + BCD_DEC(frame) - 2 * 75))); +} +static LONG Time2Block(UBYTE min, UBYTE sec, UBYTE frame) +{ + return(TestNegativeTime((LONG)((min * 60 + sec) * 75 + frame - 2 * 75))); +} +static LONG BCDTime2Block_Pointer (UBYTE *p) +{ + return BCDTime2Block (p[0], p[1], p[2]); +} +static LONG Time2Block_Pointer (UBYTE *p) +{ + return Time2Block (p[0], p[1], p[2]); +} +#endif + static void scsidev_do_scsi (struct scsidevdata *sdd, uaecptr request) { SCSI *scgp = sdd->scgp; @@ -287,21 +321,16 @@ static void scsidev_do_scsi (struct scsi /* do transfer directly to and from Amiga memory */ if (!bank_data || !bank_data->check (scsi_data, scsi_len) || - !bank_cmd || !bank_cmd->check (scsi_cmd, scsi_cmd_len)) { - put_byte (request + 31, (uae_u8)-5); /* IOERR_BADADDRESS */ - return; - } - - /* we are limited by the hosts DMA limits */ - if (scsi_len > sdd->max_dma) { - put_byte (request + 31, (uae_u8)-4); /* IOERR_BADLENGTH */ - return; + !bank_cmd || !bank_cmd->check (scsi_cmd, scsi_cmd_len)) { + put_byte (request + 31, (uae_u8)-5); /* IOERR_BADADDRESS */ + return; } -#ifndef SCSI_IS_THREAD_SAFE +#ifdef SCSI_IS_NOT_THREAD_SAFE uae_sem_wait (&scgp_sem); #endif + scmd->timeout = 80 * 60; /* the Amiga does not tell us how long the timeout shall be, so make it _very_ long (specified in seconds) */ scmd->addr = bank_data->xlateaddr (scsi_data); scmd->size = scsi_len; scmd->flags = ((scsi_flags & 1) ? SCG_RECV_DATA : 0) | SCG_DISRE_ENA; @@ -309,138 +338,182 @@ static void scsidev_do_scsi (struct scsi memcpy(&scmd->cdb, bank_cmd->xlateaddr (scsi_cmd), scsi_cmd_len); scmd->target = sdd->target; scmd->sense_len = (scsi_flags & 4) ? 4 : /* SCSIF_OLDAUTOSENSE */ - (scsi_flags & 2) ? scsi_sense_len : /* SCSIF_AUTOSENSE */ - -1; + (scsi_flags & 2) ? scsi_sense_len : /* SCSIF_AUTOSENSE */ + -1; scmd->sense_count = 0; *(uae_u8 *)&scmd->scb = 0; + #ifdef DEBUG_CDR + /* please ignore this code - it can be used to debug raw CD-R writing... */ + if (!(scsi_len % 2368)) { + /* Structure for generating bytes 2353...2368 if writing in ultra raw mode */ + typedef struct QDATAtag { + BYTE ControlAdr; + BCD Tno; + BCD Point; + BCD Min; + BCD Sec; + BCD Frame; + BYTE Zero; + BCD PMin; + BCD PSec; + BCD PFrame; + WORD Crc; + BYTE Reserved[3]; + BYTE PChannel; + } QDATA; + + int i = scsi_len / 2368; + QDATA *data = (QDATA *)&((unsigned char *)scmd->addr)[2352]; + for (; i > 0; i--, data = (QDATA *)&((unsigned char *)data)[2368]) { + printf ("$%02x: $%02x $%02x | $%02x:$%02x:$%02x = %6ld | $%02x | $%02x:$%02x:$%02x = %6ld\n", + (int)data->ControlAdr, (int)*(UBYTE *)&data->Tno, (int)*(UBYTE *)&data->Point, + (int)*(UBYTE *)&data->Min, (int)*(UBYTE *)&data->Sec, (int)*(UBYTE *)&data->Frame, + BCDTime2Block_Pointer (&data->Min) + 150, + *(UBYTE *)&data->Zero, + *(UBYTE *)&data->PMin, *(UBYTE *)&data->PSec, *(UBYTE *)&data->PFrame, + BCDTime2Block_Pointer (&data->PMin)); + } + fflush (stdout); + } + #endif + scgp->scsibus = sdd->bus; scgp->target = sdd->target; scgp->lun = sdd->lun; - scsicmd (scgp); + scgp->cmdname = "???"; + scgp->curcmdname = "???"; - /* replace MODE_SELECT/SENSE_6 if they are not supported */ - if (scmd->scb.chk && - ((struct scsi_ext_sense *)&scmd->sense)->key == 0x5 && - ((struct scsi_ext_sense *)&scmd->sense)->sense_code == 0x20 && /* INVALID_COMMAND */ - (scmd->cdb.g0_cdb.cmd == MODE_SELECT_6 || - scmd->cdb.g0_cdb.cmd == MODE_SENSE_6)) { - uae_u8 buffer[256 + 2], *data = scmd->addr, *tmp; - int len = 0, page_len, i; - int do_it = 1; - uae_u8 sp = scmd->cdb.g0_cdb.high_addr & 1; - uae_u8 alloc_len = scmd->cdb.g0_cdb.count; - uae_u8 pcf_page_code = scmd->cdb.g0_cdb.mid_addr; - uae_u8 cmd = scmd->cdb.g0_cdb.cmd; - - memset (&scmd->cdb.g1_cdb, 0, sizeof(scmd->cdb.g1_cdb)); - if (cmd == MODE_SELECT_6) { - /* expand parameter list */ - tmp = data; - buffer[len++] = *tmp++; /* first byte, should be 0 */ - buffer[len++] = 0; /* reserved */ - buffer[len++] = *tmp++; /* medium type */ - buffer[len++] = 0; *tmp++; /* ignore host application code */ - for (i = 0; i < 4; i++) { - buffer[len++] = 0; - } - if (*tmp) { - /* skip block descriptor */ - tmp += 8; - } - tmp++; - page_len = scsi_len - (tmp - data); - if (page_len > 0) { - memcpy (&buffer[len], tmp, page_len); - len += page_len; - - scmd->cdb.g1_cdb.cmd = MODE_SELECT_10; - scmd->cdb.g1_cdb.lun = sdd->lun; - scmd->cdb.g1_cdb.res = 1 << 3; /* PF bit */ - scmd->cdb.g1_cdb.reladr = sp; - scmd->cdb.g1_cdb.count[0] = len >> 8; - scmd->cdb.g1_cdb.count[1] = len; - } else { - do_it = 0; - scmd->error = 0; - *(uae_u8 *)&scmd->scb = 0; - scmd->ux_errno = 0; - } - } else { - /* MODE_SENSE_6 */ - len = alloc_len + 2; - scmd->cdb.g1_cdb.cmd = MODE_SENSE_10; - scmd->cdb.g1_cdb.lun = sdd->lun; - scmd->cdb.g1_cdb.addr[0] = pcf_page_code; - scmd->cdb.g1_cdb.count[0] = len >> 8; - scmd->cdb.g1_cdb.count[1] = len; - } - if (do_it) { - scmd->cdb_len = 10; - scmd->addr = buffer; - scmd->size = len; - scmd->sense_count = 0; - *(uae_u8 *)&scmd->scb = 0; - - scsicmd (scgp); - - if (cmd == MODE_SENSE_6 && - !scmd->error && - !scmd->ux_errno && - !*(uae_u8 *)&scmd->scb) { - int req_len = len; - - /* compress result */ - tmp = buffer; - len = 0; - tmp++; /* skip first byte of length - should better be zero */ - data[len++] = *tmp++; /* mode data length */ - data[len++] = *tmp++; /* medium type */ - data[len++] = 0; /* host application type */ - data[len++] = 0; /* block descr length */ - tmp += 4; - if (*tmp) { - /* skip block descr - should not happen */ - tmp += *tmp; - } - tmp++; - memcpy (&data[len], tmp, req_len - (tmp - buffer)); - } - } + /* replace MODE_SELECT/SENSE_6 if we access a ATAPI drive, + otherwise send it now */ + if (sdd->isatapi && + (scmd->cdb.g0_cdb.cmd == MODE_SELECT_6 || + scmd->cdb.g0_cdb.cmd == MODE_SENSE_6)) { + uae_u8 buffer[256 + 2], *data = scmd->addr, *tmp; + int len = 0, page_len, i; + int do_it = 1; + uae_u8 sp = scmd->cdb.g0_cdb.high_addr & 1; + uae_u8 alloc_len = scmd->cdb.g0_cdb.count; + uae_u8 pcf_page_code = scmd->cdb.g0_cdb.mid_addr; + uae_u8 cmd = scmd->cdb.g0_cdb.cmd; + + memset (&scmd->cdb.g1_cdb, 0, sizeof(scmd->cdb.g1_cdb)); + if (cmd == MODE_SELECT_6) { + /* expand parameter list */ + tmp = data; + buffer[len++] = *tmp++; /* first byte, should be 0 */ + buffer[len++] = 0; /* reserved */ + buffer[len++] = *tmp++; /* medium type */ + buffer[len++] = 0; *tmp++; /* ignore host application code */ + for (i = 0; i < 4; i++) { + buffer[len++] = 0; + } + if (*tmp) { + /* skip block descriptor */ + tmp += 8; + } + tmp++; + page_len = scsi_len - (tmp - data); + if (page_len > 0) { + memcpy (&buffer[len], tmp, page_len); + len += page_len; + + scmd->cdb.g1_cdb.cmd = MODE_SELECT_10; + scmd->cdb.g1_cdb.lun = sdd->lun; + scmd->cdb.g1_cdb.res = 1 << 3; /* PF bit */ + scmd->cdb.g1_cdb.reladr = sp; + scmd->cdb.g1_cdb.count[0] = len >> 8; + scmd->cdb.g1_cdb.count[1] = len; + } else { + do_it = 0; + scmd->error = 0; + *(uae_u8 *)&scmd->scb = 0; + scmd->ux_errno = 0; + } + } else { + /* MODE_SENSE_6 */ + len = alloc_len + 2; + scmd->cdb.g1_cdb.cmd = MODE_SENSE_10; + scmd->cdb.g1_cdb.lun = sdd->lun; + scmd->cdb.g1_cdb.addr[0] = pcf_page_code; + scmd->cdb.g1_cdb.count[0] = len >> 8; + scmd->cdb.g1_cdb.count[1] = len; + } + if (do_it) { + scmd->cdb_len = 10; + scmd->addr = buffer; + scmd->size = len; + scmd->sense_count = 0; + *(uae_u8 *)&scmd->scb = 0; + + scsicmd (scgp); + + if (cmd == MODE_SENSE_6 && + !scmd->error && + !scmd->ux_errno && + !*(uae_u8 *)&scmd->scb) { + int req_len = len; + + /* compress result */ + tmp = buffer; + len = 0; + tmp++; /* skip first byte of length - should better be zero */ + data[len++] = *tmp++; /* mode data length */ + data[len++] = *tmp++; /* medium type */ + data[len++] = 0; /* host application type */ + data[len++] = 0; /* block descr length */ + tmp += 4; + if (*tmp) { + /* skip block descr - should not happen */ + tmp += *tmp; + } + tmp++; + memcpy (&data[len], tmp, req_len - (tmp - buffer)); + } + } + } else { + scsicmd (scgp); } - + put_word (acmd + 18, scmd->error == SCG_FATAL ? 0 : scsi_cmd_len); /* fake scsi_CmdActual */ put_byte (acmd + 21, *(uae_u8 *)&scmd->scb); /* scsi_Status */ if (*(uae_u8 *)&scmd->scb) { - put_byte (request + 31, 45); /* HFERR_BadStatus */ + put_byte (request + 31, 45); /* HFERR_BadStatus */ - /* copy sense? */ - for (sactual = 0; - scsi_sense && sactual < scsi_sense_len && sactual < scmd->sense_count; - sactual++) { - put_byte (scsi_sense + sactual, scmd->u_sense.cmd_sense[sactual]); - } - put_long (acmd + 8, 0); /* scsi_Actual */ + /* copy sense? */ + for (sactual = 0; + scsi_sense && sactual < scsi_sense_len && sactual < scmd->sense_count; + sactual++) { + put_byte (scsi_sense + sactual, scmd->u_sense.cmd_sense[sactual]); + } + put_long (acmd + 8, 0); /* scsi_Actual */ } else { - int i; - - for (i = 0; i < scsi_sense_len; i++) { - put_byte (scsi_sense + i, 0); - } - sactual = 0; - - if (scmd->error != SCG_NO_ERROR || - scmd->ux_errno != 0) { - put_byte (request + 31, 20); /* io_Error, but not specified */ - put_long (acmd + 8, 0); /* scsi_Actual */ - } else { - put_byte (request + 31, 0); - put_long (acmd + 8, scsi_len - scmd->resid); /* scsi_Actual */ - } + int i; + + for (i = 0; i < scsi_sense_len; i++) { + put_byte (scsi_sense + i, 0); + } + sactual = 0; + + if (scmd->error != SCG_NO_ERROR || + scmd->ux_errno != 0) { + /* we might have been limited by the hosts DMA limits, + which is usually indicated by ENOMEM */ + if (scsi_len > (unsigned int)sdd->max_dma && + scmd->ux_errno == ENOMEM) { + put_byte (request + 31, (uae_u8)-4); /* IOERR_BADLENGTH */ + } else { + put_byte (request + 31, 20); /* io_Error, but not specified */ + put_long (acmd + 8, 0); /* scsi_Actual */ + } + } else { + put_byte (request + 31, 0); + put_long (acmd + 8, scsi_len - scmd->resid); /* scsi_Actual */ + } } put_word (acmd + 28, sactual); -#ifndef SCSI_IS_THREAD_SAFE +#ifdef SCSI_IS_NOT_THREAD_SAFE uae_sem_post (&scgp_sem); #endif } @@ -448,13 +521,13 @@ static void scsidev_do_scsi (struct scsi static void scsidev_do_io (struct scsidevdata *sdd, uaecptr request) { uae_u32 tmp2, dataptr, offset; - + tmp2 = get_word (request+28); /* io_Command */ switch (tmp2) { case 28: - /* HD_SCSICMD */ - scsidev_do_scsi (sdd, request); - break; + /* HD_SCSICMD */ + scsidev_do_scsi (sdd, request); + break; default: /* Command not understood. */ put_byte (request+31, (uae_u8)-3); /* io_Error */ @@ -485,13 +558,13 @@ static uae_u32 scsidev_beginio (void) #ifdef UAE_SCSIDEV_THREADS { - uae_pt data; + uae_pt data; - /* clear IOF_QUICK */ - put_byte (request+30, get_byte (request+30) & ~1); - /* forward to unit thread */ - write_comm_pipe_u32 (&sdd->requests, request, 1); - return 0; + /* clear IOF_QUICK */ + put_byte (request+30, get_byte (request+30) & ~1); + /* forward to unit thread */ + write_comm_pipe_u32 (&sdd->requests, request, 1); + return 0; } #else put_byte (request+30, get_byte (request+30) & ~1); @@ -501,19 +574,19 @@ static uae_u32 scsidev_beginio (void) } #ifdef UAE_SCSIDEV_THREADS -static void *scsidev_penguin (void *sddv) +static void *scsidev_thread (void *sddv) { struct scsidevdata *sdd = sddv; #ifdef DEBUGME printf ("scsidev_penguin: sdd = 0x%x ready\n", sdd); -#endif +#endif /* init SCSI */ - if (!(sdd->scgp = openscsi (NULL, sdd->bus, sdd->target, sdd->lun)) || - (sdd->max_dma = scsi_maxdma (sdd->scgp)) <= 0) { - sdd->thread_running = 0; - uae_sem_post (&sdd->sync_sem); - return 0; + if (!(sdd->scgp = openscsi (sdd->bus, sdd->target, sdd->lun)) || + (sdd->max_dma = scsi_bufsize (sdd->scgp, 512 * 1024)) <= 0) { + sdd->thread_running = 0; + uae_sem_post (&sdd->sync_sem); + return 0; } sdd->thread_running = 1; uae_sem_post (&sdd->sync_sem); @@ -523,21 +596,21 @@ static void *scsidev_penguin (void *sddv request = (uaecptr)read_comm_pipe_u32_blocking (&sdd->requests); #ifdef DEBUGME - printf ("scsidev_penguin: sdd = 0x%x\n", sdd); - printf ("scsidev_penguin: req = %08lx\n", (unsigned long)request); - printf ("scsidev_penguin: cmd = %d\n", (int)get_word(request+28)); + printf ("scsidev_penguin: sdd = 0x%x\n", sdd); + printf ("scsidev_penguin: req = %08lx\n", (unsigned long)request); + printf ("scsidev_penguin: cmd = %d\n", (int)get_word(request+28)); #endif - if (!request) { - printf ("scsidev_penguin: going down with 0x%x\n", sdd->sync_sem); + if (!request) { + printf ("scsidev_penguin: going down with 0x%x\n", sdd->sync_sem); /* Death message received. */ - sdd->thread_running = 0; + sdd->thread_running = 0; uae_sem_post (&sdd->sync_sem); /* Die. */ return 0; } - scsidev_do_io (sdd, request); - ReplyMsg (request); + scsidev_do_io (sdd, request); + uae_ReplyMsg (request); } return 0; } @@ -554,41 +627,43 @@ static uae_u32 scsidev_init (void) #ifdef DEBUGME printf("scsidev_init()\n"); #endif - + if (scgp) { - /* we still have everything in place */ - return m68k_dreg (regs, 0); /* device base */ + /* we still have everything in place */ + return m68k_dreg (regs, 0); /* device base */ } - + /* init global SCSI */ - if (!(scgp = openscsi (NULL, -1, -1, -1))) { - return 0; + if (!(scgp = openscsi (-1, -1, -1))) { + return 0; } uae_sem_init (&scgp_sem, 0, 1); /* add all units we find */ for (scgp->scsibus=0; scgp->scsibus < 8; scgp->scsibus++) { - if (!scsi_havebus(scgp, scgp->scsibus)) - continue; - printf("scsibus%d:\n", scgp->scsibus); - for (scgp->target=0; scgp->target < 16; scgp->target++) { - struct scsi_inquiry inq; - scgp->lun = 0; - if (inquiry (scgp, &inq, sizeof(inq))) { - continue; - } - for (scgp->lun=0; scgp->lun < 8; scgp->lun++) { - if (!inquiry (scgp, &inq, sizeof(inq))) { - int aunit = BTL2UNIT(scgp->scsibus, scgp->target, scgp->lun); - - write_log (" %2.01d,%d (= %3.d): ", scgp->target, scgp->lun, aunit); - print_product (&inq); - write_log ("\n"); - add_scsidev_data (scgp->scsibus, scgp->target, scgp->lun, aunit); + if (!scsi_havebus(scgp, scgp->scsibus)) + continue; + printf("scsibus%d:\n", scgp->scsibus); + for (scgp->target=0; scgp->target < 16; scgp->target++) { + struct scsi_inquiry inq; + scgp->lun = 0; + if (inquiry (scgp, &inq, sizeof(inq))) { + continue; + } + for (scgp->lun=0; scgp->lun < 8; scgp->lun++) { + if (!inquiry (scgp, &inq, sizeof(inq))) { + int aunit = BTL2UNIT(scgp->scsibus, scgp->target, scgp->lun); + struct scsidevdata *sdd; + + write_log (" %2.01d,%d (= %3.d): ", scgp->target, scgp->lun, aunit); + print_product (&inq); + sdd = add_scsidev_data (scgp->scsibus, scgp->target, scgp->lun, aunit); + write_log (!sdd ? " - init failed ???" : sdd->isatapi ? " - ATAPI" : " - SCSI"); + write_log ("\n"); } - } - } + } + } } return m68k_dreg (regs, 0); /* device base */ } @@ -633,7 +708,7 @@ void scsidev_install (void) /* initcode */ initcode = here (); calltrap (deftrap (scsidev_init)); dw (RTS); - + /* Open */ openfunc = here (); calltrap (deftrap (scsidev_open)); dw (RTS); @@ -712,22 +787,25 @@ void scsidev_reset (void) #ifdef SCSI_CLOSE #ifdef UAE_SCSIDEV_THREADS { - int i; + int i; - for (i = 0; i < num_drives; i++) { - write_comm_pipe (&drives[i].requests, 0, 1); - uae_sem_wait (&drives[i].sync); - } - num_drives = 0; + for (i = 0; i < num_drives; i++) { + if (!drives[i].thread_running) { + continue; + } + write_comm_pipe_int (&drives[i].requests, 0, 1); + uae_sem_wait (&drives[i].sync_sem); + } + num_drives = 0; } #endif - + if (scgp) { - closescsi (scgp); - scgp = NULL; + closescsi (scgp); + scgp = NULL; } #endif - + opencount = 0; }