diff --git a/src/devices/scsi/queue.h b/src/devices/scsi/queue.h deleted file mode 100644 index 141ae52..0000000 --- a/src/devices/scsi/queue.h +++ /dev/null @@ -1,437 +0,0 @@ -/* $NetBSD: queue.h,v 1.52 2009/04/20 09:56:08 mschuett Exp $ */ - -/* - * QEMU version: Copy from netbsd, removed debug code, removed some of - * the implementations. Left in singly-linked lists, lists, simple - * queues, and tail queues. - */ - -/* - * Copyright (c) 1991, 1993 - * The Regents of the University of California. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @(#)queue.h 8.5 (Berkeley) 8/20/94 - */ - -#ifndef QUEUE_H -#define QUEUE_H - -/* - * This file defines four types of data structures: singly-linked lists, - * lists, simple queues, and tail queues. - * - * A singly-linked list is headed by a single forward pointer. The - * elements are singly linked for minimum space and pointer manipulation - * overhead at the expense of O(n) removal for arbitrary elements. New - * elements can be added to the list after an existing element or at the - * head of the list. Elements being removed from the head of the list - * should use the explicit macro for this purpose for optimum - * efficiency. A singly-linked list may only be traversed in the forward - * direction. Singly-linked lists are ideal for applications with large - * datasets and few or no removals or for implementing a LIFO queue. - * - * A list is headed by a single forward pointer (or an array of forward - * pointers for a hash table header). The elements are doubly linked - * so that an arbitrary element can be removed without a need to - * traverse the list. New elements can be added to the list before - * or after an existing element or at the head of the list. A list - * may only be traversed in the forward direction. - * - * A simple queue is headed by a pair of pointers, one the head of the - * list and the other to the tail of the list. The elements are singly - * linked to save space, so elements can only be removed from the - * head of the list. New elements can be added to the list after - * an existing element, at the head of the list, or at the end of the - * list. A simple queue may only be traversed in the forward direction. - * - * A tail queue is headed by a pair of pointers, one to the head of the - * list and the other to the tail of the list. The elements are doubly - * linked so that an arbitrary element can be removed without a need to - * traverse the list. New elements can be added to the list before or - * after an existing element, at the head of the list, or at the end of - * the list. A tail queue may be traversed in either direction. - * - * For details on the use of these macros, see the queue(3) manual page. - */ - -/* - * List definitions. - */ -#define QLIST_HEAD(name, type) \ -struct name { \ - struct type *lh_first; /* first element */ \ -} - -#define QLIST_HEAD_INITIALIZER(head) \ - { NULL } - -#define QLIST_ENTRY(type) \ -struct { \ - struct type *le_next; /* next element */ \ - struct type **le_prev; /* address of previous next element */ \ -} - -/* - * List functions. - */ -#define QLIST_INIT(head) do { \ - (head)->lh_first = NULL; \ -} while (/*CONSTCOND*/0) - -#define QLIST_SWAP(dstlist, srclist, field) do { \ - void *tmplist; \ - tmplist = (srclist)->lh_first; \ - (srclist)->lh_first = (dstlist)->lh_first; \ - if ((srclist)->lh_first != NULL) { \ - (srclist)->lh_first->field.le_prev = &(srclist)->lh_first; \ - } \ - (dstlist)->lh_first = tmplist; \ - if ((dstlist)->lh_first != NULL) { \ - (dstlist)->lh_first->field.le_prev = &(dstlist)->lh_first; \ - } \ -} while (/*CONSTCOND*/0) - -#define QLIST_INSERT_AFTER(listelm, elm, field) do { \ - if (((elm)->field.le_next = (listelm)->field.le_next) != NULL) \ - (listelm)->field.le_next->field.le_prev = \ - &(elm)->field.le_next; \ - (listelm)->field.le_next = (elm); \ - (elm)->field.le_prev = &(listelm)->field.le_next; \ -} while (/*CONSTCOND*/0) - -#define QLIST_INSERT_BEFORE(listelm, elm, field) do { \ - (elm)->field.le_prev = (listelm)->field.le_prev; \ - (elm)->field.le_next = (listelm); \ - *(listelm)->field.le_prev = (elm); \ - (listelm)->field.le_prev = &(elm)->field.le_next; \ -} while (/*CONSTCOND*/0) - -#define QLIST_INSERT_HEAD(head, elm, field) do { \ - if (((elm)->field.le_next = (head)->lh_first) != NULL) \ - (head)->lh_first->field.le_prev = &(elm)->field.le_next;\ - (head)->lh_first = (elm); \ - (elm)->field.le_prev = &(head)->lh_first; \ -} while (/*CONSTCOND*/0) - -#define QLIST_REMOVE(elm, field) do { \ - if ((elm)->field.le_next != NULL) \ - (elm)->field.le_next->field.le_prev = \ - (elm)->field.le_prev; \ - *(elm)->field.le_prev = (elm)->field.le_next; \ -} while (/*CONSTCOND*/0) - -#define QLIST_FOREACH(var, head, field) \ - for ((var) = ((head)->lh_first); \ - (var); \ - (var) = ((var)->field.le_next)) - -#define QLIST_FOREACH_SAFE(var, head, field, next_var) \ - for ((var) = ((head)->lh_first); \ - (var) && ((next_var) = ((var)->field.le_next), 1); \ - (var) = (next_var)) - -/* - * List access methods. - */ -#define QLIST_EMPTY(head) ((head)->lh_first == NULL) -#define QLIST_FIRST(head) ((head)->lh_first) -#define QLIST_NEXT(elm, field) ((elm)->field.le_next) - - -/* - * Singly-linked List definitions. - */ -#define QSLIST_HEAD(name, type) \ -struct name { \ - struct type *slh_first; /* first element */ \ -} - -#define QSLIST_HEAD_INITIALIZER(head) \ - { NULL } - -#define QSLIST_ENTRY(type) \ -struct { \ - struct type *sle_next; /* next element */ \ -} - -/* - * Singly-linked List functions. - */ -#define QSLIST_INIT(head) do { \ - (head)->slh_first = NULL; \ -} while (/*CONSTCOND*/0) - -#define QSLIST_INSERT_AFTER(slistelm, elm, field) do { \ - (elm)->field.sle_next = (slistelm)->field.sle_next; \ - (slistelm)->field.sle_next = (elm); \ -} while (/*CONSTCOND*/0) - -#define QSLIST_INSERT_HEAD(head, elm, field) do { \ - (elm)->field.sle_next = (head)->slh_first; \ - (head)->slh_first = (elm); \ -} while (/*CONSTCOND*/0) - -#define QSLIST_INSERT_HEAD_ATOMIC(head, elm, field) do { \ - typeof(elm) save_sle_next; \ - do { \ - save_sle_next = (elm)->field.sle_next = (head)->slh_first; \ - } while (atomic_cmpxchg(&(head)->slh_first, save_sle_next, (elm)) != \ - save_sle_next); \ -} while (/*CONSTCOND*/0) - -#define QSLIST_MOVE_ATOMIC(dest, src) do { \ - (dest)->slh_first = atomic_xchg(&(src)->slh_first, NULL); \ -} while (/*CONSTCOND*/0) - -#define QSLIST_REMOVE_HEAD(head, field) do { \ - (head)->slh_first = (head)->slh_first->field.sle_next; \ -} while (/*CONSTCOND*/0) - -#define QSLIST_REMOVE_AFTER(slistelm, field) do { \ - (slistelm)->field.sle_next = \ - QSLIST_NEXT(QSLIST_NEXT((slistelm), field), field); \ -} while (/*CONSTCOND*/0) - -#define QSLIST_FOREACH(var, head, field) \ - for((var) = (head)->slh_first; (var); (var) = (var)->field.sle_next) - -#define QSLIST_FOREACH_SAFE(var, head, field, tvar) \ - for ((var) = QSLIST_FIRST((head)); \ - (var) && ((tvar) = QSLIST_NEXT((var), field), 1); \ - (var) = (tvar)) - -/* - * Singly-linked List access methods. - */ -#define QSLIST_EMPTY(head) ((head)->slh_first == NULL) -#define QSLIST_FIRST(head) ((head)->slh_first) -#define QSLIST_NEXT(elm, field) ((elm)->field.sle_next) - - -/* - * Simple queue definitions. - */ -#define QSIMPLEQ_HEAD(name, type) \ -struct name { \ - struct type *sqh_first; /* first element */ \ - struct type **sqh_last; /* addr of last next element */ \ -} - -#define QSIMPLEQ_HEAD_INITIALIZER(head) \ - { NULL, &(head).sqh_first } - -#define QSIMPLEQ_ENTRY(type) \ -struct { \ - struct type *sqe_next; /* next element */ \ -} - -/* - * Simple queue functions. - */ -#define QSIMPLEQ_INIT(head) do { \ - (head)->sqh_first = NULL; \ - (head)->sqh_last = &(head)->sqh_first; \ -} while (/*CONSTCOND*/0) - -#define QSIMPLEQ_INSERT_HEAD(head, elm, field) do { \ - if (((elm)->field.sqe_next = (head)->sqh_first) == NULL) \ - (head)->sqh_last = &(elm)->field.sqe_next; \ - (head)->sqh_first = (elm); \ -} while (/*CONSTCOND*/0) - -#define QSIMPLEQ_INSERT_TAIL(head, elm, field) do { \ - (elm)->field.sqe_next = NULL; \ - *(head)->sqh_last = (elm); \ - (head)->sqh_last = &(elm)->field.sqe_next; \ -} while (/*CONSTCOND*/0) - -#define QSIMPLEQ_INSERT_AFTER(head, listelm, elm, field) do { \ - if (((elm)->field.sqe_next = (listelm)->field.sqe_next) == NULL) \ - (head)->sqh_last = &(elm)->field.sqe_next; \ - (listelm)->field.sqe_next = (elm); \ -} while (/*CONSTCOND*/0) - -#define QSIMPLEQ_REMOVE_HEAD(head, field) do { \ - if (((head)->sqh_first = (head)->sqh_first->field.sqe_next) == NULL)\ - (head)->sqh_last = &(head)->sqh_first; \ -} while (/*CONSTCOND*/0) - -#define QSIMPLEQ_SPLIT_AFTER(head, elm, field, removed) do { \ - QSIMPLEQ_INIT(removed); \ - if (((removed)->sqh_first = (head)->sqh_first) != NULL) { \ - if (((head)->sqh_first = (elm)->field.sqe_next) == NULL) { \ - (head)->sqh_last = &(head)->sqh_first; \ - } \ - (removed)->sqh_last = &(elm)->field.sqe_next; \ - (elm)->field.sqe_next = NULL; \ - } \ -} while (/*CONSTCOND*/0) - -#define QSIMPLEQ_REMOVE(head, elm, type, field) do { \ - if ((head)->sqh_first == (elm)) { \ - QSIMPLEQ_REMOVE_HEAD((head), field); \ - } else { \ - struct type *curelm = (head)->sqh_first; \ - while (curelm->field.sqe_next != (elm)) \ - curelm = curelm->field.sqe_next; \ - if ((curelm->field.sqe_next = \ - curelm->field.sqe_next->field.sqe_next) == NULL) \ - (head)->sqh_last = &(curelm)->field.sqe_next; \ - } \ -} while (/*CONSTCOND*/0) - -#define QSIMPLEQ_FOREACH(var, head, field) \ - for ((var) = ((head)->sqh_first); \ - (var); \ - (var) = ((var)->field.sqe_next)) - -#define QSIMPLEQ_FOREACH_SAFE(var, head, field, next) \ - for ((var) = ((head)->sqh_first); \ - (var) && ((next = ((var)->field.sqe_next)), 1); \ - (var) = (next)) - -#define QSIMPLEQ_CONCAT(head1, head2) do { \ - if (!QSIMPLEQ_EMPTY((head2))) { \ - *(head1)->sqh_last = (head2)->sqh_first; \ - (head1)->sqh_last = (head2)->sqh_last; \ - QSIMPLEQ_INIT((head2)); \ - } \ -} while (/*CONSTCOND*/0) - -#define QSIMPLEQ_LAST(head, type, field) \ - (QSIMPLEQ_EMPTY((head)) ? \ - NULL : \ - ((struct type *)(void *) \ - ((char *)((head)->sqh_last) - offsetof(struct type, field)))) - -/* - * Simple queue access methods. - */ -#define QSIMPLEQ_EMPTY(head) ((head)->sqh_first == NULL) -#define QSIMPLEQ_FIRST(head) ((head)->sqh_first) -#define QSIMPLEQ_NEXT(elm, field) ((elm)->field.sqe_next) - - -/* - * Tail queue definitions. - */ -#define Q_TAILQ_HEAD(name, type, qual) \ -struct name { \ - qual type *tqh_first; /* first element */ \ - qual type *qual *tqh_last; /* addr of last next element */ \ -} -#define QTAILQ_HEAD(name, type) Q_TAILQ_HEAD(name, struct type,) - -#define QTAILQ_HEAD_INITIALIZER(head) \ - { NULL, &(head).tqh_first } - -#define Q_TAILQ_ENTRY(type, qual) \ -struct { \ - qual type *tqe_next; /* next element */ \ - qual type *qual *tqe_prev; /* address of previous next element */\ -} -#define QTAILQ_ENTRY(type) Q_TAILQ_ENTRY(struct type,) - -/* - * Tail queue functions. - */ -#define QTAILQ_INIT(head) do { \ - (head)->tqh_first = NULL; \ - (head)->tqh_last = &(head)->tqh_first; \ -} while (/*CONSTCOND*/0) - -#define QTAILQ_INSERT_HEAD(head, elm, field) do { \ - if (((elm)->field.tqe_next = (head)->tqh_first) != NULL) \ - (head)->tqh_first->field.tqe_prev = \ - &(elm)->field.tqe_next; \ - else \ - (head)->tqh_last = &(elm)->field.tqe_next; \ - (head)->tqh_first = (elm); \ - (elm)->field.tqe_prev = &(head)->tqh_first; \ -} while (/*CONSTCOND*/0) - -#define QTAILQ_INSERT_TAIL(head, elm, field) do { \ - (elm)->field.tqe_next = NULL; \ - (elm)->field.tqe_prev = (head)->tqh_last; \ - *(head)->tqh_last = (elm); \ - (head)->tqh_last = &(elm)->field.tqe_next; \ -} while (/*CONSTCOND*/0) - -#define QTAILQ_INSERT_AFTER(head, listelm, elm, field) do { \ - if (((elm)->field.tqe_next = (listelm)->field.tqe_next) != NULL)\ - (elm)->field.tqe_next->field.tqe_prev = \ - &(elm)->field.tqe_next; \ - else \ - (head)->tqh_last = &(elm)->field.tqe_next; \ - (listelm)->field.tqe_next = (elm); \ - (elm)->field.tqe_prev = &(listelm)->field.tqe_next; \ -} while (/*CONSTCOND*/0) - -#define QTAILQ_INSERT_BEFORE(listelm, elm, field) do { \ - (elm)->field.tqe_prev = (listelm)->field.tqe_prev; \ - (elm)->field.tqe_next = (listelm); \ - *(listelm)->field.tqe_prev = (elm); \ - (listelm)->field.tqe_prev = &(elm)->field.tqe_next; \ -} while (/*CONSTCOND*/0) - -#define QTAILQ_REMOVE(head, elm, field) do { \ - if (((elm)->field.tqe_next) != NULL) \ - (elm)->field.tqe_next->field.tqe_prev = \ - (elm)->field.tqe_prev; \ - else \ - (head)->tqh_last = (elm)->field.tqe_prev; \ - *(elm)->field.tqe_prev = (elm)->field.tqe_next; \ -} while (/*CONSTCOND*/0) - -#define QTAILQ_FOREACH(var, head, field) \ - for ((var) = ((head)->tqh_first); \ - (var); \ - (var) = ((var)->field.tqe_next)) - -#define QTAILQ_FOREACH_SAFE(var, head, field, next_var) \ - for ((var) = ((head)->tqh_first); \ - (var) && ((next_var) = ((var)->field.tqe_next), 1); \ - (var) = (next_var)) - -#define QTAILQ_FOREACH_REVERSE(var, head, headname, field) \ - for ((var) = (*(((struct headname *)((head)->tqh_last))->tqh_last)); \ - (var); \ - (var) = (*(((struct headname *)((var)->field.tqe_prev))->tqh_last))) - -/* - * Tail queue access methods. - */ -#define QTAILQ_EMPTY(head) ((head)->tqh_first == NULL) -#define QTAILQ_FIRST(head) ((head)->tqh_first) -#define QTAILQ_NEXT(elm, field) ((elm)->field.tqe_next) - -#define QTAILQ_LAST(head, headname) \ - (*(((struct headname *)((head)->tqh_last))->tqh_last)) -#define QTAILQ_PREV(elm, headname, field) \ - (*(((struct headname *)((elm)->field.tqe_prev))->tqh_last)) - -#endif /* QEMU_SYS_QUEUE_H */ diff --git a/src/devices/scsi/scsi_aha154x.c b/src/devices/scsi/scsi_aha154x.c index 9347f93..e6cde6c 100644 --- a/src/devices/scsi/scsi_aha154x.c +++ b/src/devices/scsi/scsi_aha154x.c @@ -10,7 +10,7 @@ * made by Adaptec, Inc. These controllers were designed for * the ISA bus. * - * Version: @(#)scsi_aha154x.c 1.0.13 2019/04/11 + * Version: @(#)scsi_aha154x.c 1.0.14 2019/04/24 * * Based on original code from TheCollector1995 and Miran Grca. * @@ -359,7 +359,8 @@ aha_cmds(void *priv) * and expects a 0x04 back in the INTR * register. --FvK */ - dev->Interrupt = shram_cmd(dev, dev->CmdBuf[0]); + if (dev->rom_shramsz > 0) + dev->Interrupt = shram_cmd(dev, dev->CmdBuf[0]); break; case CMD_BIOS_MBINIT: /* BIOS Mailbox Initialization */ @@ -782,8 +783,6 @@ aha_init(const device_t *info, UNUSED(void *parent)) } dev->fw_rev = "A005"; /* The 3.2 microcode says A012. */ dev->HostID = device_get_config_int("hostid"); - dev->rom_shram = 0x3f80; /* shadow RAM address base */ - dev->rom_shramsz = 128; /* size of shadow RAM */ dev->ha_bps = 5000000.0; /* normal SCSI */ break; diff --git a/src/devices/scsi/scsi_disk.c b/src/devices/scsi/scsi_disk.c index 124685a..4c3b2ca 100644 --- a/src/devices/scsi/scsi_disk.c +++ b/src/devices/scsi/scsi_disk.c @@ -8,6 +8,10 @@ * * Emulation of SCSI fixed disks. * + * **NOTE** Some weirdness is still going on with the sense_read code; + * until this is fixed, we return the actual device properties, + * and keep the sense data unmodifyable. + * * Version: @(#)scsi_disk.c 1.0.23 2019/04/23 * * Authors: Fred N. van Kempen, @@ -274,6 +278,8 @@ mode_sense_read(scsi_disk_t *dev, uint8_t page_control, uint8_t page, uint8_t po { uint8_t ret = 0x00; +INFO("SCSI disk%i sense_read(%i, %i, %i)\n", dev->id, page_control, page, pos); + #if 1 if (page_control == 1) return mode_sense_pages_changeable.pages[page][pos]; @@ -298,19 +304,23 @@ mode_sense_read(scsi_disk_t *dev, uint8_t page_control, uint8_t page, uint8_t po case 2: case 6: case 9: +INFO("SCSI: sense returning %i cyls (%02x)\n", dev->drv->tracks, (dev->drv->tracks >> 16) & 0xff); return (dev->drv->tracks >> 16) & 0xff; case 3: case 7: case 10: +INFO("SCSI: sense returning %i cyls (%02x)\n", dev->drv->tracks, (dev->drv->tracks >> 8) & 0xff); return (dev->drv->tracks >> 8) & 0xff; case 4: case 8: case 11: +INFO("SCSI: sense returning %i cyls (%02x)\n", dev->drv->tracks, dev->drv->tracks & 0xff); return dev->drv->tracks & 0xff; case 5: +INFO("SCSI: sense returning %i heads\n", dev->drv->hpc); return dev->drv->hpc & 0xff; } #else @@ -331,10 +341,12 @@ mode_sense_read(scsi_disk_t *dev, uint8_t page_control, uint8_t page, uint8_t po return mode_sense_pages_default.pages[page][pos]; case 10: - return (dev->drv->spt >> 8) & 0xff; +INFO("SCSI: sense returning %i spt (%02x)\n", (dev->drv->spt + 1), ((dev->drv->spt + 1) >> 8) & 0xff); + return ((dev->drv->spt + 1) >> 8) & 0xff; case 11: - return dev->drv->spt & 0xff; +INFO("SCSI: sense returning %i spt (%02x)\n", (dev->drv->spt + 1), (dev->drv->spt + 1) & 0xff); + return (dev->drv->spt + 1) & 0xff; } break; } else switch (page_control) { diff --git a/src/devices/scsi/scsi_x54x.c b/src/devices/scsi/scsi_x54x.c index bd3a377..9939837 100644 --- a/src/devices/scsi/scsi_x54x.c +++ b/src/devices/scsi/scsi_x54x.c @@ -12,13 +12,13 @@ * * These controllers were designed for various buses. * - * Version: @(#)scsi_x54x.c 1.0.15 2018/10/16 + * Version: @(#)scsi_x54x.c 1.0.16 2019/04/24 * * Authors: Fred N. van Kempen, * Miran Grca, * TheCollector1995, * - * Copyright 2017,2018 Fred N. van Kempen. + * Copyright 2017-2019 Fred N. van Kempen. * Copyright 2016-2018 Miran Grca. * * This program is free software; you can redistribute it and/or modify @@ -509,10 +509,6 @@ x54x_bios_command(x54x_t *x54x, uint8_t max_id, BIOSCMD *cmd, int8_t islba) ret = !!ret; break; - default: - DEBUG("BIOS: Unimplemented command: %02X\n", cmd->command); - /*FALLTHROUGH*/ - case 0x05: /* Format Track, invalid since SCSI has no tracks */ case 0x0a: /* ???? */ case 0x0b: /* ???? */ @@ -529,7 +525,7 @@ x54x_bios_command(x54x_t *x54x, uint8_t max_id, BIOSCMD *cmd, int8_t islba) case 0x0f: /* Write Sector Buffer */ case 0x14: /* Controller Diagnostic */ //FIXME: add a longer delay here --FvK - ret = 0x80; + ret = 0x00; break; case 0x07: /* Format Unit */ @@ -567,6 +563,10 @@ x54x_bios_command(x54x_t *x54x, uint8_t max_id, BIOSCMD *cmd, int8_t islba) } break; + + default: + DEBUG("BIOS: Unimplemented command: %02X\n", cmd->command); + return(0x01); } DEBUG("BIOS Request %02X complete: %02X\n", cmd->command, ret);