summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog63
-rw-r--r--Makefile.in10
-rw-r--r--i386/bogus/aha.h1
-rw-r--r--i386/bogus/asc.h1
-rw-r--r--i386/bogus/eaha.h1
-rw-r--r--i386/bogus/sbic.h1
-rw-r--r--i386/bogus/sci.h1
-rw-r--r--i386/bogus/sii.h1
-rw-r--r--i386/bogus/siop.h1
-rw-r--r--i386/i386at/autoconf.c143
-rw-r--r--i386/i386at/conf.c35
-rw-r--r--i386/i386at/eisa.h110
-rw-r--r--scsi/adapters/README290
-rw-r--r--scsi/adapters/scsi_33C93.h396
-rw-r--r--scsi/adapters/scsi_33C93_hdw.c2078
-rw-r--r--scsi/adapters/scsi_5380.h126
-rw-r--r--scsi/adapters/scsi_5380_hdw.c2423
-rw-r--r--scsi/adapters/scsi_53C700.h327
-rw-r--r--scsi/adapters/scsi_53C700_hdw.c696
-rw-r--r--scsi/adapters/scsi_53C94.h253
-rw-r--r--scsi/adapters/scsi_53C94_hdw.c2840
-rw-r--r--scsi/adapters/scsi_7061.h230
-rw-r--r--scsi/adapters/scsi_7061_hdw.c2603
-rw-r--r--scsi/adapters/scsi_89352.h231
-rw-r--r--scsi/adapters/scsi_89352_hdw.c2192
-rw-r--r--scsi/adapters/scsi_aha15.h347
-rw-r--r--scsi/adapters/scsi_aha15_hdw.c1467
-rw-r--r--scsi/adapters/scsi_aha17_hdw.c1371
-rw-r--r--scsi/adapters/scsi_dma.h150
-rw-r--r--scsi/adapters/scsi_user_dma.c171
-rw-r--r--scsi/adapters/scsi_user_dma.h47
-rw-r--r--scsi/compat_30.h163
-rw-r--r--scsi/disk_label.c692
-rw-r--r--scsi/mapped_scsi.c586
-rw-r--r--scsi/mapped_scsi.h90
-rw-r--r--scsi/pc_scsi_label.c196
-rw-r--r--scsi/rz.c462
-rw-r--r--scsi/rz.h60
-rw-r--r--scsi/rz_audio.c1901
-rw-r--r--scsi/rz_cpu.c450
-rw-r--r--scsi/rz_disk.c1222
-rw-r--r--scsi/rz_disk_bbr.c259
-rw-r--r--scsi/rz_host.c108
-rw-r--r--scsi/rz_labels.h243
-rw-r--r--scsi/rz_tape.c560
-rw-r--r--scsi/scsi.c642
-rw-r--r--scsi/scsi.h599
-rw-r--r--scsi/scsi2.h447
-rw-r--r--scsi/scsi_alldevs.c858
-rw-r--r--scsi/scsi_comm.c115
-rw-r--r--scsi/scsi_cpu.c109
-rw-r--r--scsi/scsi_defs.h284
-rw-r--r--scsi/scsi_disk.c624
-rw-r--r--scsi/scsi_endian.h66
-rw-r--r--scsi/scsi_jukebox.c57
-rw-r--r--scsi/scsi_optical.c57
-rw-r--r--scsi/scsi_printer.c57
-rw-r--r--scsi/scsi_rom.c401
-rw-r--r--scsi/scsi_scanner.c54
-rw-r--r--scsi/scsi_tape.c415
-rw-r--r--scsi/scsi_worm.c51
61 files changed, 63 insertions, 30371 deletions
diff --git a/ChangeLog b/ChangeLog
index 8c3c01b..e8fa71d 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -4,6 +4,69 @@
`DEVELOPMENT' for details. Partly based on suggestions by
Gianluca Guida <glguida@gmail.com>.
+ * i386/bogus/asc.h: Remove file.
+ * i386/bogus/aha.h: Likewise.
+ * i386/bogus/eaha.h: Likewise.
+ * i386/bogus/sbic.h: Likewise.
+ * i386/bogus/sci.h: Likewise.
+ * i386/bogus/sii.h: Likewise.
+ * i386/bogus/siop.h: Likewise.
+ * i386/i386at/eisa.h: Likewise.
+ * scsi/adapters/README: Likewise.
+ * scsi/adapters/scsi_33C93.h: Likewise.
+ * scsi/adapters/scsi_33C93_hdw.c: Likewise.
+ * scsi/adapters/scsi_5380.h: Likewise.
+ * scsi/adapters/scsi_5380_hdw.c: Likewise.
+ * scsi/adapters/scsi_53C700.h: Likewise.
+ * scsi/adapters/scsi_53C700_hdw.c: Likewise.
+ * scsi/adapters/scsi_53C94.h: Likewise.
+ * scsi/adapters/scsi_53C94_hdw.c: Likewise.
+ * scsi/adapters/scsi_7061.h: Likewise.
+ * scsi/adapters/scsi_7061_hdw.c: Likewise.
+ * scsi/adapters/scsi_89352.h: Likewise.
+ * scsi/adapters/scsi_89352_hdw.c: Likewise.
+ * scsi/adapters/scsi_aha15.h: Likewise.
+ * scsi/adapters/scsi_aha15_hdw.c: Likewise.
+ * scsi/adapters/scsi_aha17_hdw.c: Likewise.
+ * scsi/adapters/scsi_dma.h: Likewise.
+ * scsi/adapters/scsi_user_dma.c: Likewise.
+ * scsi/adapters/scsi_user_dma.h: Likewise.
+ * scsi/compat_30.h: Likewise.
+ * scsi/disk_label.c: Likewise.
+ * scsi/mapped_scsi.c: Likewise.
+ * scsi/mapped_scsi.h: Likewise.
+ * scsi/pc_scsi_label.c: Likewise.
+ * scsi/rz.c: Likewise.
+ * scsi/rz.h: Likewise.
+ * scsi/rz_audio.c: Likewise.
+ * scsi/rz_cpu.c: Likewise.
+ * scsi/rz_disk.c: Likewise.
+ * scsi/rz_disk_bbr.c: Likewise.
+ * scsi/rz_host.c: Likewise.
+ * scsi/rz_labels.h: Likewise.
+ * scsi/rz_tape.c: Likewise.
+ * scsi/scsi.c: Likewise.
+ * scsi/scsi.h: Likewise.
+ * scsi/scsi2.h: Likewise.
+ * scsi/scsi_alldevs.c: Likewise.
+ * scsi/scsi_comm.c: Likewise.
+ * scsi/scsi_cpu.c: Likewise.
+ * scsi/scsi_defs.h: Likewise.
+ * scsi/scsi_disk.c: Likewise.
+ * scsi/scsi_endian.h: Likewise.
+ * scsi/scsi_jukebox.c: Likewise.
+ * scsi/scsi_optical.c: Likewise.
+ * scsi/scsi_printer.c: Likewise.
+ * scsi/scsi_rom.c: Likewise.
+ * scsi/scsi_scanner.c: Likewise.
+ * scsi/scsi_tape.c: Likewise.
+ * scsi/scsi_worm.c: Likewise.
+ * i386/i386at/autoconf.c: Don't include <aha.h> and <eaha.h> anymore
+ and adopt all users of NAHA and NEAHA as if it were always defined to
+ `0'.
+ * i386/i386at/conf.c: Likewise.
+ * Makefile.in (scsi-files): Remove variable and all users of it.
+
* i386/bogus/wt.h: Remove file.
* i386/i386at/autoconf.c: Don't include <wt.h> anymore and adopt all
users of NWT as if it were always defined to `0'.
diff --git a/Makefile.in b/Makefile.in
index 89c5ad6..bdf4a73 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -99,15 +99,6 @@ chips-files = atm.c audio.c bt431.c bt455.c bt459.c build_font.c busses.c \
screen_switch.h serial_defs.h spans.h tca100.h tca100_if.h \
vs42x_rb.h xcfb_monitor.h
-# Generic code for various SCSI unit types
-scsi-files = disk_label.c mapped_scsi.c pc_scsi_label.c rz.c rz_audio.c \
- rz_cpu.c rz_disk.c rz_disk_bbr.c rz_host.c rz_tape.c scsi.c \
- scsi_alldevs.c scsi_comm.c scsi_cpu.c scsi_disk.c scsi_jukebox.c \
- scsi_optical.c scsi_printer.c scsi_rom.c scsi_scanner.c \
- scsi_tape.c scsi_worm.c \
- compat_30.h mapped_scsi.h rz.h rz_labels.h scsi.h scsi2.h \
- scsi_defs.h scsi_endian.h
-
# Icky kernel debugger
ddb-cfiles = $(addprefix db_,$(ddb-names))
ddb-names = access.c aout.c break.c command.c cond.c examine.c expr.c \
@@ -369,7 +360,6 @@ dist:
cp $(addprefix $(srcdir)/device/,$(device-files)) gnumach-$(version)/device
cp $(addprefix $(srcdir)/ipc/,$(ipc-files)) gnumach-$(version)/ipc
cp $(addprefix $(srcdir)/kern/,$(kern-files)) gnumach-$(version)/kern
- cp $(addprefix $(srcdir)/scsi/,$(scsi-files)) gnumach-$(version)/scsi
cp $(addprefix $(srcdir)/util/,$(util-files)) gnumach-$(version)/util
cp $(addprefix $(srcdir)/vm/,$(vm-files)) gnumach-$(version)/vm
cp $(addprefix $(srcdir)/include/,$(mach-headers)) gnumach-$(version)/include/mach
diff --git a/i386/bogus/aha.h b/i386/bogus/aha.h
deleted file mode 100644
index 370fd1a..0000000
--- a/i386/bogus/aha.h
+++ /dev/null
@@ -1 +0,0 @@
-#define NAHA 1
diff --git a/i386/bogus/asc.h b/i386/bogus/asc.h
deleted file mode 100644
index fcfb5ad..0000000
--- a/i386/bogus/asc.h
+++ /dev/null
@@ -1 +0,0 @@
-#define NASC 0
diff --git a/i386/bogus/eaha.h b/i386/bogus/eaha.h
deleted file mode 100644
index c79f7ad..0000000
--- a/i386/bogus/eaha.h
+++ /dev/null
@@ -1 +0,0 @@
-#define NEAHA 1
diff --git a/i386/bogus/sbic.h b/i386/bogus/sbic.h
deleted file mode 100644
index a0f322c..0000000
--- a/i386/bogus/sbic.h
+++ /dev/null
@@ -1 +0,0 @@
-#define NSBIC 0
diff --git a/i386/bogus/sci.h b/i386/bogus/sci.h
deleted file mode 100644
index 3eb2542..0000000
--- a/i386/bogus/sci.h
+++ /dev/null
@@ -1 +0,0 @@
-#define NSCI 0
diff --git a/i386/bogus/sii.h b/i386/bogus/sii.h
deleted file mode 100644
index 3a914f5..0000000
--- a/i386/bogus/sii.h
+++ /dev/null
@@ -1 +0,0 @@
-#define NSII 0
diff --git a/i386/bogus/siop.h b/i386/bogus/siop.h
deleted file mode 100644
index bffff9d..0000000
--- a/i386/bogus/siop.h
+++ /dev/null
@@ -1 +0,0 @@
-#define NSIOP 0
diff --git a/i386/i386at/autoconf.c b/i386/i386at/autoconf.c
index b8771e8..51f2a0a 100644
--- a/i386/i386at/autoconf.c
+++ b/i386/i386at/autoconf.c
@@ -47,18 +47,6 @@
#define SPL_TTY (vm_offset_t)SPLTTY
-#include <aha.h>
-#if NAHA > 0
-extern struct bus_driver aha_driver;
-extern int aha_intr();
-#endif /* NAHA */
-
-#include <eaha.h>
-#if NEAHA > 0
-extern struct bus_driver eaha_driver;
-extern int eaha_intr();
-#endif /* NEAHA */
-
#include <com.h>
#if NCOM > 0
extern struct bus_driver comdriver;
@@ -76,74 +64,6 @@ struct bus_ctlr bus_master_init[] = {
/* driver name unit intr address len phys_address
adaptor alive flags spl pic */
-#ifndef LINUX_DEV
-#if NAHA > 0
- {&aha_driver, "ahac", 0, aha_intr, 0x330, 4, 0x330,
- '?', 0, 0, SPL_FIVE, 11},
-
-#if NAHA > 1
-
- {&aha_driver, "ahac", 1, aha_intr, 0x234, 4, 0x234,
- '?', 0, 0, SPL_FIVE, 12},
- {&aha_driver, "ahac", 1, aha_intr, 0x230, 4, 0x230,
- '?', 0, 0, SPL_FIVE, 12},
- {&aha_driver, "ahac", 1, aha_intr, 0x134, 4, 0x134,
- '?', 0, 0, SPL_FIVE, 12},
- {&aha_driver, "ahac", 1, aha_intr, 0x130, 4, 0x130,
- '?', 0, 0, SPL_FIVE, 12},
-
-#else
-
- {&aha_driver, "ahac", 0, aha_intr, 0x334, 4, 0x334,
- '?', 0, 0, SPL_FIVE, 11},
- {&aha_driver, "ahac", 0, aha_intr, 0x234, 4, 0x234,
- '?', 0, 0, SPL_FIVE, 11},
- {&aha_driver, "ahac", 0, aha_intr, 0x230, 4, 0x230,
- '?', 0, 0, SPL_FIVE, 11},
- {&aha_driver, "ahac", 0, aha_intr, 0x134, 4, 0x134,
- '?', 0, 0, SPL_FIVE, 11},
- {&aha_driver, "ahac", 0, aha_intr, 0x130, 4, 0x130,
- '?', 0, 0, SPL_FIVE, 11},
-
-#endif /* NAHA > 1 */
-#endif /* NAHA > 0*/
-
-#if NEAHA > 0
-{&eaha_driver, "eahac", 0, eaha_intr, 0x0000, 4, 0x0000,
- '?', 0, 0, SPL_FIVE, 12},
-{&eaha_driver, "eahac", 0, eaha_intr, 0x1000, 4, 0x1000,
- '?', 0, 0, SPL_FIVE, 12},
-{&eaha_driver, "eahac", 0, eaha_intr, 0x2000, 4, 0x2000,
- '?', 0, 0, SPL_FIVE, 12},
-{&eaha_driver, "eahac", 0, eaha_intr, 0x3000, 4, 0x3000,
- '?', 0, 0, SPL_FIVE, 12},
-{&eaha_driver, "eahac", 0, eaha_intr, 0x4000, 4, 0x4000,
- '?', 0, 0, SPL_FIVE, 12},
-{&eaha_driver, "eahac", 0, eaha_intr, 0x5000, 4, 0x5000,
- '?', 0, 0, SPL_FIVE, 12},
-{&eaha_driver, "eahac", 0, eaha_intr, 0x6000, 4, 0x6000,
- '?', 0, 0, SPL_FIVE, 12},
-{&eaha_driver, "eahac", 0, eaha_intr, 0x7000, 4, 0x7000,
- '?', 0, 0, SPL_FIVE, 12},
-{&eaha_driver, "eahac", 0, eaha_intr, 0x8000, 4, 0x8000,
- '?', 0, 0, SPL_FIVE, 12},
-{&eaha_driver, "eahac", 0, eaha_intr, 0x9000, 4, 0x9000,
- '?', 0, 0, SPL_FIVE, 12},
-{&eaha_driver, "eahac", 0, eaha_intr, 0xa000, 4, 0xa000,
- '?', 0, 0, SPL_FIVE, 12},
-{&eaha_driver, "eahac", 0, eaha_intr, 0xb000, 4, 0xb000,
- '?', 0, 0, SPL_FIVE, 12},
-{&eaha_driver, "eahac", 0, eaha_intr, 0xc000, 4, 0xc000,
- '?', 0, 0, SPL_FIVE, 12},
-{&eaha_driver, "eahac", 0, eaha_intr, 0xd000, 4, 0xd000,
- '?', 0, 0, SPL_FIVE, 12},
-{&eaha_driver, "eahac", 0, eaha_intr, 0xe000, 4, 0xe000,
- '?', 0, 0, SPL_FIVE, 12},
-{&eaha_driver, "eahac", 0, eaha_intr, 0xf000, 4, 0xf000,
- '?', 0, 0, SPL_FIVE, 12},
-#endif /* NEAHA > 0 */
-#endif /* ! LINUX_DEV */
-
0
};
@@ -153,69 +73,6 @@ struct bus_device bus_device_init[] = {
/* driver name unit intr address am phys_address
adaptor alive ctlr slave flags *mi *next sysdep sysdep */
-#ifndef LINUX_DEV
-#if NAHA > 0
-{ &aha_driver, "rz", 0, 0, 0x0,0, 0, '?', 0, 0, 0, 0, },
-{ &aha_driver, "rz", 1, 0, 0x0,0, 0, '?', 0, 0, 1, 0, },
-{ &aha_driver, "rz", 2, 0, 0x0,0, 0, '?', 0, 0, 2, 0, },
-{ &aha_driver, "rz", 3, 0, 0x0,0, 0, '?', 0, 0, 3, 0, },
-{ &aha_driver, "rz", 4, 0, 0x0,0, 0, '?', 0, 0, 4, 0, },
-{ &aha_driver, "rz", 5, 0, 0x0,0, 0, '?', 0, 0, 5, 0, },
-{ &aha_driver, "rz", 6, 0, 0x0,0, 0, '?', 0, 0, 6, 0, },
-{ &aha_driver, "rz", 7, 0, 0x0,0, 0, '?', 0, 0, 7, 0, },
-
-{ &aha_driver, "tz", 0, 0, 0x0,0, 0, '?', 0, 0, 0, 0, },
-{ &aha_driver, "tz", 1, 0, 0x0,0, 0, '?', 0, 0, 1, 0, },
-{ &aha_driver, "tz", 2, 0, 0x0,0, 0, '?', 0, 0, 2, 0, },
-{ &aha_driver, "tz", 3, 0, 0x0,0, 0, '?', 0, 0, 3, 0, },
-{ &aha_driver, "tz", 4, 0, 0x0,0, 0, '?', 0, 0, 4, 0, },
-{ &aha_driver, "tz", 5, 0, 0x0,0, 0, '?', 0, 0, 5, 0, },
-{ &aha_driver, "tz", 6, 0, 0x0,0, 0, '?', 0, 0, 6, 0, },
-{ &aha_driver, "tz", 7, 0, 0x0,0, 0, '?', 0, 0, 7, 0, },
-
-#if NAHA > 1
-
-{ &aha_driver, "rz", 8, 0, 0x0,0, 0, '?', 0, 1, 0, 0, },
-{ &aha_driver, "rz", 9, 0, 0x0,0, 0, '?', 0, 1, 1, 0, },
-{ &aha_driver, "rz", 10, 0, 0x0,0, 0, '?', 0, 1, 2, 0, },
-{ &aha_driver, "rz", 11, 0, 0x0,0, 0, '?', 0, 1, 3, 0, },
-{ &aha_driver, "rz", 12, 0, 0x0,0, 0, '?', 0, 1, 4, 0, },
-{ &aha_driver, "rz", 13, 0, 0x0,0, 0, '?', 0, 1, 5, 0, },
-{ &aha_driver, "rz", 14, 0, 0x0,0, 0, '?', 0, 1, 6, 0, },
-{ &aha_driver, "rz", 15, 0, 0x0,0, 0, '?', 0, 1, 7, 0, },
-
-{ &aha_driver, "tz", 8, 0, 0x0,0, 0, '?', 0, 1, 0, 0, },
-{ &aha_driver, "tz", 9, 0, 0x0,0, 0, '?', 0, 1, 1, 0, },
-{ &aha_driver, "tz", 10, 0, 0x0,0, 0, '?', 0, 1, 2, 0, },
-{ &aha_driver, "tz", 11, 0, 0x0,0, 0, '?', 0, 1, 3, 0, },
-{ &aha_driver, "tz", 12, 0, 0x0,0, 0, '?', 0, 1, 4, 0, },
-{ &aha_driver, "tz", 13, 0, 0x0,0, 0, '?', 0, 1, 5, 0, },
-{ &aha_driver, "tz", 14, 0, 0x0,0, 0, '?', 0, 1, 6, 0, },
-{ &aha_driver, "tz", 15, 0, 0x0,0, 0, '?', 0, 1, 7, 0, },
-#endif /* NAHA > 1 */
-#endif /* NAHA > 0 */
-
-#if NEAHA > 0
-{ &eaha_driver, "rz", 0, 0, 0x0,0, 0, '?', 0, 0, 0, 0, },
-{ &eaha_driver, "rz", 1, 0, 0x0,0, 0, '?', 0, 0, 1, 0, },
-{ &eaha_driver, "rz", 2, 0, 0x0,0, 0, '?', 0, 0, 2, 0, },
-{ &eaha_driver, "rz", 3, 0, 0x0,0, 0, '?', 0, 0, 3, 0, },
-{ &eaha_driver, "rz", 4, 0, 0x0,0, 0, '?', 0, 0, 4, 0, },
-{ &eaha_driver, "rz", 5, 0, 0x0,0, 0, '?', 0, 0, 5, 0, },
-{ &eaha_driver, "rz", 6, 0, 0x0,0, 0, '?', 0, 0, 6, 0, },
-{ &eaha_driver, "rz", 7, 0, 0x0,0, 0, '?', 0, 0, 7, 0, },
-
-{ &eaha_driver, "tz", 0, 0, 0x0,0, 0, '?', 0, 0, 0, 0, },
-{ &eaha_driver, "tz", 1, 0, 0x0,0, 0, '?', 0, 0, 1, 0, },
-{ &eaha_driver, "tz", 2, 0, 0x0,0, 0, '?', 0, 0, 2, 0, },
-{ &eaha_driver, "tz", 3, 0, 0x0,0, 0, '?', 0, 0, 3, 0, },
-{ &eaha_driver, "tz", 4, 0, 0x0,0, 0, '?', 0, 0, 4, 0, },
-{ &eaha_driver, "tz", 5, 0, 0x0,0, 0, '?', 0, 0, 5, 0, },
-{ &eaha_driver, "tz", 6, 0, 0x0,0, 0, '?', 0, 0, 6, 0, },
-{ &eaha_driver, "tz", 7, 0, 0x0,0, 0, '?', 0, 0, 7, 0, },
-#endif /* NEAHA > 0*/
-#endif /* ! LINUX_DEV */
-
#if NCOM > 0
{&comdriver, "com", 0, comintr, 0x3f8, 8, 0x3f8,
'?', 0, -1, -1, 0, 0, 0, SPL_TTY, 4},
diff --git a/i386/i386at/conf.c b/i386/i386at/conf.c
index a7d420f..2e62ca0 100644
--- a/i386/i386at/conf.c
+++ b/i386/i386at/conf.c
@@ -36,18 +36,6 @@ extern int timeopen(), timeclose();
extern vm_offset_t timemmap();
#define timename "time"
-#include <aha.h>
-#if NAHA > 0
-int rz_open(), rz_close(), rz_read(), rz_write();
-int rz_get_status(), rz_set_status(), rz_devinfo();
-int cd_open(), cd_close(), cd_read(), cd_write();
-#define rzname "sd"
-#define tzname "st"
-#define scname "sc" /* processors */
-#define cdname "cd_audio" /* CD-ROM DA */
-
-#endif /*NAHA > 0*/
-
#include <par.h>
#if NPAR > 0
extern int paropen(), paroutput(), pargetstat(), parsetstat(),
@@ -134,29 +122,6 @@ struct dev_ops dev_name_list[] =
nodev },
#ifndef LINUX_DEV
-#if NAHA > 0
- { rzname, rz_open, rz_close, rz_read,
- rz_write, rz_get_status, rz_set_status, nomap,
- nodev, nulldev, nulldev, 1024, /* 8 */
- rz_devinfo },
-
- { tzname, rz_open, rz_close, rz_read,
- rz_write, rz_get_status, rz_set_status, nomap,
- nodev, nulldev, nulldev, 8,
- nodev },
-
- { cdname, cd_open, cd_close, cd_read,
- cd_write, nodev, nodev, nomap,
- nodev, nulldev, nulldev, 8,
- nodev },
-
- { scname, rz_open, rz_close, rz_read,
- rz_write, rz_get_status, rz_set_status, nomap,
- nodev, nulldev, nulldev, 8,
- nodev },
-
-#endif /*NAHA > 0*/
-
#if NPAR > 0
{ parname, paropen, nulldev, nulldev,
paroutput, pargetstat, parsetstat, nomap,
diff --git a/i386/i386at/eisa.h b/i386/i386at/eisa.h
deleted file mode 100644
index 33629ca..0000000
--- a/i386/i386at/eisa.h
+++ /dev/null
@@ -1,110 +0,0 @@
-/*
- * Mach Operating System
- * Copyright (c) 1993 Carnegie Mellon University
- * All Rights Reserved.
- *
- * Permission to use, copy, modify and distribute this software and its
- * documentation is hereby granted, provided that both the copyright
- * notice and this permission notice appear in all copies of the
- * software, derivative works or modified versions, and any portions
- * thereof, and that both notices appear in supporting documentation.
- *
- * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
- * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
- * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
- *
- * Carnegie Mellon requests users of this software to return to
- *
- * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
- * School of Computer Science
- * Carnegie Mellon University
- * Pittsburgh PA 15213-3890
- *
- * any improvements or extensions that they make and grant Carnegie Mellon
- * the rights to redistribute these changes.
- */
-/*
- * Copyright 1992 by Open Software Foundation,
- * Grenoble, FRANCE
- *
- * All Rights Reserved
- *
- * Permission to use, copy, modify, and distribute this software and
- * its documentation for any purpose and without fee is hereby granted,
- * provided that the above copyright notice appears in all copies and
- * that both the copyright notice and this permission notice appear in
- * supporting documentation, and that the name of OSF or Open Software
- * Foundation not be used in advertising or publicity pertaining to
- * distribution of the software without specific, written prior
- * permission.
- *
- * OSF DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE
- * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS,
- * IN NO EVENT SHALL OSF BE LIABLE FOR ANY SPECIAL, INDIRECT, OR
- * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
- * LOSS OF USE, DATA OR PROFITS, WHETHER IN ACTION OF CONTRACT,
- * NEGLIGENCE, OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
- * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-/*
- * Eisa defs
- */
-
-#ifndef _I386AT_EISA_H_
-#define _I386AT_EISA_H_
-
-#include <mach/boolean.h>
-
-#if EISA
-extern boolean_t is_eisa_bus;
-
-#define EISA_ID_REG(board, byte) (0xc80 | (byte) | ((board) << 12))
-
-#define EISA_ID_REG_0 0x0
-#define EISA_ID_REG_1 0x1
-#define EISA_ID_REG_2 0x2
-#define EISA_ID_REG_3 0x3
-
-#define EISA_SYSTEM_BOARD 0x0
-
-struct std_board_id {
- unsigned revision: 8, /* Revision number */
- product: 8; /* Product number */
-};
-
-struct sys_board_id {
- unsigned bus_vers: 3, /* EISA bus version */
- reserved: 13; /* Manufacturer reserved */
-};
-
-struct board_id {
- union {
- struct sys_board_id sys_id;
- struct std_board_id std_id;
- } bd_id;
- unsigned name_char_2: 5, /* 3nd compressed char */
- name_char_1: 5, /* 2nd compressed char */
- name_char_0: 5, /* 1st compressed char */
- not_eisa: 1; /* 0 if eisa board */
-};
-
-union eisa_board_id {
- unsigned char byte[4];
- struct board_id id;
-};
-
-typedef union eisa_board_id eisa_board_id_t;
-
-
-/* Additional DMA registers */
-
-#define DMA0HIPAGE 0x481 /* DMA 0 address: bits 24-31 */
-#define DMA0HICNT 0x405 /* DMA 0 count: bits 16-23 */
-
-
-#else /* EISA */
-#define is_eisa_bus FALSE
-#define probe_eisa()
-#endif /* EISA */
-
-#endif /* _I386AT_EISA_H_ */
diff --git a/scsi/adapters/README b/scsi/adapters/README
deleted file mode 100644
index 1bc7e7c..0000000
--- a/scsi/adapters/README
+++ /dev/null
@@ -1,290 +0,0 @@
-
-This directory contains various examples of HBA support code,
-among them:
-
- Chip/Board File Machine tested By
-
- NCR 53C94 scsi_53C94 DecStation 5000 af@cmu
- DEC 7061 scsi_7061 DecStation 3100/2100 af@cmu
- NCR 5380 scsi_5380 VaxStation 3100 af@cmu
- Fujitsu 89352 scsi_89352 Omron Luna88k danner@cmu
- Adaptec 1542B scsi_aha15 AT/PC af@cmu
-
-It should be trivial to modify them for some other machine that uses
-the same SCSI chips, hopefully by properly conditionalizing and macroizing
-the existing code.
-
-There are various rules and assumptions to keep in mind when designing/coding
-the support code for a new HBA, here is a list. Pls extend this with
-anything you find is not openly stated here and made your life miserable
-during the port, and send it back to CMU.
-
-
-AUTOCONF
-
-We assume the structures and procedures defined in chips/busses.*,
-e.g. someone will call configure_bus_master to get to our foo_probe()
-routine. This should make up its mind on how many targets it sees
-[see later for dynamic reconfig], allocate a descriptor for each
-one and leave the driver ready to accept commands (via foo_go()).
-
- On raw chips you should use a test_unit_ready command,
- selecting without ATN, and timing out on non-existant
- devices. Use LUN 0.
- On boards, there probably is a command to let the board do
- it (see Adaptec), if not do as above.
-
-The typical autoconf descriptor might look like
-
- caddr_t foo_std[NFOO] = { 0 };
- struct bus_device *foo_dinfo[NFOO*8];
- struct bus_ctlr *foo_minfo[NFOO];
- struct bus_driver foo_driver =
- { foo_probe, scsi_slave, scsi_attach, foo_go, foo_std, "rz",
- foo_dinfo, "foo", foo_minfo, BUS_INTR_B4_PROBE};
-
-which indicates that foo_probe() and foo_go() are our interface functions,
-and we use the generic scsi_slave() and scsi_attach() for the rest.
-Their definition is
-
- foo_probe(reg, ui)
- vm_offset_t reg;
- struct bus_ctlr *ui;
-
-[the "reg" argument might actually be something else on architectures that
- do not use memory mapped I/O]
-
- aha_go(tgt, cmd_count, in_count, cmd_only)
- target_info_t *tgt;
- boolean_t cmd_only;
-
-The foo_go() routine is fairly common across chips, look at any example to
-see how to structure it. Basically, the arguments tell us how much data
-to expect in either direction, and whether (cmd_only) we think we should
-be selecting with ATN (cmd_only==FALSE) or not. The only gotcha is cmd_count
-actually includes the size of any parameters.
-
-The "go" field of the scsi_softc structure describing your HBA should be
-set to your foo_go() routine, by the foo_probe() routine.
-
-DATA DEPENDENCIES
-
-The upper layer assumes that tgt->cmd_ptr is a pointer to good memory
-[e.g. no funny padding] where it places the scsi command control blocks
-AND small (less than 255 bytes) parameters. It also expects small results
-in there (things like read_capacity, for instance). I think I cleaned
-up all the places that used to assume tgt->cmd_ptr was aligned, but do not
-be surprised if I missed one.
-
-It does NOT use the dma_ptr, or any of the transient_state fields.
-
-WATCHDOG
-
-There is an optional MI watchdog facility, which can be used quite simply by
-filling in the "watchdog" field of the scsi_softc structure describing
-your HBA. To disable it, leave the field zero (or, dynamically, zero the
-timeout value). You can use a watchdog of your own if you like, or more
-likely set this field to point to the MI scsi_watchdog().
-This requires that your foo_softc descriptor starts off with a watchdog_t
-structure, with the "reset" field pointing to a function that will
-reset the SCSI bus should the watchdog expire.
-
-When a new SCSI command is initiated you should
- if (foo->wd.nactive++ == 0)
- foo->wd.watchdog_state = SCSI_WD_ACTIVE;
-to activate the watchdog, on each interrupt [or other signal that all
-is proceeding well for the command and it is making progress] you should
- if (foo->wd.nactive)
- foo->wd.watchdog_state = SCSI_WD_ACTIVE;
-bump down the watchdog 'trigger level', and when the command terminates
- if (aha->wd.nactive-- == 1)
- aha->wd.watchdog_state = SCSI_WD_INACTIVE;
-
-When you detect a SCSI bus reset (possibly we initiated it) you should
- aha->wd.nactive = 0;
-and after cleaning up properly invoke
- scsi_bus_was_reset(sc)
- scsi_softc_t sc;
-
-The functiona that is invoked on watchdog expiry is
- foo_reset_scsibus(foo)
- register foo_softc_t foo;
-
-Note that this can be used for dumb chips that do not support select timeouts
-in hardware [see the 5380 or 7061 code], but its primary use is to detect
-instances where a target is holding on the SCSI bus way too long.
-
-The one drawback of resetting the bus is that some devices (like tapes)
-lose status in case of a reset, and the MI code does not (yet?) try to
-keep enough information around to be able to recover. If you want to
-add something very useful you might change the rz_tape.c code to do just
-that, e.g. on SCSI_RET_ABORTs wait a while for the tape to do whatever,
-then rewind, and seek forward where the tape should have been positioned at
-the beginning of the command that failed, then reissue the command.
-None of the examples so far tries to be 'smart' like making an attempt
-to get the bus unstuck without resetting it, send us ideas if you have
-some.
-
-
-DYNAMIC RECONFIG
-
-Your code should be ready to add/remove targets on the fly. To do so,
-notify the upper layer that a target went offline returning
-SCSI_RET_DEVICE_DOWN when e.g. the select timed out, and clear out
-the tgt->flags field.
-To find new devices, define a function
-
- boolean_t
- foo_probe_target(tgt, ior)
- target_info_t *tgt;
- io_req_t ior;
-
-and install it in the "probe" field of the scsi_softc_t structure describing
-the HBA to the upper layer. This function should finalize all HBA-specific
-info in the target_info structure, then do a scsi_inquiry and check the
-return code. If this is not SCSI_RET_DEVICE_DOWN the target should be
-marked TGT_ALIVE.
-
-
-COMMAND TERMINATION
-
-Generally, command termination should be reported to the upper layers
-by setting the tgt->done field to the proper value [it should remain
-SCSI_RET_IN_PROGRESS while the command is executing] and invoking the
-target's completion routine, like:
- if (tgt->ior) {
- LOG(0xA,"ops->restart");
- (*tgt->dev_ops->restart)( tgt, TRUE);
- }
-Note that early on some commands will actually wait for completion
-by spinning on the tgt->done value, because autoconf happens when
-threads and the scheduler are not working.
-
-Return SCSI_RET_RETRY if the target was busy, the command will be retried
-as appropriate.
-
-Check the completion routines [in rz_disk.c and rz_tape.c for instance]
-if you are not sure what to return in a troubled case.
-
-HBA CHIPS GOTCHAS
-
-All of the examples so far use the idea of 'scripts': the interrupt routine
-matches the chip state with what is expected and if this is ok (it is
-in the common important case) it just calls a prepackaged function.
-We have found this to be _extremely_ simpler than using a state machine
-of various ridiculous and erroneous sorts, and much more handy for debugging
-also. Not to mention the saving on code.
-Nonetheless, there really are no restrictions on how to structure the HBA
-code, if you prefer state machines go ahead and use them!
-
-Scheduling of the bus among competing targets is one of the major missing
-pieces for simple HBAs. A winning strategy used so far is as follows.
-Allocate a queue_head_t of waiting_targets in your foo_softc, and two
-target_info_t pointers next_target and active_target. A three-valued
-state field is also needed. If you enter the foo_go() routine
-and find the state&BUSY simply enqueue_tail() your tgt on the waiting_targets
-queue. Otherwise mark the bus BUSY, set next_target to tgt, and proceed
-to a selection attempt.
-Note that the attempt might fail and a reselection win over it, therefore
-the attempt_selection() routine should just retrieve the next_target
-and install it in active_target, start the selection and let the interrupt
-routine take care of the rest [see scsi_5380 for a different setup].
-If a reselection wins we should note that we had a COLLISION in the state
-field, install the reconecting target and proceed to completion.
-When either a command is complete or a target disconnects you should invoke
-a foo_release_bus() routine, which might look like:
-
-boolean_t
-foo_release_bus(foo)
- register foo_softc_t foo;
-{
- boolean_t ret = TRUE;
-
- LOG(9,"release");
- if (foo->state & FOO_STATE_COLLISION) {
-
- LOG(0xB,"collided");
- foo->state &= ~FOO_STATE_COLLISION;
- foo_attempt_selection(foo);
-
- } else if (queue_empty(&foo->waiting_targets)) {
-
- foo->state &= ~FOO_STATE_BUSY;
- foo->active_target = 0;
- foo->script = 0;
- ret = FALSE;
-
- } else {
-
- LOG(0xC,"dequeue");
- foo->next_target = (target_info_t *)
- dequeue_head(&foo->waiting_targets);
- foo_attempt_selection(foo);
- }
- return ret;
-}
-
-which indicates whether the bus has been handed off to a new target or not.
-This provides the desired FIFO scheduling of the bus and gives maximum
-parallelism when targets are allowed to (and infact do) disconnect.
-
-An area where there are problems most times is how to minimize the
-interaction of selections and reselections in, e.g. foo_attempt_selection().
-This is very much chip specific, but sneaking on the SCSI bus should
-be a viable alternative in most cases. Check in the specs what happens
-if you send a command while there is already a reselection pending:
-a well behaved chip would ignore the command and not screwup its status.
-[Keep in mind that even if _now_ there is no reselection indication
- on the next cycle there might be and you won't see it!]
-
-RANDOM GOTCHAS
-
-A number of workstations do not provide real DMA support [do not ask me why]
-but rather a special 'buffer' more or less wide where you have to copy
-data to and from. This has been handled, see esp the 52C94 code which has
-even the extreme optimization of issuing the send command even before
-the data has been copied into the buffer! We have handled even machines
-where no DMA at all was provided.
-
-Speaking of DMA.. many of these chips 'prefetch' data, or have a FIFO
-on board (they have to if they do synch xfers), and when the target
-disconnects it is always a pain to find out how many bytes exactly did we
-xfer. Be advised that this hurdle exists, and that the best way to
-debug your code here is to use a tape. A safe way is to initially
-disable disconnects [so that you can get the system up from disk]
-and enable them only on the tape unit that you are using for testing.
-Later on enable disks but make sure you have some way to recover from
-a zapped disk !
-
-MOVING TO USER SPACE
-
-All examples have hooks for user-space versions of the driver, the
-ones for 54C94 and 7061 actually do work. Look in mapped_scsi.c
-for how this is done, it is fairly simple as far as the kernel is
-concerned. To keep the option of mapping to user space open you
-should structure your interrupt routine such that it does all the
-state gathering and clearing of the interrupt right away. This
-scheme gives you some assurance that your code will keep on working
-when the interrupt processing is actually delayed and you recover
-the interrupt state from the saved structure in the mapped area.
-
-
-IMPROVEMENTS
-
-There are a variety of things to be done still, for instance:
-
-- rewrite scsi_slave() and scsi_attach() to be fully SCSI-II compliant.
- There are only comments right now as to how that should be done.
-
-- add enough machinery to the tape code to be able to recover from
- bus resets. Do so in such a way that other devices might use the ideas.
-
-- add more devices, like printers scanners modems etc that are currently
- missing
-
-- add a 'generic' set_status flavor which simply executes a scsi command
- passed in from user. This seems the way many vendors and other people
- have strutured their drivers, it would make it possible to have a common
- user-level program to do special maintainance work like, for instance,
- reformatting of disks.
-
diff --git a/scsi/adapters/scsi_33C93.h b/scsi/adapters/scsi_33C93.h
deleted file mode 100644
index 454a8eb..0000000
--- a/scsi/adapters/scsi_33C93.h
+++ /dev/null
@@ -1,396 +0,0 @@
-/*
- * Mach Operating System
- * Copyright (c) 1991,1990,1989 Carnegie Mellon University
- * All Rights Reserved.
- *
- * Permission to use, copy, modify and distribute this software and its
- * documentation is hereby granted, provided that both the copyright
- * notice and this permission notice appear in all copies of the
- * software, derivative works or modified versions, and any portions
- * thereof, and that both notices appear in supporting documentation.
- *
- * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
- * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
- * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
- *
- * Carnegie Mellon requests users of this software to return to
- *
- * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
- * School of Computer Science
- * Carnegie Mellon University
- * Pittsburgh PA 15213-3890
- *
- * any improvements or extensions that they make and grant Carnegie Mellon
- * the rights to redistribute these changes.
- */
-/*
- * File: scsi_33C93.h
- * Author: Alessandro Forin, Carnegie Mellon University
- * Date: 8/91
- *
- * Defines for the WD/AMD 33C93 SBIC (SCSI Bus Interface Controller)
- */
-
-/*
- * Register map, w mux addressing
- */
-
-typedef struct {
-
- volatile unsigned char sbic_myid; /* rw: My SCSI id */
-#define sbic_cdbsize sbic_myid /* w : size of CDB */
-
- volatile unsigned char sbic_control; /* rw: Control register */
-
- volatile unsigned char sbic_timeo; /* rw: Timeout period */
-
- volatile unsigned char sbic_cdb1; /* rw: CDB, 1st byte */
-#define sbic_tsecs sbic_cdb1 /* rw: Xlate: nsectors */
-
- volatile unsigned char sbic_cdb2; /* rw: CDB, 2nd byte */
-#define sbic_theads sbic_cdb2 /* rw: Xlate: nheads */
-
- volatile unsigned char sbic_cdb3; /* rw: CDB, 3rd byte */
-#define sbic_tcyl_hi sbic_cdb3 /* rw: Xlate: ncyls, hi */
-
- volatile unsigned char sbic_cdb4; /* rw: CDB, 4th byte */
-#define sbic_tcyl_lo sbic_cdb4 /* rw: Xlate: ncyls, lo */
-
- volatile unsigned char sbic_cdb5; /* rw: CDB, 5th byte */
-#define sbic_addr_hi sbic_cdb5 /* rw: Xlate: address, hi */
-
- volatile unsigned char sbic_cdb6; /* rw: CDB, 6th byte */
-#define sbic_addr_2 sbic_cdb6 /* rw: Xlate: address */
-
- volatile unsigned char sbic_cdb7; /* rw: CDB, 7th byte */
-#define sbic_addr_3 sbic_cdb7 /* rw: Xlate: address */
-
- volatile unsigned char sbic_cdb8; /* rw: CDB, 8th byte */
-#define sbic_addr_lo sbic_cdb8 /* rw: Xlate: address, lo */
-
- volatile unsigned char sbic_cdb9; /* rw: CDB, 9th byte */
-#define sbic_secno sbic_cdb9 /* rw: Xlate: sector no */
-
- volatile unsigned char sbic_cdb10; /* rw: CDB, 10th byte */
-#define sbic_headno sbic_cdb10 /* rw: Xlate: head no */
-
- volatile unsigned char sbic_cdb11; /* rw: CDB, 11th byte */
-#define sbic_cylno_hi sbic_cdb11/* rw: Xlate: cyl no, hi */
-
- volatile unsigned char sbic_cdb12; /* rw: CDB, 12th byte */
-#define sbic_cylno_lo sbic_cdb12/* rw: Xlate: cyl no, lo */
-
- volatile unsigned char sbic_tlun; /* rw: Target LUN */
-
- volatile unsigned char sbic_cmd_phase; /* rw: Command phase */
-
- volatile unsigned char sbic_syn; /* rw: Synch xfer params */
-
- volatile unsigned char sbic_count_hi; /* rw: Xfer count, hi */
-
- volatile unsigned char sbic_count_med; /* rw: Xfer count, med */
-
- volatile unsigned char sbic_count_lo; /* rw: Xfer count, lo */
-
- volatile unsigned char sbic_selid; /* rw: Target ID (select) */
-
- volatile unsigned char sbic_rselid; /* rw: Target ID (reselect) */
-
- volatile unsigned char sbic_csr; /* r : Status register */
-
- volatile unsigned char sbic_cmd; /* rw: Command register */
-
- volatile unsigned char sbic_data; /* rw: FIFO top */
-
- char u0; /* unused, padding */
- char u1; /* unused, padding */
- char u2; /* unused, padding */
- char u3; /* unused, padding */
- char u4; /* unused, padding */
-
- volatile unsigned char sbic_asr; /* r : Aux Status Register */
-
-} sbic_mux_regmap_t;
-
-/*
- * Register map, non mux (indirect) addressing
- */
-typedef struct {
- volatile unsigned char sbic_asr; /* r : Aux Status Register */
-#define sbic_address sbic_asr /* w : desired register no */
-
- volatile unsigned char sbic_value; /* rw: register value */
-} sbic_ind_regmap_t;
-
-#define sbic_read_reg(regs,regno,val) { \
- (regs)->sbic_address = (regno); \
- wbflush(); \
- (val) = (regs)->sbic_value; \
- }
-
-#define sbic_write_reg(regs,regno,val) { \
- (regs)->sbic_address = (regno); \
- wbflush(); \
- (regs)->sbic_value = (val); \
- }
-
-#define SBIC_myid 0
-#define SBIC_cdbsize 0
-#define SBIC_control 1
-#define SBIC_timeo 2
-#define SBIC_cdb1 3
-#define SBIC_tsecs 3
-#define SBIC_cdb2 4
-#define SBIC_theads 4
-#define SBIC_cdb3 5
-#define SBIC_tcyl_hi 5
-#define SBIC_cdb4 6
-#define SBIC_tcyl_lo 6
-#define SBIC_cdb5 7
-#define SBIC_addr_hi 7
-#define SBIC_cdb6 8
-#define SBIC_addr_2 8
-#define SBIC_cdb7 9
-#define SBIC_addr_3 9
-#define SBIC_cdb8 10
-#define SBIC_addr_lo 10
-#define SBIC_cdb9 11
-#define SBIC_secno 11
-#define SBIC_cdb10 12
-#define SBIC_headno 12
-#define SBIC_cdb11 13
-#define SBIC_cylno_hi 13
-#define SBIC_cdb12 14
-#define SBIC_cylno_lo 14
-#define SBIC_tlun 15
-#define SBIC_cmd_phase 16
-#define SBIC_syn 17
-#define SBIC_count_hi 18
-#define SBIC_count_med 19
-#define SBIC_count_lo 20
-#define SBIC_selid 21
-#define SBIC_rselid 22
-#define SBIC_csr 23
-#define SBIC_cmd 24
-#define SBIC_data 25
-/* sbic_asr is addressed directly */
-
-/*
- * Register defines
- */
-
-/*
- * Auxiliary Status Register
- */
-
-#define SBIC_ASR_INT 0x80 /* Interrupt pending */
-#define SBIC_ASR_LCI 0x40 /* Last command ignored */
-#define SBIC_ASR_BSY 0x20 /* Busy, only cmd/data/asr readable */
-#define SBIC_ASR_CIP 0x10 /* Busy, cmd unavail also */
-#define SBIC_ASR_xxx 0x0c
-#define SBIC_ASR_PE 0x02 /* Parity error (even) */
-#define SBIC_ASR_DBR 0x01 /* Data Buffer Ready */
-
-/*
- * My ID register, and/or CDB Size
- */
-
-#define SBIC_ID_FS_8_10 0x00 /* Input clock is 8-10 Mhz */
- /* 11 Mhz is invalid */
-#define SBIC_ID_FS_12_15 0x40 /* Input clock is 12-15 Mhz */
-#define SBIC_ID_FS_16_20 0x80 /* Input clock is 16-20 Mhz */
-#define SBIC_ID_EHP 0x10 /* Enable host parity */
-#define SBIC_ID_EAF 0x08 /* Enable Advanced Features */
-#define SBIC_ID_MASK 0x07
-#define SBIC_ID_CBDSIZE_MASK 0x0f /* if unk SCSI cmd group */
-
-/*
- * Control register
- */
-
-#define SBIC_CTL_DMA 0x80 /* Single byte dma */
-#define SBIC_CTL_DBA_DMA 0x40 /* direct buffer acces (bus master)*/
-#define SBIC_CTL_BURST_DMA 0x20 /* continuous mode (8237) */
-#define SBIC_CTL_NO_DMA 0x00 /* Programmed I/O */
-#define SBIC_CTL_HHP 0x10 /* Halt on host parity error */
-#define SBIC_CTL_EDI 0x08 /* Ending disconnect interrupt */
-#define SBIC_CTL_IDI 0x04 /* Intermediate disconnect interrupt*/
-#define SBIC_CTL_HA 0x02 /* Halt on ATN */
-#define SBIC_CTL_HSP 0x01 /* Halt on SCSI parity error */
-
-/*
- * Timeout period register
- * [val in msecs, input clk in Mhz]
- */
-
-#define SBIC_TIMEOUT(val,clk) ((((val)*(clk))/80)+1)
-
-/*
- * CDBn registers, note that
- * cdb11 is used for status byte in target mode (send-status-and-cc)
- * cdb12 sez if linked command complete, and w/flag if so
- */
-
-/*
- * Target LUN register
- * [holds target status when select-and-xfer]
- */
-
-#define SBIC_TLUN_VALID 0x80 /* did we receive an Identify msg */
-#define SBIC_TLUN_DOK 0x40 /* Disconnect OK */
-#define SBIC_TLUN_xxx 0x38
-#define SBIC_TLUN_MASK 0x07
-
-/*
- * Command Phase register
- */
-
-#define SBIC_CPH_MASK 0x7f /* values/restarts are cmd specific */
-#define SBIC_CPH(p) ((p)&SBIC_CPH_MASK)
-
-/*
- * FIFO register
- */
-
-#define SBIC_FIFO_DEEP 12
-
-/*
- * Synchronous xfer register
- */
-
-#define SBIC_SYN_OFF_MASK 0x0f
-#define SBIC_SYN_MAX_OFFSET (SBIC_FIFO_DEEP-1)
-#define SBIC_SYN_PER_MASK 0x70
-#define SBIC_SYN_MIN_PERIOD 2 /* upto 8, encoded as 0 */
-
-#define SBIC_SYN(o,p) (((o)&SBIC_SYN_OFF_MASK)|(((p)<<4)&SBIC_SYN_PER_MASK))
-
-/*
- * Transfer count register
- * optimal access macros depend on addressing
- */
-
-/*
- * Destination ID (selid) register
- */
-
-#define SBIC_SID_SCC 0x80 /* Select command chaining (tgt) */
-#define SBIC_SID_DPD 0x40 /* Data phase direction (inittor) */
-# define SBIC_SID_FROM_SCSI 0x40
-# define SBIC_SID_TO_SCSI 0x00
-#define SBIC_SID_xxx 0x38
-#define SBIC_SID_IDMASK 0x07
-
-/*
- * Source ID (rselid) register
- */
-
-#define SBIC_RID_ER 0x80 /* Enable reselection */
-#define SBIC_RID_ES 0x40 /* Enable selection */
-#define SBIC_RID_DSP 0x20 /* Disable select parity */
-#define SBIC_RID_SIV 0x08 /* Source ID valid */
-#define SBIC_RID_MASK 0x07
-
-/*
- * Status register
- */
-
-#define SBIC_CSR_CAUSE 0xf0
-# define SBIC_CSR_RESET 0x00 /* chip was reset */
-# define SBIC_CSR_CMD_DONE 0x10 /* cmd completed */
-# define SBIC_CSR_CMD_STOPPED 0x20 /* interrupted or abrted*/
-# define SBIC_CSR_CMD_ERR 0x40 /* end with error */
-# define SBIC_CSR_BUS_SERVICE 0x80 /* REQ pending on the bus */
-
-#define SBIC_CSR_QUALIFIER 0x0f
-
- /* Reset State Interrupts */
-# define SBIC_CSR_RESET 0x00 /* reset w/advanced features*/
-# define SBIC_CSR_RESET_AM 0x01 /* reset w/advanced features*/
-
- /* Successful Completion Interrupts */
-# define SBIC_CSR_TARGET 0x10 /* reselect complete */
-# define SBIC_CSR_INITIATOR 0x11 /* select complete */
-# define SBIC_CSR_WO_ATN 0x13 /* tgt mode completion */
-# define SBIC_CSR_W_ATN 0x14 /* ditto */
-# define SBIC_CSR_XLATED 0x15 /* translate address cmd */
-# define SBIC_CSR_S_XFERRED 0x16 /* initiator mode completion*/
-# define SBIC_CSR_XFERRED 0x18 /* phase in low bits */
-
- /* Paused or Aborted Interrupts */
-# define SBIC_CSR_MSGIN_W_ACK 0x20 /* (I) msgin, ACK asserted*/
-# define SBIC_CSR_SDP 0x21 /* (I) SDP msg received */
-# define SBIC_CSR_SEL_ABRT 0x22 /* sel/resel aborted */
-# define SBIC_CSR_XFR_PAUSED 0x23 /* (T) no ATN */
-# define SBIC_CSR_XFR_PAUSED_ATN 0x24 /* (T) ATN is asserted */
-# define SBIC_CSR_RSLT_AM 0x27 /* (I) lost selection (AM) */
-# define SBIC_CSR_MIS 0x28 /* (I) xfer aborted, ph mis */
-
- /* Terminated Interrupts */
-# define SBIC_CSR_CMD_INVALID 0x40
-# define SBIC_CSR_DISC 0x41 /* (I) tgt disconnected */
-# define SBIC_CSR_SEL_TIMEO 0x42
-# define SBIC_CSR_PE 0x43 /* parity error */
-# define SBIC_CSR_PE_ATN 0x44 /* ditto, ATN is asserted */
-# define SBIC_CSR_XLATE_TOOBIG 0x45
-# define SBIC_CSR_RSLT_NOAM 0x46 /* (I) lost sel, no AM mode */
-# define SBIC_CSR_BAD_STATUS 0x47 /* status byte was nok */
-# define SBIC_CSR_MIS_1 0x48 /* ph mis, see low bits */
-
- /* Service Required Interrupts */
-# define SBIC_CSR_RSLT_NI 0x80 /* reselected, no ify msg */
-# define SBIC_CSR_RSLT_IFY 0x81 /* ditto, AM mode, got ify */
-# define SBIC_CSR_SLT 0x82 /* selected, no ATN */
-# define SBIC_CSR_SLT_ATN 0x83 /* selected with ATN */
-# define SBIC_CSR_ATN 0x84 /* (T) ATN asserted */
-# define SBIC_CSR_DISC_1 0x85 /* (I) bus is free */
-# define SBIC_CSR_UNK_GROUP 0x87 /* strange CDB1 */
-# define SBIC_CSR_MIS_2 0x88 /* (I) ph mis, see low bits */
-
-#define SBIC_PHASE(csr) SCSI_PHASE(csr)
-
-/*
- * Command register (command codes)
- */
-
-#define SBIC_CMD_SBT 0x80 /* Single byte xfer qualifier */
-#define SBIC_CMD_MASK 0x7f
-
- /* Miscellaneous */
-#define SBIC_CMD_RESET 0x00 /* (DTI) lev I */
-#define SBIC_CMD_ABORT 0x01 /* (DTI) lev I */
-#define SBIC_CMD_DISC 0x04 /* ( TI) lev I */
-#define SBIC_CMD_SSCC 0x0d /* ( TI) lev I */
-#define SBIC_CMD_SET_IDI 0x0f /* (DTI) lev I */
-#define SBIC_CMD_XLATE 0x18 /* (DT ) lev II */
-
- /* Initiator state */
-#define SBIC_CMD_SET_ATN 0x02 /* ( I) lev I */
-#define SBIC_CMD_CLR_ACK 0x03 /* ( I) lev I */
-#define SBIC_CMD_XFER_INFO 0x20 /* ( I) lev II */
-
- /* Target state */
-#define SBIC_CMD_SND_DISC 0x0e /* ( T ) lev II */
-#define SBIC_CMD_RCV_CMD 0x10 /* ( T ) lev II */
-#define SBIC_CMD_RCV_DATA 0x11 /* ( T ) lev II */
-#define SBIC_CMD_RCV_MSG_OUT 0x12 /* ( T ) lev II */
-#define SBIC_CMD_RCV 0x13 /* ( T ) lev II */
-#define SBIC_CMD_SND_STATUS 0x14 /* ( T ) lev II */
-#define SBIC_CMD_SND_DATA 0x15 /* ( T ) lev II */
-#define SBIC_CMD_SND_MSG_IN 0x16 /* ( T ) lev II */
-#define SBIC_CMD_SND 0x17 /* ( T ) lev II */
-
- /* Disconnected state */
-#define SBIC_CMD_RESELECT 0x05 /* (D ) lev II */
-#define SBIC_CMD_SEL_ATN 0x06 /* (D ) lev II */
-#define SBIC_CMD_SEL 0x07 /* (D ) lev II */
-#define SBIC_CMD_SEL_ATN_XFER 0x08 /* (D I) lev II */
-#define SBIC_CMD_SEL_XFER 0x09 /* (D I) lev II */
-#define SBIC_CMD_RESELECT_RECV 0x0a /* (DT ) lev II */
-#define SBIC_CMD_RESELECT_SEND 0x0b /* (DT ) lev II */
-#define SBIC_CMD_WAIT_SEL_RECV 0x0c /* (DT ) lev II */
-
-
-/* approximate, but we won't do SBT on selects */
-#define sbic_isa_select(cmd) (((cmd)>0x5)&&((cmd)<0xa))
-
diff --git a/scsi/adapters/scsi_33C93_hdw.c b/scsi/adapters/scsi_33C93_hdw.c
deleted file mode 100644
index 169ccbf..0000000
--- a/scsi/adapters/scsi_33C93_hdw.c
+++ /dev/null
@@ -1,2078 +0,0 @@
-/*
- * Mach Operating System
- * Copyright (c) 1991,1990,1989 Carnegie Mellon University
- * All Rights Reserved.
- *
- * Permission to use, copy, modify and distribute this software and its
- * documentation is hereby granted, provided that both the copyright
- * notice and this permission notice appear in all copies of the
- * software, derivative works or modified versions, and any portions
- * thereof, and that both notices appear in supporting documentation.
- *
- * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS AS-IS
- * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
- * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
- *
- * Carnegie Mellon requests users of this software to return to
- *
- * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
- * School of Computer Science
- * Carnegie Mellon University
- * Pittsburgh PA 15213-3890
- *
- * any improvements or extensions that they make and grant Carnegie Mellon
- * the rights to redistribute these changes.
- */
-/*
- * File: scsi_33C93_hdw.h
- * Author: Alessandro Forin, Carnegie Mellon University
- * Date: 8/91
- *
- * Bottom layer of the SCSI driver: chip-dependent functions
- *
- * This file contains the code that is specific to the WD/AMD 33C93
- * SCSI chip (Host Bus Adapter in SCSI parlance): probing, start
- * operation, and interrupt routine.
- */
-
-#if 0
-DISCLAIMER: THIS DOES NOT EVEN COMPILE YET, it went in by mistake.
-Code that probably makes some sense is from here to "TILL HERE"
-
-/*
- * This layer works based on small simple 'scripts' that are installed
- * at the start of the command and drive the chip to completion.
- * The idea comes from the specs of the NCR 53C700 'script' processor.
- *
- * There are various reasons for this, mainly
- * - Performance: identify the common (successful) path, and follow it;
- * at interrupt time no code is needed to find the current status
- * - Code size: it should be easy to compact common operations
- * - Adaptability: the code skeleton should adapt to different chips without
- * terrible complications.
- * - Error handling: and it is easy to modify the actions performed
- * by the scripts to cope with strange but well identified sequences
- *
- */
-
-#include <sbic.h>
-#if NSBIC > 0
-#include <platforms.h>
-
-#ifdef IRIS
-#define PAD(n) char n[3] /* or whatever */
-#define SBIC_MUX_ADDRESSING /* comment out if wrong */
-#define SBIC_CLOCK_FREQUENCY 20 /* FIXME FIXME FIXME */
-#define SBIC_MACHINE_DMA_MODE SBIC_CTL_DMA /* FIXME FIXME FIXME */
-
-#define SBIC_SET_RST_ADDR /*SCSI_INIT_ADDR*/
-#define SBIC_CLR_RST_ADDR /*SCSI_RDY_ADDR*/
-#define SBIC_MACHINE_RESET_SCSIBUS(regs,per) \
- { int temp; \
- temp = *(volatile unsigned int *)SBIC_SET_RST_ADDR; \
- delay(per); \
- temp = *(volatile unsigned int *)SBIC_CLR_RST_ADDR; \
- }
-
-#endif
-
-#include <machine/machspl.h> /* spl definitions */
-#include <mach/std_types.h>
-#include <sys/types.h>
-#include <chips/busses.h>
-#include <scsi/compat_30.h>
-
-#include <scsi/scsi.h>
-#include <scsi/scsi2.h>
-
-#include <scsi/adapters/scsi_33C93.h>
-#include <scsi/scsi_defs.h>
-#include <scsi/adapters/scsi_dma.h>
-
-/*
- * Spell out all combinations of padded/nopadded and mux/nomux
- */
-#ifdef PAD
-typedef struct {
-
- volatile unsigned char sbic_myid; /* rw: My SCSI id */
-/*#define sbic_cdbsize sbic_myid /* w : size of CDB */
- PAD(pad0)
- volatile unsigned char sbic_control; /* rw: Control register */
- PAD(pad1)
- volatile unsigned char sbic_timeo; /* rw: Timeout period */
- PAD(pad2)
- volatile unsigned char sbic_cdb1; /* rw: CDB, 1st byte */
- PAD(pad3)
- volatile unsigned char sbic_cdb2; /* rw: CDB, 2nd byte */
- PAD(pad4)
- volatile unsigned char sbic_cdb3; /* rw: CDB, 3rd byte */
- PAD(pad5)
- volatile unsigned char sbic_cdb4; /* rw: CDB, 4th byte */
- PAD(pad6)
- volatile unsigned char sbic_cdb5; /* rw: CDB, 5th byte */
- PAD(pad7)
- volatile unsigned char sbic_cdb6; /* rw: CDB, 6th byte */
- PAD(pad8)
- volatile unsigned char sbic_cdb7; /* rw: CDB, 7th byte */
- PAD(pad9)
- volatile unsigned char sbic_cdb8; /* rw: CDB, 8th byte */
- PAD(pad10)
- volatile unsigned char sbic_cdb9; /* rw: CDB, 9th byte */
- PAD(pad11)
- volatile unsigned char sbic_cdb10; /* rw: CDB, 10th byte */
- PAD(pad12)
- volatile unsigned char sbic_cdb11; /* rw: CDB, 11th byte */
- PAD(pad13)
- volatile unsigned char sbic_cdb12; /* rw: CDB, 12th byte */
- PAD(pad14)
- volatile unsigned char sbic_tlun; /* rw: Target LUN */
- PAD(pad15)
- volatile unsigned char sbic_cmd_phase; /* rw: Command phase */
- PAD(pad16)
- volatile unsigned char sbic_syn; /* rw: Synch xfer params */
- PAD(pad17)
- volatile unsigned char sbic_count_hi; /* rw: Xfer count, hi */
- PAD(pad18)
- volatile unsigned char sbic_count_med; /* rw: Xfer count, med */
- PAD(pad19)
- volatile unsigned char sbic_count_lo; /* rw: Xfer count, lo */
- PAD(pad20)
- volatile unsigned char sbic_selid; /* rw: Target ID (select) */
- PAD(pad21)
- volatile unsigned char sbic_rselid; /* rw: Target ID (reselect) */
- PAD(pad22)
- volatile unsigned char sbic_csr; /* r : Status register */
- PAD(pad23)
- volatile unsigned char sbic_cmd; /* rw: Command register */
- PAD(pad24)
- volatile unsigned char sbic_data; /* rw: FIFO top */
- PAD(pad25)
- char u0; /* unused, padding */
- PAD(pad26)
- char u1; /* unused, padding */
- PAD(pad27)
- char u2; /* unused, padding */
- PAD(pad28)
- char u3; /* unused, padding */
- PAD(pad29)
- char u4; /* unused, padding */
- PAD(pad30)
- volatile unsigned char sbic_asr; /* r : Aux Status Register */
- PAD(pad31)
-
-} sbic_padded_mux_regmap_t;
-
-typedef struct {
- volatile unsigned char sbic_asr; /* r : Aux Status Register */
-/*#define sbic_address sbic_asr /* w : desired register no */
- PAD(pad0);
- volatile unsigned char sbic_value; /* rw: register value */
- PAD(pad1);
-} sbic_padded_ind_regmap_t;
-
-#else /* !PAD */
-
-typedef sbic_mux_regmap_t sbic_padded_mux_regmap_t;
-typedef sbic_ind_regmap_t sbic_padded_ind_regmap_t;
-
-#endif /* !PAD */
-
-/*
- * Could have used some non-ANSIsm in the following :-))
- */
-#ifdef SBIC_MUX_ADDRESSING
-
-typedef sbic_padded_mux_regmap_t sbic_padded_regmap_t;
-
-#define SET_SBIC_myid(regs,val) (regs)->sbic_myid = (val)
-#define GET_SBIC_myid(regs,val) (val) = (regs)->sbic_myid
-#define SET_SBIC_cdbsize(regs,val) (regs)->sbic_cdbsize = (val)
-#define GET_SBIC_cdbsize(regs,val) (val) = (regs)->sbic_cdbsize
-#define SET_SBIC_control(regs,val) (regs)->sbic_control = (val)
-#define GET_SBIC_control(regs,val) (val) = (regs)->sbic_control
-#define SET_SBIC_timeo(regs,val) (regs)->sbic_timeo = (val)
-#define GET_SBIC_timeo(regs,val) (val) = (regs)->sbic_timeo
-#define SET_SBIC_cdb1(regs,val) (regs)->sbic_cdb1 = (val)
-#define GET_SBIC_cdb1(regs,val) (val) = (regs)->sbic_cdb1
-#define SET_SBIC_cdb2(regs,val) (regs)->sbic_cdb2 = (val)
-#define GET_SBIC_cdb2(regs,val) (val) = (regs)->sbic_cdb2
-#define SET_SBIC_cdb3(regs,val) (regs)->sbic_cdb3 = (val)
-#define GET_SBIC_cdb3(regs,val) (val) = (regs)->sbic_cdb3
-#define SET_SBIC_cdb4(regs,val) (regs)->sbic_cdb4 = (val)
-#define GET_SBIC_cdb4(regs,val) (val) = (regs)->sbic_cdb4
-#define SET_SBIC_cdb5(regs,val) (regs)->sbic_cdb5 = (val)
-#define GET_SBIC_cdb5(regs,val) (val) = (regs)->sbic_cdb5
-#define SET_SBIC_cdb6(regs,val) (regs)->sbic_cdb6 = (val)
-#define GET_SBIC_cdb6(regs,val) (val) = (regs)->sbic_cdb6
-#define SET_SBIC_cdb7(regs,val) (regs)->sbic_cdb7 = (val)
-#define GET_SBIC_cdb7(regs,val) (val) = (regs)->sbic_cdb7
-#define SET_SBIC_cdb8(regs,val) (regs)->sbic_cdb8 = (val)
-#define GET_SBIC_cdb8(regs,val) (val) = (regs)->sbic_cdb8
-#define SET_SBIC_cdb9(regs,val) (regs)->sbic_cdb9 = (val)
-#define GET_SBIC_cdb9(regs,val) (val) = (regs)->sbic_cdb9
-#define SET_SBIC_cdb10(regs,val) (regs)->sbic_cdb10 = (val)
-#define GET_SBIC_cdb10(regs,val) (val) = (regs)->sbic_cdb10
-#define SET_SBIC_cdb11(regs,val) (regs)->sbic_cdb11 = (val)
-#define GET_SBIC_cdb11(regs,val) (val) = (regs)->sbic_cdb11
-#define SET_SBIC_cdb12(regs,val) (regs)->sbic_cdb12 = (val)
-#define GET_SBIC_cdb12(regs,val) (val) = (regs)->sbic_cdb12
-#define SET_SBIC_tlun(regs,val) (regs)->sbic_tlun = (val)
-#define GET_SBIC_tlun(regs,val) (val) = (regs)->sbic_tlun
-#define SET_SBIC_cmd_phase(regs,val) (regs)->sbic_cmd_phase = (val)
-#define GET_SBIC_cmd_phase(regs,val) (val) = (regs)->sbic_cmd_phase
-#define SET_SBIC_syn(regs,val) (regs)->sbic_syn = (val)
-#define GET_SBIC_syn(regs,val) (val) = (regs)->sbic_syn
-#define SET_SBIC_count_hi(regs,val) (regs)->sbic_count_hi = (val)
-#define GET_SBIC_count_hi(regs,val) (val) = (regs)->sbic_count_hi
-#define SET_SBIC_count_med(regs,val) (regs)->sbic_count_med = (val)
-#define GET_SBIC_count_med(regs,val) (val) = (regs)->sbic_count_med
-#define SET_SBIC_count_lo(regs,val) (regs)->sbic_count_lo = (val)
-#define GET_SBIC_count_lo(regs,val) (val) = (regs)->sbic_count_lo
-#define SET_SBIC_selid(regs,val) (regs)->sbic_selid = (val)
-#define GET_SBIC_selid(regs,val) (val) = (regs)->sbic_selid
-#define SET_SBIC_rselid(regs,val) (regs)->sbic_rselid = (val)
-#define GET_SBIC_rselid(regs,val) (val) = (regs)->sbic_rselid
-#define SET_SBIC_csr(regs,val) (regs)->sbic_csr = (val)
-#define GET_SBIC_csr(regs,val) (val) = (regs)->sbic_csr
-#define SET_SBIC_cmd(regs,val) (regs)->sbic_cmd = (val)
-#define GET_SBIC_cmd(regs,val) (val) = (regs)->sbic_cmd
-#define SET_SBIC_data(regs,val) (regs)->sbic_data = (val)
-#define GET_SBIC_data(regs,val) (val) = (regs)->sbic_data
-
-#define SBIC_TC_SET(regs,val) { \
- (regs)->sbic_count_hi = ((val)>>16)); \
- (regs)->sbic_count_med = (val)>>8; \
- (regs)->sbic_count_lo = (val); \
- }
-#define SBIC_TC_GET(regs,val) { \
- (val) = ((regs)->sbic_count_hi << 16) | \
- ((regs)->sbic_count_med << 8) | \
- ((regs)->sbic_count_lo); \
- }
-
-#define SBIC_LOAD_COMMAND(regs,cmd,cmdsize) { \
- register char *ptr = (char*)(cmd); \
- (regs)->cis_cdb1 = *ptr++; \
- (regs)->cis_cdb2 = *ptr++; \
- (regs)->cis_cdb3 = *ptr++; \
- (regs)->cis_cdb4 = *ptr++; \
- (regs)->cis_cdb5 = *ptr++; \
- (regs)->cis_cdb6 = *ptr++; \
- if (cmdsize > 6) { \
- (regs)->cis_cdb7 = *ptr++; \
- (regs)->cis_cdb8 = *ptr++; \
- (regs)->cis_cdb9 = *ptr++; \
- (regs)->cis_cdb10 = *ptr++; \
- } \
- if (cmdsize > 10) { \
- (regs)->cis_cdb11 = *ptr++; \
- (regs)->cis_cdb12 = *ptr; \
- } \
- }
-
-#else /*SBIC_MUX_ADDRESSING*/
-
-typedef sbic_padded_ind_regmap_t sbic_padded_regmap_t;
-
-#define SET_SBIC_myid(regs,val) sbic_write_reg(regs,SBIC_myid,val)
-#define GET_SBIC_myid(regs,val) sbic_read_reg(regs,SBIC_myid,val)
-#define SET_SBIC_cdbsize(regs,val) sbic_write_reg(regs,SBIC_cdbsize,val)
-#define GET_SBIC_cdbsize(regs,val) sbic_read_reg(regs,SBIC_cdbsize,val)
-#define SET_SBIC_control(regs,val) sbic_write_reg(regs,SBIC_control,val)
-#define GET_SBIC_control(regs,val) sbic_read_reg(regs,SBIC_control,val)
-#define SET_SBIC_timeo(regs,val) sbic_write_reg(regs,SBIC_timeo,val)
-#define GET_SBIC_timeo(regs,val) sbic_read_reg(regs,SBIC_timeo,val)
-#define SET_SBIC_cdb1(regs,val) sbic_write_reg(regs,SBIC_cdb1,val)
-#define GET_SBIC_cdb1(regs,val) sbic_read_reg(regs,SBIC_cdb1,val)
-#define SET_SBIC_cdb2(regs,val) sbic_write_reg(regs,SBIC_cdb2,val)
-#define GET_SBIC_cdb2(regs,val) sbic_read_reg(regs,SBIC_cdb2,val)
-#define SET_SBIC_cdb3(regs,val) sbic_write_reg(regs,SBIC_cdb3,val)
-#define GET_SBIC_cdb3(regs,val) sbic_read_reg(regs,SBIC_cdb3,val)
-#define SET_SBIC_cdb4(regs,val) sbic_write_reg(regs,SBIC_cdb4,val)
-#define GET_SBIC_cdb4(regs,val) sbic_read_reg(regs,SBIC_cdb4,val)
-#define SET_SBIC_cdb5(regs,val) sbic_write_reg(regs,SBIC_cdb5,val)
-#define GET_SBIC_cdb5(regs,val) sbic_read_reg(regs,SBIC_cdb5,val)
-#define SET_SBIC_cdb6(regs,val) sbic_write_reg(regs,SBIC_cdb6,val)
-#define GET_SBIC_cdb6(regs,val) sbic_read_reg(regs,SBIC_cdb6,val)
-#define SET_SBIC_cdb7(regs,val) sbic_write_reg(regs,SBIC_cdb7,val)
-#define GET_SBIC_cdb7(regs,val) sbic_read_reg(regs,SBIC_cdb7,val)
-#define SET_SBIC_cdb8(regs,val) sbic_write_reg(regs,SBIC_cdb8,val)
-#define GET_SBIC_cdb8(regs,val) sbic_read_reg(regs,SBIC_cdb8,val)
-#define SET_SBIC_cdb9(regs,val) sbic_write_reg(regs,SBIC_cdb9,val)
-#define GET_SBIC_cdb9(regs,val) sbic_read_reg(regs,SBIC_cdb9,val)
-#define SET_SBIC_cdb10(regs,val) sbic_write_reg(regs,SBIC_cdb10,val)
-#define GET_SBIC_cdb10(regs,val) sbic_read_reg(regs,SBIC_cdb10,val)
-#define SET_SBIC_cdb11(regs,val) sbic_write_reg(regs,SBIC_cdb11,val)
-#define GET_SBIC_cdb11(regs,val) sbic_read_reg(regs,SBIC_cdb11,val)
-#define SET_SBIC_cdb12(regs,val) sbic_write_reg(regs,SBIC_cdb12,val)
-#define GET_SBIC_cdb12(regs,val) sbic_read_reg(regs,SBIC_cdb12,val)
-#define SET_SBIC_tlun(regs,val) sbic_write_reg(regs,SBIC_tlun,val)
-#define GET_SBIC_tlun(regs,val) sbic_read_reg(regs,SBIC_tlun,val)
-#define SET_SBIC_cmd_phase(regs,val) sbic_write_reg(regs,SBIC_cmd_phase,val)
-#define GET_SBIC_cmd_phase(regs,val) sbic_read_reg(regs,SBIC_cmd_phase,val)
-#define SET_SBIC_syn(regs,val) sbic_write_reg(regs,SBIC_syn,val)
-#define GET_SBIC_syn(regs,val) sbic_read_reg(regs,SBIC_syn,val)
-#define SET_SBIC_count_hi(regs,val) sbic_write_reg(regs,SBIC_count_hi,val)
-#define GET_SBIC_count_hi(regs,val) sbic_read_reg(regs,SBIC_count_hi,val)
-#define SET_SBIC_count_med(regs,val) sbic_write_reg(regs,SBIC_count_med,val)
-#define GET_SBIC_count_med(regs,val) sbic_read_reg(regs,SBIC_count_med,val)
-#define SET_SBIC_count_lo(regs,val) sbic_write_reg(regs,SBIC_count_lo,val)
-#define GET_SBIC_count_lo(regs,val) sbic_read_reg(regs,SBIC_count_lo,val)
-#define SET_SBIC_selid(regs,val) sbic_write_reg(regs,SBIC_selid,val)
-#define GET_SBIC_selid(regs,val) sbic_read_reg(regs,SBIC_selid,val)
-#define SET_SBIC_rselid(regs,val) sbic_write_reg(regs,SBIC_rselid,val)
-#define GET_SBIC_rselid(regs,val) sbic_read_reg(regs,SBIC_rselid,val)
-#define SET_SBIC_csr(regs,val) sbic_write_reg(regs,SBIC_csr,val)
-#define GET_SBIC_csr(regs,val) sbic_read_reg(regs,SBIC_csr,val)
-#define SET_SBIC_cmd(regs,val) sbic_write_reg(regs,SBIC_cmd,val)
-#define GET_SBIC_cmd(regs,val) sbic_read_reg(regs,SBIC_cmd,val)
-#define SET_SBIC_data(regs,val) sbic_write_reg(regs,SBIC_data,val)
-#define GET_SBIC_data(regs,val) sbic_read_reg(regs,SBIC_data,val)
-
-#define SBIC_TC_SET(regs,val) { \
- sbic_write_reg(regs,SBIC_count_hi,((val)>>16)); \
- (regs)->sbic_value = (val)>>8; wbflush(); \
- (regs)->sbic_value = (val); \
- }
-#define SBIC_TC_GET(regs,val) { \
- sbic_read_reg(regs,SBIC_count_hi,(val)); \
- (val) = ((val)<<8) | (regs)->sbic_value; \
- (val) = ((val)<<8) | (regs)->sbic_value; \
- }
-
-#define SBIC_LOAD_COMMAND(regs,cmd,cmdsize) {
- register int n=cmdsize-1; \
- register char *ptr = (char*)(cmd); \
- sbic_write_reg(regs,SBIC_cdb1,*ptr++); \
- while (n-- > 0) (regs)->sbic_value = *ptr++; \
- }
-
-#endif /*SBIC_MUX_ADDRESSING*/
-
-#define GET_SBIC_asr(regs,val) (val) = (regs)->sbic_asr
-
-
-/*
- * If all goes well (cross fingers) the typical read/write operation
- * should complete in just one interrupt. Therefore our scripts
- * have only two parts: a pre-condition and an action. The first
- * triggers error handling if not satisfied and in our case it is a match
- * of ....
- * The action part is just a function pointer, invoked in a standard way.
- * The script proceeds only if the action routine returns TRUE.
- * See sbic_intr() for how and where this is all done.
- */
-
-typedef struct script {
- struct { /* expected state at interrupt: */
- unsigned char csr; /* interrupt cause */
- unsigned char pha; /* command phase */
- } condition;
-/* unsigned char unused[2]; /* unused padding */
- boolean_t (*action)(); /* extra operations */
-} *script_t;
-
-/* Matching on the condition value */
-#define ANY 0xff
-#define SCRIPT_MATCH(csr,pha,cond) \
- (((cond).csr == (csr)) && \
- (((cond).pha == (pha)) || ((cond).pha==ANY)))
-
-
-/* forward decls of script actions */
-boolean_t
- sbic_end(), /* all come to an end */
- sbic_get_status(), /* get status from target */
- sbic_dma_in(), /* get data from target via dma */
- sbic_dma_in_r(), /* get data from target via dma (restartable)*/
- sbic_dma_out(), /* send data to target via dma */
- sbic_dma_out_r(), /* send data to target via dma (restartable) */
- sbic_dosynch(), /* negotiate synch xfer */
- sbic_msg_in(), /* receive the disconenct message */
- sbic_disconnected(), /* target has disconnected */
- sbic_reconnect(); /* target reconnected */
-
-/* forward decls of error handlers */
-boolean_t
- sbic_err_generic(), /* generic handler */
- sbic_err_disconn(), /* target disconnects amidst */
- gimmeabreak(); /* drop into the debugger */
-
-int sbic_reset_scsibus();
-boolean_t sbic_probe_target();
-static sbic_wait();
-
-/*
- * State descriptor for this layer. There is one such structure
- * per (enabled) SCSI-33c93 interface
- */
-struct sbic_softc {
- watchdog_t wd;
- sbic_padded_regmap_t *regs; /* 33c93 registers */
-
- scsi_dma_ops_t *dma_ops; /* DMA operations and state */
- opaque_t dma_state;
-
- script_t script; /* what should happen next */
- boolean_t (*error_handler)();/* what if something is wrong */
- int in_count; /* amnt we expect to receive */
- int out_count; /* amnt we are going to ship */
-
- volatile char state;
-#define SBIC_STATE_BUSY 0x01 /* selecting or currently connected */
-#define SBIC_STATE_TARGET 0x04 /* currently selected as target */
-#define SBIC_STATE_COLLISION 0x08 /* lost selection attempt */
-#define SBIC_STATE_DMA_IN 0x10 /* tgt --> initiator xfer */
-#define SBIC_STATE_AM_MODE 0x20 /* 33c93A with advanced mode (AM) */
-
- unsigned char ntargets; /* how many alive on this scsibus */
- unsigned char done;
- unsigned char unused;
-
- scsi_softc_t *sc; /* HBA-indep info */
- target_info_t *active_target; /* the current one */
-
- target_info_t *next_target; /* trying to seize bus */
- queue_head_t waiting_targets;/* other targets competing for bus */
-
-} sbic_softc_data[NSBIC];
-
-typedef struct sbic_softc *sbic_softc_t;
-
-sbic_softc_t sbic_softc[NSBIC];
-
-/*
- * Synch xfer parameters, and timing conversions
- */
-int sbic_min_period = SBIC_SYN_MIN_PERIOD; /* in cycles = f(ICLK,FSn) */
-int sbic_max_offset = SBIC_SYN_MAX_OFFSET; /* pure number */
-
-int sbic_to_scsi_period(regs,a)
-{
- unsigned int fs;
-
- /* cycle = DIV / (2*CLK) */
- /* DIV = FS+2 */
- /* best we can do is 200ns at 20Mhz, 2 cycles */
-
- GET_SBIC_myid(regs,fs);
- fs = (fs >>6) + 2; /* DIV */
- fs = (fs * 1000) / (SBIC_CLOCK_FREQUENCY<<1); /* Cycle, in ns */
- if (a < 2) a = 8; /* map to Cycles */
- return ((fs*a)>>2); /* in 4 ns units */
-}
-
-int scsi_period_to_sbic(regs,p)
-{
- register unsigned int fs;
-
- /* Just the inverse of the above */
-
- GET_SBIC_myid(regs,fs);
- fs = (fs >>6) + 2; /* DIV */
- fs = (fs * 1000) / (SBIC_CLOCK_FREQUENCY<<1); /* Cycle, in ns */
-
- ret = p << 2; /* in ns units */
- ret = ret / fs; /* in Cycles */
- if (ret < sbic_min_period)
- return sbic_min_period;
- /* verify rounding */
- if (sbic_to_scsi_period(regs,ret) < p)
- ret++;
- return (ret >= 8) ? 0 : ret;
-}
-
-#define u_min(a,b) (((a) < (b)) ? (a) : (b))
-
-/*
- * Definition of the controller for the auto-configuration program.
- */
-
-int sbic_probe(), scsi_slave(), scsi_attach(), sbic_go(), sbic_intr();
-
-caddr_t sbic_std[NSBIC] = { 0 };
-struct bus_device *sbic_dinfo[NSBIC*8];
-struct bus_ctlr *sbic_minfo[NSBIC];
-struct bus_driver sbic_driver =
- { sbic_probe, scsi_slave, scsi_attach, sbic_go, sbic_std, "rz", sbic_dinfo,
- "sbic", sbic_minfo, BUS_INTR_B4_PROBE};
-
-
-sbic_set_dmaops(unit, dmaops)
- unsigned int unit;
- scsi_dma_ops_t *dmaops;
-{
- if (unit < NSBIC)
- sbic_std[unit] = (caddr_t)dmaops;
-}
-
-/*
- * Scripts
- */
-struct script
-sbic_script_any_cmd[] = { /* started with SEL & XFER */
- {{SBIC_CSR_S_XFERRED, 0x60}, sbic_get_status},
-},
-
-sbic_script_try_synch[] = { /* started with SEL */
- {{SBIC_CSR_INITIATOR, ANY}, sbic_dosynch},
- {{SBIC_CSR_S_XFERRED, 0x60}, sbic_get_status},
-};
-
-
-#define DEBUG
-#ifdef DEBUG
-
-#define PRINT(x) if (scsi_debug) printf x
-
-sbic_state(regs, overrule)
- sbic_padded_regmap_t *regs;
-{
- register unsigned char asr,tmp;
-
- if (regs == 0) {
- if (sbic_softc[0])
- regs = sbic_softc[0]->regs;
- else
- regs = (sbic_padded_regmap_t*)0xXXXXXXXX;
- }
-
- GET_SBIC_asr(regs,asr);
-
- if ((asr & SBIC_ASR_BSY) && !overrule)
- db_printf("-BUSY- ");
- else {
- unsigned char tlun,pha,selid,rselid;
- unsigned int cnt;
- GET_SBIC_tlun(regs,tlun);
- GET_SBIC_cmd_phase(regs,pha);
- GET_SBIC_selid(regs,selid);
- GET_SBIC_rselid(regs,rselid);
- SBIC_TC_GET(regs,cnt);
- db_printf("tc %x tlun %x sel %x rsel %x pha %x ",
- cnt, tlun, selid, rselid, pha);
- }
-
- if (asr & SBIC_ASR_INT)
- db_printf("-INT- ");
- else {
- GET_SBIC_csr(regs,tmp);
- db_printf("csr %x ", tmp);
- }
-
- if (asr & SBIC_ASR_CIP)
- db_printf("-CIP-\n");
- else {
- GET_SBIC_cmd(regs,tmp);
- db_printf("cmd %x\n", tmp);
- }
- return 0;
-}
-
-sbic_target_state(tgt)
- target_info_t *tgt;
-{
- if (tgt == 0)
- tgt = sbic_softc[0]->active_target;
- if (tgt == 0)
- return 0;
- db_printf("@x%x: fl %x dma %X+%x cmd %x@%X id %x per %x off %x ior %X ret %X\n",
- tgt,
- tgt->flags, tgt->dma_ptr, tgt->transient_state.dma_offset, tgt->cur_cmd,
- tgt->cmd_ptr, tgt->target_id, tgt->sync_period, tgt->sync_offset,
- tgt->ior, tgt->done);
- if (tgt->flags & TGT_DISCONNECTED){
- script_t spt;
-
- spt = tgt->transient_state.script;
- db_printf("disconnected at ");
- db_printsym(spt,1);
- db_printf(": %x %x ", spt->condition.csr, spt->condition.pha);
- db_printsym(spt->action,1);
- db_printf(", ");
- db_printsym(tgt->transient_state.handler, 1);
- db_printf("\n");
- }
-
- return 0;
-}
-
-sbic_all_targets(unit)
-{
- int i;
- target_info_t *tgt;
- for (i = 0; i < 8; i++) {
- tgt = sbic_softc[unit]->sc->target[i];
- if (tgt)
- sbic_target_state(tgt);
- }
-}
-
-sbic_script_state(unit)
-{
- script_t spt = sbic_softc[unit]->script;
-
- if (spt == 0) return 0;
- db_printsym(spt,1);
- db_printf(": %x %x ", spt->condition.csr, spt->condition.pha);
- db_printsym(spt->action,1);
- db_printf(", ");
- db_printsym(sbic_softc[unit]->error_handler, 1);
- return 0;
-}
-
-#define TRMAX 200
-int tr[TRMAX+3];
-int trpt, trpthi;
-#define TR(x) tr[trpt++] = x
-#define TRWRAP trpthi = trpt; trpt = 0;
-#define TRCHECK if (trpt > TRMAX) {TRWRAP}
-
-#define TRACE
-
-#ifdef TRACE
-
-#define LOGSIZE 256
-int sbic_logpt;
-char sbic_log[LOGSIZE];
-
-#define MAXLOG_VALUE 0x1e
-struct {
- char *name;
- unsigned int count;
-} logtbl[MAXLOG_VALUE];
-
-static LOG(e,f)
- char *f;
-{
- sbic_log[sbic_logpt++] = (e);
- if (sbic_logpt == LOGSIZE) sbic_logpt = 0;
- if ((e) < MAXLOG_VALUE) {
- logtbl[(e)].name = (f);
- logtbl[(e)].count++;
- }
-}
-
-sbic_print_log(skip)
- int skip;
-{
- register int i, j;
- register unsigned char c;
-
- for (i = 0, j = sbic_logpt; i < LOGSIZE; i++) {
- c = sbic_log[j];
- if (++j == LOGSIZE) j = 0;
- if (skip-- > 0)
- continue;
- if (c < MAXLOG_VALUE)
- db_printf(" %s", logtbl[c].name);
- else
- db_printf("-x%x", c & 0x7f);
- }
-}
-
-sbic_print_stat()
-{
- register int i;
- register char *p;
- for (i = 0; i < MAXLOG_VALUE; i++) {
- if (p = logtbl[i].name)
- printf("%d %s\n", logtbl[i].count, p);
- }
-}
-
-#else /*TRACE*/
-#define LOG(e,f)
-#define LOGSIZE
-#endif /*TRACE*/
-
-#else /*DEBUG*/
-#define PRINT(x)
-#define LOG(e,f)
-#define LOGSIZE
-
-#endif /*DEBUG*/
-
-
-/*
- * Probe/Slave/Attach functions
- */
-
-/*
- * Probe routine:
- * Should find out (a) if the controller is
- * present and (b) which/where slaves are present.
- *
- * Implementation:
- * Send a test-unit-ready to each possible target on the bus
- * except of course ourselves.
- */
-sbic_probe(reg, ui)
- unsigned reg;
- struct bus_ctlr *ui;
-{
- int unit = ui->unit;
- sbic_softc_t sbic = &sbic_softc_data[unit];
- int target_id;
- scsi_softc_t *sc;
- register sbic_padded_regmap_t *regs;
- spl_t s;
- boolean_t did_banner = FALSE;
-
- /*
- * We are only called if the right board is there,
- * but make sure anyways..
- */
- if (check_memory(reg, 0))
- return 0;
-
-#if MAPPABLE
- /* Mappable version side */
- SBIC_probe(reg, ui);
-#endif /*MAPPABLE*/
-
- /*
- * Initialize hw descriptor, cache some pointers
- */
- sbic_softc[unit] = sbic;
- sbic->regs = (sbic_padded_regmap_t *) (reg);
-
- if ((sbic->dma_ops = (scsi_dma_ops_t *)sbic_std[unit]) == 0)
- /* use same as unit 0 if undefined */
- sbic->dma_ops = (scsi_dma_ops_t *)sbic_std[0];
-
- sbic->dma_state = (*sbic->dma_ops->init)(unit, reg);
-
- queue_init(&sbic->waiting_targets);
-
- sc = scsi_master_alloc(unit, sbic);
- sbic->sc = sc;
-
- sc->go = sbic_go;
- sc->watchdog = scsi_watchdog;
- sc->probe = sbic_probe_target;
- sbic->wd.reset = sbic_reset_scsibus;
-
-#ifdef MACH_KERNEL
- sc->max_dma_data = -1;
-#else
- sc->max_dma_data = scsi_per_target_virtual;
-#endif
-
- regs = sbic->regs;
-
- /*
- * Reset chip, fully. Note that interrupts are already enabled.
- */
- s = splbio();
- if (sbic_reset(regs, TRUE))
- sbic->state |= SBIC_STATE_AM_MODE;
-
- /*
- * Our SCSI id on the bus.
- * The user can probably set this via the prom.
- * If not, it is easy to fix: make a default that
- * can be changed as boot arg. Otherwise we keep
- * what the prom used.
- */
-#ifdef unneeded
- SET_SBIC_myid(regs, (scsi_initiator_id[unit] & 0x7));
- sbic_reset(regs, TRUE);
-#endif
- GET_SBIC_myid(regs,sc->initiator_id);
- sc->initiator_id &= 0x7;
- printf("%s%d: SCSI id %d", ui->name, unit, sc->initiator_id);
-
- /*
- * For all possible targets, see if there is one and allocate
- * a descriptor for it if it is there.
- */
- for (target_id = 0; target_id < 8; target_id++) {
- register unsigned char asr, csr, pha;
- register scsi_status_byte_t status;
-
- /* except of course ourselves */
- if (target_id == sc->initiator_id)
- continue;
-
- SBIC_TC_SET(regs,0);
- SET_SBIC_selid(regs,target_id);
- SET_SBIC_timo(regs,SBIC_TIMEOUT(250,SBIC_CLOCK_FREQUENCY));
-
- /*
- * See if the unit is ready.
- * XXX SHOULD inquiry LUN 0 instead !!!
- */
- {
- scsi_command_test_unit_ready_y c;
- bzero(&c, sizeof(c));
- c.scsi_cmd_code = SCSI_CMD_TEST_UNIT_READY;
- SBIC_LOAD_COMMAND(regs,&c,sizeof(c));
- }
-
- /* select and send it */
- SET_SBIC_cmd(regs,SBIC_CMD_SEL_XFER);
-
- /* wait for the chip to complete, or timeout */
- asr = sbic_wait(regs, SBIC_ASR_INT);
- GET_SBIC_csr(regs,csr);
-
- /*
- * Check if the select timed out
- */
- GET_SBIC_cmd_phase(regs,pha);
- if ((SBIC_CPH(pha) == 0) && (csr & SBIC_CSR_CMD_ERR)) {
- /* noone out there */
-#if notsure
- SET_SBIC_cmd(regs,SBIC_CMD_DISC);
- asr = sbic_wait(regs, SBIC_ASR_INT);
- GET_SBIC_csr(regs,csr);
-#endif
- continue;
- }
-
- printf(",%s%d", did_banner++ ? " " : " target(s) at ",
- target_id);
-
- if (SBIC_CPH(pha) < 0x60)
- /* XXX recover by hand XXX */
- panic(" target acts weirdo");
-
- GET_SBIC_tlun(regs,status.bits);
-
- if (status.st.scsi_status_code != SCSI_ST_GOOD)
- scsi_error( 0, SCSI_ERR_STATUS, status.bits, 0);
-
- /*
- * Found a target
- */
- sbic->ntargets++;
- {
- register target_info_t *tgt;
- tgt = scsi_slave_alloc(sc->masterno, target_id, sbic);
-
- (*sbic->dma_ops->new_target)(sbic->dma_state, tgt);
- }
- }
-
- printf(".\n");
-
- splx(s);
- return 1;
-}
-
-boolean_t
-sbic_probe_target(tgt, ior)
- target_info_t *tgt;
- io_req_t ior;
-{
- sbic_softc_t sbic = sbic_softc[tgt->masterno];
- boolean_t newlywed;
-
- newlywed = (tgt->cmd_ptr == 0);
- if (newlywed) {
- (*sbic->dma_ops->new_target)(sbic->dma_state, tgt);
- }
-
- if (scsi_inquiry(tgt, SCSI_INQ_STD_DATA) == SCSI_RET_DEVICE_DOWN)
- return FALSE;
-
- tgt->flags = TGT_ALIVE;
- return TRUE;
-}
-
-static sbic_wait(regs, until)
- sbic_padded_regmap_t *regs;
- char until;
-{
- register unsigned char val;
- int timeo = 1000000;
-
- GET_SBIC_asr(regs,val);
- while ((val & until) == 0) {
- if (!timeo--) {
- printf("sbic_wait TIMEO with x%x\n", regs->sbic_csr);
- break;
- }
- delay(1);
- GET_SBIC_asr(regs,val);
- }
- return val;
-}
-
-boolean_t
-sbic_reset(regs, quick)
- sbic_padded_regmap_t *regs;
-{
- char my_id, csr;
-
- /* preserve our ID for now */
- GET_SBIC_myid(regs,my_id);
- my_id &= SBIC_ID_MASK;
-
- if (SBIC_CLOCK_FREQUENCY < 11)
- my_id |= SBIC_ID_FS_8_10;
- else if (SBIC_CLOCK_FREQUENCY < 16)
- my_id |= SBIC_ID_FS_12_15;
- else if (SBIC_CLOCK_FREQUENCY < 21)
- my_id |= SBIC_ID_FS_16_20;
-
- my_id |= SBIC_ID_EAF|SBIC_ID_EHP;
-
- SET_SBIC_myid(regs,myid);
- wbflush();
-
- /*
- * Reset chip and wait till done
- */
- SET_SBIC_cmd(regs,SBIC_CMD_RESET);
- delay(25);
-
- (void) sbic_wait(regs, SBIC_ASR_INT);
- GET_SBIC_csr(regs,csr); /* clears interrupt also */
-
- /*
- * Set up various chip parameters
- */
- SET_SBIC_control(regs, SBIC_CTL_HHP|SBIC_CTL_EDI|SBIC_CTL_HSP|
- SBIC_MACHINE_DMA_MODE);
- /* will do IDI on the fly */
- SET_SBIC_rselid(regs, SBIC_RID_ER|SBIC_RID_ES|SBIC_RID_DSP);
- SET_SBIC_syn(regs,SBIC_SYN(0,sbic_min_period)); /* asynch for now */
-
- /* anything else was zeroed by reset */
-
- if (quick)
- return (csr & SBIC_CSR_RESET_AM);
-
- /*
- * reset the scsi bus, the interrupt routine does the rest
- * or you can call sbic_bus_reset().
- */
- /*
- * Now HOW do I do this ? I just want to drive the SCSI "RST"
- * signal true for about 25 usecs; But the chip has no notion
- * of such a signal at all. The spec suggest that the chip's
- * reset pin be connected to the RST signal, which makes this
- * operation a machdep one.
- */
- SBIC_MACHINE_RESET_SCSIBUS(regs, 30);
-
- return (csr & SBIC_CSR_RESET_AM);
-}
-
-/*
- * Operational functions
- */
-
-/*
- * Start a SCSI command on a target
- */
-sbic_go(tgt, cmd_count, in_count, cmd_only)
- target_info_t *tgt;
- boolean_t cmd_only;
-{
- sbic_softc_t sbic;
- register spl_t s;
- boolean_t disconn;
- script_t scp;
- boolean_t (*handler)();
-
- LOG(1,"go");
-
- sbic = (sbic_softc_t)tgt->hw_state;
-
- tgt->transient_state.cmd_count = cmd_count; /* keep it here */
-
- (*sbic->dma_ops->map)(sbic->dma_state, tgt);
-
- disconn = BGET(scsi_might_disconnect,tgt->masterno,tgt->target_id);
- disconn = disconn && (sbic->ntargets > 1);
- disconn |= BGET(scsi_should_disconnect,tgt->masterno,tgt->target_id);
-
- /*
- * Setup target state
- */
- tgt->done = SCSI_RET_IN_PROGRESS;
-
- handler = (disconn) ? sbic_err_disconn : sbic_err_generic;
- scp = sbic_script_any_cmd;
-
- switch (tgt->cur_cmd) {
- case SCSI_CMD_READ:
- case SCSI_CMD_LONG_READ:
- LOG(2,"readop");
- break;
- case SCSI_CMD_WRITE:
- case SCSI_CMD_LONG_WRITE:
- LOG(0x1a,"writeop");
- break;
- case SCSI_CMD_INQUIRY:
- /* This is likely the first thing out:
- do the synch neg if so */
- if (!cmd_only && ((tgt->flags&TGT_DID_SYNCH)==0)) {
- scp = sbic_script_try_synch;
- tgt->flags |= TGT_TRY_SYNCH;
- break;
- }
- case SCSI_CMD_MODE_SELECT:
- case SCSI_CMD_REASSIGN_BLOCKS:
- case SCSI_CMD_FORMAT_UNIT:
- tgt->transient_state.cmd_count = sizeof(scsi_command_group_0);
- tgt->transient_state.out_count = cmd_count - sizeof(scsi_command_group_0);
- /* fall through */
- case SCSI_CMD_REQUEST_SENSE:
- case SCSI_CMD_MODE_SENSE:
- case SCSI_CMD_RECEIVE_DIAG_RESULTS:
- case SCSI_CMD_READ_CAPACITY:
- case SCSI_CMD_READ_BLOCK_LIMITS:
- case SCSI_CMD_READ_TOC:
- case SCSI_CMD_READ_SUBCH:
- case SCSI_CMD_READ_HEADER:
- LOG(0x1c,"cmdop");
- LOG(0x80+tgt->cur_cmd,0);
- break;
- case SCSI_CMD_TEST_UNIT_READY:
- /*
- * Do the synch negotiation here, unless prohibited
- * or done already
- */
- if ( ! (tgt->flags & TGT_DID_SYNCH)) {
- scp = sbic_script_try_synch;
- tgt->flags |= TGT_TRY_SYNCH;
- cmd_only = FALSE;
- }
- /* fall through */
- default:
- LOG(0x1c,"cmdop");
- LOG(0x80+tgt->cur_cmd,0);
- break;
- }
-
- tgt->transient_state.script = scp;
- tgt->transient_state.handler = handler;
- tgt->transient_state.identify = (cmd_only) ? 0xff :
- (disconn ? SCSI_IDENTIFY|SCSI_IFY_ENABLE_DISCONNECT :
- SCSI_IDENTIFY);
-
- if (in_count)
- tgt->transient_state.in_count =
- (in_count < tgt->block_size) ? tgt->block_size : in_count;
- else
- tgt->transient_state.in_count = 0;
-
- /*
- * See if another target is currently selected on
- * this SCSI bus, e.g. lock the sbic structure.
- * Note that it is the strategy routine's job
- * to serialize ops on the same target as appropriate.
- * XXX here and everywhere, locks!
- */
- /*
- * Protection viz reconnections makes it tricky.
- */
- s = splbio();
-
- if (sbic->wd.nactive++ == 0)
- sbic->wd.watchdog_state = SCSI_WD_ACTIVE;
-
- if (sbic->state & SBIC_STATE_BUSY) {
- /*
- * Queue up this target, note that this takes care
- * of proper FIFO scheduling of the scsi-bus.
- */
- LOG(3,"enqueue");
- enqueue_tail(&sbic->waiting_targets, (queue_entry_t) tgt);
- } else {
- /*
- * It is down to at most two contenders now,
- * we will treat reconnections same as selections
- * and let the scsi-bus arbitration process decide.
- */
- sbic->state |= SBIC_STATE_BUSY;
- sbic->next_target = tgt;
- sbic_attempt_selection(sbic);
- /*
- * Note that we might still lose arbitration..
- */
- }
- splx(s);
-}
-
-sbic_attempt_selection(sbic)
- sbic_softc_t sbic;
-{
- target_info_t *tgt;
- sbic_padded_regmap_t *regs;
- register unsigned char val;
- register int out_count;
-
- regs = sbic->regs;
- tgt = sbic->next_target;
-
- LOG(4,"select");
- LOG(0x80+tgt->target_id,0);
-
- /*
- * We own the bus now.. unless we lose arbitration
- */
- sbic->active_target = tgt;
-
- /* Try to avoid reselect collisions */
- GET_SBIC_asr(regs,val);
- if (val & SBIC_ASR_INT)
- return;
-
- /*
- * Init bus state variables
- */
- sbic->script = tgt->transient_state.script;
- sbic->error_handler = tgt->transient_state.handler;
- sbic->done = SCSI_RET_IN_PROGRESS;
-
- sbic->out_count = 0;
- sbic->in_count = 0;
-
- /* Define how the identify msg should be built */
- GET_SBIC_rselid(regs, val);
- val &= ~(SBIC_RID_MASK|SBIC_RID_ER);
- /* the enable reselection bit is used to build the identify msg */
- if (tgt->transient_state.identify != 0xff)
- val |= (tgt->transient_state.identify & SCSI_IFY_ENABLE_DISCONNECT) << 1;
- SET_SBIC_rselid(regs, val);
- SET_SBIC_tlun(regs, tgt->lun);
-
- /*
- * Start the chip going
- */
- out_count = (*sbic->dma_ops->start_cmd)(sbic->dma_state, tgt);
- SBIC_TC_PUT(regs, out_count);
-
- val = tgt->target_id;
- if (tgt->transient_state.in_count)
- val |= SBIC_SID_FROM_SCSI;
- SET_SBIC_selid(regs, val);
-
- SET_SBIC_timo(regs,SBIC_TIMEOUT(250,SBIC_CLOCK_FREQUENCY));
-
- SET_SBIC_syn(regs,SBIC_SYN(tgt->sync_offset,tgt->sync_period));
-
- /* ugly little help for compiler */
-#define command out_count
- if (tgt->flags & TGT_DID_SYNCH) {
- command = (tgt->transient_state.identify == 0xff) ?
- SBIC_CMD_SEL_XFER :
- SBIC_CMD_SEL_ATN_XFER; /*preferred*/
- } else if (tgt->flags & TGT_TRY_SYNCH)
- command = SBIC_CMD_SEL_ATN;
- else
- command = SBIC_CMD_SEL_XFER;
-
- /* load 10 bytes anyways, the chip knows how much to use */
- SBIC_LOAD_COMMAND(regs, tgt->cmd_ptr, 10);
-
- /* Try to avoid reselect collisions */
- GET_SBIC_asr(regs,val);
- if (val & SBIC_ASR_INT)
- return;
-
- SET_SBIC_cmd_phase(regs, 0); /* not a resume */
- SET_SBIC_cmd(regs, command);
-#undef command
-}
-
-/*
- * Interrupt routine
- * Take interrupts from the chip
- *
- * Implementation:
- * Move along the current command's script if
- * all is well, invoke error handler if not.
- */
-sbic_intr(unit, spllevel)
- spl_t spllevel;
-{
- register sbic_softc_t sbic;
- register script_t scp;
- register int asr, csr, pha;
- register sbic_padded_regmap_t *regs;
-#if MAPPABLE
- extern boolean_t rz_use_mapped_interface;
-
- if (rz_use_mapped_interface)
- return SBIC_intr(unit,spllevel);
-#endif /*MAPPABLE*/
-
- sbic = sbic_softc[unit];
- regs = sbic->regs;
-
- LOG(5,"\n\tintr");
-
- /* drop spurious interrupts */
- GET_SBIC_asr(regs, asr);
- if ((asr & SBIC_ASR_INT) == 0)
- return;
-
- /* collect ephemeral information */
- GET_SBIC_cmd_phase(regs, pha);
- GET_SBIC_csr(regs, csr);
-
-TR(csr);TR(asr);TR(pha);TRCHECK
-
- /* XXX verify this is indeed the case for a SCSI RST asserted */
- if ((csr & SBIC_CSR_CAUSE) == SBIC_CSR_RESET)
- return sbic_bus_reset(sbic);
-
- /* we got an interrupt allright */
- if (sbic->active_target)
- sbic->wd.watchdog_state = SCSI_WD_ACTIVE;
-
- splx(spllevel); /* drop priority */
-
- if ((sbic->state & SBIC_STATE_TARGET) ||
- (csr == SBIC_CSR_RSLT_AM) || (csr == SBIC_CSR_RSLT_NOAM) ||
- (csr == SBIC_CSR_SLT) || (csr == SBIC_CSR_SLT_ATN))
- return sbic_target_intr(sbic);
-
- /*
- * In attempt_selection() we gave the select command even if
- * the chip might have been reconnected already.
- */
- if ((csr == SBIC_CSR_RSLT_NI) || (csr == SBIC_CSR_RSLT_IFY))
- return sbic_reconnect(sbic, csr, pha);
-
- /*
- * Check for parity errors
- */
- if (asr & SBIC_ASR_PE) {
- char *msg;
-printf("{PE %x,%x}", asr, pha);
-
- msg = "SCSI bus parity error";
- /* all we can do is to throw a reset on the bus */
- printf( "sbic%d: %s%s", sbic - sbic_softc_data, msg,
- ", attempting recovery.\n");
- sbic_reset(regs, FALSE);
- return;
- }
-
- if ((scp = sbic->script) == 0) /* sanity */
- return;
-
- LOG(6,"match");
- if (SCRIPT_MATCH(csr,pha,scp->condition)) {
- /*
- * Perform the appropriate operation,
- * then proceed
- */
- if ((*scp->action)(sbic, csr, pha)) {
- sbic->script = scp + 1;
- }
- } else
- return (*sbic->error_handler)(sbic, csr, pha);
-}
-
-sbic_target_intr()
-{
- panic("SBIC: TARGET MODE !!!\n");
-}
-
-/*
- * Routines that the interrupt code might switch to
- */
-
-boolean_t
-sbic_end(sbic, csr, pha)
- register sbic_softc_t sbic;
-{
- register target_info_t *tgt;
- register io_req_t ior;
-
- LOG(8,"end");
-
- tgt = sbic->active_target;
- if ((tgt->done = sbic->done) == SCSI_RET_IN_PROGRESS)
- tgt->done = SCSI_RET_SUCCESS;
-
- sbic->script = 0;
-
- if (sbic->wd.nactive-- == 1)
- sbic->wd.watchdog_state = SCSI_WD_INACTIVE;
-
- sbic_release_bus(sbic);
-
- if (ior = tgt->ior) {
- (*sbic->dma_ops->end_cmd)(sbic->dma_state, tgt, ior);
- LOG(0xA,"ops->restart");
- (*tgt->dev_ops->restart)( tgt, TRUE);
- }
-
- return FALSE;
-}
-
-boolean_t
-sbic_release_bus(sbic)
- register sbic_softc_t sbic;
-{
- boolean_t ret = TRUE;
-
- LOG(9,"release");
- if (sbic->state & SBIC_STATE_COLLISION) {
-
- LOG(0xB,"collided");
- sbic->state &= ~SBIC_STATE_COLLISION;
- sbic_attempt_selection(sbic);
-
- } else if (queue_empty(&sbic->waiting_targets)) {
-
- sbic->state &= ~SBIC_STATE_BUSY;
- sbic->active_target = 0;
- sbic->script = 0;
- ret = FALSE;
-
- } else {
-
- LOG(0xC,"dequeue");
- sbic->next_target = (target_info_t *)
- dequeue_head(&sbic->waiting_targets);
- sbic_attempt_selection(sbic);
- }
- return ret;
-}
-
-boolean_t
-sbic_get_status(sbic, csr, pha)
- register sbic_softc_t sbic;
-{
- register sbic_padded_regmap_t *regs = sbic->regs;
- register scsi2_status_byte_t status;
- int len;
- io_req_t ior;
- register target_info_t *tgt = sbic->active_target;
-
- LOG(0xD,"get_status");
-TRWRAP
-
- sbic->state &= ~SBIC_STATE_DMA_IN;
-
- /*
- * Get the status byte
- */
- GET_SBIC_tlun(regs, status.bits);
-
- if (status.st.scsi_status_code != SCSI_ST_GOOD) {
- scsi_error(sbic->active_target, SCSI_ERR_STATUS, status.bits, 0);
- sbic->done = (status.st.scsi_status_code == SCSI_ST_BUSY) ?
- SCSI_RET_RETRY : SCSI_RET_NEED_SENSE;
- } else
- sbic->done = SCSI_RET_SUCCESS;
-
- /* Tell DMA engine we are done */
- (*sbic->dma_ops->end_xfer)(sbic->dma_state, tgt, tgt->transient_state.in_count);
-
- return sbic_end(sbic, csr, pha);
-
-}
-
-#if 0
-
-boolean_t
-sbic_dma_in(sbic, csr, ir)
- register sbic_softc_t sbic;
-{
- register target_info_t *tgt;
- register sbic_padded_regmap_t *regs = sbic->regs;
- register int count;
- unsigned char ff = regs->sbic_flags;
-
- LOG(0xE,"dma_in");
- tgt = sbic->active_target;
-
- sbic->state |= SBIC_STATE_DMA_IN;
-
- count = (*sbic->dma_ops->start_datain)(sbic->dma_state, tgt);
- SBIC_TC_PUT(regs, count);
-
- if ((sbic->in_count = count) == tgt->transient_state.in_count)
- return TRUE;
- regs->sbic_cmd = sbic->script->command;
- sbic->script = sbic_script_restart_data_in;
- return FALSE;
-}
-
-sbic_dma_in_r(sbic, csr, ir)
- register sbic_softc_t sbic;
-{
- register target_info_t *tgt;
- register sbic_padded_regmap_t *regs = sbic->regs;
- register int count;
- boolean_t advance_script = TRUE;
-
-
- LOG(0xE,"dma_in");
- tgt = sbic->active_target;
-
- sbic->state |= SBIC_STATE_DMA_IN;
-
- if (sbic->in_count == 0) {
- /*
- * Got nothing yet, we just reconnected.
- */
- register int avail;
-
- /*
- * Rather than using the messy RFB bit in cnfg2
- * (which only works for synch xfer anyways)
- * we just bump up the dma offset. We might
- * endup with one more interrupt at the end,
- * so what.
- * This is done in sbic_err_disconn(), this
- * way dma (of msg bytes too) is always aligned
- */
-
- count = (*sbic->dma_ops->restart_datain_1)
- (sbic->dma_state, tgt);
-
- /* common case of 8k-or-less read ? */
- advance_script = (tgt->transient_state.in_count == count);
-
- } else {
-
- /*
- * We received some data.
- */
- register int offset, xferred;
-
- /*
- * Problem: sometimes we get a 'spurious' interrupt
- * right after a reconnect. It goes like disconnect,
- * reconnect, dma_in_r, here but DMA is still rolling.
- * Since there is no good reason we got here to begin with
- * we just check for the case and dismiss it: we should
- * get another interrupt when the TC goes to zero or the
- * target disconnects.
- */
- SBIC_TC_GET(regs,xferred);
- if (xferred != 0)
- return FALSE;
-
- xferred = sbic->in_count - xferred;
- assert(xferred > 0);
-
- tgt->transient_state.in_count -= xferred;
- assert(tgt->transient_state.in_count > 0);
-
- count = (*sbic->dma_ops->restart_datain_2)
- (sbic->dma_state, tgt, xferred);
-
- sbic->in_count = count;
- SBIC_TC_PUT(regs, count);
- regs->sbic_cmd = sbic->script->command;
-
- (*sbic->dma_ops->restart_datain_3)
- (sbic->dma_state, tgt);
-
- /* last chunk ? */
- if (count == tgt->transient_state.in_count)
- sbic->script++;
-
- return FALSE;
- }
-
- sbic->in_count = count;
- SBIC_TC_PUT(regs, count);
-
- if (!advance_script) {
- regs->sbic_cmd = sbic->script->command;
- }
- return advance_script;
-}
-
-
-/* send data to target. Only called to start the xfer */
-
-boolean_t
-sbic_dma_out(sbic, csr, ir)
- register sbic_softc_t sbic;
-{
- register sbic_padded_regmap_t *regs = sbic->regs;
- register int reload_count;
- register target_info_t *tgt;
- int command;
-
- LOG(0xF,"dma_out");
-
- SBIC_TC_GET(regs, reload_count);
- sbic->extra_count = regs->sbic_flags & SBIC_FLAGS_FIFO_CNT;
- reload_count += sbic->extra_count;
- SBIC_TC_PUT(regs, reload_count);
- sbic->state &= ~SBIC_STATE_DMA_IN;
-
- tgt = sbic->active_target;
-
- command = sbic->script->command;
-
- if ((sbic->out_count = reload_count) >=
- tgt->transient_state.out_count)
- sbic->script++;
- else
- sbic->script = sbic_script_restart_data_out;
-
- if ((*sbic->dma_ops->start_dataout)
- (sbic->dma_state, tgt, &regs->sbic_cmd, command)) {
- regs->sbic_cmd = command;
- }
-
- return FALSE;
-}
-
-/* send data to target. Called in two different ways:
- (a) to restart a big transfer and
- (b) after reconnection
- */
-boolean_t
-sbic_dma_out_r(sbic, csr, ir)
- register sbic_softc_t sbic;
-{
- register sbic_padded_regmap_t *regs = sbic->regs;
- register target_info_t *tgt;
- boolean_t advance_script = TRUE;
- int count;
-
-
- LOG(0xF,"dma_out");
-
- tgt = sbic->active_target;
- sbic->state &= ~SBIC_STATE_DMA_IN;
-
- if (sbic->out_count == 0) {
- /*
- * Nothing committed: we just got reconnected
- */
- count = (*sbic->dma_ops->restart_dataout_1)
- (sbic->dma_state, tgt);
-
- /* is this the last chunk ? */
- advance_script = (tgt->transient_state.out_count == count);
- } else {
- /*
- * We sent some data.
- */
- register int offset, xferred;
-
- SBIC_TC_GET(regs,count);
-
- /* see comment above */
- if (count) {
- return FALSE;
- }
-
- count += (regs->sbic_flags & SBIC_FLAGS_FIFO_CNT);
- count -= sbic->extra_count;
- xferred = sbic->out_count - count;
- assert(xferred > 0);
-
- tgt->transient_state.out_count -= xferred;
- assert(tgt->transient_state.out_count > 0);
-
- count = (*sbic->dma_ops->restart_dataout_2)
- (sbic->dma_state, tgt, xferred);
-
- /* last chunk ? */
- if (tgt->transient_state.out_count == count)
- goto quickie;
-
- sbic->out_count = count;
-
- sbic->extra_count = (*sbic->dma_ops->restart_dataout_3)
- (sbic->dma_state, tgt, &regs->sbic_fifo);
- SBIC_TC_PUT(regs, count);
- regs->sbic_cmd = sbic->script->command;
-
- (*sbic->dma_ops->restart_dataout_4)(sbic->dma_state, tgt);
-
- return FALSE;
- }
-
-quickie:
- sbic->extra_count = (*sbic->dma_ops->restart_dataout_3)
- (sbic->dma_state, tgt, &regs->sbic_fifo);
-
- sbic->out_count = count;
-
- SBIC_TC_PUT(regs, count);
-
- if (!advance_script) {
- regs->sbic_cmd = sbic->script->command;
- }
- return advance_script;
-}
-#endif /*0*/
-
-boolean_t
-sbic_dosynch(sbic, csr, pha)
- register sbic_softc_t sbic;
- register unsigned char csr, pha;
-{
- register sbic_padded_regmap_t *regs = sbic->regs;
- register unsigned char c;
- int i, per, offs;
- register target_info_t *tgt;
-
- /*
- * Try synch negotiation
- * Phase is MSG_OUT here.
- */
- tgt = sbic->active_target;
-
-#if 0
- regs->sbic_cmd = SBIC_CMD_FLUSH;
- delay(2);
-
- per = sbic_min_period;
- if (BGET(scsi_no_synchronous_xfer,sbic->sc->masterno,tgt->target_id))
- offs = 0;
- else
- offs = sbic_max_offset;
-
- tgt->flags |= TGT_DID_SYNCH; /* only one chance */
- tgt->flags &= ~TGT_TRY_SYNCH;
-
- regs->sbic_fifo = SCSI_EXTENDED_MESSAGE;
- regs->sbic_fifo = 3;
- regs->sbic_fifo = SCSI_SYNC_XFER_REQUEST;
- regs->sbic_fifo = sbic_to_scsi_period(regs,sbic_min_period);
- regs->sbic_fifo = offs;
- regs->sbic_cmd = SBIC_CMD_XFER_INFO;
- csr = sbic_wait(regs, SBIC_CSR_INT);
- ir = regs->sbic_intr;
-
- if (SCSI_PHASE(csr) != SCSI_PHASE_MSG_IN)
- gimmeabreak();
-
- regs->sbic_cmd = SBIC_CMD_XFER_INFO;
- csr = sbic_wait(regs, SBIC_CSR_INT);
- ir = regs->sbic_intr;
-
- while ((regs->sbic_flags & SBIC_FLAGS_FIFO_CNT) > 0)
- c = regs->sbic_fifo; /* see what it says */
-
- if (c == SCSI_MESSAGE_REJECT) {
- printf(" did not like SYNCH xfer ");
-
- /* Tk50s get in trouble with ATN, sigh. */
- regs->sbic_cmd = SBIC_CMD_CLR_ATN;
-
- goto cmd;
- }
-
- /*
- * Receive the rest of the message
- */
- regs->sbic_cmd = SBIC_CMD_MSG_ACPT;
- sbic_wait(regs, SBIC_CSR_INT);
- ir = regs->sbic_intr;
-
- if (c != SCSI_EXTENDED_MESSAGE)
- gimmeabreak();
-
- regs->sbic_cmd = SBIC_CMD_XFER_INFO;
- sbic_wait(regs, SBIC_CSR_INT);
- c = regs->sbic_intr;
- if (regs->sbic_fifo != 3)
- panic("sbic_dosynch");
-
- for (i = 0; i < 3; i++) {
- regs->sbic_cmd = SBIC_CMD_MSG_ACPT;
- sbic_wait(regs, SBIC_CSR_INT);
- c = regs->sbic_intr;
-
- regs->sbic_cmd = SBIC_CMD_XFER_INFO;
- sbic_wait(regs, SBIC_CSR_INT);
- c = regs->sbic_intr;/*ack*/
- c = regs->sbic_fifo;
-
- if (i == 1) tgt->sync_period = scsi_period_to_sbic(regs,c);
- if (i == 2) tgt->sync_offset = c;
- }
-
-cmd:
- regs->sbic_cmd = SBIC_CMD_MSG_ACPT;
- csr = sbic_wait(regs, SBIC_CSR_INT);
- c = regs->sbic_intr;
-
- /* phase should normally be command here */
- if (SCSI_PHASE(csr) == SCSI_PHASE_CMD) {
- /* test unit ready or what ? */
- regs->sbic_fifo = 0;
- regs->sbic_fifo = 0;
- regs->sbic_fifo = 0;
- regs->sbic_fifo = 0;
- regs->sbic_fifo = 0;
- regs->sbic_fifo = 0;
- SBIC_TC_PUT(regs,0xff);
- regs->sbic_cmd = SBIC_CMD_XFER_PAD; /*0x98*/
- csr = sbic_wait(regs, SBIC_CSR_INT);
- ir = regs->sbic_intr;/*ack*/
- }
-
-status:
- if (SCSI_PHASE(csr) != SCSI_PHASE_STATUS)
- gimmeabreak();
-
-#endif
- return TRUE;
-}
-
-/*
- * The bus was reset
- */
-sbic_bus_reset(sbic)
- register sbic_softc_t sbic;
-{
- register sbic_padded_regmap_t *regs = sbic->regs;
-
- LOG(0x1d,"bus_reset");
-
- /*
- * Clear bus descriptor
- */
- sbic->script = 0;
- sbic->error_handler = 0;
- sbic->active_target = 0;
- sbic->next_target = 0;
- sbic->state &= SBIC_STATE_AM_MODE; /* save this one bit only */
- queue_init(&sbic->waiting_targets);
- sbic->wd.nactive = 0;
- (void) sbic_reset(regs, TRUE);
-
- printf("sbic: (%d) bus reset ", ++sbic->wd.reset_count);
- delay(scsi_delay_after_reset); /* some targets take long to reset */
-
- if (sbic->sc == 0) /* sanity */
- return;
-
- scsi_bus_was_reset(sbic->sc);
-}
-
-/*
- * Disconnect/reconnect mode ops
- */
-
-/* save all relevant data, free the BUS */
-boolean_t
-sbic_disconnected(sbic, csr, pha)
- register sbic_softc_t sbic;
- register unsigned char csr, pha;
-
-{
- register target_info_t *tgt;
-
- LOG(0x11,"disconnected");
-
- tgt = sbic->active_target;
- tgt->flags |= TGT_DISCONNECTED;
- tgt->transient_state.handler = sbic->error_handler;
- /* anything else was saved in sbic_err_disconn() */
-
- PRINT(("{D%d}", tgt->target_id));
-
- sbic_release_bus(sbic);
-
- return FALSE;
-}
-
-/* See who reconnected, restore BUS */
-boolean_t
-sbic_reconnect(sbic, csr, ir)
- register sbic_softc_t sbic;
- register unsigned char csr, ir;
-
-{
- register target_info_t *tgt;
- sbic_padded_regmap_t *regs;
- int id, pha;
-
- LOG(0x12,"reconnect");
- /*
- * See if this reconnection collided with a selection attempt
- */
- if (sbic->state & SBIC_STATE_BUSY)
- sbic->state |= SBIC_STATE_COLLISION;
-
- sbic->state |= SBIC_STATE_BUSY;
-
- /* find tgt */
- regs = sbic->regs;
- GET_SBIC_rselid(regs,id);
-
- id &= 0x7;
-
- if ((sbic->state & SBIC_STATE_AM) == 0) {
- /* Must pick the identify */
- pha = 0x44;
- } else
- pha = 0x45;
-
- tgt = sbic->sc->target[id];
- if (id > 7 || tgt == 0) panic("sbic_reconnect");
-
- /* synch things*/
- SET_SBIC_syn(regs,SBIC_SYN(tgt->sync_offset,tgt->sync_period));
-
- PRINT(("{R%d}", id));
- if (sbic->state & SBIC_STATE_COLLISION)
- PRINT(("[B %d-%d]", sbic->active_target->target_id, id));
-
- LOG(0x80+id,0);
-
- sbic->active_target = tgt;
- tgt->flags &= ~TGT_DISCONNECTED;
-
- sbic->script = tgt->transient_state.script;
- sbic->error_handler = tgt->transient_state.handler;
- sbic->in_count = 0;
- sbic->out_count = 0;
-
-set counter and setup dma, then
-
- /* Resume the command now */
- SET_SBIC_cmd_phase(regs, pha);
- SET_SBIC_cmd(regs, SBIC_CMD_SEL_XFER);
-
- return FALSE;
-}
-
-TILL HERE
-
-/*
- * Error handlers
- */
-
-/*
- * Fall-back error handler.
- */
-sbic_err_generic(sbic, csr, ir)
- register sbic_softc_t sbic;
-{
- LOG(0x13,"err_generic");
-
- /* handle non-existant or powered off devices here */
- if ((ir == SBIC_INT_DISC) &&
- (sbic_isa_select(sbic->cmd_was)) &&
- (SBIC_SS(sbic->ss_was) == 0)) {
- /* Powered off ? */
- if (sbic->active_target->flags & TGT_FULLY_PROBED)
- sbic->active_target->flags = 0;
- sbic->done = SCSI_RET_DEVICE_DOWN;
- sbic_end(sbic, csr, ir);
- return;
- }
-
- switch (SCSI_PHASE(csr)) {
- case SCSI_PHASE_STATUS:
- if (sbic->script[-1].condition == SCSI_PHASE_STATUS) {
- /* some are just slow to get out.. */
- } else
- sbic_err_to_status(sbic, csr, ir);
- return;
- break;
- case SCSI_PHASE_DATAI:
- if (sbic->script->condition == SCSI_PHASE_STATUS) {
-/* printf("{P}");*/
- return;
- }
- break;
- case SCSI_PHASE_DATAO:
- if (sbic->script->condition == SCSI_PHASE_STATUS) {
- /*
- * See comment above. Actually seen on hitachis.
- */
-/* printf("{P}");*/
- return;
- }
- }
- gimmeabreak();
-}
-
-/*
- * Handle disconnections as exceptions
- */
-sbic_err_disconn(sbic, csr, ir)
- register sbic_softc_t sbic;
- register unsigned char csr, ir;
-{
- register sbic_padded_regmap_t *regs;
- register target_info_t *tgt;
- int count;
- boolean_t callback = FALSE;
-
- LOG(0x16,"err_disconn");
-
- if (SCSI_PHASE(csr) != SCSI_PHASE_MSG_IN)
- return sbic_err_generic(sbic, csr, ir);
-
- regs = sbic->regs;
- tgt = sbic->active_target;
-
- switch (sbic->script->condition) {
- case SCSI_PHASE_DATAO:
- LOG(0x1b,"+DATAO");
- if (sbic->out_count) {
- register int xferred, offset;
-
- SBIC_TC_GET(regs,xferred); /* temporary misnomer */
- xferred += regs->sbic_flags & SBIC_FLAGS_FIFO_CNT;
- xferred -= sbic->extra_count;
- xferred = sbic->out_count - xferred; /* ok now */
- tgt->transient_state.out_count -= xferred;
- assert(tgt->transient_state.out_count > 0);
-
- callback = (*sbic->dma_ops->disconn_1)
- (sbic->dma_state, tgt, xferred);
-
- } else {
-
- callback = (*sbic->dma_ops->disconn_2)
- (sbic->dma_state, tgt);
-
- }
- sbic->extra_count = 0;
- tgt->transient_state.script = sbic_script_restart_data_out;
- break;
-
-
- case SCSI_PHASE_DATAI:
- LOG(0x17,"+DATAI");
- if (sbic->in_count) {
- register int offset, xferred;
-
- SBIC_TC_GET(regs,count);
- xferred = sbic->in_count - count;
- assert(xferred > 0);
-
-if (regs->sbic_flags & 0xf)
-printf("{Xf %x,%x,%x}", xferred, sbic->in_count, regs->sbic_flags & SBIC_FLAGS_FIFO_CNT);
- tgt->transient_state.in_count -= xferred;
- assert(tgt->transient_state.in_count > 0);
-
- callback = (*sbic->dma_ops->disconn_3)
- (sbic->dma_state, tgt, xferred);
-
- tgt->transient_state.script = sbic_script_restart_data_in;
- if (tgt->transient_state.in_count == 0)
- tgt->transient_state.script++;
-
- }
- tgt->transient_state.script = sbic->script;
- break;
-
- case SCSI_PHASE_STATUS:
- /* will have to restart dma */
- SBIC_TC_GET(regs,count);
- if (sbic->state & SBIC_STATE_DMA_IN) {
- register int offset, xferred;
-
- LOG(0x1a,"+STATUS+R");
-
- xferred = sbic->in_count - count;
- assert(xferred > 0);
-
-if (regs->sbic_flags & 0xf)
-printf("{Xf %x,%x,%x}", xferred, sbic->in_count, regs->sbic_flags & SBIC_FLAGS_FIFO_CNT);
- tgt->transient_state.in_count -= xferred;
-/* assert(tgt->transient_state.in_count > 0);*/
-
- callback = (*sbic->dma_ops->disconn_4)
- (sbic->dma_state, tgt, xferred);
-
- tgt->transient_state.script = sbic_script_restart_data_in;
- if (tgt->transient_state.in_count == 0)
- tgt->transient_state.script++;
-
- } else {
-
- /* add what's left in the fifo */
- count += (regs->sbic_flags & SBIC_FLAGS_FIFO_CNT);
- /* take back the extra we might have added */
- count -= sbic->extra_count;
- /* ..and drop that idea */
- sbic->extra_count = 0;
-
- LOG(0x19,"+STATUS+W");
-
-
- if ((count == 0) && (tgt->transient_state.out_count == sbic->out_count)) {
- /* all done */
- tgt->transient_state.script = sbic->script;
- tgt->transient_state.out_count = 0;
- } else {
- register int xferred, offset;
-
- /* how much we xferred */
- xferred = sbic->out_count - count;
-
- tgt->transient_state.out_count -= xferred;
- assert(tgt->transient_state.out_count > 0);
-
- callback = (*sbic->dma_ops->disconn_5)
- (sbic->dma_state,tgt,xferred);
-
- tgt->transient_state.script = sbic_script_restart_data_out;
- }
- sbic->out_count = 0;
- }
- break;
- default:
- gimmeabreak();
- return;
- }
- sbic_msg_in(sbic,csr,ir);
- sbic->script = sbic_script_disconnect;
- regs->sbic_cmd = SBIC_CMD_XFER_INFO|SBIC_CMD_DMA;
- if (callback)
- (*sbic->dma_ops->disconn_callback)(sbic->dma_state, tgt);
-}
-
-/*
- * Watchdog
- *
- * We know that some (name withdrawn) disks get
- * stuck in the middle of dma phases...
- */
-sbic_reset_scsibus(sbic)
- register sbic_softc_t sbic;
-{
- register target_info_t *tgt = sbic->active_target;
- register sbic_padded_regmap_t *regs = sbic->regs;
- register int ir;
-
- if (scsi_debug && tgt) {
- int dmalen;
- SBIC_TC_GET(sbic->regs,dmalen);
- printf("Target %d was active, cmd x%x in x%x out x%x Sin x%x Sou x%x dmalen x%x\n",
- tgt->target_id, tgt->cur_cmd,
- tgt->transient_state.in_count, tgt->transient_state.out_count,
- sbic->in_count, sbic->out_count,
- dmalen);
- }
- ir = regs->sbic_intr;
- if ((ir & SBIC_INT_RESEL) && (SCSI_PHASE(regs->sbic_csr) == SCSI_PHASE_MSG_IN)) {
- /* getting it out of the woods is a bit tricky */
- spl_t s = splbio();
-
- (void) sbic_reconnect(sbic, regs->sbic_csr, ir);
- sbic_wait(regs, SBIC_CSR_INT);
- ir = regs->sbic_intr;
- regs->sbic_cmd = SBIC_CMD_MSG_ACPT;
- splx(s);
- } else {
- regs->sbic_cmd = SBIC_CMD_BUS_RESET;
- delay(35);
- }
-}
-
-#endif NSBIC > 0
-
-#endif 0
diff --git a/scsi/adapters/scsi_5380.h b/scsi/adapters/scsi_5380.h
deleted file mode 100644
index 12be922..0000000
--- a/scsi/adapters/scsi_5380.h
+++ /dev/null
@@ -1,126 +0,0 @@
-/*
- * Mach Operating System
- * Copyright (c) 1991,1990,1989 Carnegie Mellon University
- * All Rights Reserved.
- *
- * Permission to use, copy, modify and distribute this software and its
- * documentation is hereby granted, provided that both the copyright
- * notice and this permission notice appear in all copies of the
- * software, derivative works or modified versions, and any portions
- * thereof, and that both notices appear in supporting documentation.
- *
- * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS
- * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
- * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
- *
- * Carnegie Mellon requests users of this software to return to
- *
- * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
- * School of Computer Science
- * Carnegie Mellon University
- * Pittsburgh PA 15213-3890
- *
- * any improvements or extensions that they make and grant Carnegie the
- * rights to redistribute these changes.
- */
-/*
- * File: scsi_5380.h
- * Author: Alessandro Forin, Carnegie Mellon University
- * Date: 5/91
- *
- * Defines for the NCR 5380 (SCSI chip), aka Am5380
- */
-
-/*
- * Register map
- */
-
-typedef struct {
- volatile unsigned char sci_data; /* r: Current data */
-#define sci_odata sci_data /* w: Out data */
- volatile unsigned char sci_icmd; /* rw: Initiator command */
- volatile unsigned char sci_mode; /* rw: Mode */
- volatile unsigned char sci_tcmd; /* rw: Target command */
- volatile unsigned char sci_bus_csr; /* r: Bus Status */
-#define sci_sel_enb sci_bus_csr /* w: Select enable */
- volatile unsigned char sci_csr; /* r: Status */
-#define sci_dma_send sci_csr /* w: Start dma send data */
- volatile unsigned char sci_idata; /* r: Input data */
-#define sci_trecv sci_idata /* w: Start dma receive, target */
- volatile unsigned char sci_iack; /* r: Interrupt Acknowledge */
-#define sci_irecv sci_iack /* w: Start dma receive, initiator */
-} sci_regmap_t;
-
-
-/*
- * Initiator command register
- */
-
-#define SCI_ICMD_DATA 0x01 /* rw: Assert data bus */
-#define SCI_ICMD_ATN 0x02 /* rw: Assert ATN signal */
-#define SCI_ICMD_SEL 0x04 /* rw: Assert SEL signal */
-#define SCI_ICMD_BSY 0x08 /* rw: Assert BSY signal */
-#define SCI_ICMD_ACK 0x10 /* rw: Assert ACK signal */
-#define SCI_ICMD_LST 0x20 /* r: Lost arbitration */
-#define SCI_ICMD_DIFF SCI_ICMD_LST /* w: Differential cable */
-#define SCI_ICMD_AIP 0x40 /* r: Arbitration in progress */
-#define SCI_ICMD_TEST SCI_ICMD_AIP /* w: Test mode */
-#define SCI_ICMD_RST 0x80 /* rw: Assert RST signal */
-
-
-/*
- * Mode register
- */
-
-#define SCI_MODE_ARB 0x01 /* rw: Start arbitration */
-#define SCI_MODE_DMA 0x02 /* rw: Enable DMA xfers */
-#define SCI_MODE_MONBSY 0x04 /* rw: Monitor BSY signal */
-#define SCI_MODE_DMA_IE 0x08 /* rw: Enable DMA complete interrupt */
-#define SCI_MODE_PERR_IE 0x10 /* rw: Interrupt on parity errors */
-#define SCI_MODE_PAR_CHK 0x20 /* rw: Check parity */
-#define SCI_MODE_TARGET 0x40 /* rw: Target mode (Initiator if 0) */
-#define SCI_MODE_BLOCKDMA 0x80 /* rw: Block-mode DMA handshake (MBZ) */
-
-
-/*
- * Target command register
- */
-
-#define SCI_TCMD_IO 0x01 /* rw: Assert I/O signal */
-#define SCI_TCMD_CD 0x02 /* rw: Assert C/D signal */
-#define SCI_TCMD_MSG 0x04 /* rw: Assert MSG signal */
-#define SCI_TCMD_PHASE_MASK 0x07 /* r: Mask for current bus phase */
-#define SCI_TCMD_REQ 0x08 /* rw: Assert REQ signal */
-#define SCI_TCMD_LAST_SENT 0x80 /* ro: Last byte was xferred
- * (not on 5380/1) */
-
-#define SCI_PHASE(x) SCSI_PHASE(x)
-
-/*
- * Current (SCSI) Bus status
- */
-
-#define SCI_BUS_DBP 0x01 /* r: Data Bus parity */
-#define SCI_BUS_SEL 0x02 /* r: SEL signal */
-#define SCI_BUS_IO 0x04 /* r: I/O signal */
-#define SCI_BUS_CD 0x08 /* r: C/D signal */
-#define SCI_BUS_MSG 0x10 /* r: MSG signal */
-#define SCI_BUS_REQ 0x20 /* r: REQ signal */
-#define SCI_BUS_BSY 0x40 /* r: BSY signal */
-#define SCI_BUS_RST 0x80 /* r: RST signal */
-
-#define SCI_CUR_PHASE(x) SCSI_PHASE((x)>>2)
-
-/*
- * Bus and Status register
- */
-
-#define SCI_CSR_ACK 0x01 /* r: ACK signal */
-#define SCI_CSR_ATN 0x02 /* r: ATN signal */
-#define SCI_CSR_DISC 0x04 /* r: Disconnected (BSY==0) */
-#define SCI_CSR_PHASE_MATCH 0x08 /* r: Bus and SCI_TCMD match */
-#define SCI_CSR_INT 0x10 /* r: Interrupt request */
-#define SCI_CSR_PERR 0x20 /* r: Parity error */
-#define SCI_CSR_DREQ 0x40 /* r: DMA request */
-#define SCI_CSR_DONE 0x80 /* r: DMA count is zero */
-
diff --git a/scsi/adapters/scsi_5380_hdw.c b/scsi/adapters/scsi_5380_hdw.c
deleted file mode 100644
index 2fc7d89..0000000
--- a/scsi/adapters/scsi_5380_hdw.c
+++ /dev/null
@@ -1,2423 +0,0 @@
-/*
- * Mach Operating System
- * Copyright (c) 1991,1990,1989 Carnegie Mellon University
- * All Rights Reserved.
- *
- * Permission to use, copy, modify and distribute this software and its
- * documentation is hereby granted, provided that both the copyright
- * notice and this permission notice appear in all copies of the
- * software, derivative works or modified versions, and any portions
- * thereof, and that both notices appear in supporting documentation.
- *
- * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS
- * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
- * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
- *
- * Carnegie Mellon requests users of this software to return to
- *
- * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
- * School of Computer Science
- * Carnegie Mellon University
- * Pittsburgh PA 15213-3890
- *
- * any improvements or extensions that they make and grant Carnegie the
- * rights to redistribute these changes.
- */
-/*
- * File: scsi_5380_hdw.c
- * Author: Alessandro Forin, Carnegie Mellon University
- * Date: 4/91
- *
- * Bottom layer of the SCSI driver: chip-dependent functions
- *
- * This file contains the code that is specific to the NCR 5380
- * SCSI chip (Host Bus Adapter in SCSI parlance): probing, start
- * operation, and interrupt routine.
- */
-
-/*
- * This layer works based on small simple 'scripts' that are installed
- * at the start of the command and drive the chip to completion.
- * The idea comes from the specs of the NCR 53C700 'script' processor.
- *
- * There are various reasons for this, mainly
- * - Performance: identify the common (successful) path, and follow it;
- * at interrupt time no code is needed to find the current status
- * - Code size: it should be easy to compact common operations
- * - Adaptability: the code skeleton should adapt to different chips without
- * terrible complications.
- * - Error handling: and it is easy to modify the actions performed
- * by the scripts to cope with strange but well identified sequences
- *
- */
-
-#include <sci.h>
-#if NSCI > 0
-#include <platforms.h>
-
-#include <mach/std_types.h>
-#include <sys/types.h>
-#include <chips/busses.h>
-#include <scsi/compat_30.h>
-#include <machine/machspl.h>
-
-#include <sys/syslog.h>
-
-#include <scsi/scsi.h>
-#include <scsi/scsi2.h>
-#include <scsi/scsi_defs.h>
-
-#ifdef VAXSTATION
-#define PAD(n) char n[3]
-#endif
-
-#include <scsi/adapters/scsi_5380.h>
-
-#ifdef PAD
-typedef struct {
- volatile unsigned char sci_data; /* r: Current data */
-/*#define sci_odata sci_data /* w: Out data */
- PAD(pad0);
-
- volatile unsigned char sci_icmd; /* rw: Initiator command */
- PAD(pad1);
-
- volatile unsigned char sci_mode; /* rw: Mode */
- PAD(pad2);
-
- volatile unsigned char sci_tcmd; /* rw: Target command */
- PAD(pad3);
-
- volatile unsigned char sci_bus_csr; /* r: Bus Status */
-/*#define sci_sel_enb sci_bus_csr /* w: Select enable */
- PAD(pad4);
-
- volatile unsigned char sci_csr; /* r: Status */
-/*#define sci_dma_send sci_csr /* w: Start dma send data */
- PAD(pad5);
-
- volatile unsigned char sci_idata; /* r: Input data */
-/*#define sci_trecv sci_idata /* w: Start dma receive, target */
- PAD(pad6);
-
- volatile unsigned char sci_iack; /* r: Interrupt Acknowledge */
-/*#define sci_irecv sci_iack /* w: Start dma receive, initiator */
- PAD(pad7);
-
-} sci_padded_regmap_t;
-#else
-typedef sci_regmap_t sci_padded_regmap_t;
-#endif
-
-#ifdef VAXSTATION
-#define check_memory(addr,dow) ((dow) ? wbadaddr(addr,4) : badaddr(addr,4))
-
-/* vax3100 */
-#include <chips/vs42x_rb.h>
-#define STC_5380_A VAX3100_STC_5380_A
-#define STC_5380_B VAX3100_STC_5380_B
-#define STC_DMAREG_OFF VAX3100_STC_DMAREG_OFF
-
-static int mem; /* mem++ seems to take approx 0.34 usecs */
-#define delay_1p2_us() {mem++;mem++;mem++;mem++;}
-#define my_scsi_id(ctlr) (ka3100_scsi_id((ctlr)))
-#endif /* VAXSTATION */
-
-
-#ifndef STC_5380_A /* cross compile check */
-typedef struct {
- int sci_dma_dir, sci_dma_adr;
-} *sci_dmaregs_t;
-#define STC_DMAREG_OFF 0
-#define SCI_DMA_DIR_WRITE 0
-#define SCI_DMA_DIR_READ 1
-#define STC_5380_A 0
-#define STC_5380_B 0x100
-#define SCI_RAM_SIZE 0x10000
-#endif
-
-/*
- * The 5380 can't tell you the scsi ID it uses, so
- * unless there is another way use the defaults
- */
-#ifndef my_scsi_id
-#define my_scsi_id(ctlr) (scsi_initiator_id[(ctlr)])
-#endif
-
-/*
- * Statically partition the DMA buffer between targets.
- * This way we will eventually be able to attach/detach
- * drives on-fly. And 18k/target is enough.
- */
-#define PER_TGT_DMA_SIZE ((SCI_RAM_SIZE/7) & ~(sizeof(int)-1))
-
-/*
- * Round to 4k to make debug easier
- */
-#define PER_TGT_BUFF_SIZE ((PER_TGT_DMA_SIZE >> 12) << 12)
-#define PER_TGT_BURST_SIZE (PER_TGT_BUFF_SIZE>>1)
-
-/*
- * Macros to make certain things a little more readable
- */
-
-#define SCI_ACK(ptr,phase) (ptr)->sci_tcmd = (phase)
-#define SCI_CLR_INTR(regs) {register int temp = regs->sci_iack;}
-
-
-/*
- * A script has a two parts: a pre-condition and an action.
- * The first triggers error handling if not satisfied and in
- * our case it is formed by the current bus phase and connected
- * condition as per bus status bits. The action part is just a
- * function pointer, invoked in a standard way. The script
- * pointer is advanced only if the action routine returns TRUE.
- * See sci_intr() for how and where this is all done.
- */
-
-typedef struct script {
- int condition; /* expected state at interrupt */
- int (*action)(); /* action routine */
-} *script_t;
-
-#define SCRIPT_MATCH(cs,bs) (((bs)&SCI_BUS_BSY)|SCI_CUR_PHASE((bs)))
-
-#define SCI_PHASE_DISC 0x0 /* sort of .. */
-
-
-/* forward decls of script actions */
-boolean_t
- sci_dosynch(), /* negotiate synch xfer */
- sci_dma_in(), /* get data from target via dma */
- sci_dma_out(), /* send data to target via dma */
- sci_get_status(), /* get status from target */
- sci_end_transaction(), /* all come to an end */
- sci_msg_in(), /* get disconnect message(s) */
- sci_disconnected(); /* current target disconnected */
-/* forward decls of error handlers */
-boolean_t
- sci_err_generic(), /* generic error handler */
- sci_err_disconn(), /* when a target disconnects */
- gimmeabreak(); /* drop into the debugger */
-
-int sci_reset_scsibus();
-boolean_t sci_probe_target();
-
-scsi_ret_t sci_select_target();
-
-#ifdef VAXSTATION
-/*
- * This should be somewhere else, and it was a
- * mistake to share this buffer across SCSIs.
- */
-struct dmabuffer {
- volatile char *base;
- char *sbrk;
-} dmab[1];
-
-volatile char *
-sci_buffer_base(unit)
-{
- return dmab[unit].base;
-}
-
-sci_buffer_init(dmar, ram)
- sci_dmaregs_t dmar;
- volatile char *ram;
-{
- dmar->sci_dma_rammode = SCI_RAM_EXPMODE;
- dmab[0].base = dmab[0].sbrk = (char *) ram;
- blkclr((char *) ram, SCI_RAM_SIZE);
-}
-char *
-sci_buffer_sbrk(size)
-{
- char *ret = dmab[0].sbrk;
-
- dmab[0].sbrk += size;
- if ((dmab[0].sbrk - dmab[0].base) > SCI_RAM_SIZE)
- panic("scialloc");
- return ret;
-}
-
-#endif /* VAXSTATION */
-
-/*
- * State descriptor for this layer. There is one such structure
- * per (enabled) 5380 interface
- */
-struct sci_softc {
- watchdog_t wd;
- sci_padded_regmap_t *regs; /* 5380 registers */
- sci_dmaregs_t dmar; /* DMA controller registers */
- volatile char *buff; /* DMA buffer memory (I/O space) */
- script_t script;
- int (*error_handler)();
- int in_count; /* amnt we expect to receive */
- int out_count; /* amnt we are going to ship */
-
- volatile char state;
-#define SCI_STATE_BUSY 0x01 /* selecting or currently connected */
-#define SCI_STATE_TARGET 0x04 /* currently selected as target */
-#define SCI_STATE_COLLISION 0x08 /* lost selection attempt */
-#define SCI_STATE_DMA_IN 0x10 /* tgt --> initiator xfer */
-
- unsigned char ntargets; /* how many alive on this scsibus */
- unsigned char done;
- unsigned char extra_byte;
-
- scsi_softc_t *sc;
- target_info_t *active_target;
-
- target_info_t *next_target; /* trying to seize bus */
- queue_head_t waiting_targets;/* other targets competing for bus */
-
-} sci_softc_data[NSCI];
-
-typedef struct sci_softc *sci_softc_t;
-
-sci_softc_t sci_softc[NSCI];
-
-/*
- * Definition of the controller for the auto-configuration program.
- */
-
-int sci_probe(), scsi_slave(), sci_go(), sci_intr();
-void scsi_attach();
-
-vm_offset_t sci_std[NSCI] = { 0 };
-struct bus_device *sci_dinfo[NSCI*8];
-struct bus_ctlr *sci_minfo[NSCI];
-struct bus_driver sci_driver =
- { sci_probe, scsi_slave, scsi_attach, sci_go, sci_std, "rz", sci_dinfo,
- "sci", sci_minfo, BUS_INTR_B4_PROBE};
-
-/*
- * Scripts
- */
-struct script
-sci_script_data_in[] = {
- { SCSI_PHASE_DATAI|SCI_BUS_BSY, sci_dma_in},
- { SCSI_PHASE_STATUS|SCI_BUS_BSY, sci_get_status},
- { SCSI_PHASE_MSG_IN|SCI_BUS_BSY, sci_end_transaction}
-},
-
-sci_script_data_out[] = {
- { SCSI_PHASE_DATAO|SCI_BUS_BSY, sci_dma_out},
- { SCSI_PHASE_STATUS|SCI_BUS_BSY, sci_get_status},
- { SCSI_PHASE_MSG_IN|SCI_BUS_BSY, sci_end_transaction}
-},
-
-sci_script_cmd[] = {
- { SCSI_PHASE_STATUS|SCI_BUS_BSY, sci_get_status},
- { SCSI_PHASE_MSG_IN|SCI_BUS_BSY, sci_end_transaction}
-},
-
-/* Synchronous transfer neg(oti)ation */
-
-sci_script_try_synch[] = {
- { SCSI_PHASE_MSG_OUT|SCI_BUS_BSY, sci_dosynch}
-},
-
-/* Disconnect sequence */
-
-sci_script_disconnect[] = {
- { SCI_PHASE_DISC, sci_disconnected}
-};
-
-
-
-#define u_min(a,b) (((a) < (b)) ? (a) : (b))
-
-
-#define DEBUG
-#ifdef DEBUG
-
-sci_state(base)
- vm_offset_t base;
-{
- sci_padded_regmap_t *regs;
- sci_dmaregs_t dmar;
- extern char *sci;
- unsigned dmadr;
- int cnt, i;
-
- if (base == 0)
- base = (vm_offset_t)sci;
-
- for (i = 0; i < 2; i++) {
- regs = (sci_padded_regmap_t*) (base +
- (i ? STC_5380_B : STC_5380_A));
- dmar = (sci_dmaregs_t) ((char*)regs + STC_DMAREG_OFF);
- SCI_DMADR_GET(dmar,dmadr);
- SCI_TC_GET(dmar,cnt);
-
- db_printf("scsi%d: ph %x (sb %x), mode %x, tph %x, csr %x, cmd %x, ",
- i,
- (unsigned) SCI_CUR_PHASE(regs->sci_bus_csr),
- (unsigned) regs->sci_bus_csr,
- (unsigned) regs->sci_mode,
- (unsigned) regs->sci_tcmd,
- (unsigned) regs->sci_csr,
- (unsigned) regs->sci_icmd);
- db_printf("dma%c %x @ %x\n",
- (dmar->sci_dma_dir) ? 'I' : 'O', cnt, dmadr);
- }
- return 0;
-}
-sci_target_state(tgt)
- target_info_t *tgt;
-{
- if (tgt == 0)
- tgt = sci_softc[0]->active_target;
- if (tgt == 0)
- return 0;
- db_printf("fl %x dma %x+%x cmd %x id %x per %x off %x ior %x ret %x\n",
- tgt->flags, tgt->dma_ptr, tgt->transient_state.dma_offset,
- tgt->cmd_ptr, tgt->target_id, tgt->sync_period, tgt->sync_offset,
- tgt->ior, tgt->done);
- if (tgt->flags & TGT_DISCONNECTED){
- script_t spt;
-
- spt = tgt->transient_state.script;
- db_printf("disconnected at ");
- db_printsym(spt,1);
- db_printf(": %x ", spt->condition);
- db_printsym(spt->action,1);
- db_printf(", ");
- db_printsym(tgt->transient_state.handler, 1);
- db_printf("\n");
- }
-
- return 0;
-}
-
-sci_all_targets(unit)
-{
- int i;
- target_info_t *tgt;
- for (i = 0; i < 8; i++) {
- tgt = sci_softc[unit]->sc->target[i];
- if (tgt)
- sci_target_state(tgt);
- }
-}
-
-sci_script_state(unit)
-{
- script_t spt = sci_softc[unit]->script;
-
- if (spt == 0) return 0;
- db_printsym(spt,1);
- db_printf(": %x ", spt->condition);
- db_printsym(spt->action,1);
- db_printf(", ");
- db_printsym(sci_softc[unit]->error_handler, 1);
- return 0;
-
-}
-
-#define PRINT(x) if (scsi_debug) printf x
-
-#define TRMAX 200
-int tr[TRMAX+3];
-int trpt, trpthi;
-#define TR(x) tr[trpt++] = x
-#define TRWRAP trpthi = trpt; trpt = 0;
-#define TRCHECK if (trpt > TRMAX) {TRWRAP}
-
-#define TRACE
-
-#ifdef TRACE
-
-#define LOGSIZE 256
-int sci_logpt;
-char sci_log[LOGSIZE];
-
-#define MAXLOG_VALUE 0x24
-struct {
- char *name;
- unsigned int count;
-} logtbl[MAXLOG_VALUE];
-
-static LOG(e,f)
- char *f;
-{
- sci_log[sci_logpt++] = (e);
- if (sci_logpt == LOGSIZE) sci_logpt = 0;
- if ((e) < MAXLOG_VALUE) {
- logtbl[(e)].name = (f);
- logtbl[(e)].count++;
- }
-}
-
-sci_print_log(skip)
- int skip;
-{
- register int i, j;
- register unsigned char c;
-
- for (i = 0, j = sci_logpt; i < LOGSIZE; i++) {
- c = sci_log[j];
- if (++j == LOGSIZE) j = 0;
- if (skip-- > 0)
- continue;
- if (c < MAXLOG_VALUE)
- db_printf(" %s", logtbl[c].name);
- else
- db_printf("-%d", c & 0x7f);
- }
- db_printf("\n");
- return 0;
-}
-
-sci_print_stat()
-{
- register int i;
- register char *p;
- for (i = 0; i < MAXLOG_VALUE; i++) {
- if (p = logtbl[i].name)
- printf("%d %s\n", logtbl[i].count, p);
- }
-}
-
-#else /* TRACE */
-#define LOG(e,f)
-#endif /* TRACE */
-
-#else /* DEBUG */
-#define PRINT(x)
-#define LOG(e,f)
-#define TR(x)
-#define TRCHECK
-#define TRWRAP
-#endif /* DEBUG */
-
-
-/*
- * Probe/Slave/Attach functions
- */
-
-/*
- * Probe routine:
- * Should find out (a) if the controller is
- * present and (b) which/where slaves are present.
- *
- * Implementation:
- * Send an identify msg to each possible target on the bus
- * except of course ourselves.
- */
-sci_probe(reg, ui)
- char *reg;
- struct bus_ctlr *ui;
-{
- int unit = ui->unit;
- sci_softc_t sci = &sci_softc_data[unit];
- int target_id, i;
- scsi_softc_t *sc;
- register sci_padded_regmap_t *regs;
- spl_t s;
- boolean_t did_banner = FALSE;
- char *cmd_ptr;
- static char *here = "sci_probe";
-
- /*
- * We are only called if the chip is there,
- * but make sure anyways..
- */
- regs = (sci_padded_regmap_t *) (reg);
- if (check_memory(regs, 0))
- return 0;
-
-#if notyet
- /* Mappable version side */
- SCI_probe(reg, ui);
-#endif
-
- /*
- * Initialize hw descriptor
- */
- sci_softc[unit] = sci;
- sci->regs = regs;
- sci->dmar = (sci_dmaregs_t)(reg + STC_DMAREG_OFF);
- sci->buff = sci_buffer_base(0);
-
- queue_init(&sci->waiting_targets);
-
- sc = scsi_master_alloc(unit, sci);
- sci->sc = sc;
-
- sc->go = sci_go;
- sc->probe = sci_probe_target;
- sc->watchdog = scsi_watchdog;
- sci->wd.reset = sci_reset_scsibus;
-
-#ifdef MACH_KERNEL
- sc->max_dma_data = -1; /* unlimited */
-#else
- sc->max_dma_data = scsi_per_target_virtual;
-#endif
-
- scsi_might_disconnect[unit] = 0; /* still true */
-
- /*
- * Reset chip
- */
- s = splbio();
- sci_reset(sci, TRUE);
- SCI_CLR_INTR(regs);
-
- /*
- * Our SCSI id on the bus.
- */
-
- sc->initiator_id = my_scsi_id(unit);
- printf("%s%d: my SCSI id is %d", ui->name, unit, sc->initiator_id);
-
- /*
- * For all possible targets, see if there is one and allocate
- * a descriptor for it if it is there.
- */
- cmd_ptr = sci_buffer_sbrk(0);
- for (target_id = 0; target_id < 8; target_id++) {
-
- register unsigned csr, dsr;
- scsi_status_byte_t status;
-
- /* except of course ourselves */
- if (target_id == sc->initiator_id)
- continue;
-
- if (sci_select_target( regs, sc->initiator_id, target_id, FALSE) == SCSI_RET_DEVICE_DOWN) {
- SCI_CLR_INTR(regs);
- continue;
- }
-
- printf(",%s%d", did_banner++ ? " " : " target(s) at ",
- target_id);
-
- /* should be command phase here: we selected wo ATN! */
- while (SCI_CUR_PHASE(regs->sci_bus_csr) != SCSI_PHASE_CMD)
- ;
-
- SCI_ACK(regs,SCSI_PHASE_CMD);
-
- /* build command in dma area */
- {
- unsigned char *p = (unsigned char*) cmd_ptr;
-
- p[0] = SCSI_CMD_TEST_UNIT_READY;
- p[1] =
- p[2] =
- p[3] =
- p[4] =
- p[5] = 0;
- }
-
- sci_data_out(regs, SCSI_PHASE_CMD, 6, cmd_ptr);
-
- while (SCI_CUR_PHASE(regs->sci_bus_csr) != SCSI_PHASE_STATUS)
- ;
-
- SCI_ACK(regs,SCSI_PHASE_STATUS);
-
- sci_data_in(regs, SCSI_PHASE_STATUS, 1, &status.bits);
-
- if (status.st.scsi_status_code != SCSI_ST_GOOD)
- scsi_error( 0, SCSI_ERR_STATUS, status.bits, 0);
-
- /* get cmd_complete message */
- while (SCI_CUR_PHASE(regs->sci_bus_csr) != SCSI_PHASE_MSG_IN)
- ;
-
- SCI_ACK(regs,SCSI_PHASE_MSG_IN);
-
- sci_data_in(regs, SCSI_PHASE_MSG_IN, 1, &i);
-
- /* check disconnected, clear all intr bits */
- while (regs->sci_bus_csr & SCI_BUS_BSY)
- ;
- SCI_ACK(regs,SCI_PHASE_DISC);
-
- SCI_CLR_INTR(regs);
-
- /* ... */
-
- /*
- * Found a target
- */
- sci->ntargets++;
- {
- register target_info_t *tgt;
-
- tgt = scsi_slave_alloc(unit, target_id, sci);
-
- /* "virtual" address for our use */
- tgt->cmd_ptr = sci_buffer_sbrk(PER_TGT_DMA_SIZE);
- /* "physical" address for dma engine */
- tgt->dma_ptr = (char*)(tgt->cmd_ptr - sci->buff);
-#ifdef MACH_KERNEL
-#else /*MACH_KERNEL*/
- fdma_init(&tgt->fdma, scsi_per_target_virtual);
-#endif /*MACH_KERNEL*/
- }
- }
- printf(".\n");
-
- splx(s);
- return 1;
-}
-
-boolean_t
-sci_probe_target(tgt, ior)
- target_info_t *tgt;
- io_req_t ior;
-{
- sci_softc_t sci = sci_softc[tgt->masterno];
- boolean_t newlywed;
-
- newlywed = (tgt->cmd_ptr == 0);
- if (newlywed) {
- /* desc was allocated afresh */
-
- /* "virtual" address for our use */
- tgt->cmd_ptr = sci_buffer_sbrk(PER_TGT_DMA_SIZE);
- /* "physical" address for dma engine */
- tgt->dma_ptr = (char*)(tgt->cmd_ptr - sci->buff);
-#ifdef MACH_KERNEL
-#else /*MACH_KERNEL*/
- fdma_init(&tgt->fdma, scsi_per_target_virtual);
-#endif /*MACH_KERNEL*/
-
- }
-
- if (scsi_inquiry(tgt, SCSI_INQ_STD_DATA) == SCSI_RET_DEVICE_DOWN)
- return FALSE;
-
- tgt->flags = TGT_ALIVE;
- return TRUE;
-}
-
-
-static sci_wait(preg, until)
- volatile unsigned char *preg;
-{
- int timeo = 1000000;
- /* read it over to avoid bus glitches */
- while ( ((*preg & until) != until) ||
- ((*preg & until) != until) ||
- ((*preg & until) != until)) {
- delay(1);
- if (!timeo--) {
- printf("sci_wait TIMEO with x%x\n", *preg);
- break;
- }
- }
- return *preg;
-}
-
-scsi_ret_t
-sci_select_target(regs, myid, id, with_atn)
- register sci_padded_regmap_t *regs;
- unsigned char myid, id;
- boolean_t with_atn;
-{
- register unsigned char bid, icmd;
- scsi_ret_t ret = SCSI_RET_RETRY;
-
- if ((regs->sci_bus_csr & (SCI_BUS_BSY|SCI_BUS_SEL)) &&
- (regs->sci_bus_csr & (SCI_BUS_BSY|SCI_BUS_SEL)) &&
- (regs->sci_bus_csr & (SCI_BUS_BSY|SCI_BUS_SEL)))
- return ret;
-
- /* for our purposes.. */
- myid = 1 << myid;
- id = 1 << id;
-
- regs->sci_sel_enb = myid; /* if not there already */
-
- regs->sci_odata = myid;
- regs->sci_mode |= SCI_MODE_ARB;
- /* AIP might not set if BSY went true after we checked */
- for (bid = 0; bid < 20; bid++) /* 20usec circa */
- if (regs->sci_icmd & SCI_ICMD_AIP)
- break;
- if ((regs->sci_icmd & SCI_ICMD_AIP) == 0) {
- goto lost;
- }
-
- delay(2); /* 2.2us arb delay */
-
- if (regs->sci_icmd & SCI_ICMD_LST) {
- goto lost;
- }
-
- regs->sci_mode &= ~SCI_MODE_PAR_CHK;
- bid = regs->sci_data;
-
- if ((bid & ~myid) > myid) {
- goto lost;
- }
- if (regs->sci_icmd & SCI_ICMD_LST) {
- goto lost;
- }
-
- /* Won arbitration, enter selection phase now */
- icmd = regs->sci_icmd & ~(SCI_ICMD_DIFF|SCI_ICMD_TEST);
- icmd |= (with_atn ? (SCI_ICMD_SEL|SCI_ICMD_ATN) : SCI_ICMD_SEL);
- regs->sci_icmd = icmd;
-
- if (regs->sci_icmd & SCI_ICMD_LST) {
- goto nosel;
- }
-
- /* XXX a target that violates specs might still drive the bus XXX */
- /* XXX should put our id out, and after the delay check nothi XXX */
- /* XXX ng else is out there. XXX */
-
- delay_1p2_us();
-
- regs->sci_sel_enb = 0;
-
- regs->sci_odata = myid | id;
-
- icmd |= SCI_ICMD_BSY|SCI_ICMD_DATA;
- regs->sci_icmd = icmd;
-
- regs->sci_mode &= ~SCI_MODE_ARB; /* 2 deskew delays, too */
-
- icmd &= ~SCI_ICMD_BSY;
- regs->sci_icmd = icmd;
-
- /* bus settle delay, 400ns */
- delay(0); /* too much ? */
-
- regs->sci_mode |= SCI_MODE_PAR_CHK;
-
- {
- register int timeo = 2500;/* 250 msecs in 100 usecs chunks */
- while ((regs->sci_bus_csr & SCI_BUS_BSY) == 0)
- if (--timeo > 0)
- delay(100);
- else {
- goto nodev;
- }
- }
-
- icmd &= ~(SCI_ICMD_DATA|SCI_ICMD_SEL);
- regs->sci_icmd = icmd;
-/* regs->sci_sel_enb = myid;*/ /* looks like we should NOT have it */
- return SCSI_RET_SUCCESS;
-nodev:
- ret = SCSI_RET_DEVICE_DOWN;
- regs->sci_sel_enb = myid;
-nosel:
- icmd &= ~(SCI_ICMD_DATA|SCI_ICMD_SEL|SCI_ICMD_ATN);
- regs->sci_icmd = icmd;
-lost:
- bid = regs->sci_mode;
- bid &= ~SCI_MODE_ARB;
- bid |= SCI_MODE_PAR_CHK;
- regs->sci_mode = bid;
-
- return ret;
-}
-
-sci_data_out(regs, phase, count, data)
- register sci_padded_regmap_t *regs;
- unsigned char *data;
-{
- register unsigned char icmd;
-
- /* ..checks.. */
-
- icmd = regs->sci_icmd & ~(SCI_ICMD_DIFF|SCI_ICMD_TEST);
-loop:
- if (SCI_CUR_PHASE(regs->sci_bus_csr) != phase)
- return count;
-
- while ( ((regs->sci_bus_csr & SCI_BUS_REQ) == 0) &&
- ((regs->sci_bus_csr & SCI_BUS_REQ) == 0) &&
- ((regs->sci_bus_csr & SCI_BUS_REQ) == 0))
- ;
- icmd |= SCI_ICMD_DATA;
- regs->sci_icmd = icmd;
- regs->sci_odata = *data++;
- icmd |= SCI_ICMD_ACK;
- regs->sci_icmd = icmd;
-
- icmd &= ~(SCI_ICMD_DATA|SCI_ICMD_ACK);
- while ( (regs->sci_bus_csr & SCI_BUS_REQ) &&
- (regs->sci_bus_csr & SCI_BUS_REQ) &&
- (regs->sci_bus_csr & SCI_BUS_REQ))
- ;
- regs->sci_icmd = icmd;
- if (--count > 0)
- goto loop;
- return 0;
-}
-
-sci_data_in(regs, phase, count, data)
- register sci_padded_regmap_t *regs;
- unsigned char *data;
-{
- register unsigned char icmd;
-
- /* ..checks.. */
-
- icmd = regs->sci_icmd & ~(SCI_ICMD_DIFF|SCI_ICMD_TEST);
-loop:
- if (SCI_CUR_PHASE(regs->sci_bus_csr) != phase)
- return count;
-
- while ( ((regs->sci_bus_csr & SCI_BUS_REQ) == 0) &&
- ((regs->sci_bus_csr & SCI_BUS_REQ) == 0) &&
- ((regs->sci_bus_csr & SCI_BUS_REQ) == 0))
- ;
- *data++ = regs->sci_data;
- icmd |= SCI_ICMD_ACK;
- regs->sci_icmd = icmd;
-
- icmd &= ~SCI_ICMD_ACK;
- while ( (regs->sci_bus_csr & SCI_BUS_REQ) &&
- (regs->sci_bus_csr & SCI_BUS_REQ) &&
- (regs->sci_bus_csr & SCI_BUS_REQ))
- ;
- regs->sci_icmd = icmd;
- if (--count > 0)
- goto loop;
- return 0;
-
-}
-
-sci_reset(sci, quickly)
- sci_softc_t sci;
- boolean_t quickly;
-{
- register sci_padded_regmap_t *regs = sci->regs;
- register sci_dmaregs_t dma = sci->dmar;
- int dummy;
-
- regs->sci_icmd = SCI_ICMD_TEST; /* don't drive outputs */
- regs->sci_icmd = SCI_ICMD_TEST|SCI_ICMD_RST;
- delay(25);
- regs->sci_icmd = 0;
-
- regs->sci_mode = SCI_MODE_PAR_CHK|SCI_MODE_PERR_IE;
- regs->sci_tcmd = SCI_PHASE_DISC; /* make sure we do not miss transition */
- regs->sci_sel_enb = 0;
-
- /* idle the dma controller */
- dma->sci_dma_adr = 0;
- dma->sci_dma_dir = SCI_DMA_DIR_WRITE;
- SCI_TC_PUT(dma,0);
-
- /* clear interrupt (two might be queued?) */
- SCI_CLR_INTR(regs);
- SCI_CLR_INTR(regs);
-
- if (quickly)
- return;
-
- /*
- * reset the scsi bus, the interrupt routine does the rest
- * or you can call sci_bus_reset().
- */
- regs->sci_icmd = SCI_ICMD_RST;
-
-}
-
-/*
- * Operational functions
- */
-
-/*
- * Start a SCSI command on a target
- */
-sci_go(tgt, cmd_count, in_count, cmd_only)
- target_info_t *tgt;
- boolean_t cmd_only;
-{
- sci_softc_t sci;
- register spl_t s;
- boolean_t disconn;
- script_t scp;
- boolean_t (*handler)();
-
- LOG(1,"go");
-
- sci = (sci_softc_t)tgt->hw_state;
-
- /*
- * We cannot do real DMA.
- */
-#ifdef MACH_KERNEL
-#else /*MACH_KERNEL*/
- if (tgt->ior)
- fdma_map(&tgt->fdma, tgt->ior);
-#endif /*MACH_KERNEL*/
-
- if ((tgt->cur_cmd == SCSI_CMD_WRITE) ||
- (tgt->cur_cmd == SCSI_CMD_LONG_WRITE)){
- io_req_t ior = tgt->ior;
- register int len = ior->io_count;
-
- tgt->transient_state.out_count = len;
-
- if (len > PER_TGT_BUFF_SIZE)
- len = PER_TGT_BUFF_SIZE;
- bcopy( ior->io_data,
- tgt->cmd_ptr + cmd_count,
- len);
- tgt->transient_state.copy_count = len;
-
- /* avoid leaks */
- if (len < tgt->block_size) {
- bzero( tgt->cmd_ptr + cmd_count + len,
- tgt->block_size - len);
- tgt->transient_state.out_count = tgt->block_size;
- }
- } else {
- tgt->transient_state.out_count = 0;
- tgt->transient_state.copy_count = 0;
- }
-
- tgt->transient_state.cmd_count = cmd_count;
-
- disconn = BGET(scsi_might_disconnect,tgt->masterno,tgt->target_id);
- disconn = disconn && (sci->ntargets > 1);
- disconn |= BGET(scsi_should_disconnect,tgt->masterno,tgt->target_id);
-
- /*
- * Setup target state
- */
- tgt->done = SCSI_RET_IN_PROGRESS;
-
- handler = (disconn) ? sci_err_disconn : sci_err_generic;
-
- switch (tgt->cur_cmd) {
- case SCSI_CMD_READ:
- case SCSI_CMD_LONG_READ:
- LOG(0x13,"readop");
- scp = sci_script_data_in;
- break;
- case SCSI_CMD_WRITE:
- case SCSI_CMD_LONG_WRITE:
- LOG(0x14,"writeop");
- scp = sci_script_data_out;
- break;
- case SCSI_CMD_INQUIRY:
- /* This is likely the first thing out:
- do the synch neg if so */
- if (!cmd_only && ((tgt->flags&TGT_DID_SYNCH)==0)) {
- scp = sci_script_try_synch;
- tgt->flags |= TGT_TRY_SYNCH;
- break;
- }
- case SCSI_CMD_REQUEST_SENSE:
- case SCSI_CMD_MODE_SENSE:
- case SCSI_CMD_RECEIVE_DIAG_RESULTS:
- case SCSI_CMD_READ_CAPACITY:
- case SCSI_CMD_READ_BLOCK_LIMITS:
- case SCSI_CMD_READ_TOC:
- case SCSI_CMD_READ_SUBCH:
- case SCSI_CMD_READ_HEADER:
- case 0xc4: /* despised: SCSI_CMD_DEC_PLAYBACK_STATUS */
- case 0xdd: /* despised: SCSI_CMD_NEC_READ_SUBCH_Q */
- case 0xde: /* despised: SCSI_CMD_NEC_READ_TOC */
- scp = sci_script_data_in;
- LOG(0x1c,"cmdop");
- LOG(0x80+tgt->cur_cmd,0);
- break;
- case SCSI_CMD_MODE_SELECT:
- case SCSI_CMD_REASSIGN_BLOCKS:
- case SCSI_CMD_FORMAT_UNIT:
- case 0xc9: /* vendor-spec: SCSI_CMD_DEC_PLAYBACK_CONTROL */
- tgt->transient_state.cmd_count = sizeof_scsi_command(tgt->cur_cmd);
- tgt->transient_state.out_count =
- cmd_count - tgt->transient_state.cmd_count;
- scp = sci_script_data_out;
- LOG(0x1c,"cmdop");
- LOG(0x80+tgt->cur_cmd,0);
- break;
- case SCSI_CMD_TEST_UNIT_READY:
- /*
- * Do the synch negotiation here, unless prohibited
- * or done already
- */
- if (tgt->flags & TGT_DID_SYNCH) {
- scp = sci_script_cmd;
- } else {
- scp = sci_script_try_synch;
- tgt->flags |= TGT_TRY_SYNCH;
- cmd_only = FALSE;
- }
- LOG(0x1c,"cmdop");
- LOG(0x80+tgt->cur_cmd,0);
- break;
- default:
- LOG(0x1c,"cmdop");
- LOG(0x80+tgt->cur_cmd,0);
- scp = sci_script_cmd;
- }
-
- tgt->transient_state.script = scp;
- tgt->transient_state.handler = handler;
- tgt->transient_state.identify = (cmd_only) ? 0xff :
- (disconn ? SCSI_IDENTIFY|SCSI_IFY_ENABLE_DISCONNECT :
- SCSI_IDENTIFY);
-
- if (in_count)
- tgt->transient_state.in_count =
- (in_count < tgt->block_size) ? tgt->block_size : in_count;
- else
- tgt->transient_state.in_count = 0;
- tgt->transient_state.dma_offset = 0;
-
- /*
- * See if another target is currently selected on
- * this SCSI bus, e.g. lock the sci structure.
- * Note that it is the strategy routine's job
- * to serialize ops on the same target as appropriate.
- * XXX here and everywhere, locks!
- */
- /*
- * Protection viz reconnections makes it tricky.
- */
-/* s = splbio();*/
- s = splhigh();
-
- if (sci->wd.nactive++ == 0)
- sci->wd.watchdog_state = SCSI_WD_ACTIVE;
-
- if (sci->state & SCI_STATE_BUSY) {
- /*
- * Queue up this target, note that this takes care
- * of proper FIFO scheduling of the scsi-bus.
- */
- LOG(3,"enqueue");
- enqueue_tail(&sci->waiting_targets, (queue_entry_t) tgt);
- } else {
- /*
- * It is down to at most two contenders now,
- * we will treat reconnections same as selections
- * and let the scsi-bus arbitration process decide.
- */
- sci->state |= SCI_STATE_BUSY;
- sci->next_target = tgt;
- sci_attempt_selection(sci);
- /*
- * Note that we might still lose arbitration..
- */
- }
- splx(s);
-}
-
-sci_attempt_selection(sci)
- sci_softc_t sci;
-{
- target_info_t *tgt;
- register int out_count;
- sci_padded_regmap_t *regs;
- sci_dmaregs_t dmar;
- register int cmd;
- boolean_t ok;
- scsi_ret_t ret;
-
- regs = sci->regs;
- dmar = sci->dmar;
- tgt = sci->next_target;
-
- LOG(4,"select");
- LOG(0x80+tgt->target_id,0);
-
- /*
- * Init bus state variables and set registers.
- */
- sci->active_target = tgt;
-
- /* reselection pending ? */
- if ((regs->sci_bus_csr & (SCI_BUS_BSY|SCI_BUS_SEL)) &&
- (regs->sci_bus_csr & (SCI_BUS_BSY|SCI_BUS_SEL)) &&
- (regs->sci_bus_csr & (SCI_BUS_BSY|SCI_BUS_SEL)))
- return;
-
- sci->script = tgt->transient_state.script;
- sci->error_handler = tgt->transient_state.handler;
- sci->done = SCSI_RET_IN_PROGRESS;
-
- sci->in_count = 0;
- sci->out_count = 0;
- sci->extra_byte = 0;
-
- /*
- * This is a bit involved, but the bottom line is we want to
- * know after we selected with or w/o ATN if the selection
- * went well (ret) and if it is (ok) to send the command.
- */
- ok = TRUE;
- if (tgt->flags & TGT_DID_SYNCH) {
- if (tgt->transient_state.identify == 0xff) {
- /* Select w/o ATN */
- ret = sci_select_target(regs, sci->sc->initiator_id,
- tgt->target_id, FALSE);
- } else {
- /* Select with ATN */
- ret = sci_select_target(regs, sci->sc->initiator_id,
- tgt->target_id, TRUE);
- if (ret == SCSI_RET_SUCCESS) {
- register unsigned char icmd;
-
- while (SCI_CUR_PHASE(regs->sci_bus_csr) != SCSI_PHASE_MSG_OUT)
- ;
- icmd = regs->sci_icmd & ~(SCI_ICMD_DIFF|SCI_ICMD_TEST);
- icmd &= ~SCI_ICMD_ATN;
- regs->sci_icmd = icmd;
- SCI_ACK(regs,SCSI_PHASE_MSG_OUT);
- ok = (sci_data_out(regs, SCSI_PHASE_MSG_OUT,
- 1, &tgt->transient_state.identify) == 0);
- }
- }
- } else if (tgt->flags & TGT_TRY_SYNCH) {
- /* Select with ATN, do the synch xfer neg */
- ret = sci_select_target(regs, sci->sc->initiator_id,
- tgt->target_id, TRUE);
- if (ret == SCSI_RET_SUCCESS) {
- while (SCI_CUR_PHASE(regs->sci_bus_csr) != SCSI_PHASE_MSG_OUT)
- ;
- ok = sci_dosynch( sci, regs->sci_csr, regs->sci_bus_csr);
- }
- } else {
- ret = sci_select_target(regs, sci->sc->initiator_id,
- tgt->target_id, FALSE);
- }
-
- if (ret == SCSI_RET_DEVICE_DOWN) {
- sci->done = ret;
- sci_end(sci, regs->sci_csr, regs->sci_bus_csr);
- return;
- }
- if ((ret != SCSI_RET_SUCCESS) || !ok)
- return;
-
-/* time this out or do it via dma !! */
- while (SCI_CUR_PHASE(regs->sci_bus_csr) != SCSI_PHASE_CMD)
- ;
-
- /* set dma pointer and counter to xfer command */
- out_count = tgt->transient_state.cmd_count;
-#if 0
- SCI_ACK(regs,SCSI_PHASE_CMD);
- sci_data_out(regs,SCSI_PHASE_CMD,out_count,tgt->cmd_ptr);
- regs->sci_mode = SCI_MODE_PAR_CHK|SCI_MODE_DMA|SCI_MODE_MONBSY;
-#else
- SCI_DMADR_PUT(dmar,tgt->dma_ptr);
- delay_1p2_us();
- SCI_TC_PUT(dmar,out_count);
- dmar->sci_dma_dir = SCI_DMA_DIR_WRITE;
- SCI_ACK(regs,SCSI_PHASE_CMD);
- SCI_CLR_INTR(regs);
- regs->sci_mode = SCI_MODE_PAR_CHK|SCI_MODE_DMA|SCI_MODE_MONBSY;
- regs->sci_icmd = SCI_ICMD_DATA;
- regs->sci_dma_send = 1;
-#endif
-}
-
-/*
- * Interrupt routine
- * Take interrupts from the chip
- *
- * Implementation:
- * Move along the current command's script if
- * all is well, invoke error handler if not.
- */
-sci_intr(unit)
-{
- register sci_softc_t sci;
- register script_t scp;
- register unsigned csr, bs, cmd;
- register sci_padded_regmap_t *regs;
- boolean_t try_match;
-#if notyet
- extern boolean_t rz_use_mapped_interface;
-
- if (rz_use_mapped_interface)
- return SCI_intr(unit);
-#endif
-
- LOG(5,"\n\tintr");
-
- sci = sci_softc[unit];
- regs = sci->regs;
-
- /* ack interrupt */
- csr = regs->sci_csr;
- bs = regs->sci_bus_csr;
- cmd = regs->sci_icmd;
-TR(regs->sci_mode);
- SCI_CLR_INTR(regs);
-
-TR(csr);
-TR(bs);
-TR(cmd);
-TRCHECK;
-
- if (cmd & SCI_ICMD_RST){
- sci_bus_reset(sci);
- return;
- }
-
- /* we got an interrupt allright */
- if (sci->active_target)
- sci->wd.watchdog_state = SCSI_WD_ACTIVE;
-
- /* drop spurious calls */
- if ((csr & SCI_CSR_INT) == 0) {
- LOG(2,"SPURIOUS");
- return;
- }
-
- /* Note: reselect has I/O asserted, select has not */
- if ((sci->state & SCI_STATE_TARGET) ||
- ((bs & (SCI_BUS_BSY|SCI_BUS_SEL|SCI_BUS_IO)) == SCI_BUS_SEL)) {
- sci_target_intr(sci,csr,bs);
- return;
- }
-
- scp = sci->script;
-
- /* Race: disconnecting, we get the disconnected notification
- (csr sez BSY dropped) at the same time a reselect is active */
- if ((csr & SCI_CSR_DISC) &&
- scp && (scp->condition == SCI_PHASE_DISC)) {
- (void) (*scp->action)(sci, csr, bs);
- /* takes care of calling reconnect if necessary */
- return;
- }
-
- /* check who got the bus */
- if ((scp == 0) || (cmd & SCI_ICMD_LST) ||
- ((bs & (SCI_BUS_BSY|SCI_BUS_SEL|SCI_BUS_IO)) == (SCI_BUS_SEL|SCI_BUS_IO))) {
- sci_reconnect(sci, csr, bs);
- return;
- }
-
- if (SCRIPT_MATCH(csr,bs) != scp->condition) {
- if (try_match = (*sci->error_handler)(sci, csr, bs)) {
- csr = regs->sci_csr;
- bs = regs->sci_bus_csr;
- }
- } else
- try_match = TRUE;
-
- /* might have been side effected */
- scp = sci->script;
-
- if (try_match && (SCRIPT_MATCH(csr,bs) == scp->condition)) {
- /*
- * Perform the appropriate operation,
- * then proceed
- */
- if ((*scp->action)(sci, csr, bs)) {
- /* might have been side effected */
- scp = sci->script;
- sci->script = scp + 1;
- }
- }
-}
-
-
-sci_target_intr(sci)
- register sci_softc_t sci;
-{
- panic("SCI: TARGET MODE !!!\n");
-}
-
-/*
- * All the many little things that the interrupt
- * routine might switch to
- */
-boolean_t
-sci_end_transaction( sci, csr, bs)
- register sci_softc_t sci;
-{
- register sci_padded_regmap_t *regs = sci->regs;
- char cmc;
-
- LOG(0x1f,"end_t");
-
- /* Stop dma, no interrupt on disconnect */
- regs->sci_icmd = 0;
- regs->sci_mode &= ~(SCI_MODE_DMA|SCI_MODE_MONBSY|SCI_MODE_DMA_IE);
-/* dmar->sci_dma_dir = SCI_DMA_DIR_WRITE;/* make sure we steal not */
-
- SCI_ACK(regs,SCSI_PHASE_MSG_IN);
-
- regs->sci_sel_enb = (1 << sci->sc->initiator_id);
-
- sci_data_in(regs, SCSI_PHASE_MSG_IN, 1, &cmc);
-
- if (cmc != SCSI_COMMAND_COMPLETE)
- printf("{T%x}", cmc);
-
- /* check disconnected, clear all intr bits */
- while (regs->sci_bus_csr & SCI_BUS_BSY)
- ;
- SCI_CLR_INTR(regs);
- SCI_ACK(regs,SCI_PHASE_DISC);
-
- if (!sci_end(sci, csr, bs)) {
- SCI_CLR_INTR(regs);
- (void) sci_reconnect(sci, csr, bs);
- }
- return FALSE;
-}
-
-boolean_t
-sci_end( sci, csr, bs)
- register sci_softc_t sci;
-{
- register target_info_t *tgt;
- register io_req_t ior;
- register sci_padded_regmap_t *regs = sci->regs;
- boolean_t reconn_pending;
-
- LOG(6,"end");
-
- tgt = sci->active_target;
-
- if ((tgt->done = sci->done) == SCSI_RET_IN_PROGRESS)
- tgt->done = SCSI_RET_SUCCESS;
-
- sci->script = 0;
-
- if (sci->wd.nactive-- == 1)
- sci->wd.watchdog_state = SCSI_WD_INACTIVE;
-
- /* check reconnection not pending */
- bs = regs->sci_bus_csr;
- reconn_pending = ((bs & (SCI_BUS_BSY|SCI_BUS_SEL|SCI_BUS_IO)) == (SCI_BUS_SEL|SCI_BUS_IO));
- if (!reconn_pending) {
- sci_release_bus(sci);
- } else {
- sci->active_target = 0;
-/* sci->state &= ~SCI_STATE_BUSY; later */
- }
-
- if (ior = tgt->ior) {
-#ifdef MACH_KERNEL
-#else /*MACH_KERNEL*/
- fdma_unmap(&tgt->fdma, ior);
-#endif /*MACH_KERNEL*/
- LOG(0xA,"ops->restart");
- (*tgt->dev_ops->restart)( tgt, TRUE);
- if (reconn_pending)
- sci->state &= ~SCI_STATE_BUSY;
- }
-
- return (!reconn_pending);
-}
-
-boolean_t
-sci_release_bus(sci)
- register sci_softc_t sci;
-{
- boolean_t ret = FALSE;
-
- LOG(9,"release");
-
- sci->script = 0;
-
- if (sci->state & SCI_STATE_COLLISION) {
-
- LOG(0xB,"collided");
- sci->state &= ~SCI_STATE_COLLISION;
- sci_attempt_selection(sci);
-
- } else if (queue_empty(&sci->waiting_targets)) {
-
- sci->state &= ~SCI_STATE_BUSY;
- sci->active_target = 0;
- ret = TRUE;
-
- } else {
-
- LOG(0xC,"dequeue");
- sci->next_target = (target_info_t *)
- dequeue_head(&sci->waiting_targets);
- sci_attempt_selection(sci);
- }
- return ret;
-}
-
-boolean_t
-sci_get_status( sci, csr, bs)
- register sci_softc_t sci;
-{
- register sci_padded_regmap_t *regs = sci->regs;
- register sci_dmaregs_t dmar = sci->dmar;
- scsi2_status_byte_t status;
- register target_info_t *tgt;
- unsigned int len, mode;
-
- LOG(0xD,"get_status");
-TRWRAP;
-
- /* Stop dma */
- regs->sci_icmd = 0;
- mode = regs->sci_mode;
- regs->sci_mode = (mode & ~(SCI_MODE_DMA|SCI_MODE_DMA_IE));
- dmar->sci_dma_dir = SCI_DMA_DIR_WRITE;/* make sure we steal not */
-
- sci->state &= ~SCI_STATE_DMA_IN;
-
- tgt = sci->active_target;
-
- if (len = sci->in_count) {
- register int count;
- SCI_TC_GET(dmar,count);
- if ((tgt->cur_cmd != SCSI_CMD_READ) &&
- (tgt->cur_cmd != SCSI_CMD_LONG_READ)){
- len -= count;
- } else {
- if (count) {
-#if 0
- this is incorrect and besides..
- tgt->ior->io_residual = count;
-#endif
- len -= count;
- }
- sci_copyin( tgt, tgt->transient_state.dma_offset,
- len, 0, 0);
- }
- }
-
- /* to get the phase mismatch intr */
- regs->sci_mode = mode;
-
- SCI_ACK(regs,SCSI_PHASE_STATUS);
-
- sci_data_in(regs, SCSI_PHASE_STATUS, 1, &status.bits);
-
- SCI_TC_PUT(dmar,0);
-
- if (status.st.scsi_status_code != SCSI_ST_GOOD) {
- scsi_error(sci->active_target, SCSI_ERR_STATUS, status.bits, 0);
- sci->done = (status.st.scsi_status_code == SCSI_ST_BUSY) ?
- SCSI_RET_RETRY : SCSI_RET_NEED_SENSE;
- } else
- sci->done = SCSI_RET_SUCCESS;
-
- return TRUE;
-}
-
-boolean_t
-sci_dma_in( sci, csr, bs)
- register sci_softc_t sci;
-{
- register target_info_t *tgt;
- register sci_padded_regmap_t *regs = sci->regs;
- register sci_dmaregs_t dmar = sci->dmar;
- char *dma_ptr;
- register int count;
- boolean_t advance_script = TRUE;
-
- LOG(0xE,"dma_in");
-
- /*
- * Problem: the 5380 pipelines xfers between the scsibus and
- * itself and between itself and the DMA engine --> halting ?
- * In the dmaout direction all is ok, except that (see NCR notes)
- * the EOP interrupt is generated before the pipe is empty.
- * In the dmain direction (here) the interrupt comes when
- * one too many bytes have been xferred on chip!
- *
- * More specifically, IF we asked for count blindly and we had
- * more than count bytes coming (double buffering) we would endup
- * actually xferring count+1 from the scsibus, but only count
- * to memory [hopefully the last byte sits in the sci_datai reg].
- * This could be helped, except most times count is an exact multiple
- * of the sector size which is where disks disconnect....
- *
- * INSTEAD, we recognize here that we expect more than count bytes
- * coming and set the DMA count to count-1 but keep sci->in_count
- * above to count. This will be wrong if the target disconnects
- * amidst, but we can cure it.
- *
- * The places where this has an effect are marked by "EXTRA_BYTE"
- */
-
- tgt = sci->active_target;
- sci->state |= SCI_STATE_DMA_IN;
-
- /* ought to stop dma to start another */
- regs->sci_mode &= ~ (SCI_MODE_DMA|SCI_MODE_DMA_IE);
- regs->sci_icmd = 0;
-
- if (sci->in_count == 0) {
- /*
- * Got nothing yet: either just sent the command
- * or just reconnected
- */
- register int avail;
-
- count = tgt->transient_state.in_count;
- count = u_min(count, (PER_TGT_BURST_SIZE));
- avail = PER_TGT_BUFF_SIZE - tgt->transient_state.dma_offset;
- count = u_min(count, avail);
-
- /* common case of 8k-or-less read ? */
- advance_script = (tgt->transient_state.in_count == count);
-
- } else {
-
- /*
- * We received some data.
- */
- register int offset, xferred, eb;
- unsigned char extrab = regs->sci_idata; /* EXTRA_BYTE */
-
- SCI_TC_GET(dmar,xferred);
- assert(xferred == 0);
-if (scsi_debug) {
-printf("{B %x %x %x (%x)}",
- sci->in_count, xferred, sci->extra_byte, extrab);
-}
- /* ++EXTRA_BYTE */
- xferred = sci->in_count - xferred;
- eb = sci->extra_byte;
- /* --EXTRA_BYTE */
- assert(xferred > 0);
- tgt->transient_state.in_count -= xferred;
- assert(tgt->transient_state.in_count > 0);
- offset = tgt->transient_state.dma_offset;
- tgt->transient_state.dma_offset += xferred;
- count = u_min(tgt->transient_state.in_count, (PER_TGT_BURST_SIZE));
- if (tgt->transient_state.dma_offset == PER_TGT_BUFF_SIZE) {
- tgt->transient_state.dma_offset = 0;
- } else {
- register int avail;
- avail = PER_TGT_BUFF_SIZE - tgt->transient_state.dma_offset;
- count = u_min(count, avail);
- }
- advance_script = (tgt->transient_state.in_count == count);
-
- /* get some more */
- dma_ptr = tgt->dma_ptr + tgt->transient_state.dma_offset;
- sci->in_count = count;
- /* ++EXTRA_BYTE */
- if (!advance_script) {
- sci->extra_byte = 1; /* that's the cure.. */
- count--;
- } else
- sci->extra_byte = 0;
- /* --EXTRA_BYTE */
- SCI_TC_PUT(dmar,count);
-/* regs->sci_icmd = 0;*/
- SCI_DMADR_PUT(dmar,dma_ptr);
- delay_1p2_us();
- SCI_ACK(regs,SCSI_PHASE_DATAI);
- SCI_CLR_INTR(regs);
- regs->sci_mode |= (advance_script ? SCI_MODE_DMA
- : (SCI_MODE_DMA|SCI_MODE_DMA_IE));
- dmar->sci_dma_dir = SCI_DMA_DIR_READ;
- regs->sci_irecv = 1;
-
- /* copy what we got */
- sci_copyin( tgt, offset, xferred, eb, extrab);
-
- /* last chunk ? */
- return advance_script;
- }
-
- sci->in_count = count;
- dma_ptr = tgt->dma_ptr + tgt->transient_state.dma_offset;
-
- /* ++EXTRA_BYTE */
- if (!advance_script) {
- sci->extra_byte = 1; /* that's the cure.. */
- count--;
- } else
- sci->extra_byte = 0;
- /* --EXTRA_BYTE */
-
- SCI_TC_PUT(dmar,count);
-/* regs->sci_icmd = 0;*/
- SCI_DMADR_PUT(dmar,dma_ptr);
- delay_1p2_us();
- SCI_ACK(regs,SCSI_PHASE_DATAI);
- SCI_CLR_INTR(regs);
- regs->sci_mode |= (advance_script ? SCI_MODE_DMA
- : (SCI_MODE_DMA|SCI_MODE_DMA_IE));
- dmar->sci_dma_dir = SCI_DMA_DIR_READ;
- regs->sci_irecv = 1;
-
- return advance_script;
-}
-
-/* send data to target. Called in three different ways:
- (a) to start transfer (b) to restart a bigger-than-8k
- transfer (c) after reconnection
- */
-int sci_delay = 1;
-
-boolean_t
-sci_dma_out( sci, csr, bs)
- register sci_softc_t sci;
-{
- register sci_padded_regmap_t *regs = sci->regs;
- register sci_dmaregs_t dmar = sci->dmar;
- register char *dma_ptr;
- register target_info_t *tgt;
- boolean_t advance_script = TRUE;
- int count = sci->out_count;
- spl_t s;
- register int tmp;
-
- LOG(0xF,"dma_out");
-
- tgt = sci->active_target;
- sci->state &= ~SCI_STATE_DMA_IN;
-
- if (sci->out_count == 0) {
- /*
- * Nothing committed: either just sent the
- * command or reconnected
- */
- register int remains;
-
- /* ought to stop dma to start another */
- regs->sci_mode &= ~ (SCI_MODE_DMA|SCI_MODE_DMA_IE);
- dmar->sci_dma_dir = SCI_DMA_DIR_READ;/*hold it */
-
- regs->sci_icmd = SCI_ICMD_DATA;
-
- SCI_ACK(regs,SCSI_PHASE_DATAO);
-
- count = tgt->transient_state.out_count;
- count = u_min(count, (PER_TGT_BURST_SIZE));
- remains = PER_TGT_BUFF_SIZE - tgt->transient_state.dma_offset;
- count = u_min(count, remains);
-
- /* common case of 8k-or-less write ? */
- advance_script = (tgt->transient_state.out_count == count);
- } else {
- /*
- * We sent some data.
- * Also, take care of bogus interrupts
- */
- register int offset, xferred;
-
-if (sci_delay & 1) delay(1000);
- /* ought to stop dma to start another */
- regs->sci_mode &= ~ (SCI_MODE_DMA|SCI_MODE_DMA_IE);
- dmar->sci_dma_dir = SCI_DMA_DIR_READ;/*hold it */
-/* regs->sci_icmd = SCI_ICMD_DATA; */
-
- SCI_TC_GET(dmar,xferred);
-if (xferred) printf("{A %x}", xferred);
- xferred = sci->out_count - xferred;
- assert(xferred > 0);
- tgt->transient_state.out_count -= xferred;
- assert(tgt->transient_state.out_count > 0);
- offset = tgt->transient_state.dma_offset;
- tgt->transient_state.dma_offset += xferred;
- count = u_min(tgt->transient_state.out_count, (PER_TGT_BURST_SIZE));
- if (tgt->transient_state.dma_offset == PER_TGT_BUFF_SIZE) {
- tgt->transient_state.dma_offset = 0;
- } else {
- register int remains;
- remains = PER_TGT_BUFF_SIZE - tgt->transient_state.dma_offset;
- count = u_min(count, remains);
- }
- /* last chunk ? */
- if (tgt->transient_state.out_count == count)
- goto quickie;
-
- /* ship some more */
- dma_ptr = tgt->dma_ptr +
- tgt->transient_state.cmd_count + tgt->transient_state.dma_offset;
- sci->out_count = count;
- /*
- * Mistery: sometimes the first byte
- * of an 8k chunk is missing from the tape, it must
- * be that somehow touching the 5380 registers
- * after the dma engine is ready screws up: false DRQ?
- */
-s = splhigh();
- SCI_TC_PUT(dmar,count);
-/* SCI_CLR_INTR(regs);*/
- regs->sci_mode = SCI_MODE_PAR_CHK | SCI_MODE_DMA |
- SCI_MODE_MONBSY | SCI_MODE_DMA_IE;
-/* regs->sci_icmd = SCI_ICMD_DATA;*/
- dmar->sci_dma_dir = SCI_DMA_DIR_WRITE;
- SCI_DMADR_PUT(dmar,dma_ptr);
- delay_1p2_us();
-
- regs->sci_dma_send = 1;
-splx(s);
- /* copy some more data */
- sci_copyout(tgt, offset, xferred);
- return FALSE;
- }
-
-quickie:
- sci->out_count = count;
- dma_ptr = tgt->dma_ptr +
- tgt->transient_state.cmd_count + tgt->transient_state.dma_offset;
- tmp = (advance_script ?
- SCI_MODE_PAR_CHK|SCI_MODE_DMA|SCI_MODE_MONBSY:
- SCI_MODE_PAR_CHK|SCI_MODE_DMA|SCI_MODE_MONBSY|SCI_MODE_DMA_IE);
-s = splhigh();
- SCI_TC_PUT(dmar,count);
-/* SCI_CLR_INTR(regs);*/
- regs->sci_mode = tmp;
-/* regs->sci_icmd = SCI_ICMD_DATA;*/
- SCI_DMADR_PUT(dmar,dma_ptr);
- delay_1p2_us();
- dmar->sci_dma_dir = SCI_DMA_DIR_WRITE;
- regs->sci_dma_send = 1;
-splx(s);
-
- return advance_script;
-}
-
-/* disconnect-reconnect ops */
-
-/* get the message in via dma */
-boolean_t
-sci_msg_in(sci, csr, bs)
- register sci_softc_t sci;
-{
- register target_info_t *tgt;
- char *dma_ptr;
- register sci_padded_regmap_t *regs = sci->regs;
- register sci_dmaregs_t dmar = sci->dmar;
-
- LOG(0x15,"msg_in");
-
- tgt = sci->active_target;
-
- dma_ptr = tgt->dma_ptr;
- /* We would clobber the data for READs */
- if (sci->state & SCI_STATE_DMA_IN) {
- register int offset;
- offset = tgt->transient_state.cmd_count + tgt->transient_state.dma_offset;
- dma_ptr += offset;
- }
-
- /* ought to stop dma to start another */
- regs->sci_mode &= ~ (SCI_MODE_DMA|SCI_MODE_DMA_IE);
- regs->sci_icmd = 0;
-
- /* We only really expect two bytes */
- SCI_TC_PUT(dmar,sizeof(scsi_command_group_0));
-/* regs->sci_icmd = 0*/
- SCI_DMADR_PUT(dmar,dma_ptr);
- delay_1p2_us();
- SCI_ACK(regs,SCSI_PHASE_MSG_IN);
- SCI_CLR_INTR(regs);
- regs->sci_mode |= SCI_MODE_DMA;
- dmar->sci_dma_dir = SCI_DMA_DIR_READ;
- regs->sci_irecv = 1;
-
- return TRUE;
-}
-
-/* check the message is indeed a DISCONNECT */
-boolean_t
-sci_disconnect(sci, csr, bs)
- register sci_softc_t sci;
-{
- register int len;
- boolean_t ok = FALSE;
- register sci_dmaregs_t dmar = sci->dmar;
- register char *msgs;
- unsigned int offset;
-
-
- SCI_TC_GET(dmar,len);
- len = sizeof(scsi_command_group_0) - len;
- PRINT(("{G%d}",len));
-
- /* wherever it was, take it from there */
- SCI_DMADR_GET(dmar,offset);
- msgs = (char*)sci->buff + offset - len;
-
- if ((len == 0) || (len > 2))
- ok = FALSE;
- else {
- /* A SDP message preceeds it in non-completed READs */
- ok = ((msgs[0] == SCSI_DISCONNECT) || /* completed op */
- ((msgs[0] == SCSI_SAVE_DATA_POINTER) && /* incomplete */
- (msgs[1] == SCSI_DISCONNECT)));
- }
- if (!ok)
- printf("[tgt %d bad msg (%d): %x]",
- sci->active_target->target_id, len, *msgs);
-
- return TRUE;
-}
-
-/* save all relevant data, free the BUS */
-boolean_t
-sci_disconnected(sci, csr, bs)
- register sci_softc_t sci;
-{
- register target_info_t *tgt;
- sci_padded_regmap_t *regs = sci->regs;
-
- regs->sci_mode &= ~(SCI_MODE_MONBSY|SCI_MODE_DMA);
- SCI_CLR_INTR(regs);/*retriggered by MONBSY cuz intr routine did CLR */
- SCI_ACK(regs,SCI_PHASE_DISC);
-
- LOG(0x16,"disconnected");
-
- sci_disconnect(sci,csr,bs);
-
- tgt = sci->active_target;
- tgt->flags |= TGT_DISCONNECTED;
- tgt->transient_state.handler = sci->error_handler;
- /* the rest has been saved in sci_err_disconn() */
-
- PRINT(("{D%d}", tgt->target_id));
-
- sci_release_bus(sci);
-
- return FALSE;
-}
-
-/* get reconnect message, restore BUS */
-boolean_t
-sci_reconnect(sci, csr, bs)
- register sci_softc_t sci;
-{
- register target_info_t *tgt;
- sci_padded_regmap_t *regs;
- register int id;
- int msg;
-
- LOG(0x17,"reconnect");
-
- if (sci->wd.nactive == 0) {
- LOG(2,"SPURIOUS");
- return FALSE;
- }
-
- regs = sci->regs;
-
- regs->sci_mode &= ~SCI_MODE_PAR_CHK;
- id = regs->sci_data;/*parity!*/
- regs->sci_mode |= SCI_MODE_PAR_CHK;
-
- /* xxx check our id is in there */
-
- id &= ~(1 << sci->sc->initiator_id);
- {
- register int i;
- for (i = 0; i < 8; i++)
- if (id & (1 << i)) break;
-if (i == 8) {printf("{P%x}", id);return;}
- id = i;
- }
- regs->sci_icmd = SCI_ICMD_BSY;
- while (regs->sci_bus_csr & SCI_BUS_SEL)
- ;
- regs->sci_icmd = 0;
- delay_1p2_us();
- while ( ((regs->sci_bus_csr & SCI_BUS_BSY) == 0) &&
- ((regs->sci_bus_csr & SCI_BUS_BSY) == 0) &&
- ((regs->sci_bus_csr & SCI_BUS_BSY) == 0))
- ;
-
- regs->sci_mode |= SCI_MODE_MONBSY;
-
- /* Now should wait for correct phase: REQ signals it */
- while ( ((regs->sci_bus_csr & SCI_BUS_REQ) == 0) &&
- ((regs->sci_bus_csr & SCI_BUS_REQ) == 0) &&
- ((regs->sci_bus_csr & SCI_BUS_REQ) == 0))
- ;
-
- /*
- * See if this reconnection collided with a selection attempt
- */
- if (sci->state & SCI_STATE_BUSY)
- sci->state |= SCI_STATE_COLLISION;
-
- sci->state |= SCI_STATE_BUSY;
-
- /* Get identify msg */
- bs = regs->sci_bus_csr;
-if (SCI_CUR_PHASE(bs) != SCSI_PHASE_MSG_IN) gimmeabreak();
- SCI_ACK(regs,SCSI_PHASE_MSG_IN);
- msg = 0;
- sci_data_in(regs, SCSI_PHASE_MSG_IN, 1, &msg);
- regs->sci_mode = SCI_MODE_PAR_CHK|SCI_MODE_DMA|SCI_MODE_MONBSY;
- regs->sci_sel_enb = 0;
-
- if (msg != SCSI_IDENTIFY)
- printf("{I%x %x}", id, msg);
-
- tgt = sci->sc->target[id];
- if (id > 7 || tgt == 0) panic("sci_reconnect");
-
- PRINT(("{R%d}", id));
- if (sci->state & SCI_STATE_COLLISION)
- PRINT(("[B %d-%d]", sci->active_target->target_id, id));
-
- LOG(0x80+id,0);
-
- sci->active_target = tgt;
- tgt->flags &= ~TGT_DISCONNECTED;
-
- sci->script = tgt->transient_state.script;
- sci->error_handler = tgt->transient_state.handler;
- sci->in_count = 0;
- sci->out_count = 0;
-
- /* Should get a phase mismatch when tgt changes phase */
-
- return TRUE;
-}
-
-
-
-/* do the synch negotiation */
-boolean_t
-sci_dosynch( sci, csr, bs)
- register sci_softc_t sci;
-{
- /*
- * Phase is MSG_OUT here, cmd has not been xferred
- */
- int len;
- register target_info_t *tgt;
- register sci_padded_regmap_t *regs = sci->regs;
- unsigned char off, icmd;
- register unsigned char *p;
-
- regs->sci_mode |= SCI_MODE_MONBSY;
-
- LOG(0x11,"dosync");
-
- /* ATN still asserted */
- SCI_ACK(regs,SCSI_PHASE_MSG_OUT);
-
- tgt = sci->active_target;
-
- tgt->flags |= TGT_DID_SYNCH; /* only one chance */
- tgt->flags &= ~TGT_TRY_SYNCH;
-
- p = (unsigned char *)tgt->cmd_ptr + tgt->transient_state.cmd_count +
- tgt->transient_state.dma_offset;
- p[0] = SCSI_IDENTIFY;
- p[1] = SCSI_EXTENDED_MESSAGE;
- p[2] = 3;
- p[3] = SCSI_SYNC_XFER_REQUEST;
- /* We cannot run synchronous */
-#define sci_to_scsi_period(x) 0xff
-#define scsi_period_to_sci(x) (x)
- off = 0;
- p[4] = sci_to_scsi_period(sci_min_period);
- p[5] = off;
-
- /* xfer all but last byte with ATN set */
- sci_data_out(regs, SCSI_PHASE_MSG_OUT,
- sizeof(scsi_synch_xfer_req_t), p);
- icmd = regs->sci_icmd & ~(SCI_ICMD_DIFF|SCI_ICMD_TEST);
- icmd &= ~SCI_ICMD_ATN;
- regs->sci_icmd = icmd;
- sci_data_out(regs, SCSI_PHASE_MSG_OUT, 1,
- &p[sizeof(scsi_synch_xfer_req_t)]);
-
- /* wait for phase change */
- while (regs->sci_csr & SCI_CSR_PHASE_MATCH)
- ;
- bs = regs->sci_bus_csr;
-
- /* The standard sez there nothing else the target can do but.. */
- if (SCI_CUR_PHASE(bs) != SCSI_PHASE_MSG_IN)
- panic("sci_dosync");/* XXX put offline */
-
-msgin:
- /* ack */
- SCI_ACK(regs,SCSI_PHASE_MSG_IN);
-
- /* get answer */
- len = sizeof(scsi_synch_xfer_req_t);
- len = sci_data_in(regs, SCSI_PHASE_MSG_IN, len, p);
-
- /* do not cancel the phase mismatch interrupt ! */
-
- /* look at the answer and see if we like it */
- if (len || (p[0] != SCSI_EXTENDED_MESSAGE)) {
- /* did not like it at all */
- printf(" did not like SYNCH xfer ");
- } else {
- /* will NOT do synch */
- printf(" but we cannot do SYNCH xfer ");
- tgt->sync_period = scsi_period_to_sci(p[3]);
- tgt->sync_offset = p[4];
- /* sanity */
- if (tgt->sync_offset != 0)
- printf(" ?OFFSET %x? ", tgt->sync_offset);
- }
-
- /* wait for phase change */
- while (regs->sci_csr & SCI_CSR_PHASE_MATCH)
- ;
- bs = regs->sci_bus_csr;
-
- /* phase should be command now */
- /* continue with simple command script */
- sci->error_handler = sci_err_generic;
- sci->script = sci_script_cmd;
-
- if (SCI_CUR_PHASE(bs) == SCSI_PHASE_CMD )
- return TRUE;
-
-/* sci->script++;*/
- if (SCI_CUR_PHASE(bs) == SCSI_PHASE_STATUS )
- return TRUE; /* intr is pending */
-
- sci->script++;
- if (SCI_CUR_PHASE(bs) == SCSI_PHASE_MSG_IN )
- return TRUE;
-
- if ((bs & SCI_BUS_BSY) == 0) /* uhu? disconnected */
- return sci_end_transaction(sci, regs->sci_csr, regs->sci_bus_csr);
-
- panic("sci_dosynch");
- return FALSE;
-}
-
-/*
- * The bus was reset
- */
-sci_bus_reset(sci)
- register sci_softc_t sci;
-{
- register target_info_t *tgt;
- register sci_padded_regmap_t *regs = sci->regs;
- int i;
-
- LOG(0x21,"bus_reset");
-
- /*
- * Clear bus descriptor
- */
- sci->script = 0;
- sci->error_handler = 0;
- sci->active_target = 0;
- sci->next_target = 0;
- sci->state = 0;
- queue_init(&sci->waiting_targets);
- sci->wd.nactive = 0;
- sci_reset(sci, TRUE);
-
- printf("sci%d: (%d) bus reset ", sci->sc->masterno, ++sci->wd.reset_count);
- delay(scsi_delay_after_reset); /* some targets take long to reset */
-
- if (sci->sc == 0) /* sanity */
- return;
-
- scsi_bus_was_reset(sci->sc);
-}
-
-/*
- * Error handlers
- */
-
-/*
- * Generic, default handler
- */
-boolean_t
-sci_err_generic(sci, csr, bs)
- register sci_softc_t sci;
-{
- register int cond = sci->script->condition;
-
- LOG(0x10,"err_generic");
-
- if (SCI_CUR_PHASE(bs) == SCSI_PHASE_STATUS)
- return sci_err_to_status(sci, csr, bs);
- gimmeabreak();
- return FALSE;
-}
-
-/*
- * Handle generic errors that are reported as
- * an unexpected change to STATUS phase
- */
-sci_err_to_status(sci, csr, bs)
- register sci_softc_t sci;
-{
- script_t scp = sci->script;
-
- LOG(0x20,"err_tostatus");
- while (SCSI_PHASE(scp->condition) != SCSI_PHASE_STATUS)
- scp++;
- sci->script = scp;
-#if 0
- /*
- * Normally, we would already be able to say the command
- * is in error, e.g. the tape had a filemark or something.
- * But in case we do disconnected mode WRITEs, it is quite
- * common that the following happens:
- * dma_out -> disconnect -> reconnect
- * and our script might expect at this point that the dma
- * had to be restarted (it didn't know it was completed
- * because the tape record is shorter than we asked for).
- * And in any event.. it is both correct and cleaner to
- * declare error iff the STATUS byte says so.
- */
- sci->done = SCSI_RET_NEED_SENSE;
-#endif
- return TRUE;
-}
-
-/*
- * Watch for a disconnection
- */
-boolean_t
-sci_err_disconn(sci, csr, bs)
- register sci_softc_t sci;
-{
- register sci_padded_regmap_t *regs;
- register sci_dmaregs_t dmar = sci->dmar;
- register target_info_t *tgt;
- int count;
-
- LOG(0x18,"err_disconn");
-
- if (SCI_CUR_PHASE(bs) != SCSI_PHASE_MSG_IN)
- return sci_err_generic(sci, csr, bs);
-
- regs = sci->regs;
-
- tgt = sci->active_target;
-
- switch (SCSI_PHASE(sci->script->condition)) {
- case SCSI_PHASE_DATAO:
- LOG(0x1b,"+DATAO");
-
-if (sci_delay & 1) delay(1000);
- /* Stop dma */
- regs->sci_icmd = 0;
- regs->sci_mode &= ~(SCI_MODE_DMA|SCI_MODE_DMA_IE);
- dmar->sci_dma_dir = SCI_DMA_DIR_READ;/* make sure we steal not */
-
- if (sci->out_count) {
- register int xferred, offset;
-
- SCI_TC_GET(dmar,xferred);
-if (scsi_debug)
-printf("{O %x %x}", xferred, sci->out_count);
- /* 5380 prefetches */
- xferred = sci->out_count - xferred - 1;
-/* assert(xferred > 0);*/
- tgt->transient_state.out_count -= xferred;
- assert(tgt->transient_state.out_count > 0);
- offset = tgt->transient_state.dma_offset;
- tgt->transient_state.dma_offset += xferred;
- if (tgt->transient_state.dma_offset >= PER_TGT_BUFF_SIZE)
- tgt->transient_state.dma_offset = 0;
-
- sci_copyout( tgt, offset, xferred);
-
- }
- tgt->transient_state.script = sci_script_data_out;
- break;
-
- case SCSI_PHASE_DATAI:
- LOG(0x19,"+DATAI");
-
- /* Stop dma */
- regs->sci_icmd = 0;
- regs->sci_mode &= ~(SCI_MODE_DMA|SCI_MODE_DMA_IE);
- dmar->sci_dma_dir = SCI_DMA_DIR_WRITE;/* make sure we steal not */
-
- if (sci->in_count) {
- register int offset, xferred;
-/* unsigned char extrab = regs->sci_idata;*/
-
- SCI_TC_GET(dmar,xferred);
- /* ++EXTRA_BYTE */
-if (scsi_debug)
-printf("{A %x %x %x}", xferred, sci->in_count, sci->extra_byte);
- xferred = sci->in_count - xferred - sci->extra_byte;
- /* ++EXTRA_BYTE */
- assert(xferred > 0);
- tgt->transient_state.in_count -= xferred;
- assert(tgt->transient_state.in_count > 0);
- offset = tgt->transient_state.dma_offset;
- tgt->transient_state.dma_offset += xferred;
- if (tgt->transient_state.dma_offset >= PER_TGT_BUFF_SIZE)
- tgt->transient_state.dma_offset = 0;
-
- /* copy what we got */
- sci_copyin( tgt, offset, xferred, 0, 0/*extrab*/);
- }
- tgt->transient_state.script = sci_script_data_in;
- break;
-
- case SCSI_PHASE_STATUS:
- /* will have to restart dma */
- SCI_TC_GET(dmar,count);
- if (sci->state & SCI_STATE_DMA_IN) {
- register int offset, xferred;
-/* unsigned char extrab = regs->sci_idata;*/
-
- LOG(0x1a,"+STATUS+R");
-
-
- /* Stop dma */
- regs->sci_icmd = 0;
- regs->sci_mode &= ~(SCI_MODE_DMA|SCI_MODE_DMA_IE);
- dmar->sci_dma_dir = SCI_DMA_DIR_WRITE;/* make sure we steal not */
-
- /* ++EXTRA_BYTE */
-if (scsi_debug)
-printf("{A %x %x %x}", count, sci->in_count, sci->extra_byte);
- xferred = sci->in_count - count - sci->extra_byte;
- /* ++EXTRA_BYTE */
- assert(xferred > 0);
- tgt->transient_state.in_count -= xferred;
-/* assert(tgt->transient_state.in_count > 0);*/
- offset = tgt->transient_state.dma_offset;
- tgt->transient_state.dma_offset += xferred;
- if (tgt->transient_state.dma_offset >= PER_TGT_BUFF_SIZE)
- tgt->transient_state.dma_offset = 0;
-
- /* copy what we got */
- sci_copyin( tgt, offset, xferred, 0, 0/*/extrab*/);
-
- tgt->transient_state.script = sci_script_data_in;
- if (tgt->transient_state.in_count == 0)
- tgt->transient_state.script++;
-
- } else {
-
- LOG(0x1d,"+STATUS+W");
-
-if (sci_delay & 1) delay(1000);
- /* Stop dma */
- regs->sci_icmd = 0;
- regs->sci_mode &= ~(SCI_MODE_DMA|SCI_MODE_DMA_IE);
- dmar->sci_dma_dir = SCI_DMA_DIR_READ;/* make sure we steal not */
-
-if (scsi_debug)
-printf("{O %x %x}", count, sci->out_count);
- if ((count == 0) && (tgt->transient_state.out_count == sci->out_count)) {
- /* all done */
- tgt->transient_state.script = &sci_script_data_out[1];
- tgt->transient_state.out_count = 0;
- } else {
- register int xferred, offset;
-
- /* how much we xferred */
- xferred = sci->out_count - count - 1;/*prefetch*/
-
- tgt->transient_state.out_count -= xferred;
- assert(tgt->transient_state.out_count > 0);
- offset = tgt->transient_state.dma_offset;
- tgt->transient_state.dma_offset += xferred;
- if (tgt->transient_state.dma_offset >= PER_TGT_BUFF_SIZE)
- tgt->transient_state.dma_offset = 0;
-
- sci_copyout( tgt, offset, xferred);
-
- tgt->transient_state.script = sci_script_data_out;
- }
- sci->out_count = 0;
- }
- break;
- default:
- gimmeabreak();
- }
- sci->extra_byte = 0;
-
-/* SCI_ACK(regs,SCSI_PHASE_MSG_IN); later */
- (void) sci_msg_in(sci,csr,bs);
-
- regs->sci_sel_enb = (1 << sci->sc->initiator_id);
-
- sci->script = sci_script_disconnect;
-
- return FALSE;
-}
-
-/*
- * Watchdog
- *
- */
-sci_reset_scsibus(sci)
- register sci_softc_t sci;
-{
- register target_info_t *tgt = sci->active_target;
- if (tgt) {
- int cnt;
- SCI_TC_GET(sci->dmar,cnt);
- log( LOG_KERN,
- "Target %d was active, cmd x%x in x%x out x%x Sin x%x Sou x%x dmalen x%x\n",
- tgt->target_id, tgt->cur_cmd,
- tgt->transient_state.in_count, tgt->transient_state.out_count,
- sci->in_count, sci->out_count, cnt);
- }
- sci->regs->sci_icmd = SCI_ICMD_RST;
- delay(25);
-}
-
-/*
- * Copy routines
- */
-/*static*/
-sci_copyin(tgt, offset, len, isaobb, obb)
- register target_info_t *tgt;
- unsigned char obb;
-{
- register char *from, *to;
- register int count;
-
- count = tgt->transient_state.copy_count;
-
- from = tgt->cmd_ptr + offset;
- to = tgt->ior->io_data + count;
- tgt->transient_state.copy_count = count + len;
-
- bcopy( from, to, len);
- /* check for last, poor little odd byte */
- if (isaobb) {
- to += len;
- to[-1] = obb;
- }
-}
-
-/*static*/
-sci_copyout( tgt, offset, len)
- register target_info_t *tgt;
-{
- register char *from, *to;
- register int count, olen;
- unsigned char c;
- char *p;
-
- count = tgt->ior->io_count - tgt->transient_state.copy_count;
- if (count > 0) {
-
- len = u_min(count, len);
- offset += tgt->transient_state.cmd_count;
-
- count = tgt->transient_state.copy_count;
- tgt->transient_state.copy_count = count + len;
-
- from = tgt->ior->io_data + count;
- to = tgt->cmd_ptr + offset;
-
- bcopy(from, to, len);
-
- }
-}
-
-#endif /*NSCI > 0*/
-
diff --git a/scsi/adapters/scsi_53C700.h b/scsi/adapters/scsi_53C700.h
deleted file mode 100644
index 224fc5b..0000000
--- a/scsi/adapters/scsi_53C700.h
+++ /dev/null
@@ -1,327 +0,0 @@
-/*
- * Mach Operating System
- * Copyright (c) 1991,1990,1989 Carnegie Mellon University
- * All Rights Reserved.
- *
- * Permission to use, copy, modify and distribute this software and its
- * documentation is hereby granted, provided that both the copyright
- * notice and this permission notice appear in all copies of the
- * software, derivative works or modified versions, and any portions
- * thereof, and that both notices appear in supporting documentation.
- *
- * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS
- * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
- * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
- *
- * Carnegie Mellon requests users of this software to return to
- *
- * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
- * School of Computer Science
- * Carnegie Mellon University
- * Pittsburgh PA 15213-3890
- *
- * any improvements or extensions that they make and grant Carnegie the
- * rights to redistribute these changes.
- */
-/*
- * File: scsi_53C700.h
- * Author: Alessandro Forin, Carnegie Mellon University
- * Date: 8/91
- *
- * Defines for the NCR 53C700 (SCSI I/O Processor)
- */
-
-/*
- * Register map
- */
-
-typedef struct {
- volatile unsigned char siop_scntl0; /* rw: SCSI control reg 0 */
- volatile unsigned char siop_scntl1; /* rw: SCSI control reg 1 */
- volatile unsigned char siop_sdid; /* rw: SCSI Destination ID */
- volatile unsigned char siop_sien; /* rw: SCSI Interrupt Enable */
- volatile unsigned char siop_scid; /* rw: SCSI Chip ID reg */
- volatile unsigned char siop_sxfer; /* rw: SCSI Transfer reg */
- volatile unsigned char siop_sodl; /* rw: SCSI Output Data Latch */
- volatile unsigned char siop_socl; /* rw: SCSI Output Control Latch */
- volatile unsigned char siop_sfbr; /* ro: SCSI First Byte Received */
- volatile unsigned char siop_sidl; /* ro: SCSI Input Data Latch */
- volatile unsigned char siop_sbdl; /* ro: SCSI Bus Data Lines */
- volatile unsigned char siop_sbcl; /* ro: SCSI Bus Control Lines */
- volatile unsigned char siop_dstat; /* ro: DMA status */
- volatile unsigned char siop_sstat0; /* ro: SCSI status reg 0 */
- volatile unsigned char siop_sstat1; /* ro: SCSI status reg 1 */
- volatile unsigned char siop_sstat2; /* ro: SCSI status reg 2 */
- volatile unsigned char siop_res1;
- volatile unsigned char siop_res2;
- volatile unsigned char siop_res3;
- volatile unsigned char siop_res4;
- volatile unsigned char siop_ctest0; /* ro: Chip test register 0 */
- volatile unsigned char siop_ctest1; /* ro: Chip test register 1 */
- volatile unsigned char siop_ctest2; /* ro: Chip test register 2 */
- volatile unsigned char siop_ctest3; /* ro: Chip test register 3 */
- volatile unsigned char siop_ctest4; /* rw: Chip test register 4 */
- volatile unsigned char siop_ctest5; /* rw: Chip test register 5 */
- volatile unsigned char siop_ctest6; /* rw: Chip test register 6 */
- volatile unsigned char siop_ctest7; /* rw: Chip test register 7 */
- volatile unsigned char siop_temp0; /* rw: Temporary Stack reg */
- volatile unsigned char siop_temp1;
- volatile unsigned char siop_temp2;
- volatile unsigned char siop_temp3;
- volatile unsigned char siop_dfifo; /* rw: DMA FIFO */
- volatile unsigned char siop_istat; /* rw: Interrupt Status reg */
- volatile unsigned char siop_res5;
- volatile unsigned char siop_res6;
- volatile unsigned char siop_dbc0; /* rw: DMA Byte Counter reg */
- volatile unsigned char siop_dbc1;
- volatile unsigned char siop_dbc2;
- volatile unsigned char siop_dcmd; /* rw: DMA Command Register */
- volatile unsigned char siop_dnad0; /* rw: DMA Next Address */
- volatile unsigned char siop_dnad1;
- volatile unsigned char siop_dnad2;
- volatile unsigned char siop_dnad3;
- volatile unsigned char siop_dsp0; /* rw: DMA SCRIPTS Pointer reg */
- volatile unsigned char siop_dsp1;
- volatile unsigned char siop_dsp2;
- volatile unsigned char siop_dsp3;
- volatile unsigned char siop_dsps0; /* rw: DMA SCRIPTS Pointer Save reg */
- volatile unsigned char siop_dsps1;
- volatile unsigned char siop_dsps2;
- volatile unsigned char siop_dsps3;
- volatile unsigned char siop_dmode; /* rw: DMA Mode reg */
- volatile unsigned char siop_res7;
- volatile unsigned char siop_res8;
- volatile unsigned char siop_res9;
- volatile unsigned char siop_res10;
- volatile unsigned char siop_dien; /* rw: DMA Interrupt Enable */
- volatile unsigned char siop_dwt; /* rw: DMA Watchdog Timer */
- volatile unsigned char siop_dcntl; /* rw: DMA Control reg */
- volatile unsigned char siop_res11;
- volatile unsigned char siop_res12;
- volatile unsigned char siop_res13;
- volatile unsigned char siop_res14;
-
-} siop_regmap_t;
-
-/*
- * Register defines
- */
-
-/* Scsi control register 0 (scntl0) */
-
-#define SIOP_SCNTL0_ARB 0xc0 /* Arbitration mode */
-# define SIOP_ARB_SIMPLE 0x00
-# define SIOP_ARB_FULL 0xc0
-#define SIOP_SCNTL0_START 0x20 /* Start Sequence */
-#define SIOP_SCNTL0_WATN 0x10 /* (Select) With ATN */
-#define SIOP_SCNTL0_EPC 0x08 /* Enable Parity Checking */
-#define SIOP_SCNTL0_EPG 0x04 /* Enable Parity Generation */
-#define SIOP_SCNTL0_AAP 0x02 /* Assert ATN on Parity Error */
-#define SIOP_SCNTL0_TRG 0x01 /* Target Mode */
-
-/* Scsi control register 1 (scntl1) */
-
-#define SIOP_SCNTL1_EXC 0x80 /* Extra Clock Cycle of data setup */
-#define SIOP_SCNTL1_ADB 0x40 /* Assert Data Bus */
-#define SIOP_SCNTL1_ESR 0x20 /* Enable Selection/Reselection */
-#define SIOP_SCNTL1_CON 0x10 /* Connected */
-#define SIOP_SCNTL1_RST 0x08 /* Assert RST */
-#define SIOP_SCNTL1_PAR 0x04 /* Force bad Parity */
-#define SIOP_SCNTL1_SND 0x02 /* Start Send operation */
-#define SIOP_SCNTL1_RCV 0x01 /* Start Receive operation */
-
-/* Scsi interrupt enable register (sien) */
-
-#define SIOP_SIEN_M_A 0x80 /* Phase Mismatch or ATN active */
-#define SIOP_SIEN_FC 0x40 /* Function Complete */
-#define SIOP_SIEN_STO 0x20 /* (Re)Selection timeout */
-#define SIOP_SIEN_SEL 0x10 /* (Re)Selected */
-#define SIOP_SIEN_SGE 0x08 /* SCSI Gross Error */
-#define SIOP_SIEN_UDC 0x04 /* Unexpected Disconnect */
-#define SIOP_SIEN_RST 0x02 /* RST asserted */
-#define SIOP_SIEN_PAR 0x01 /* Parity Error */
-
-/* Scsi chip ID (scid) */
-
-#define SIOP_SCID_VALUE(i) (1<<i)
-
-/* Scsi transfer register (sxfer) */
-
-#define SIOP_SXFER_DHP 0x80 /* Disable Halt on Parity error/ ATN asserted */
-#define SIOP_SXFER_TP 0x70 /* Synch Transfer Period */
- /* see specs for formulas:
- Period = TCP * (4 + XFERP )
- TCP = 1 + CLK + 1..2;
- */
-#define SIOP_SXFER_MO 0x0f /* Synch Max Offset */
-# define SIOP_MAX_OFFSET 8
-
-/* Scsi output data latch register (sodl) */
-
-/* Scsi output control latch register (socl) */
-
-#define SIOP_REQ 0x80 /* SCSI signal <x> asserted */
-#define SIOP_ACK 0x40
-#define SIOP_BSY 0x20
-#define SIOP_SEL 0x10
-#define SIOP_ATN 0x08
-#define SIOP_MSG 0x04
-#define SIOP_CD 0x02
-#define SIOP_IO 0x01
-
-#define SIOP_PHASE(socl) SCSI_PHASE(socl)
-
-/* Scsi first byte received register (sfbr) */
-
-/* Scsi input data latch register (sidl) */
-
-/* Scsi bus data lines register (sbdl) */
-
-/* Scsi bus control lines register (sbcl). Same as socl */
-
-/* DMA status register (dstat) */
-
-#define SIOP_DSTAT_DFE 0x80 /* DMA FIFO empty */
-#define SIOP_DSTAT_RES 0x60
-#define SIOP_DSTAT_ABRT 0x10 /* Aborted */
-#define SIOP_DSTAT_SSI 0x08 /* SCRIPT Single Step */
-#define SIOP_DSTAT_SIR 0x04 /* SCRIPT Interrupt Instruction */
-#define SIOP_DSTAT_WTD 0x02 /* Watchdog Timeout Detected */
-#define SIOP_DSTAT_OPC 0x01 /* Invalid SCRIPTS Opcode */
-
-/* Scsi status register 0 (sstat0) */
-
-#define SIOP_SSTAT0_M_A 0x80 /* Phase Mismatch or ATN active */
-#define SIOP_SSTAT0_FC 0x40 /* Function Complete */
-#define SIOP_SSTAT0_STO 0x20 /* (Re)Selection timeout */
-#define SIOP_SSTAT0_SEL 0x10 /* (Re)Selected */
-#define SIOP_SSTAT0_SGE 0x08 /* SCSI Gross Error */
-#define SIOP_SSTAT0_UDC 0x04 /* Unexpected Disconnect */
-#define SIOP_SSTAT0_RST 0x02 /* RST asserted */
-#define SIOP_SSTAT0_PAR 0x01 /* Parity Error */
-
-/* Scsi status register 1 (sstat1) */
-
-#define SIOP_SSTAT1_ILF 0x80 /* Input latch (sidl) full */
-#define SIOP_SSTAT1_ORF 0x40 /* output reg (sodr) full */
-#define SIOP_SSTAT1_OLF 0x20 /* output latch (sodl) full */
-#define SIOP_SSTAT1_AIP 0x10 /* Arbitration in progress */
-#define SIOP_SSTAT1_LOA 0x08 /* Lost arbitration */
-#define SIOP_SSTAT1_WOA 0x04 /* Won arbitration */
-#define SIOP_SSTAT1_RST 0x02 /* SCSI RST current value */
-#define SIOP_SSTAT1_SDP 0x01 /* SCSI SDP current value */
-
-/* Scsi status register 2 (sstat2) */
-
-#define SIOP_SSTAT2_FF 0xf0 /* SCSI FIFO flags (bytecount) */
-# define SIOP_SCSI_FIFO_DEEP 8
-#define SIOP_SSTAT2_SDP 0x08 /* Latched (on REQ) SCSI SDP */
-#define SIOP_SSTAT2_MSG 0x04 /* Latched SCSI phase */
-#define SIOP_SSTAT2_CD 0x02
-#define SIOP_SSTAT2_IO 0x01
-
-/* Chip test register 0 (ctest0) */
-
-#define SIOP_CTEST0_RES 0xfc
-#define SIOP_CTEST0_RTRG 0x02 /* Real Target mode */
-#define SIOP_CTEST0_DDIR 0x01 /* Xfer direction (1-> from SCSI bus) */
-
-/* Chip test register 1 (ctest1) */
-
-#define SIOP_CTEST1_FMT 0xf0 /* Byte empty in DMA FIFO bottom (high->byte3) */
-#define SIOP_CTEST1_FFL 0x0f /* Byte full in DMA FIFO top, same */
-
-/* Chip test register 2 (ctest2) */
-
-#define SIOP_CTEST2_RES 0xc0
-#define SIOP_CTEST2_SOFF 0x20 /* Synch Offset compare (1-> zero Init, max Tgt */
-#define SIOP_CTEST2_SFP 0x10 /* SCSI FIFO Parity */
-#define SIOP_CTEST2_DFP 0x08 /* DMA FIFO Parity */
-#define SIOP_CTEST2_TEOP 0x04 /* True EOP (a-la 5380) */
-#define SIOP_CTEST2_DREQ 0x02 /* DREQ status */
-#define SIOP_CTEST2_DACK 0x01 /* DACK status */
-
-/* Chip test register 3 (ctest3) read-only, top of SCSI FIFO */
-
-/* Chip test register 4 (ctest4) */
-
-#define SIOP_CTEST4_RES 0x80
-#define SIOP_CTEST4_ZMOD 0x40 /* High-impedance outputs */
-#define SIOP_CTEST4_SZM 0x20 /* ditto, SCSI "outputs" */
-#define SIOP_CTEST4_SLBE 0x10 /* SCSI loobpack enable */
-#define SIOP_CTEST4_SFWR 0x08 /* SCSI FIFO write enable (from sodl) */
-#define SIOP_CTEST4_FBL 0x07 /* DMA FIFO Byte Lane select (from ctest6)
- 4->0, .. 7->3 */
-
-/* Chip test register 5 (ctest5) */
-
-#define SIOP_CTEST5_ADCK 0x80 /* Clock Address Incrementor */
-#define SIOP_CTEST5_BBCK 0x40 /* Clock Byte counter */
-#define SIOP_CTEST5_ROFF 0x20 /* Reset SCSI offset */
-#define SIOP_CTEST5_MASR 0x10 /* Master set/reset pulses (of bits 3-0) */
-#define SIOP_CTEST5_DDIR 0x08 /* (re)set internal DMA direction */
-#define SIOP_CTEST5_EOP 0x04 /* (re)set internal EOP */
-#define SIOP_CTEST5_DREQ 0x02 /* (re)set internal REQ */
-#define SIOP_CTEST5_DACK 0x01 /* (re)set internal ACK */
-
-/* Chip test register 6 (ctest6) DMA FIFO access */
-
-/* Chip test register 7 (ctest7) */
-
-#define SIOP_CTEST7_RES 0xe0
-#define SIOP_CTEST7_STD 0x10 /* Disable selection timeout */
-#define SIOP_CTEST7_DFP 0x08 /* DMA FIFO parity bit */
-#define SIOP_CTEST7_EVP 0x04 /* Even parity (to host bus) */
-#define SIOP_CTEST7_DC 0x02 /* Drive DC pin low on SCRIPT fetches */
-#define SIOP_CTEST7_DIFF 0x01 /* Differential mode */
-
-/* DMA FIFO register (dfifo) */
-
-#define SIOP_DFIFO_FLF 0x80 /* Flush (spill) DMA FIFO */
-#define SIOP_DFIFO_CLF 0x40 /* Clear DMA and SCSI FIFOs */
-#define SIOP_DFIFO_BO 0x3f /* FIFO byte offset counter */
-
-/* Interrupt status register (istat) */
-
-#define SIOP_ISTAT_ABRT 0x80 /* Abort operation */
-#define SIOP_ISTAT_RES 0x70
-#define SIOP_ISTAT_CON 0x08 /* Connected */
-#define SIOP_ISTAT_PRE 0x04 /* Pointer register empty */
-#define SIOP_ISTAT_SIP 0x02 /* SCSI Interrupt pending */
-#define SIOP_ISTAT_DIP 0x01 /* DMA Interrupt pending */
-
-
-/* DMA Mode register (dmode) */
-
-#define SIOP_DMODE_BL_MASK 0xc0 /* 0->1 1->2 2->4 3->8 */
-#define SIOP_DMODE_BW16 0x20 /* Bus Width is 16 bits */
-#define SIOP_DMODE_286 0x10 /* 286 mode */
-#define SIOP_DMODE_IO_M 0x08 /* xfer data to memory or I/O space */
-#define SIOP_DMODE_FAM 0x04 /* fixed address mode */
-#define SIOP_DMODE_PIPE 0x02 /* SCRIPTS in Pipeline mode */
-#define SIOP_DMODE_MAN 0x01 /* SCRIPTS in Manual start mode */
-
-/* DMA interrupt enable register (dien) */
-
-#define SIOP_DIEN_RES 0xe0
-#define SIOP_DIEN_ABRT 0x10 /* On Abort */
-#define SIOP_DIEN_SSI 0x08 /* On SCRIPTS sstep */
-#define SIOP_DIEN_SIR 0x04 /* On SCRIPTS intr instruction */
-#define SIOP_DIEN_WTD 0x02 /* On watchdog timeout */
-#define SIOP_DIEN_OPC 0x01 /* On SCRIPTS illegal opcode */
-
-/* DMA control register (dcntl) */
-
-#define SIOP_DCNTL_CF_MASK 0xc0 /* Clock frequency dividers:
- 0 --> 37.51..50.00 Mhz, div=2
- 1 --> 25.01..37.50 Mhz, div=1.5
- 2 --> 16.67..25.00 Mhz, div=1
- 3 --> reserved
- */
-#define SIOP_DCNTL_S16 0x20 /* SCRIPTS fetches 16bits at a time */
-#define SIOP_DCNTL_SSM 0x10 /* Single step mode */
-#define SIOP_DCNTL_LLM 0x08 /* Enable Low-level mode */
-#define SIOP_DCNTL_STD 0x04 /* Start SCRIPTS operation */
-#define SIOP_DCNTL_RES 0x02
-#define SIOP_DCNTL_RST 0x01 /* Software reset */
-
diff --git a/scsi/adapters/scsi_53C700_hdw.c b/scsi/adapters/scsi_53C700_hdw.c
deleted file mode 100644
index 61b5a3b..0000000
--- a/scsi/adapters/scsi_53C700_hdw.c
+++ /dev/null
@@ -1,696 +0,0 @@
-/*
- * Mach Operating System
- * Copyright (c) 1991,1990,1989 Carnegie Mellon University
- * All Rights Reserved.
- *
- * Permission to use, copy, modify and distribute this software and its
- * documentation is hereby granted, provided that both the copyright
- * notice and this permission notice appear in all copies of the
- * software, derivative works or modified versions, and any portions
- * thereof, and that both notices appear in supporting documentation.
- *
- * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS
- * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
- * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
- *
- * Carnegie Mellon requests users of this software to return to
- *
- * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
- * School of Computer Science
- * Carnegie Mellon University
- * Pittsburgh PA 15213-3890
- *
- * any improvements or extensions that they make and grant Carnegie the
- * rights to redistribute these changes.
- */
-/*
- * File: scsi_53C700_hdw.c
- * Author: Alessandro Forin, Carnegie Mellon University
- * Date: 8/91
- *
- * Bottom layer of the SCSI driver: chip-dependent functions
- *
- * This file contains the code that is specific to the NCR 53C700
- * SCSI chip (Host Bus Adapter in SCSI parlance): probing, start
- * operation, and interrupt routine.
- */
-
-
-#include <siop.h>
-#if NSIOP > 0
-#include <platforms.h>
-
-#include <mach/std_types.h>
-#include <sys/types.h>
-#include <chips/busses.h>
-#include <scsi/compat_30.h>
-#include <machine/machspl.h>
-
-#include <sys/syslog.h>
-
-#include <scsi/scsi.h>
-#include <scsi/scsi2.h>
-#include <scsi/scsi_defs.h>
-
-#include <scsi/adapters/scsi_53C700.h>
-
-#ifdef PAD
-typedef struct {
- volatile unsigned char siop_scntl0; /* rw: SCSI control reg 0 */
- PAD(pad0);
- volatile unsigned char siop_scntl1; /* rw: SCSI control reg 1 */
- PAD(pad1);
- volatile unsigned char siop_sdid; /* rw: SCSI Destination ID */
- PAD(pad2);
- volatile unsigned char siop_sien; /* rw: SCSI Interrupt Enable */
- PAD(pad3);
- volatile unsigned char siop_scid; /* rw: SCSI Chip ID reg */
- PAD(pad4);
- volatile unsigned char siop_sxfer; /* rw: SCSI Transfer reg */
- PAD(pad5);
- volatile unsigned char siop_sodl; /* rw: SCSI Output Data Latch */
- PAD(pad6);
- volatile unsigned char siop_socl; /* rw: SCSI Output Control Latch */
- PAD(pad7);
- volatile unsigned char siop_sfbr; /* ro: SCSI First Byte Received */
- PAD(pad8);
- volatile unsigned char siop_sidl; /* ro: SCSI Input Data Latch */
- PAD(pad9);
- volatile unsigned char siop_sbdl; /* ro: SCSI Bus Data Lines */
- PAD(pad10);
- volatile unsigned char siop_sbcl; /* ro: SCSI Bus Control Lines */
- PAD(pad11);
- volatile unsigned char siop_dstat; /* ro: DMA status */
- PAD(pad12);
- volatile unsigned char siop_sstat0; /* ro: SCSI status reg 0 */
- PAD(pad13);
- volatile unsigned char siop_sstat1; /* ro: SCSI status reg 1 */
- PAD(pad14);
- volatile unsigned char siop_sstat2; /* ro: SCSI status reg 2 */
- PAD(pad15);
- volatile unsigned char siop_res1;
- PAD(pad16);
- volatile unsigned char siop_res2;
- PAD(pad17);
- volatile unsigned char siop_res3;
- PAD(pad18);
- volatile unsigned char siop_res4;
- PAD(pad19);
- volatile unsigned char siop_ctest0; /* ro: Chip test register 0 */
- PAD(pad20);
- volatile unsigned char siop_ctest1; /* ro: Chip test register 1 */
- PAD(pad21);
- volatile unsigned char siop_ctest2; /* ro: Chip test register 2 */
- PAD(pad22);
- volatile unsigned char siop_ctest3; /* ro: Chip test register 3 */
- PAD(pad23);
- volatile unsigned char siop_ctest4; /* rw: Chip test register 4 */
- PAD(pad24);
- volatile unsigned char siop_ctest5; /* rw: Chip test register 5 */
- PAD(pad25);
- volatile unsigned char siop_ctest6; /* rw: Chip test register 6 */
- PAD(pad26);
- volatile unsigned char siop_ctest7; /* rw: Chip test register 7 */
- PAD(pad27);
- volatile unsigned char siop_temp0; /* rw: Temporary Stack reg */
- PAD(pad28);
- volatile unsigned char siop_temp1;
- PAD(pad29);
- volatile unsigned char siop_temp2;
- PAD(pad30);
- volatile unsigned char siop_temp3;
- PAD(pad31);
- volatile unsigned char siop_dfifo; /* rw: DMA FIFO */
- PAD(pad32);
- volatile unsigned char siop_istat; /* rw: Interrupt Status reg */
- PAD(pad33);
- volatile unsigned char siop_res5;
- PAD(pad34);
- volatile unsigned char siop_res6;
- PAD(pad35);
- volatile unsigned char siop_dbc0; /* rw: DMA Byte Counter reg */
- PAD(pad36);
- volatile unsigned char siop_dbc1;
- PAD(pad37);
- volatile unsigned char siop_dbc2;
- PAD(pad38);
- volatile unsigned char siop_dcmd; /* rw: DMA Command Register */
- PAD(pad39);
- volatile unsigned char siop_dnad0; /* rw: DMA Next Address */
- PAD(pad40);
- volatile unsigned char siop_dnad1;
- PAD(pad41);
- volatile unsigned char siop_dnad2;
- PAD(pad42);
- volatile unsigned char siop_dnad3;
- PAD(pad43);
- volatile unsigned char siop_dsp0; /* rw: DMA SCRIPTS Pointer reg */
- PAD(pad44);
- volatile unsigned char siop_dsp1;
- PAD(pad45);
- volatile unsigned char siop_dsp2;
- PAD(pad46);
- volatile unsigned char siop_dsp3;
- PAD(pad47);
- volatile unsigned char siop_dsps0; /* rw: DMA SCRIPTS Pointer Save reg */
- PAD(pad48);
- volatile unsigned char siop_dsps1;
- PAD(pad49);
- volatile unsigned char siop_dsps2;
- PAD(pad50);
- volatile unsigned char siop_dsps3;
- PAD(pad51);
- volatile unsigned char siop_dmode; /* rw: DMA Mode reg */
- PAD(pad52);
- volatile unsigned char siop_res7;
- PAD(pad53);
- volatile unsigned char siop_res8;
- PAD(pad54);
- volatile unsigned char siop_res9;
- PAD(pad55);
- volatile unsigned char siop_res10;
- PAD(pad56);
- volatile unsigned char siop_dien; /* rw: DMA Interrupt Enable */
- PAD(pad57);
- volatile unsigned char siop_dwt; /* rw: DMA Watchdog Timer */
- PAD(pad58);
- volatile unsigned char siop_dcntl; /* rw: DMA Control reg */
- PAD(pad59);
- volatile unsigned char siop_res11;
- PAD(pad60);
- volatile unsigned char siop_res12;
- PAD(pad61);
- volatile unsigned char siop_res13;
- PAD(pad62);
- volatile unsigned char siop_res14;
- PAD(pad63);
-} siop_padded_regmap_t;
-#else
-typedef siop_regmap_t siop_padded_regmap_t;
-#endif
-
-/*
- * Macros to make certain things a little more readable
- */
-
-/* forward decls */
-
-int siop_reset_scsibus();
-boolean_t siop_probe_target();
-
-/*
- * State descriptor for this layer. There is one such structure
- * per (enabled) 53C700 interface
- */
-struct siop_softc {
- watchdog_t wd;
- siop_padded_regmap_t *regs; /* 53C700 registers */
- scsi_dma_ops_t *dma_ops; /* DMA operations and state */
- opaque_t dma_state;
-
- script_t script;
- int (*error_handler)();
- int in_count; /* amnt we expect to receive */
- int out_count; /* amnt we are going to ship */
-
- volatile char state;
-#define SIOP_STATE_BUSY 0x01 /* selecting or currently connected */
-#define SIOP_STATE_TARGET 0x04 /* currently selected as target */
-#define SIOP_STATE_COLLISION 0x08 /* lost selection attempt */
-#define SIOP_STATE_DMA_IN 0x10 /* tgt --> initiator xfer */
-
- unsigned char ntargets; /* how many alive on this scsibus */
- unsigned char done;
-
- scsi_softc_t *sc;
- target_info_t *active_target;
-
- target_info_t *next_target; /* trying to seize bus */
- queue_head_t waiting_targets;/* other targets competing for bus */
-
-} siop_softc_data[NSIOP];
-
-typedef struct siop_softc *siop_softc_t;
-
-siop_softc_t siop_softc[NSIOP];
-
-/*
- * Definition of the controller for the auto-configuration program.
- */
-
-int siop_probe(), scsi_slave(), scsi_attach(), siop_go(), siop_intr();
-
-caddr_t siop_std[NSIOP] = { 0 };
-struct bus_device *siop_dinfo[NSIOP*8];
-struct bus_ctlr *siop_minfo[NSIOP];
-struct bus_driver siop_driver =
- { siop_probe, scsi_slave, scsi_attach, siop_go, siop_std, "rz", siop_dinfo,
- "siop", siop_minfo, BUS_INTR_B4_PROBE};
-
-/*
- * Scripts
- */
-struct script
-siop_script_data_in[] = {
-},
-
-siop_script_data_out[] = {
-},
-
-siop_script_cmd[] = {
-},
-
-/* Synchronous transfer neg(oti)ation */
-
-siop_script_try_synch[] = {
-},
-
-/* Disconnect sequence */
-
-siop_script_disconnect[] = {
-};
-
-
-#define DEBUG
-#ifdef DEBUG
-
-siop_state(base)
- vm_offset_t base;
-{
- siop_padded_regmap_t *regs;
-....
- return 0;
-}
-siop_target_state(tgt)
- target_info_t *tgt;
-{
- if (tgt == 0)
- tgt = siop_softc[0]->active_target;
- if (tgt == 0)
- return 0;
- db_printf("@x%x: fl %x dma %X+%x cmd %x@%X id %x per %x off %x ior %X ret %X\n",
- tgt,
- tgt->flags, tgt->dma_ptr, tgt->transient_state.dma_offset, tgt->cur_cmd,
- tgt->cmd_ptr, tgt->target_id, tgt->sync_period, tgt->sync_offset,
- tgt->ior, tgt->done);
- if (tgt->flags & TGT_DISCONNECTED){
- script_t spt;
-
- spt = tgt->transient_state.script;
- db_printf("disconnected at ");
- db_printsym(spt,1);
- db_printf(": %x ", spt->condition);
- db_printsym(spt->action,1);
- db_printf(", ");
- db_printsym(tgt->transient_state.handler, 1);
- db_printf("\n");
- }
-
- return 0;
-}
-
-siop_all_targets(unit)
-{
- int i;
- target_info_t *tgt;
- for (i = 0; i < 8; i++) {
- tgt = siop_softc[unit]->sc->target[i];
- if (tgt)
- siop_target_state(tgt);
- }
-}
-
-siop_script_state(unit)
-{
- script_t spt = siop_softc[unit]->script;
-
- if (spt == 0) return 0;
- db_printsym(spt,1);
- db_printf(": %x ", spt->condition);
- db_printsym(spt->action,1);
- db_printf(", ");
- db_printsym(siop_softc[unit]->error_handler, 1);
- return 0;
-
-}
-
-#define PRINT(x) if (scsi_debug) printf x
-
-#define TRMAX 200
-int tr[TRMAX+3];
-int trpt, trpthi;
-#define TR(x) tr[trpt++] = x
-#define TRWRAP trpthi = trpt; trpt = 0;
-#define TRCHECK if (trpt > TRMAX) {TRWRAP}
-
-#define TRACE
-
-#ifdef TRACE
-
-#define LOGSIZE 256
-int siop_logpt;
-char siop_log[LOGSIZE];
-
-#define MAXLOG_VALUE 0x24
-struct {
- char *name;
- unsigned int count;
-} logtbl[MAXLOG_VALUE];
-
-static LOG(e,f)
- char *f;
-{
- siop_log[siop_logpt++] = (e);
- if (siop_logpt == LOGSIZE) siop_logpt = 0;
- if ((e) < MAXLOG_VALUE) {
- logtbl[(e)].name = (f);
- logtbl[(e)].count++;
- }
-}
-
-siop_print_log(skip)
- int skip;
-{
- register int i, j;
- register unsigned char c;
-
- for (i = 0, j = siop_logpt; i < LOGSIZE; i++) {
- c = siop_log[j];
- if (++j == LOGSIZE) j = 0;
- if (skip-- > 0)
- continue;
- if (c < MAXLOG_VALUE)
- db_printf(" %s", logtbl[c].name);
- else
- db_printf("-%d", c & 0x7f);
- }
- db_printf("\n");
- return 0;
-}
-
-siop_print_stat()
-{
- register int i;
- register char *p;
- for (i = 0; i < MAXLOG_VALUE; i++) {
- if (p = logtbl[i].name)
- printf("%d %s\n", logtbl[i].count, p);
- }
-}
-
-#else /* TRACE */
-#define LOG(e,f)
-#endif /* TRACE */
-
-#else /* DEBUG */
-#define PRINT(x)
-#define LOG(e,f)
-#define TR(x)
-#define TRCHECK
-#define TRWRAP
-#endif /* DEBUG */
-
-
-/*
- * Probe/Slave/Attach functions
- */
-
-/*
- * Probe routine:
- * Should find out (a) if the controller is
- * present and (b) which/where slaves are present.
- *
- * Implementation:
- * Send an identify msg to each possible target on the bus
- * except of course ourselves.
- */
-siop_probe(reg, ui)
- char *reg;
- struct bus_ctlr *ui;
-{
- int unit = ui->unit;
- siop_softc_t siop = &siop_softc_data[unit];
- int target_id, i;
- scsi_softc_t *sc;
- register siop_padded_regmap_t *regs;
- int s;
- boolean_t did_banner = FALSE;
- char *cmd_ptr;
- static char *here = "siop_probe";
-
- /*
- * We are only called if the chip is there,
- * but make sure anyways..
- */
- regs = (siop_padded_regmap_t *) (reg);
- if (check_memory(regs, 0))
- return 0;
-
-#if notyet
- /* Mappable version side */
- SIOP_probe(reg, ui);
-#endif
-
- /*
- * Initialize hw descriptor
- */
- siop_softc[unit] = siop;
- siop->regs = regs;
-
- if ((siop->dma_ops = (scsi_dma_ops_t *)siop_std[unit]) == 0)
- /* use same as unit 0 if undefined */
- siop->dma_ops = (scsi_dma_ops_t *)siop_std[0];
- siop->dma_state = (*siop->dma_ops->init)(unit, reg);
-
- queue_init(&siop->waiting_targets);
-
- sc = scsi_master_alloc(unit, siop);
- siop->sc = sc;
-
- sc->go = siop_go;
- sc->probe = siop_probe_target;
- sc->watchdog = scsi_watchdog;
- siop->wd.reset = siop_reset_scsibus;
-
-#ifdef MACH_KERNEL
- sc->max_dma_data = -1; /* unlimited */
-#else
- sc->max_dma_data = scsi_per_target_virtual;
-#endif
-
- /*
- * Reset chip
- */
- s = splbio();
- siop_reset(siop, TRUE);
-
- /*
- * Our SCSI id on the bus.
- */
-
- sc->initiator_id = my_scsi_id(unit);
- printf("%s%d: my SCSI id is %d", ui->name, unit, sc->initiator_id);
-
- /*
- * For all possible targets, see if there is one and allocate
- * a descriptor for it if it is there.
- */
- for (target_id = 0; target_id < 8; target_id++) {
-
- register unsigned csr, dsr;
- scsi_status_byte_t status;
-
- /* except of course ourselves */
- if (target_id == sc->initiator_id)
- continue;
-
- .....
-
- printf(",%s%d", did_banner++ ? " " : " target(s) at ",
- target_id);
-
- .....
-
-
- /*
- * Found a target
- */
- siop->ntargets++;
- {
- register target_info_t *tgt;
-
- tgt = scsi_slave_alloc(unit, target_id, siop);
-
- tgt->cmd_ptr = ...
- tgt->dma_ptr = ...
-#ifdef MACH_KERNEL
-#else /*MACH_KERNEL*/
- fdma_init(&tgt->fdma, scsi_per_target_virtual);
-#endif /*MACH_KERNEL*/
- }
- }
- printf(".\n");
-
- splx(s);
- return 1;
-}
-
-boolean_t
-siop_probe_target(sc, tgt, ior)
- scsi_softc_t *sc;
- target_info_t *tgt;
- io_req_t ior;
-{
- siop_softc_t siop = siop_softc[sc->masterno];
- boolean_t newlywed;
-
- newlywed = (tgt->cmd_ptr == 0);
- if (newlywed) {
- /* desc was allocated afresh */
-
- tgt->cmd_ptr = ...
- tgt->dma_ptr = ...
-#ifdef MACH_KERNEL
-#else /*MACH_KERNEL*/
- fdma_init(&tgt->fdma, scsi_per_target_virtual);
-#endif /*MACH_KERNEL*/
-
- }
-
- if (scsi_inquiry(sc, tgt, SCSI_INQ_STD_DATA) == SCSI_RET_DEVICE_DOWN)
- return FALSE;
-
- tgt->flags = TGT_ALIVE;
- return TRUE;
-}
-
-
-static siop_wait(preg, until)
- volatile unsigned char *preg;
-{
- int timeo = 1000000;
- while ((*preg & until) != until) {
- delay(1);
- if (!timeo--) {
- printf("siop_wait TIMEO with x%x\n", *preg);
- break;
- }
- }
- return *preg;
-}
-
-
-siop_reset(siop, quickly)
- siop_softc_t siop;
- boolean_t quickly;
-{
- register siop_padded_regmap_t *regs = siop->regs;
-
- ....
-
- if (quickly)
- return;
-
- /*
- * reset the scsi bus, the interrupt routine does the rest
- * or you can call siop_bus_reset().
- */
- ....
-
-}
-
-/*
- * Operational functions
- */
-
-/*
- * Start a SCSI command on a target
- */
-siop_go(sc, tgt, cmd_count, in_count, cmd_only)
- scsi_softc_t *sc;
- target_info_t *tgt;
- boolean_t cmd_only;
-{
- siop_softc_t siop;
- register int s;
- boolean_t disconn;
- script_t scp;
- boolean_t (*handler)();
-
- LOG(1,"go");
-
- siop = (siop_softc_t)tgt->hw_state;
-
- ....
-}
-
-siop_attempt_selection(siop)
- siop_softc_t siop;
-{
- target_info_t *tgt;
- register int out_count;
- siop_padded_regmap_t *regs;
- register int cmd;
- boolean_t ok;
- scsi_ret_t ret;
-
- regs = siop->regs;
- tgt = siop->next_target;
-
- LOG(4,"select");
- LOG(0x80+tgt->target_id,0);
-
- /*
- * Init bus state variables and set registers.
- */
- siop->active_target = tgt;
-
- /* reselection pending ? */
- ......
-}
-
-/*
- * Interrupt routine
- * Take interrupts from the chip
- *
- * Implementation:
- * Move along the current command's script if
- * all is well, invoke error handler if not.
- */
-siop_intr(unit)
-{
- register siop_softc_t siop;
- register script_t scp;
- register unsigned csr, bs, cmd;
- register siop_padded_regmap_t *regs;
- boolean_t try_match;
-#if notyet
- extern boolean_t rz_use_mapped_interface;
-
- if (rz_use_mapped_interface)
- return SIOP_intr(unit);
-#endif
-
- LOG(5,"\n\tintr");
-
- siop = siop_softc[unit];
- regs = siop->regs;
-
- /* ack interrupt */
- ....
-}
-
-
-siop_target_intr(siop)
- register siop_softc_t siop;
-{
- panic("SIOP: TARGET MODE !!!\n");
-}
-
-/*
- * All the many little things that the interrupt
- * routine might switch to
- */
-
-#endif /*NSIOP > 0*/
-
diff --git a/scsi/adapters/scsi_53C94.h b/scsi/adapters/scsi_53C94.h
deleted file mode 100644
index 82891f3..0000000
--- a/scsi/adapters/scsi_53C94.h
+++ /dev/null
@@ -1,253 +0,0 @@
-/*
- * Mach Operating System
- * Copyright (c) 1991,1990,1989 Carnegie Mellon University
- * All Rights Reserved.
- *
- * Permission to use, copy, modify and distribute this software and its
- * documentation is hereby granted, provided that both the copyright
- * notice and this permission notice appear in all copies of the
- * software, derivative works or modified versions, and any portions
- * thereof, and that both notices appear in supporting documentation.
- *
- * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
- * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
- * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
- *
- * Carnegie Mellon requests users of this software to return to
- *
- * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
- * School of Computer Science
- * Carnegie Mellon University
- * Pittsburgh PA 15213-3890
- *
- * any improvements or extensions that they make and grant Carnegie Mellon
- * the rights to redistribute these changes.
- */
-/*
- * File: scsi_53C94.h
- * Author: Alessandro Forin, Carnegie Mellon University
- * Date: 9/90
- *
- * Defines for the NCR 53C94 ASC (SCSI interface)
- * Some gotcha came from the "86C01/53C94 DMA lab work" written
- * by Ken Stewart (NCR MED Logic Products Applications Engineer)
- * courtesy of NCR. Thanks Ken !
- */
-
-/*
- * Register map
- */
-
-typedef struct {
- volatile unsigned char asc_tc_lsb; /* rw: Transfer Counter LSB */
- volatile unsigned char asc_tc_msb; /* rw: Transfer Counter MSB */
- volatile unsigned char asc_fifo; /* rw: FIFO top */
- volatile unsigned char asc_cmd; /* rw: Command */
- volatile unsigned char asc_csr; /* r: Status */
-#define asc_dbus_id asc_csr /* w: Destination Bus ID */
- volatile unsigned char asc_intr; /* r: Interrupt */
-#define asc_sel_timo asc_intr /* w: (re)select timeout */
- volatile unsigned char asc_ss; /* r: Sequence Step */
-#define asc_syn_p asc_ss /* w: synchronous period */
- volatile unsigned char asc_flags; /* r: FIFO flags + seq step */
-#define asc_syn_o asc_flags /* w: synchronous offset */
- volatile unsigned char asc_cnfg1; /* rw: Configuration 1 */
- volatile unsigned char asc_ccf; /* w: Clock Conv. Factor */
- volatile unsigned char asc_test; /* w: Test Mode */
- volatile unsigned char asc_cnfg2; /* rw: Configuration 2 */
- volatile unsigned char asc_cnfg3; /* rw: Configuration 3 */
- volatile unsigned char asc_rfb; /* w: Reserve FIFO byte */
-} asc_regmap_t;
-
-
-/*
- * Transfer Count: access macros
- * That a NOP is required after loading the dma counter
- * I learned on the NCR test code. Sic.
- */
-
-#define ASC_TC_MAX 0x10000
-
-#define ASC_TC_GET(ptr,val) \
- val = ((ptr)->asc_tc_lsb&0xff)|(((ptr)->asc_tc_msb&0xff)<<8)
-#define ASC_TC_PUT(ptr,val) \
- (ptr)->asc_tc_lsb=(val); \
- (ptr)->asc_tc_msb=(val)>>8; mb(); \
- (ptr)->asc_cmd = ASC_CMD_NOP|ASC_CMD_DMA;
-
-/*
- * FIFO register
- */
-
-#define ASC_FIFO_DEEP 16
-
-
-/*
- * Command register (command codes)
- */
-
-#define ASC_CMD_DMA 0x80
- /* Miscellaneous */
-#define ASC_CMD_NOP 0x00
-#define ASC_CMD_FLUSH 0x01
-#define ASC_CMD_RESET 0x02
-#define ASC_CMD_BUS_RESET 0x03
- /* Initiator state */
-#define ASC_CMD_XFER_INFO 0x10
-#define ASC_CMD_I_COMPLETE 0x11
-#define ASC_CMD_MSG_ACPT 0x12
-#define ASC_CMD_XFER_PAD 0x18
-#define ASC_CMD_SET_ATN 0x1a
-#define ASC_CMD_CLR_ATN 0x1b
- /* Target state */
-#define ASC_CMD_SND_MSG 0x20
-#define ASC_CMD_SND_STATUS 0x21
-#define ASC_CMD_SND_DATA 0x22
-#define ASC_CMD_DISC_SEQ 0x23
-#define ASC_CMD_TERM 0x24
-#define ASC_CMD_T_COMPLETE 0x25
-#define ASC_CMD_DISC 0x27
-#define ASC_CMD_RCV_MSG 0x28
-#define ASC_CMD_RCV_CDB 0x29
-#define ASC_CMD_RCV_DATA 0x2a
-#define ASC_CMD_RCV_CMD 0x2b
-#define ASC_CMD_ABRT_DMA 0x04
- /* Disconnected state */
-#define ASC_CMD_RESELECT 0x40
-#define ASC_CMD_SEL 0x41
-#define ASC_CMD_SEL_ATN 0x42
-#define ASC_CMD_SEL_ATN_STOP 0x43
-#define ASC_CMD_ENABLE_SEL 0x44
-#define ASC_CMD_DISABLE_SEL 0x45
-#define ASC_CMD_SEL_ATN3 0x46
-
-/* this is approximate (no ATN3) but good enough */
-#define asc_isa_select(cmd) (((cmd)&0x7c)==0x40)
-
-/*
- * Status register, and phase encoding
- */
-
-#define ASC_CSR_INT 0x80
-#define ASC_CSR_GE 0x40
-#define ASC_CSR_PE 0x20
-#define ASC_CSR_TC 0x10
-#define ASC_CSR_VGC 0x08
-#define ASC_CSR_MSG 0x04
-#define ASC_CSR_CD 0x02
-#define ASC_CSR_IO 0x01
-
-#define ASC_PHASE(csr) SCSI_PHASE(csr)
-
-/*
- * Destination Bus ID
- */
-
-#define ASC_DEST_ID_MASK 0x07
-
-
-/*
- * Interrupt register
- */
-
-#define ASC_INT_RESET 0x80
-#define ASC_INT_ILL 0x40
-#define ASC_INT_DISC 0x20
-#define ASC_INT_BS 0x10
-#define ASC_INT_FC 0x08
-#define ASC_INT_RESEL 0x04
-#define ASC_INT_SEL_ATN 0x02
-#define ASC_INT_SEL 0x01
-
-
-/*
- * Timeout register:
- *
- * val = (timeout * CLK_freq) / (8192 * CCF);
- */
-
-#define asc_timeout_250(clk,ccf) ((31*clk)/ccf)
-
-/*
- * Sequence Step register
- */
-
-#define ASC_SS_XXXX 0xf0
-#define ASC_SS_SOM 0x80
-#define ASC_SS_MASK 0x07
-#define ASC_SS(ss) ((ss)&ASC_SS_MASK)
-
-/*
- * Synchronous Transfer Period
- */
-
-#define ASC_STP_MASK 0x1f
-#define ASC_STP_MIN 0x05 /* 5 clk per byte */
-#define ASC_STP_MAX 0x04 /* after ovfl, 35 clk/byte */
-
-/*
- * FIFO flags
- */
-
-#define ASC_FLAGS_SEQ_STEP 0xe0
-#define ASC_FLAGS_FIFO_CNT 0x1f
-
-/*
- * Synchronous offset
- */
-
-#define ASC_SYNO_MASK 0x0f /* 0 -> asyn */
-
-/*
- * Configuration 1
- */
-
-#define ASC_CNFG1_SLOW 0x80
-#define ASC_CNFG1_SRD 0x40
-#define ASC_CNFG1_P_TEST 0x20
-#define ASC_CNFG1_P_CHECK 0x10
-#define ASC_CNFG1_TEST 0x08
-#define ASC_CNFG1_MY_BUS_ID 0x07
-
-/*
- * CCF register
- */
-
-#define ASC_CCF_10MHz 0x2
-#define ASC_CCF_15MHz 0x3
-#define ASC_CCF_20MHz 0x4
-#define ASC_CCF_25MHz 0x5
-
-#define mhz_to_ccf(x) (((x-1)/5)+1) /* see specs for limits */
-
-/*
- * Test register
- */
-
-#define ASC_TEST_XXXX 0xf8
-#define ASC_TEST_HI_Z 0x04
-#define ASC_TEST_I 0x02
-#define ASC_TEST_T 0x01
-
-/*
- * Configuration 2
- */
-
-#define ASC_CNFG2_RFB 0x80
-#define ASC_CNFG2_EPL 0x40
-#define ASC_CNFG2_EBC 0x20
-#define ASC_CNFG2_DREQ_HIZ 0x10
-#define ASC_CNFG2_SCSI2 0x08
-#define ASC_CNFG2_BPA 0x04
-#define ASC_CNFG2_RPE 0x02
-#define ASC_CNFG2_DPE 0x01
-
-/*
- * Configuration 3
- */
-
-#define ASC_CNFG3_XXXX 0xf8
-#define ASC_CNFG3_SRB 0x04
-#define ASC_CNFG3_ALT_DMA 0x02
-#define ASC_CNFG3_T8 0x01
-
diff --git a/scsi/adapters/scsi_53C94_hdw.c b/scsi/adapters/scsi_53C94_hdw.c
deleted file mode 100644
index dad9b22..0000000
--- a/scsi/adapters/scsi_53C94_hdw.c
+++ /dev/null
@@ -1,2840 +0,0 @@
-/*
- * Mach Operating System
- * Copyright (c) 1993,1992,1991,1990,1989 Carnegie Mellon University
- * All Rights Reserved.
- *
- * Permission to use, copy, modify and distribute this software and its
- * documentation is hereby granted, provided that both the copyright
- * notice and this permission notice appear in all copies of the
- * software, derivative works or modified versions, and any portions
- * thereof, and that both notices appear in supporting documentation.
- *
- * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS AS-IS
- * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
- * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
- *
- * Carnegie Mellon requests users of this software to return to
- *
- * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
- * School of Computer Science
- * Carnegie Mellon University
- * Pittsburgh PA 15213-3890
- *
- * any improvements or extensions that they make and grant Carnegie Mellon
- * the rights to redistribute these changes.
- */
-/*
- * File: scsi_53C94_hdw.h
- * Author: Alessandro Forin, Carnegie Mellon University
- * Date: 9/90
- *
- * Bottom layer of the SCSI driver: chip-dependent functions
- *
- * This file contains the code that is specific to the NCR 53C94
- * SCSI chip (Host Bus Adapter in SCSI parlance): probing, start
- * operation, and interrupt routine.
- */
-
-/*
- * This layer works based on small simple 'scripts' that are installed
- * at the start of the command and drive the chip to completion.
- * The idea comes from the specs of the NCR 53C700 'script' processor.
- *
- * There are various reasons for this, mainly
- * - Performance: identify the common (successful) path, and follow it;
- * at interrupt time no code is needed to find the current status
- * - Code size: it should be easy to compact common operations
- * - Adaptability: the code skeleton should adapt to different chips without
- * terrible complications.
- * - Error handling: and it is easy to modify the actions performed
- * by the scripts to cope with strange but well identified sequences
- *
- */
-
-#include <asc.h>
-#if NASC > 0
-#include <platforms.h>
-
-#ifdef DECSTATION
-typedef unsigned char asc_register_t;
-#define PAD(n) char n[3];
-#define mb()
-#ifdef MACH_KERNEL
-#define HAS_MAPPED_SCSI
-#endif
-#define ASC_PROBE_DYNAMICALLY FALSE /* established custom */
-#define DEBUG 1
-#define TRACE 1
-#endif
-
-#ifdef FLAMINGO
-typedef unsigned int asc_register_t;
-#define PAD(n) int n; /* sparse ! */
-#define mb() wbflush() /* memory barrier */
-#define ASC_PROBE_DYNAMICALLY TRUE
-#define DEBUG 1
-#define TRACE 1
-#endif
-
-#include <mach/std_types.h>
-#include <sys/types.h>
-#include <chips/busses.h>
-#include <scsi/compat_30.h>
-#include <machine/machspl.h>
-
-#include <scsi/scsi.h>
-#include <scsi/scsi2.h>
-
-#include <scsi/adapters/scsi_53C94.h>
-#include <scsi/scsi_defs.h>
-#include <scsi/adapters/scsi_dma.h>
-
-#define private static
-
-#ifdef PAD
-typedef struct {
- volatile asc_register_t asc_tc_lsb; /* rw: Transfer Counter LSB */
- PAD(pad0)
- volatile asc_register_t asc_tc_msb; /* rw: Transfer Counter MSB */
- PAD(pad1)
- volatile asc_register_t asc_fifo; /* rw: FIFO top */
- PAD(pad2)
- volatile asc_register_t asc_cmd; /* rw: Command */
- PAD(pad3)
- volatile asc_register_t asc_csr; /* r: Status */
-/*#define asc_dbus_id asc_csr /* w: Destination Bus ID */
- PAD(pad4)
- volatile asc_register_t asc_intr; /* r: Interrupt */
-/*#define asc_sel_timo asc_intr /* w: (re)select timeout */
- PAD(pad5)
- volatile asc_register_t asc_ss; /* r: Sequence Step */
-/*#define asc_syn_p asc_ss /* w: synchronous period */
- PAD(pad6)
- volatile asc_register_t asc_flags; /* r: FIFO flags + seq step */
-/*#define asc_syn_o asc_flags /* w: synchronous offset */
- PAD(pad7)
- volatile asc_register_t asc_cnfg1; /* rw: Configuration 1 */
- PAD(pad8)
- volatile asc_register_t asc_ccf; /* w: Clock Conv. Factor */
- PAD(pad9)
- volatile asc_register_t asc_test; /* w: Test Mode */
- PAD(pad10)
- volatile asc_register_t asc_cnfg2; /* rw: Configuration 2 */
- PAD(pad11)
- volatile asc_register_t asc_cnfg3; /* rw: Configuration 3 */
- PAD(pad12)
- volatile asc_register_t asc_rfb; /* w: Reserve FIFO byte */
- PAD(pad13)
-} asc_padded_regmap_t;
-
-#else /* !PAD */
-
-typedef asc_regmap_t asc_padded_regmap_t;
-
-#endif /* !PAD */
-
-#define get_reg(r,x) ((unsigned char)((r)->x))
-
-#define fifo_count(r) ((r)->asc_flags & ASC_FLAGS_FIFO_CNT)
-#define get_fifo(r) get_reg(r,asc_fifo)
-
-boolean_t asc_probe_dynamically = ASC_PROBE_DYNAMICALLY;
-
-/*
- * We might need to use some fields usually
- * handled by the DMA engine, if asked to.
- * These are "dma_ptr" and "hba_dep".
- */
-#define has_oddb hba_dep[0]
-#define the_oddb hba_dep[1]
-
-/*
- * A script has a three parts: a pre-condition, an action, and
- * an optional command to the chip. The first triggers error
- * handling if not satisfied and in our case it is a match
- * of the expected and actual scsi-bus phases.
- * The action part is just a function pointer, and the
- * command is what the 53c90 should be told to do at the end
- * of the action processing. This command is only issued and the
- * script proceeds if the action routine returns TRUE.
- * See asc_intr() for how and where this is all done.
- */
-
-typedef struct script {
- unsigned char condition; /* expected state at interrupt */
- unsigned char command; /* command to the chip */
- unsigned short flags; /* unused padding */
- boolean_t (*action)(); /* extra operations */
-} *script_t;
-
-/* Matching on the condition value */
-#define ANY 0xff
-#define SCRIPT_MATCH(csr,ir,value) ((SCSI_PHASE(csr)==(value)) || \
- (((value)==ANY) && \
- ((ir)&(ASC_INT_DISC|ASC_INT_FC))))
-
-/* When no command is needed */
-#define SCRIPT_END -1
-
-/* forward decls of script actions */
-boolean_t
- asc_end(), /* all come to an end */
- asc_clean_fifo(), /* .. in preparation for status byte */
- asc_get_status(), /* get status from target */
- asc_put_status(), /* send status to initiator */
- asc_dma_in(), /* get data from target via dma */
- asc_dma_in_r(), /* get data from target via dma (restartable)*/
- asc_dma_out(), /* send data to target via dma */
- asc_dma_out_r(), /* send data to target via dma (restartable) */
- asc_dosynch(), /* negotiate synch xfer */
- asc_msg_in(), /* receive the disconenct message */
- asc_disconnected(), /* target has disconnected */
- asc_reconnect(); /* target reconnected */
-
-/* forward decls of error handlers */
-boolean_t
- asc_err_generic(), /* generic handler */
- asc_err_disconn(), /* target disconnects amidst */
- gimmeabreak(); /* drop into the debugger */
-
-int asc_reset_scsibus();
-boolean_t asc_probe_target();
-private asc_wait();
-
-/*
- * State descriptor for this layer. There is one such structure
- * per (enabled) SCSI-53c90 interface
- */
-struct asc_softc {
- watchdog_t wd;
- asc_padded_regmap_t *regs; /* 53c90 registers */
-
- scsi_dma_ops_t *dma_ops; /* DMA operations and state */
- opaque_t dma_state;
-
- script_t script; /* what should happen next */
- boolean_t (*error_handler)();/* what if something is wrong */
- int in_count; /* amnt we expect to receive */
- int out_count; /* amnt we are going to ship */
-
- volatile char state;
-#define ASC_STATE_BUSY 0x01 /* selecting or currently connected */
-#define ASC_STATE_TARGET 0x04 /* currently selected as target */
-#define ASC_STATE_COLLISION 0x08 /* lost selection attempt */
-#define ASC_STATE_DMA_IN 0x10 /* tgt --> initiator xfer */
-#define ASC_STATE_SPEC_DMA 0x20 /* special, 8 byte threshold dma */
-#define ASC_STATE_DO_RFB 0x40 /* DMA engine cannot handle odd bytes */
-
- unsigned char ntargets; /* how many alive on this scsibus */
- unsigned char done;
- unsigned char extra_count; /* sleazy trick to spare an interrupt */
- int dmacnt_at_end;
-
- scsi_softc_t *sc; /* HBA-indep info */
- target_info_t *active_target; /* the current one */
-
- target_info_t *next_target; /* trying to seize bus */
- queue_head_t waiting_targets;/* other targets competing for bus */
-
- unsigned char ss_was; /* districate powered on/off devices */
- unsigned char cmd_was;
-
- unsigned char timeout; /* cache a couple numbers */
- unsigned char ccf;
- unsigned char clk;
-
-} asc_softc_data[NASC];
-
-typedef struct asc_softc *asc_softc_t;
-
-asc_softc_t asc_softc[NASC];
-
-/*
- * Synch xfer parameters, and timing conversions
- */
-int asc_min_period = 5; /* in CLKS/BYTE, e.g. 1 CLK = 40nsecs @25 Mhz */
-int asc_max_offset = 15; /* pure number */
-
-int asc_to_scsi_period(a,clk)
-{
- /* Note: the SCSI unit is 4ns, hence
- A_P * 1,000,000,000
- ------------------- = S_P
- C_Mhz * 4
- */
- return a * (250 / clk);
-
-}
-
-int scsi_period_to_asc(p,clk)
-{
- register int ret;
-
- ret = (p * clk) / 250;
- if (ret < asc_min_period)
- return asc_min_period;
- if ((asc_to_scsi_period(ret,clk)) < p)
- return ret + 1;
- return ret;
-}
-
-#define readback(a) {register int foo; foo = a; mb();}
-
-#define u_min(a,b) (((a) < (b)) ? (a) : (b))
-
-/*
- * Definition of the controller for the auto-configuration program.
- */
-
-int asc_probe(), scsi_slave(), asc_go(), asc_intr();
-void scsi_attach();
-
-vm_offset_t asc_std[NASC] = { 0 };
-struct bus_device *asc_dinfo[NASC*8];
-struct bus_ctlr *asc_minfo[NASC];
-struct bus_driver asc_driver =
- { asc_probe, scsi_slave, scsi_attach, asc_go, asc_std, "rz", asc_dinfo,
- "asc", asc_minfo, BUS_INTR_B4_PROBE};
-
-
-int asc_clock_speed_in_mhz[NASC] = {25,25,25,25}; /* original 3max */
-
-asc_set_dmaops(unit, dmaops)
- unsigned int unit;
- scsi_dma_ops_t *dmaops;
-{
- if (unit < NASC)
- asc_std[unit] = (vm_offset_t)dmaops;
-}
-
-/*
- * Scripts
- */
-struct script
-asc_script_data_in[] = { /* started with SEL & DMA */
- {SCSI_PHASE_DATAI, ASC_CMD_XFER_INFO|ASC_CMD_DMA, 0, asc_dma_in},
- {SCSI_PHASE_STATUS, ASC_CMD_I_COMPLETE, 0, asc_clean_fifo},
- {SCSI_PHASE_MSG_IN, ASC_CMD_MSG_ACPT, 0, asc_get_status},
- {ANY, SCRIPT_END, 0, asc_end}
-},
-
-asc_script_data_out[] = { /* started with SEL & DMA */
- {SCSI_PHASE_DATAO, ASC_CMD_XFER_INFO|ASC_CMD_DMA, 0, asc_dma_out},
- {SCSI_PHASE_STATUS, ASC_CMD_I_COMPLETE, 0, asc_clean_fifo},
- {SCSI_PHASE_MSG_IN, ASC_CMD_MSG_ACPT, 0, asc_get_status},
- {ANY, SCRIPT_END, 0, asc_end}
-},
-
-asc_script_try_synch[] = {
- {SCSI_PHASE_MSG_OUT, ASC_CMD_I_COMPLETE,0, asc_dosynch},
- {SCSI_PHASE_MSG_IN, ASC_CMD_MSG_ACPT, 0, asc_get_status},
- {ANY, SCRIPT_END, 0, asc_end}
-},
-
-asc_script_simple_cmd[] = {
- {SCSI_PHASE_STATUS, ASC_CMD_I_COMPLETE, 0, asc_clean_fifo},
- {SCSI_PHASE_MSG_IN, ASC_CMD_MSG_ACPT, 0, asc_get_status},
- {ANY, SCRIPT_END, 0, asc_end}
-},
-
-asc_script_disconnect[] = {
- {ANY, ASC_CMD_ENABLE_SEL, 0, asc_disconnected},
-/**/ {SCSI_PHASE_MSG_IN, ASC_CMD_MSG_ACPT, 0, asc_reconnect}
-},
-
-asc_script_restart_data_in[] = { /* starts after disconnect */
- {SCSI_PHASE_DATAI, ASC_CMD_XFER_INFO|ASC_CMD_DMA, 0, asc_dma_in_r},
- {SCSI_PHASE_STATUS, ASC_CMD_I_COMPLETE, 0, asc_clean_fifo},
- {SCSI_PHASE_MSG_IN, ASC_CMD_MSG_ACPT, 0, asc_get_status},
- {ANY, SCRIPT_END, 0, asc_end}
-},
-
-asc_script_restart_data_out[] = { /* starts after disconnect */
- {SCSI_PHASE_DATAO, ASC_CMD_XFER_INFO|ASC_CMD_DMA, 0, asc_dma_out_r},
- {SCSI_PHASE_STATUS, ASC_CMD_I_COMPLETE, 0, asc_clean_fifo},
- {SCSI_PHASE_MSG_IN, ASC_CMD_MSG_ACPT, 0, asc_get_status},
- {ANY, SCRIPT_END, 0, asc_end}
-},
-
-#if documentation
-/*
- * This is what might happen during a read
- * that disconnects
- */
-asc_script_data_in_wd[] = { /* started with SEL & DMA & allow disconnect */
- {SCSI_PHASE_MSG_IN, ASC_CMD_XFER_INFO|ASC_CMD_DMA, 0, asc_msg_in},
- {ANY, ASC_CMD_ENABLE_SEL, 0, asc_disconnected},
- {SCSI_PHASE_MSG_IN, ASC_CMD_MSG_ACPT, 0, asc_reconnect},
- {SCSI_PHASE_DATAI, ASC_CMD_XFER_INFO|ASC_CMD_DMA, 0, asc_dma_in},
- {SCSI_PHASE_STATUS, ASC_CMD_I_COMPLETE, 0, asc_clean_fifo},
- {SCSI_PHASE_MSG_IN, ASC_CMD_MSG_ACPT, 0, asc_get_status},
- {ANY, SCRIPT_END, 0, asc_end}
-},
-#endif
-
-/*
- * Target mode scripts
- */
-asc_script_t_data_in[] = {
- {SCSI_PHASE_CMD, ASC_CMD_RCV_DATA|ASC_CMD_DMA, 0, asc_dma_in_r},
- {SCSI_PHASE_DATAO, ASC_CMD_TERM, 0, asc_put_status},
- {ANY, SCRIPT_END, 0, asc_end}
-},
-
-asc_script_t_data_out[] = {
- {SCSI_PHASE_CMD, ASC_CMD_SND_DATA|ASC_CMD_DMA, 0, asc_dma_out_r},
- {SCSI_PHASE_DATAI, ASC_CMD_TERM, 0, asc_put_status},
- {ANY, SCRIPT_END, 0, asc_end}
-};
-
-
-#ifdef DEBUG
-
-#define PRINT(x) if (scsi_debug) printf x
-
-asc_state(regs)
- asc_padded_regmap_t *regs;
-{
- register unsigned char ff,csr,ir,d0,d1,cmd;
-
- if (regs == 0) {
- if (asc_softc[0])
- regs = asc_softc[0]->regs;
- else
- regs = (asc_padded_regmap_t*)0xbf400000;
- }
- ff = get_reg(regs,asc_flags);
- csr = get_reg(regs,asc_csr);
-/* ir = get_reg(regs,asc_intr); nope, clears interrupt */
- d0 = get_reg(regs,asc_tc_lsb);
- d1 = get_reg(regs,asc_tc_msb);
- cmd = get_reg(regs,asc_cmd);
- printf("dma %x ff %x csr %x cmd %x\n",
- (d1 << 8) | d0, ff, csr, cmd);
- return 0;
-}
-
-asc_target_state(tgt)
- target_info_t *tgt;
-{
- if (tgt == 0)
- tgt = asc_softc[0]->active_target;
- if (tgt == 0)
- return 0;
- db_printf("@x%x: fl %x dma %X+%x cmd %x@%X id %x per %x off %x ior %X ret %X\n",
- tgt,
- tgt->flags, tgt->dma_ptr, tgt->transient_state.dma_offset, tgt->cur_cmd,
- tgt->cmd_ptr, (long)tgt->target_id,
- (long)tgt->sync_period, (long)tgt->sync_offset,
- tgt->ior, (long)tgt->done);
- if (tgt->flags & TGT_DISCONNECTED){
- script_t spt;
-
- spt = tgt->transient_state.script;
- db_printf("disconnected at ");
- db_printsym(spt,1);
- db_printf(": %x %x ", spt->condition, spt->command);
- db_printsym(spt->action,1);
- db_printf(", ");
- db_printsym(tgt->transient_state.handler, 1);
- db_printf("\n");
- }
-
- return 0;
-}
-
-asc_all_targets(unit)
-{
- int i;
- target_info_t *tgt;
- for (i = 0; i < 8; i++) {
- tgt = asc_softc[unit]->sc->target[i];
- if (tgt)
- asc_target_state(tgt);
- }
-}
-
-asc_script_state(unit)
-{
- script_t spt = asc_softc[unit]->script;
-
- if (spt == 0) return 0;
- db_printsym(spt,1);
- db_printf(": %x %x ", spt->condition, spt->command);
- db_printsym(spt->action,1);
- db_printf(", ");
- db_printsym(asc_softc[unit]->error_handler, 1);
- return 0;
-}
-
-#define TRMAX 200
-int tr[TRMAX+3];
-int trpt, trpthi;
-#define TR(x) tr[trpt++] = x
-#define TRWRAP trpthi = trpt; trpt = 0;
-#define TRCHECK if (trpt > TRMAX) {TRWRAP}
-
-
-#ifdef TRACE
-
-#define LOGSIZE 256
-int asc_logpt;
-char asc_log[LOGSIZE];
-
-#define MAXLOG_VALUE 0x42
-struct {
- char *name;
- unsigned int count;
-} logtbl[MAXLOG_VALUE];
-
-/* private */ LOG(e,f)
- char *f;
-{
- asc_log[asc_logpt++] = (e);
- if (asc_logpt == LOGSIZE) asc_logpt = 0;
- if ((e) < MAXLOG_VALUE) {
- logtbl[(e)].name = (f);
- logtbl[(e)].count++;
- }
-}
-
-asc_print_log(skip)
- int skip;
-{
- register int i, j;
- register unsigned char c;
-
- for (i = 0, j = asc_logpt; i < LOGSIZE; i++) {
- c = asc_log[j];
- if (++j == LOGSIZE) j = 0;
- if (skip-- > 0)
- continue;
- if (c < MAXLOG_VALUE)
- db_printf(" %s", logtbl[c].name);
- else
- db_printf("-x%x", c & 0x7f);
- }
-}
-
-asc_print_stat()
-{
- register int i;
- register char *p;
- for (i = 0; i < MAXLOG_VALUE; i++) {
- if (p = logtbl[i].name)
- printf("%d %s\n", logtbl[i].count, p);
- }
-}
-
-#else /*TRACE*/
-#define LOG(e,f)
-#define LOGSIZE
-#endif /*TRACE*/
-
-#else /*DEBUG*/
-#define PRINT(x)
-#define LOG(e,f)
-#define LOGSIZE
-#define TR(x)
-#define TRCHECK
-#define TRWRAP
-
-#endif /*DEBUG*/
-
-
-/*
- * Probe/Slave/Attach functions
- */
-
-/*
- * Probe routine:
- * Should find out (a) if the controller is
- * present and (b) which/where slaves are present.
- *
- * Implementation:
- * Send a test-unit-ready to each possible target on the bus
- * except of course ourselves.
- */
-asc_probe(reg, ui)
- vm_offset_t reg;
- struct bus_ctlr *ui;
-{
- int unit = ui->unit;
- asc_softc_t asc = &asc_softc_data[unit];
- int target_id;
- scsi_softc_t *sc;
- register asc_padded_regmap_t *regs;
- spl_t s;
- boolean_t did_banner = FALSE;
-
- /*
- * We are only called if the right board is there,
- * but make sure anyways..
- */
- if (check_memory(reg, 0))
- return 0;
-
-#if defined(HAS_MAPPED_SCSI)
- /* Mappable version side */
- ASC_probe(reg, ui);
-#endif
-
- /*
- * Initialize hw descriptor, cache some pointers
- */
- asc_softc[unit] = asc;
- asc->regs = (asc_padded_regmap_t *) (reg);
-
- if ((asc->dma_ops = (scsi_dma_ops_t *)asc_std[unit]) == 0)
- /* use same as unit 0 if undefined */
- asc->dma_ops = (scsi_dma_ops_t *)asc_std[0];
- {
- int dma_bsize = 16; /* bits, preferred */
- boolean_t do_rfb = FALSE;
-
- asc->dma_state = (*asc->dma_ops->init)(unit, reg, &dma_bsize, &do_rfb);
- if (dma_bsize > 16)
- asc->state |= ASC_STATE_SPEC_DMA;
- if (do_rfb)
- asc->state |= ASC_STATE_DO_RFB;
- }
-
- queue_init(&asc->waiting_targets);
-
- asc->clk = asc_clock_speed_in_mhz[unit];
- asc->ccf = mhz_to_ccf(asc->clk); /* see .h file */
- asc->timeout = asc_timeout_250(asc->clk,asc->ccf);
-
- sc = scsi_master_alloc(unit, asc);
- asc->sc = sc;
-
- sc->go = asc_go;
- sc->watchdog = scsi_watchdog;
- sc->probe = asc_probe_target;
- asc->wd.reset = asc_reset_scsibus;
-
-#ifdef MACH_KERNEL
- sc->max_dma_data = -1;
-#else
- sc->max_dma_data = scsi_per_target_virtual;
-#endif
-
- regs = asc->regs;
-
- /*
- * Our SCSI id on the bus.
- * The user can set this via the prom on 3maxen/pmaxen.
- * If this changes it is easy to fix: make a default that
- * can be changed as boot arg.
- */
- {
- register unsigned char my_id;
-
- my_id = scsi_initiator_id[unit] & 0x7;
- if (my_id != 7)
- regs->asc_cnfg1 = my_id; mb();
- }
-
- /*
- * Reset chip, fully. Note that interrupts are already enabled.
- */
- s = splbio();
- asc_reset(asc, TRUE, asc->state & ASC_STATE_SPEC_DMA);
-
- sc->initiator_id = regs->asc_cnfg1 & ASC_CNFG1_MY_BUS_ID;
- printf("%s%d: SCSI id %d", ui->name, unit, sc->initiator_id);
-
- {
- register target_info_t *tgt;
-
- tgt = scsi_slave_alloc(sc->masterno, sc->initiator_id, asc);
- (*asc->dma_ops->new_target)(asc->dma_state, tgt);
- sccpu_new_initiator(tgt, tgt);
- }
-
- if (asc_probe_dynamically)
- printf("%s", ", will probe targets on demand");
- else {
-
- /*
- * For all possible targets, see if there is one and allocate
- * a descriptor for it if it is there.
- */
- for (target_id = 0; target_id < 8; target_id++) {
- register unsigned char csr, ss, ir, ff;
- register scsi_status_byte_t status;
-
- /* except of course ourselves */
- if (target_id == sc->initiator_id)
- continue;
-
- regs->asc_cmd = ASC_CMD_FLUSH; /* empty fifo */
- mb();
- delay(2);
-
- regs->asc_dbus_id = target_id; mb();
- regs->asc_sel_timo = asc->timeout; mb();
-
- /*
- * See if the unit is ready.
- * XXX SHOULD inquiry LUN 0 instead !!!
- */
- regs->asc_fifo = SCSI_CMD_TEST_UNIT_READY; mb();
- regs->asc_fifo = 0; mb();
- regs->asc_fifo = 0; mb();
- regs->asc_fifo = 0; mb();
- regs->asc_fifo = 0; mb();
- regs->asc_fifo = 0; mb();
-
- /* select and send it */
- regs->asc_cmd = ASC_CMD_SEL; mb();
-
- /* wait for the chip to complete, or timeout */
- csr = asc_wait(regs, ASC_CSR_INT, 1);
- ss = get_reg(regs,asc_ss);
- ir = get_reg(regs,asc_intr);
-
- /* empty fifo, there is garbage in it if timeout */
- regs->asc_cmd = ASC_CMD_FLUSH; mb();
- delay(2);
-
- /*
- * Check if the select timed out
- */
- if ((ASC_SS(ss) == 0) && (ir == ASC_INT_DISC))
- /* noone out there */
- continue;
-
- if (SCSI_PHASE(csr) != SCSI_PHASE_STATUS) {
- printf( " %s%d%s", "ignoring target at ", target_id,
- " cuz it acts weirdo");
- continue;
- }
-
- printf(",%s%d", did_banner++ ? " " : " target(s) at ",
- target_id);
-
- regs->asc_cmd = ASC_CMD_I_COMPLETE;
- wbflush();
- csr = asc_wait(regs, ASC_CSR_INT, 1);
- ir = get_reg(regs,asc_intr); /* ack intr */
- mb();
-
- status.bits = get_fifo(regs); /* empty fifo */
- mb();
- ff = get_fifo(regs);
-
- if (status.st.scsi_status_code != SCSI_ST_GOOD)
- scsi_error( 0, SCSI_ERR_STATUS, status.bits, 0);
-
- regs->asc_cmd = ASC_CMD_MSG_ACPT; mb();
- csr = asc_wait(regs, ASC_CSR_INT, 1);
- ir = get_reg(regs,asc_intr); /* ack intr */
- mb();
-
- /*
- * Found a target
- */
- asc->ntargets++;
- {
- register target_info_t *tgt;
- tgt = scsi_slave_alloc(sc->masterno, target_id, asc);
-
- (*asc->dma_ops->new_target)(asc->dma_state, tgt);
- }
- }
- } /* asc_probe_dynamically */
-
- regs->asc_cmd = ASC_CMD_ENABLE_SEL; mb();
-
- printf(".\n");
-
- splx(s);
- return 1;
-}
-
-boolean_t
-asc_probe_target(tgt, ior)
- target_info_t *tgt;
- io_req_t ior;
-{
- asc_softc_t asc = asc_softc[tgt->masterno];
- boolean_t newlywed;
-
- newlywed = (tgt->cmd_ptr == 0);
- if (newlywed) {
- (*asc->dma_ops->new_target)(asc->dma_state, tgt);
- }
-
- if (scsi_inquiry(tgt, SCSI_INQ_STD_DATA) == SCSI_RET_DEVICE_DOWN)
- return FALSE;
-
- asc->ntargets++;
- tgt->flags = TGT_ALIVE;
- return TRUE;
-}
-
-private asc_wait(regs, until, complain)
- asc_padded_regmap_t *regs;
-{
- int timeo = 1000000;
- while ((regs->asc_csr & until) == 0) {
- mb();
- delay(1);
- if (!timeo--) {
- if (complain)
- printf("asc_wait TIMEO with x%x\n", get_reg(regs,asc_csr));
- break;
- }
- }
- return get_reg(regs,asc_csr);
-}
-
-asc_reset(asc, quick, special_dma)
- asc_softc_t asc;
-{
- char my_id;
- int ccf;
- asc_padded_regmap_t *regs;
-
- regs = asc->regs;
-
- /* preserve our ID for now */
- my_id = (regs->asc_cnfg1 & ASC_CNFG1_MY_BUS_ID);
-
- /*
- * Reset chip and wait till done
- */
- regs->asc_cmd = ASC_CMD_RESET;
- wbflush(); delay(25);
-
- /* spec says this is needed after reset */
- regs->asc_cmd = ASC_CMD_NOP;
- wbflush(); delay(25);
-
- /*
- * Set up various chip parameters
- */
- regs->asc_ccf = asc->ccf;
- wbflush();
- delay(25);
- regs->asc_sel_timo = asc->timeout; mb();
- /* restore our ID */
- regs->asc_cnfg1 = my_id | ASC_CNFG1_P_CHECK; mb();
- regs->asc_cnfg2 = ASC_CNFG2_SCSI2;
- mb();
- regs->asc_cnfg3 = special_dma ? (ASC_CNFG3_T8|ASC_CNFG3_ALT_DMA) : 0;
- mb();
- /* zero anything else */
- ASC_TC_PUT(regs, 0); mb();
- regs->asc_syn_p = asc_min_period; mb();
- regs->asc_syn_o = 0; mb(); /* asynch for now */
-
- regs->asc_cmd = ASC_CMD_ENABLE_SEL; mb();
-
- if (quick) return;
-
- /*
- * reset the scsi bus, the interrupt routine does the rest
- * or you can call asc_bus_reset().
- */
- regs->asc_cmd = ASC_CMD_BUS_RESET; mb();
-}
-
-
-/*
- * Operational functions
- */
-
-/*
- * Start a SCSI command on a target
- */
-asc_go(tgt, cmd_count, in_count, cmd_only)
- target_info_t *tgt;
- boolean_t cmd_only;
-{
- asc_softc_t asc;
- register spl_t s;
- boolean_t disconn;
- script_t scp;
- boolean_t (*handler)();
-
- LOG(1,"go");
-
- asc = (asc_softc_t)tgt->hw_state;
-
- tgt->transient_state.cmd_count = cmd_count; /* keep it here */
- tgt->transient_state.out_count = 0; /* default */
-
- (*asc->dma_ops->map)(asc->dma_state, tgt);
-
- disconn = BGET(scsi_might_disconnect,tgt->masterno,tgt->target_id);
- disconn = disconn && (asc->ntargets > 1);
- disconn |= BGET(scsi_should_disconnect,tgt->masterno,tgt->target_id);
-
- /*
- * Setup target state
- */
- tgt->done = SCSI_RET_IN_PROGRESS;
-
- handler = (disconn) ? asc_err_disconn : asc_err_generic;
-
- switch (tgt->cur_cmd) {
- case SCSI_CMD_READ:
- case SCSI_CMD_LONG_READ:
- LOG(2,"readop");
- scp = asc_script_data_in;
- break;
- case SCSI_CMD_WRITE:
- case SCSI_CMD_LONG_WRITE:
- LOG(0x18,"writeop");
- scp = asc_script_data_out;
- break;
- case SCSI_CMD_INQUIRY:
- /* This is likely the first thing out:
- do the synch neg if so */
- if (!cmd_only && ((tgt->flags&TGT_DID_SYNCH)==0)) {
- scp = asc_script_try_synch;
- tgt->flags |= TGT_TRY_SYNCH;
- disconn = FALSE;
- break;
- }
- case SCSI_CMD_REQUEST_SENSE:
- case SCSI_CMD_MODE_SENSE:
- case SCSI_CMD_RECEIVE_DIAG_RESULTS:
- case SCSI_CMD_READ_CAPACITY:
- case SCSI_CMD_READ_BLOCK_LIMITS:
- case SCSI_CMD_READ_TOC:
- case SCSI_CMD_READ_SUBCH:
- case SCSI_CMD_READ_HEADER:
- case 0xc4: /* despised: SCSI_CMD_DEC_PLAYBACK_STATUS */
- case 0xdd: /* despised: SCSI_CMD_NEC_READ_SUBCH_Q */
- case 0xde: /* despised: SCSI_CMD_NEC_READ_TOC */
- scp = asc_script_data_in;
- LOG(0x1c,"cmdop");
- LOG(0x80+tgt->cur_cmd,0);
- break;
- case SCSI_CMD_MODE_SELECT:
- case SCSI_CMD_REASSIGN_BLOCKS:
- case SCSI_CMD_FORMAT_UNIT:
- case 0xc9: /* vendor-spec: SCSI_CMD_DEC_PLAYBACK_CONTROL */
- tgt->transient_state.cmd_count = sizeof_scsi_command(tgt->cur_cmd);
- tgt->transient_state.out_count =
- cmd_count - tgt->transient_state.cmd_count;
- scp = asc_script_data_out;
- LOG(0x1c,"cmdop");
- LOG(0x80+tgt->cur_cmd,0);
- break;
- case SCSI_CMD_TEST_UNIT_READY:
- /*
- * Do the synch negotiation here, unless prohibited
- * or done already
- */
- if (tgt->flags & TGT_DID_SYNCH) {
- scp = asc_script_simple_cmd;
- } else {
- scp = asc_script_try_synch;
- tgt->flags |= TGT_TRY_SYNCH;
- cmd_only = FALSE;
- disconn = FALSE;
- }
- LOG(0x1c,"cmdop");
- LOG(0x80+tgt->cur_cmd,0);
- break;
- default:
- LOG(0x1c,"cmdop");
- LOG(0x80+tgt->cur_cmd,0);
- scp = asc_script_simple_cmd;
- }
-
- tgt->transient_state.script = scp;
- tgt->transient_state.handler = handler;
- tgt->transient_state.identify = (cmd_only) ? 0xff :
- (disconn ? SCSI_IDENTIFY|SCSI_IFY_ENABLE_DISCONNECT :
- SCSI_IDENTIFY);
-
- if (in_count)
- tgt->transient_state.in_count =
- (in_count < tgt->block_size) ? tgt->block_size : in_count;
- else
- tgt->transient_state.in_count = 0;
-
- /*
- * See if another target is currently selected on
- * this SCSI bus, e.g. lock the asc structure.
- * Note that it is the strategy routine's job
- * to serialize ops on the same target as appropriate.
- * XXX here and everywhere, locks!
- */
- /*
- * Protection viz reconnections makes it tricky.
- */
- s = splbio();
-
- if (asc->wd.nactive++ == 0)
- asc->wd.watchdog_state = SCSI_WD_ACTIVE;
-
- if (asc->state & ASC_STATE_BUSY) {
- /*
- * Queue up this target, note that this takes care
- * of proper FIFO scheduling of the scsi-bus.
- */
- LOG(3,"enqueue");
- enqueue_tail(&asc->waiting_targets, (queue_entry_t) tgt);
- } else {
- /*
- * It is down to at most two contenders now,
- * we will treat reconnections same as selections
- * and let the scsi-bus arbitration process decide.
- */
- asc->state |= ASC_STATE_BUSY;
- asc->next_target = tgt;
- asc_attempt_selection(asc);
- /*
- * Note that we might still lose arbitration..
- */
- }
- splx(s);
-}
-
-asc_attempt_selection(asc)
- asc_softc_t asc;
-{
- target_info_t *tgt;
- asc_padded_regmap_t *regs;
- register int out_count;
-
- regs = asc->regs;
- tgt = asc->next_target;
-
- LOG(4,"select");
- LOG(0x80+tgt->target_id,0);
-
- /*
- * We own the bus now.. unless we lose arbitration
- */
- asc->active_target = tgt;
-
- /* Try to avoid reselect collisions */
- if ((regs->asc_csr & (ASC_CSR_INT|SCSI_PHASE_MSG_IN)) ==
- (ASC_CSR_INT|SCSI_PHASE_MSG_IN))
- return;
-
- /*
- * Cleanup the FIFO
- */
- regs->asc_cmd = ASC_CMD_FLUSH;
- readback(regs->asc_cmd);
- /*
- * This value is not from spec, I have seen it failing
- * without this delay and with logging disabled. That had
- * about 42 extra instructions @25Mhz.
- */
- delay(2);/* XXX time & move later */
-
-
- /*
- * Init bus state variables
- */
- asc->script = tgt->transient_state.script;
- asc->error_handler = tgt->transient_state.handler;
- asc->done = SCSI_RET_IN_PROGRESS;
-
- asc->out_count = 0;
- asc->in_count = 0;
- asc->extra_count = 0;
-
- /*
- * Start the chip going
- */
- out_count = (*asc->dma_ops->start_cmd)(asc->dma_state, tgt);
- if (tgt->transient_state.identify != 0xff) {
- regs->asc_fifo = tgt->transient_state.identify | tgt->lun;
- mb();
- }
- ASC_TC_PUT(regs, out_count);
- readback(regs->asc_cmd);
-
- regs->asc_dbus_id = tgt->target_id;
- readback(regs->asc_dbus_id);
-
- regs->asc_sel_timo = asc->timeout;
- readback(regs->asc_sel_timo);
-
- regs->asc_syn_p = tgt->sync_period;
- readback(regs->asc_syn_p);
-
- regs->asc_syn_o = tgt->sync_offset;
- readback(regs->asc_syn_o);
-
- /* ugly little help for compiler */
-#define command out_count
- if (tgt->flags & TGT_DID_SYNCH) {
- command = (tgt->transient_state.identify == 0xff) ?
- ASC_CMD_SEL | ASC_CMD_DMA :
- ASC_CMD_SEL_ATN | ASC_CMD_DMA; /*preferred*/
- } else if (tgt->flags & TGT_TRY_SYNCH)
- command = ASC_CMD_SEL_ATN_STOP;
- else
- command = ASC_CMD_SEL | ASC_CMD_DMA;
-
- /* Try to avoid reselect collisions */
- if ((regs->asc_csr & (ASC_CSR_INT|SCSI_PHASE_MSG_IN)) !=
- (ASC_CSR_INT|SCSI_PHASE_MSG_IN)) {
- register int tmp;
-
- regs->asc_cmd = command; mb();
- /*
- * Very nasty but infrequent problem here. We got/will get
- * reconnected but the chip did not interrupt. The watchdog would
- * fix it allright, but it stops the machine before it expires!
- * Too bad we cannot just look at the interrupt register, sigh.
- */
- tmp = get_reg(regs,asc_cmd);
- if ((tmp != command) && (tmp == (ASC_CMD_NOP|ASC_CMD_DMA))) {
- if ((regs->asc_csr & ASC_CSR_INT) == 0) {
- delay(250); /* increase if in trouble */
-
- if (get_reg(regs,asc_csr) == SCSI_PHASE_MSG_IN) {
- /* ok, take the risk of reading the ir */
- tmp = get_reg(regs,asc_intr); mb();
- if (tmp & ASC_INT_RESEL) {
- (void) asc_reconnect(asc, get_reg(regs,asc_csr), tmp);
- asc_wait(regs, ASC_CSR_INT, 1);
- tmp = get_reg(regs,asc_intr); mb();
- regs->asc_cmd = ASC_CMD_MSG_ACPT;
- readback(regs->asc_cmd);
- } else /* does not happen, but who knows.. */
- asc_reset(asc,FALSE,asc->state & ASC_STATE_SPEC_DMA);
- }
- }
- }
- }
-#undef command
-}
-
-/*
- * Interrupt routine
- * Take interrupts from the chip
- *
- * Implementation:
- * Move along the current command's script if
- * all is well, invoke error handler if not.
- */
-asc_intr(unit, spllevel)
- spl_t spllevel;
-{
- register asc_softc_t asc;
- register script_t scp;
- register int ir, csr;
- register asc_padded_regmap_t *regs;
-#if defined(HAS_MAPPED_SCSI)
- extern boolean_t rz_use_mapped_interface;
-
- if (rz_use_mapped_interface)
- return ASC_intr(unit,spllevel);
-#endif
-
- asc = asc_softc[unit];
-
- LOG(5,"\n\tintr");
- /* collect ephemeral information */
- regs = asc->regs;
- csr = get_reg(regs,asc_csr); mb();
- asc->ss_was = get_reg(regs,asc_ss); mb();
- asc->cmd_was = get_reg(regs,asc_cmd); mb();
-
- /* drop spurious interrupts */
- if ((csr & ASC_CSR_INT) == 0)
- return;
-
- ir = get_reg(regs,asc_intr); /* this re-latches CSR (and SSTEP) */
- mb();
-
-TR(csr);TR(ir);TR(get_reg(regs,asc_cmd));TRCHECK
-
- /* this must be done within 250msec of disconnect */
- if (ir & ASC_INT_DISC) {
- regs->asc_cmd = ASC_CMD_ENABLE_SEL;
- readback(regs->asc_cmd);
- }
-
- if (ir & ASC_INT_RESET)
- return asc_bus_reset(asc);
-
- /* we got an interrupt allright */
- if (asc->active_target)
- asc->wd.watchdog_state = SCSI_WD_ACTIVE;
-
-#if mips
- splx(spllevel); /* drop priority */
-#endif
-
- if ((asc->state & ASC_STATE_TARGET) ||
- (ir & (ASC_INT_SEL|ASC_INT_SEL_ATN)))
- return asc_target_intr(asc, csr, ir);
-
- /*
- * In attempt_selection() we could not check the asc_intr
- * register to see if a reselection was in progress [else
- * we would cancel the interrupt, and it would not be safe
- * anyways]. So we gave the select command even if sometimes
- * the chip might have been reconnected already. What
- * happens then is that we get an illegal command interrupt,
- * which is why the second clause. Sorry, I'd do it better
- * if I knew of a better way.
- */
- if ((ir & ASC_INT_RESEL) ||
- ((ir & ASC_INT_ILL) && (regs->asc_cmd & ASC_CMD_SEL_ATN)))
- return asc_reconnect(asc, csr, ir);
-
- /*
- * Check for various errors
- */
- if ((csr & (ASC_CSR_GE|ASC_CSR_PE)) || (ir & ASC_INT_ILL)) {
- char *msg;
-printf("{E%x,%x}", csr, ir);
- if (csr & ASC_CSR_GE)
- return;/* sit and prey? */
-
- if (csr & ASC_CSR_PE)
- msg = "SCSI bus parity error";
- if (ir & ASC_INT_ILL)
- msg = "Chip sez Illegal Command";
- /* all we can do is to throw a reset on the bus */
- printf( "asc%d: %s%s", asc - asc_softc_data, msg,
- ", attempting recovery.\n");
- asc_reset(asc, FALSE, asc->state & ASC_STATE_SPEC_DMA);
- return;
- }
-
- if ((scp = asc->script) == 0) /* sanity */
- return;
-
- LOG(6,"match");
- if (SCRIPT_MATCH(csr,ir,scp->condition)) {
- /*
- * Perform the appropriate operation,
- * then proceed
- */
- if ((*scp->action)(asc, csr, ir)) {
- asc->script = scp + 1;
- regs->asc_cmd = scp->command; mb();
- }
- } else
- (void) (*asc->error_handler)(asc, csr, ir);
-}
-
-asc_target_intr(asc, csr, ir)
- register asc_softc_t asc;
-
-{
- register script_t scp;
-
- LOG(0x1e,"tmode");
-
- if ((asc->state & ASC_STATE_TARGET) == 0) {
-
- /*
- * We just got selected
- */
- asc->state |= ASC_STATE_TARGET;
-
- /*
- * See if this selection collided with our selection attempt
- */
- if (asc->state & ASC_STATE_BUSY)
- asc->state |= ASC_STATE_COLLISION;
- asc->state |= ASC_STATE_BUSY;
-
- return asc_selected(asc, csr, ir);
-
- }
- /* We must be executing a script here */
- scp = asc->script;
- assert(scp != 0);
-
- LOG(6,"match");
- if (SCRIPT_MATCH(csr,ir,scp->condition)) {
- /*
- * Perform the appropriate operation,
- * then proceed
- */
- if ((*scp->action)(asc, csr, ir)) {
- asc->script = scp + 1;
- asc->regs->asc_cmd = scp->command; mb();
- }
- } else
- (void) (*asc->error_handler)(asc, csr, ir);
-
-}
-
-/*
- * All the many little things that the interrupt
- * routine might switch to
- */
-boolean_t
-asc_clean_fifo(asc, csr, ir)
- register asc_softc_t asc;
-
-{
- register asc_padded_regmap_t *regs = asc->regs;
- register char ff;
-
- ASC_TC_GET(regs,asc->dmacnt_at_end);
-
- ASC_TC_PUT(regs,0); /* stop dma engine */
- readback(regs->asc_cmd);
-
- LOG(7,"clean_fifo");
-
- while (fifo_count(regs)) {
- ff = get_fifo(regs);
- mb();
- }
- return TRUE;
-}
-
-boolean_t
-asc_end(asc, csr, ir)
- register asc_softc_t asc;
-{
- register target_info_t *tgt;
- register io_req_t ior;
-
- LOG(8,"end");
-
- asc->state &= ~ASC_STATE_TARGET;
- asc->regs->asc_syn_p = 0; mb();
- asc->regs->asc_syn_o = 0; mb();
-
- tgt = asc->active_target;
- if ((tgt->done = asc->done) == SCSI_RET_IN_PROGRESS)
- tgt->done = SCSI_RET_SUCCESS;
-
- asc->script = 0;
-
- if (asc->wd.nactive-- == 1)
- asc->wd.watchdog_state = SCSI_WD_INACTIVE;
-
- asc_release_bus(asc);
-
- if (ior = tgt->ior) {
- /*
- * WARNING: the above might have scheduled the
- * DMA engine off to someone else. Keep it in
- * mind in the following code
- */
- (*asc->dma_ops->end_cmd)(asc->dma_state, tgt, ior);
-
- LOG(0xA,"ops->restart");
- (*tgt->dev_ops->restart)( tgt, TRUE);
- }
-
- return FALSE;
-}
-
-boolean_t
-asc_release_bus(asc)
- register asc_softc_t asc;
-{
- boolean_t ret = TRUE;
-
- LOG(9,"release");
- if (asc->state & ASC_STATE_COLLISION) {
-
- LOG(0xB,"collided");
- asc->state &= ~ASC_STATE_COLLISION;
- asc_attempt_selection(asc);
-
- } else if (queue_empty(&asc->waiting_targets)) {
-
- asc->state &= ~ASC_STATE_BUSY;
- asc->active_target = 0;
- asc->script = 0;
- ret = FALSE;
-
- } else {
-
- LOG(0xC,"dequeue");
- asc->next_target = (target_info_t *)
- dequeue_head(&asc->waiting_targets);
- asc_attempt_selection(asc);
- }
- return ret;
-}
-
-boolean_t
-asc_get_status(asc, csr, ir)
- register asc_softc_t asc;
-{
- register asc_padded_regmap_t *regs = asc->regs;
- register scsi2_status_byte_t status;
- int len;
- boolean_t ret;
- io_req_t ior;
- register target_info_t *tgt = asc->active_target;
-
- LOG(0xD,"get_status");
-TRWRAP
-
- asc->state &= ~ASC_STATE_DMA_IN;
-
- if (asc->state & ASC_STATE_DO_RFB) {
- tgt->transient_state.has_oddb = FALSE;
- regs->asc_cnfg2 = ASC_CNFG2_SCSI2;
- }
-
- /*
- * Get the last two bytes in FIFO
- */
- while (fifo_count(regs) > 2) {
- status.bits = get_fifo(regs); mb();
- }
-
- status.bits = get_fifo(regs); mb();
-
- if (status.st.scsi_status_code != SCSI_ST_GOOD) {
- scsi_error(asc->active_target, SCSI_ERR_STATUS, status.bits, 0);
- asc->done = (status.st.scsi_status_code == SCSI_ST_BUSY) ?
- SCSI_RET_RETRY : SCSI_RET_NEED_SENSE;
- } else
- asc->done = SCSI_RET_SUCCESS;
-
- status.bits = get_fifo(regs); /* just pop the command_complete */
- mb();
-
- /* if reading, move the last piece of data in main memory */
- if (len = asc->in_count) {
- register int count;
-
- count = asc->dmacnt_at_end;
- if (count) {
-#if 0
- this is incorrect and besides..
- tgt->ior->io_residual = count;
-#endif
- len -= count;
- }
- regs->asc_cmd = asc->script->command;
- readback(regs->asc_cmd);
-
- ret = FALSE;
- } else
- ret = TRUE;
-
- asc->dmacnt_at_end = 0;
- (*asc->dma_ops->end_xfer)(asc->dma_state, tgt, len);
- if (!ret)
- asc->script++;
- return ret;
-}
-
-boolean_t
-asc_put_status(asc, csr, ir)
- register asc_softc_t asc;
-{
- register asc_padded_regmap_t *regs = asc->regs;
- register scsi2_status_byte_t status;
- register target_info_t *tgt = asc->active_target;
- int len;
-
- LOG(0x21,"put_status");
-
- asc->state &= ~ASC_STATE_DMA_IN;
-
- if (len = asc->in_count) {
- register int count;
-
- ASC_TC_GET(regs,count); mb();
- if (count)
- len -= count;
- }
- (*asc->dma_ops->end_xfer)(asc->dma_state, tgt, len);
-
-/* status.st.scsi_status_code = SCSI_ST_GOOD; */
- regs->asc_fifo = 0; mb();
- regs->asc_fifo = SCSI_COMMAND_COMPLETE; mb();
-
- return TRUE;
-}
-
-
-boolean_t
-asc_dma_in(asc, csr, ir)
- register asc_softc_t asc;
-{
- register target_info_t *tgt;
- register asc_padded_regmap_t *regs = asc->regs;
- register int count;
- unsigned char ff = get_reg(regs,asc_flags); mb();
-
- LOG(0xE,"dma_in");
- tgt = asc->active_target;
-
- /*
- * This seems to be needed on certain rudimentary targets
- * (such as the DEC TK50 tape) which apparently only pick
- * up 6 initial bytes: when you add the initial IDENTIFY
- * you are left with 1 pending byte, which is left in the
- * FIFO and would otherwise show up atop the data we are
- * really requesting.
- *
- * This is only speculation, though, based on the fact the
- * sequence step value of 3 out of select means the target
- * changed phase too quick and some bytes have not been
- * xferred (see NCR manuals). Counter to this theory goes
- * the fact that the extra byte that shows up is not alwyas
- * zero, and appears to be pretty random.
- * Note that asc_flags say there is one byte in the FIFO
- * even in the ok case, but the sstep value is the right one.
- * Note finally that this might all be a sync/async issue:
- * I have only checked the ok case on synch disks so far.
- *
- * Indeed it seems to be an asynch issue: exabytes do it too.
- */
- if ((tgt->sync_offset == 0) && ((ff & ASC_FLAGS_SEQ_STEP) != 0x80)) {
- regs->asc_cmd = ASC_CMD_NOP;
- wbflush();
- PRINT(("[tgt %d: %x while %d]", tgt->target_id, ff, tgt->cur_cmd));
- while ((ff & ASC_FLAGS_FIFO_CNT) != 0) {
- ff = get_fifo(regs); mb();
- ff = get_reg(regs,asc_flags); mb();
- }
- }
-
- asc->state |= ASC_STATE_DMA_IN;
-
- count = (*asc->dma_ops->start_datain)(asc->dma_state, tgt);
- ASC_TC_PUT(regs, count);
- readback(regs->asc_cmd);
-
- if ((asc->in_count = count) == tgt->transient_state.in_count)
- return TRUE;
- regs->asc_cmd = asc->script->command; mb();
- asc->script = asc_script_restart_data_in;
- return FALSE;
-}
-
-asc_dma_in_r(asc, csr, ir)
- register asc_softc_t asc;
-{
- register target_info_t *tgt;
- register asc_padded_regmap_t *regs = asc->regs;
- register int count;
- boolean_t advance_script = TRUE;
-
-
- LOG(0x1f,"dma_in_r");
- tgt = asc->active_target;
-
- asc->state |= ASC_STATE_DMA_IN;
-
- if (asc->in_count == 0) {
- /*
- * Got nothing yet, we just reconnected.
- */
- register int avail;
-
- /*
- * NOTE: if we have to handle the RFB (obb),
- * the odd byte has been installed at reconnect
- * time, before switching to data-in phase. Now
- * we are already in data-in phase.
- * It is up to the DMA engine to trim the dma_ptr
- * down one byte.
- */
-
- count = (*asc->dma_ops->restart_datain_1)
- (asc->dma_state, tgt);
-
- /* common case of 8k-or-less read ? */
- advance_script = (tgt->transient_state.in_count == count);
-
- } else {
-
- /*
- * We received some data.
- */
- register int offset, xferred;
-
- /*
- * Problem: sometimes we get a 'spurious' interrupt
- * right after a reconnect. It goes like disconnect,
- * reconnect, dma_in_r, here but DMA is still rolling.
- * Since there is no good reason we got here to begin with
- * we just check for the case and dismiss it: we should
- * get another interrupt when the TC goes to zero or the
- * target disconnects.
- */
- ASC_TC_GET(regs,xferred); mb();
- if (xferred != 0)
- return FALSE;
-
- xferred = asc->in_count - xferred;
- assert(xferred > 0);
-
- tgt->transient_state.in_count -= xferred;
- assert(tgt->transient_state.in_count > 0);
-
- /*
- * There should NOT be any obb issues here,
- * we would have no control anyways.
- */
- count = (*asc->dma_ops->restart_datain_2)
- (asc->dma_state, tgt, xferred);
-
- asc->in_count = count;
- ASC_TC_PUT(regs, count);
- readback(regs->asc_cmd);
- regs->asc_cmd = asc->script->command; mb();
-
- (*asc->dma_ops->restart_datain_3)
- (asc->dma_state, tgt);
-
- /* last chunk ? */
- if (count == tgt->transient_state.in_count)
- asc->script++;
-
- return FALSE;
- }
-
- asc->in_count = count;
- ASC_TC_PUT(regs, count);
- readback(regs->asc_cmd);
-
- if (!advance_script) {
- regs->asc_cmd = asc->script->command;
- readback(regs->asc_cmd);
- }
- return advance_script;
-}
-
-
-/* send data to target. Only called to start the xfer */
-
-boolean_t
-asc_dma_out(asc, csr, ir)
- register asc_softc_t asc;
-{
- register asc_padded_regmap_t *regs = asc->regs;
- register int reload_count;
- register target_info_t *tgt;
- int command;
-
- LOG(0xF,"dma_out");
-
- ASC_TC_GET(regs, reload_count); mb();
- asc->extra_count = fifo_count(regs);
- reload_count += asc->extra_count;
- ASC_TC_PUT(regs, reload_count);
- asc->state &= ~ASC_STATE_DMA_IN;
- readback(regs->asc_cmd);
-
- tgt = asc->active_target;
-
- command = asc->script->command;
-
- if (reload_count == 0) reload_count = ASC_TC_MAX;
- asc->out_count = reload_count;
-
- if (reload_count >= tgt->transient_state.out_count)
- asc->script++;
- else
- asc->script = asc_script_restart_data_out;
-
- if ((*asc->dma_ops->start_dataout)
- (asc->dma_state, tgt, (volatile unsigned *)&regs->asc_cmd,
- command, &asc->extra_count)) {
- regs->asc_cmd = command;
- readback(regs->asc_cmd);
- }
-
- return FALSE;
-}
-
-/* send data to target. Called in two different ways:
- (a) to restart a big transfer and
- (b) after reconnection
- */
-boolean_t
-asc_dma_out_r(asc, csr, ir)
- register asc_softc_t asc;
-{
- register asc_padded_regmap_t *regs = asc->regs;
- register target_info_t *tgt;
- boolean_t advance_script = TRUE;
- int count;
-
-
- LOG(0x20,"dma_out_r");
-
- tgt = asc->active_target;
- asc->state &= ~ASC_STATE_DMA_IN;
-
- if (asc->out_count == 0) {
- /*
- * Nothing committed: we just got reconnected
- */
- count = (*asc->dma_ops->restart_dataout_1)
- (asc->dma_state, tgt);
-
- /* is this the last chunk ? */
- advance_script = (tgt->transient_state.out_count == count);
- } else {
- /*
- * We sent some data.
- */
- register int offset, xferred;
-
- ASC_TC_GET(regs,count); mb();
-
- /* see comment above */
- if (count) {
- return FALSE;
- }
-
- count += fifo_count(regs);
- count -= asc->extra_count;
- xferred = asc->out_count - count;
- assert(xferred > 0);
-
- tgt->transient_state.out_count -= xferred;
- assert(tgt->transient_state.out_count > 0);
-
- count = (*asc->dma_ops->restart_dataout_2)
- (asc->dma_state, tgt, xferred);
-
- /* last chunk ? */
- if (tgt->transient_state.out_count == count)
- goto quickie;
-
- asc->out_count = count;
-
- asc->extra_count = (*asc->dma_ops->restart_dataout_3)
- (asc->dma_state, tgt,
- (volatile unsigned *)&regs->asc_fifo);
- ASC_TC_PUT(regs, count);
- readback(regs->asc_cmd);
- regs->asc_cmd = asc->script->command; mb();
-
- (*asc->dma_ops->restart_dataout_4)(asc->dma_state, tgt);
-
- return FALSE;
- }
-
-quickie:
- asc->extra_count = (*asc->dma_ops->restart_dataout_3)
- (asc->dma_state, tgt,
- (volatile unsigned *)&regs->asc_fifo);
-
- asc->out_count = count;
-
- ASC_TC_PUT(regs, count);
- readback(regs->asc_cmd);
-
- if (!advance_script) {
- regs->asc_cmd = asc->script->command;
- }
- return advance_script;
-}
-
-boolean_t
-asc_dosynch(asc, csr, ir)
- register asc_softc_t asc;
- register unsigned char csr, ir;
-{
- register asc_padded_regmap_t *regs = asc->regs;
- register unsigned char c;
- int i, per, offs;
- register target_info_t *tgt;
-
- /*
- * Phase is MSG_OUT here.
- * Try to go synchronous, unless prohibited
- */
- tgt = asc->active_target;
- regs->asc_cmd = ASC_CMD_FLUSH;
- readback(regs->asc_cmd);
- delay(1);
-
- per = asc_min_period;
- if (BGET(scsi_no_synchronous_xfer,asc->sc->masterno,tgt->target_id))
- offs = 0;
- else
- offs = asc_max_offset;
-
- tgt->flags |= TGT_DID_SYNCH; /* only one chance */
- tgt->flags &= ~TGT_TRY_SYNCH;
-
- regs->asc_fifo = SCSI_EXTENDED_MESSAGE; mb();
- regs->asc_fifo = 3; mb();
- regs->asc_fifo = SCSI_SYNC_XFER_REQUEST; mb();
- regs->asc_fifo = asc_to_scsi_period(asc_min_period,asc->clk); mb();
- regs->asc_fifo = offs; mb();
- regs->asc_cmd = ASC_CMD_XFER_INFO;
- readback(regs->asc_cmd);
- csr = asc_wait(regs, ASC_CSR_INT, 1);
- ir = get_reg(regs,asc_intr); mb();
-
- /* some targets might be slow to move to msg-in */
-
- if (SCSI_PHASE(csr) != SCSI_PHASE_MSG_IN) {
-
- /* wait for direction bit to flip */
- csr = asc_wait(regs, SCSI_IO, 0);
- ir = get_reg(regs,asc_intr); mb();
- /* Some ugly targets go stright to command phase.
- "You could at least say goodbye" */
- if (SCSI_PHASE(csr) == SCSI_PHASE_CMD)
- goto did_not;
- if (SCSI_PHASE(csr) != SCSI_PHASE_MSG_IN)
- gimmeabreak();
- }
-
- regs->asc_cmd = ASC_CMD_XFER_INFO; mb();
- csr = asc_wait(regs, ASC_CSR_INT, 1);
- ir = get_reg(regs,asc_intr); mb();
-
- /* some targets do not even take all the bytes out */
- while (fifo_count(regs) > 0) {
- c = get_fifo(regs); /* see what it says */
- mb();
- }
-
- if (c == SCSI_MESSAGE_REJECT) {
-did_not:
- printf(" did not like SYNCH xfer ");
-
- /* Tk50s get in trouble with ATN, sigh. */
- regs->asc_cmd = ASC_CMD_CLR_ATN;
- readback(regs->asc_cmd);
-
- goto cmd;
- }
-
- /*
- * Receive the rest of the message
- */
- regs->asc_cmd = ASC_CMD_MSG_ACPT; mb();
- asc_wait(regs, ASC_CSR_INT, 1);
- ir = get_reg(regs,asc_intr); mb();
-
- if (c != SCSI_EXTENDED_MESSAGE)
- gimmeabreak();
-
- regs->asc_cmd = ASC_CMD_XFER_INFO; mb();
- asc_wait(regs, ASC_CSR_INT, 1);
- c = get_reg(regs,asc_intr); mb();
- if (get_fifo(regs) != 3)
- panic("asc_dosynch");
-
- for (i = 0; i < 3; i++) {
- regs->asc_cmd = ASC_CMD_MSG_ACPT; mb();
- asc_wait(regs, ASC_CSR_INT, 1);
- c = get_reg(regs,asc_intr); mb();
-
- regs->asc_cmd = ASC_CMD_XFER_INFO; mb();
- asc_wait(regs, ASC_CSR_INT, 1);
- c = get_reg(regs,asc_intr);/*ack*/ mb();
- c = get_fifo(regs); mb();
-
- if (i == 1) tgt->sync_period = scsi_period_to_asc(c,asc->clk);
- if (i == 2) tgt->sync_offset = c;
- }
-
-cmd:
- regs->asc_cmd = ASC_CMD_MSG_ACPT; mb();
- csr = asc_wait(regs, ASC_CSR_INT, 1);
- c = get_reg(regs,asc_intr); mb();
-
- /* Might have to wait a bit longer for slow targets */
- for (c = 0; SCSI_PHASE(get_reg(regs,asc_csr)) == SCSI_PHASE_MSG_IN; c++) {
- mb();
- delay(2);
- if (c & 0x80) break; /* waited too long */
- }
- csr = get_reg(regs,asc_csr); mb();
-
- /* phase should normally be command here */
- if (SCSI_PHASE(csr) == SCSI_PHASE_CMD) {
- register char *cmd = tgt->cmd_ptr;
-
- /* test unit ready or inquiry */
- for (i = 0; i < sizeof(scsi_command_group_0); i++) {
- regs->asc_fifo = *cmd++; mb();
- }
- ASC_TC_PUT(regs,0xff); mb();
- regs->asc_cmd = ASC_CMD_XFER_PAD; /*0x18*/ mb();
-
- if (tgt->cur_cmd == SCSI_CMD_INQUIRY) {
- tgt->transient_state.script = asc_script_data_in;
- asc->script = tgt->transient_state.script;
- regs->asc_syn_p = tgt->sync_period;
- regs->asc_syn_o = tgt->sync_offset; mb();
- return FALSE;
- }
-
- csr = asc_wait(regs, ASC_CSR_INT, 1);
- ir = get_reg(regs,asc_intr);/*ack*/ mb();
- }
-
- if (SCSI_PHASE(csr) != SCSI_PHASE_STATUS)
- csr = asc_wait(regs, SCSI_IO, 1); /* direction flip */
-
-status:
- if (SCSI_PHASE(csr) != SCSI_PHASE_STATUS)
- gimmeabreak();
-
- return TRUE;
-}
-
-/* The other side of the coin.. */
-asc_odsynch(asc, initiator)
- register asc_softc_t asc;
- target_info_t *initiator;
-{
- register asc_padded_regmap_t *regs = asc->regs;
- register unsigned char c;
- int len, per, offs;
-
- /*
- * Phase is MSG_OUT, we are the target and we have control.
- * Any IDENTIFY messages have been handled already.
- */
- initiator->flags |= TGT_DID_SYNCH;
- initiator->flags &= ~TGT_TRY_SYNCH;
-
- /*
- * We only understand synch negotiations
- */
- c = get_fifo(regs); mb();
- if (c != SCSI_EXTENDED_MESSAGE) goto bad;
-
- /*
- * This is not in the specs, but apparently the chip knows
- * enough about scsi to receive the length automatically.
- * So there were two bytes in the fifo at function call.
- */
- len = get_fifo(regs); mb();
- if (len != 3) goto bad;
- while (len) {
- if (fifo_count(regs) == 0) {
- regs->asc_cmd = ASC_CMD_RCV_MSG;
- readback(regs->asc_cmd);
- asc_wait(regs, ASC_CSR_INT, 1);
- c = get_reg(regs,asc_intr); mb();
- }
- c = get_fifo(regs); mb();
- if (len == 1) offs = c;
- if (len == 2) per = c;
- len--;
- }
-
- /*
- * Adjust the proposed parameters
- */
- c = scsi_period_to_asc(per,asc->clk);
- initiator->sync_period = c;
- per = asc_to_scsi_period(c,asc->clk);
-
- if (offs > asc_max_offset) offs = asc_max_offset;
- initiator->sync_offset = offs;
-
- /*
- * Tell him what the deal is
- */
- regs->asc_fifo = SCSI_EXTENDED_MESSAGE; mb();
- regs->asc_fifo = 3; mb();
- regs->asc_fifo = SCSI_SYNC_XFER_REQUEST; mb();
- regs->asc_fifo = per; mb();
- regs->asc_fifo = offs; mb();
- regs->asc_cmd = ASC_CMD_SND_MSG;
- readback(regs->asc_cmd);
- asc_wait(regs, ASC_CSR_INT, 1);
- c = get_reg(regs,asc_intr); mb();
-
- /*
- * Exit conditions: fifo empty, phase undefined but non-command
- */
- return;
-
- /*
- * Something wrong, reject the message
- */
-bad:
- while (fifo_count(regs)) {
- c = get_fifo(regs); mb();
- }
- regs->asc_fifo = SCSI_MESSAGE_REJECT; mb();
- regs->asc_cmd = ASC_CMD_SND_MSG;
- readback(regs->asc_cmd);
- asc_wait(regs, ASC_CSR_INT, 1);
- c = get_reg(regs,asc_intr); mb();
-}
-
-/*
- * The bus was reset
- */
-asc_bus_reset(asc)
- register asc_softc_t asc;
-{
- register asc_padded_regmap_t *regs = asc->regs;
-
- LOG(0x1d,"bus_reset");
-
- /*
- * Clear bus descriptor
- */
- asc->script = 0;
- asc->error_handler = 0;
- asc->active_target = 0;
- asc->next_target = 0;
- asc->state &= ASC_STATE_SPEC_DMA | ASC_STATE_DO_RFB;
- queue_init(&asc->waiting_targets);
- asc->wd.nactive = 0;
- asc_reset(asc, TRUE, asc->state & ASC_STATE_SPEC_DMA);
-
- printf("asc: (%d) bus reset ", ++asc->wd.reset_count);
-
- /* some targets take long to reset */
- delay( scsi_delay_after_reset +
- asc->sc->initiator_id * 500000); /* if multiple initiators */
-
- if (asc->sc == 0) /* sanity */
- return;
-
- scsi_bus_was_reset(asc->sc);
-}
-
-/*
- * Disconnect/reconnect mode ops
- */
-
-/* get the message in via dma */
-boolean_t
-asc_msg_in(asc, csr, ir)
- register asc_softc_t asc;
- register unsigned char csr, ir;
-{
- register target_info_t *tgt;
- register asc_padded_regmap_t *regs = asc->regs;
- unsigned char ff;
-
- LOG(0x10,"msg_in");
- /* must clean FIFO as in asc_dma_in, sigh */
- while (fifo_count(regs) != 0) {
- ff = get_fifo(regs); mb();
- }
-
- (void) (*asc->dma_ops->start_msgin)(asc->dma_state, asc->active_target);
- /* We only really expect two bytes, at tgt->cmd_ptr */
- ASC_TC_PUT(regs, sizeof(scsi_command_group_0));
- readback(regs->asc_cmd);
-
- return TRUE;
-}
-
-/* check the message is indeed a DISCONNECT */
-boolean_t
-asc_disconnect(asc, csr, ir)
- register asc_softc_t asc;
- register unsigned char csr, ir;
-
-{
- register char *msgs, ff;
- register target_info_t *tgt;
- asc_padded_regmap_t *regs;
-
- tgt = asc->active_target;
-
- (*asc->dma_ops->end_msgin)(asc->dma_state, tgt);
-
- /*
- * Do not do this. It is most likely a reconnection
- * message that sits there already by the time we
- * get here. The chip is smart enough to only dma
- * the bytes that correctly came in as msg_in proper,
- * the identify and selection bytes are not dma-ed.
- * Yes, sometimes the hardware does the right thing.
- */
-#if 0
- /* First check message got out of the fifo */
- regs = asc->regs;
- while (fifo_count(regs) != 0) {
- *msgs++ = get_fifo(regs);
- }
-#endif
- msgs = tgt->cmd_ptr;
-
- /* A SDP message preceeds it in non-completed READs */
- if ((msgs[0] == SCSI_DISCONNECT) || /* completed */
- ((msgs[0] == SCSI_SAVE_DATA_POINTER) && /* non complete */
- (msgs[1] == SCSI_DISCONNECT))) {
- /* that's the ok case */
- } else
- printf("[tgt %d bad SDP: x%x]",
- tgt->target_id, *((unsigned short *)msgs));
-
- return TRUE;
-}
-
-/* save all relevant data, free the BUS */
-boolean_t
-asc_disconnected(asc, csr, ir)
- register asc_softc_t asc;
- register unsigned char csr, ir;
-
-{
- register target_info_t *tgt;
-
- LOG(0x11,"disconnected");
- asc_disconnect(asc,csr,ir);
-
- tgt = asc->active_target;
- tgt->flags |= TGT_DISCONNECTED;
- tgt->transient_state.handler = asc->error_handler;
- /* anything else was saved in asc_err_disconn() */
-
- PRINT(("{D%d}", tgt->target_id));
-
- asc_release_bus(asc);
-
- return FALSE;
-}
-
-int asc_restore_ptr = 1;
-
-/* get reconnect message out of fifo, restore BUS */
-boolean_t
-asc_reconnect(asc, csr, ir)
- register asc_softc_t asc;
- register unsigned char csr, ir;
-
-{
- register target_info_t *tgt;
- asc_padded_regmap_t *regs;
- unsigned int id;
-
- LOG(0x12,"reconnect");
- /*
- * See if this reconnection collided with a selection attempt
- */
- if (asc->state & ASC_STATE_BUSY)
- asc->state |= ASC_STATE_COLLISION;
-
- asc->state |= ASC_STATE_BUSY;
-
- /* find tgt: first byte in fifo is (tgt_id|our_id) */
- regs = asc->regs;
- while (fifo_count(regs) > 2) /* sanity */ {
- id = get_fifo(regs); mb();
- }
- if (fifo_count(regs) != 2)
- gimmeabreak();
-
- id = get_fifo(regs); /* must decode this now */
- mb();
- id &= ~(1 << asc->sc->initiator_id);
- {
- register int i;
- for (i = 0; id > 1; i++)
- id >>= 1;
- id = i;
- }
-
- tgt = asc->sc->target[id];
- if (tgt == 0) panic("asc_reconnect");
-
- /* synch things*/
- regs->asc_syn_p = tgt->sync_period;
- regs->asc_syn_o = tgt->sync_offset;
- readback(regs->asc_syn_o);
-
- /* Get IDENTIFY message */
- {
- register int i = get_fifo(regs);
- if ((i & SCSI_IDENTIFY) == 0)
- gimmeabreak();
- i &= 0x7;
- /* If not LUN 0 see which target it is */
- if (i) {
- target_info_t *tgt1;
- for (tgt1 = tgt->next_lun;
- tgt1 && tgt1 != tgt;
- tgt1 = tgt1->next_lun)
- if (tgt1->lun == i) {
- tgt = tgt1;
- break;
- }
- }
- }
-
- if (asc->state & ASC_STATE_DO_RFB) {
- if (tgt->transient_state.has_oddb) {
- if (tgt->sync_period) {
- regs->asc_cnfg2 = ASC_CNFG2_SCSI2 | ASC_CNFG2_RFB;
- wbflush();
- regs->asc_rfb = tgt->transient_state.the_oddb;
- } else {
- regs->asc_fifo = tgt->transient_state.the_oddb;
- }
- tgt->transient_state.has_oddb = FALSE;
- } else {
- regs->asc_cnfg2 = ASC_CNFG2_SCSI2;
- }
- wbflush();
- }
-
- PRINT(("{R%d}", id));
- if (asc->state & ASC_STATE_COLLISION)
- PRINT(("[B %d-%d]", asc->active_target->target_id, id));
-
- LOG(0x80+id,0);
-
- asc->active_target = tgt;
- tgt->flags &= ~TGT_DISCONNECTED;
-
- asc->script = tgt->transient_state.script;
- asc->error_handler = tgt->transient_state.handler;
- asc->in_count = 0;
- asc->out_count = 0;
-
- regs->asc_cmd = ASC_CMD_MSG_ACPT;
- readback(regs->asc_cmd);
-
- /* What if there is a RESTORE_PTR msgin ? */
- if (asc_restore_ptr) {
-more_msgin:
- csr = asc_wait(regs, ASC_CSR_INT, 1);
-
- if (SCSI_PHASE(csr) == SCSI_PHASE_MSG_IN) {
- /* ack intr */
- id = get_reg(regs,asc_intr); mb();
-
- /* Ok, get msg */
- regs->asc_cmd = ASC_CMD_XFER_INFO;
- readback(regs->asc_cmd);
- /* wait for xfer done */
- csr = asc_wait(regs, ASC_CSR_INT, 1);
-
- /* look at what we got */
- id = get_fifo(regs);
-
- if (id != SCSI_RESTORE_POINTERS)
- printf("asc%d: uhu msg %x\n", asc->sc->masterno, id);
- /* ack intr */
- id = get_reg(regs,asc_intr); mb();
-
- /* move on */
- regs->asc_cmd = ASC_CMD_MSG_ACPT;
- readback(regs->asc_cmd);
- goto more_msgin;
- }
- }
-
- return FALSE;
-}
-
-
-/* We have been selected as target */
-
-boolean_t
-asc_selected(asc, csr, ir)
- register asc_softc_t asc;
- register unsigned csr, ir;
-{
- register asc_padded_regmap_t *regs = asc->regs;
- register unsigned char id;
- target_info_t *self, *initiator;
- unsigned int len;
-
- /*
- * Find initiator's id: the head of the fifo is (init_id|our_id)
- */
-
- id = get_fifo(regs); /* must decode this now */
- mb();
- id &= ~(1 << asc->sc->initiator_id);
- {
- register int i;
- for (i = 0; id > 1; i++)
- id >>= 1;
- id = i;
- }
-
- /*
- * See if we have seen him before
- */
- self = asc->sc->target[asc->sc->initiator_id];
- initiator = asc->sc->target[id];
- if (initiator == 0) {
-
- initiator = scsi_slave_alloc(asc->sc->masterno, id, asc);
- (*asc->dma_ops->new_target)(asc->dma_state, initiator);
-
- }
-
- if (! (initiator->flags & TGT_ONLINE) )
- sccpu_new_initiator(self, initiator);
-
- /*
- * If selected with ATN the chip did the msg-out
- * phase already, let us look at the message(s)
- */
- if (ir & ASC_INT_SEL_ATN) {
- register unsigned char m;
-
- m = get_fifo(regs); mb();
- if ((m & SCSI_IDENTIFY) == 0)
- gimmeabreak();
-
- csr = get_reg(regs,asc_csr); mb();
- if ((SCSI_PHASE(csr) == SCSI_PHASE_MSG_OUT) &&
- fifo_count(regs))
- asc_odsynch(asc, initiator);
-
- /* Get the command now, unless we have it already */
- mb();
- if (fifo_count(regs) < sizeof(scsi_command_group_0)) {
- regs->asc_cmd = ASC_CMD_RCV_CMD;
- readback(regs->asc_cmd);
- asc_wait(regs, ASC_CSR_INT, 1);
- ir = get_reg(regs,asc_intr); mb();
- csr = get_reg(regs,asc_csr); mb();
- }
- } else {
- /*
- * Pop away the null byte that follows the id
- */
- if (get_fifo(regs) != 0)
- gimmeabreak();
-
- }
-
- /*
- * Take rest of command out of fifo
- */
- self->dev_info.cpu.req_pending = TRUE;
- self->dev_info.cpu.req_id = id;
- self->dev_info.cpu.req_cmd = get_fifo(regs);
- self->dev_info.cpu.req_lun = get_fifo(regs);
-
- LOG(0x80+self->dev_info.cpu.req_cmd, 0);
-
- switch ((self->dev_info.cpu.req_cmd & SCSI_CODE_GROUP) >> 5) {
- case 0:
- len = get_fifo(regs) << 16; mb();
- len |= get_fifo(regs) << 8; mb();
- len |= get_fifo(regs); mb();
- break;
- case 1:
- case 2:
- len = get_fifo(regs); /* xxx lba1 */ mb();
- len = get_fifo(regs); /* xxx lba2 */ mb();
- len = get_fifo(regs); /* xxx lba3 */ mb();
- len = get_fifo(regs); /* xxx lba4 */ mb();
- len = get_fifo(regs); /* xxx xxx */ mb();
- len = get_fifo(regs) << 8; mb();
- len |= get_fifo(regs); mb();
- break;
- case 5:
- len = get_fifo(regs); /* xxx lba1 */ mb();
- len = get_fifo(regs); /* xxx lba2 */ mb();
- len = get_fifo(regs); /* xxx lba3 */ mb();
- len = get_fifo(regs); /* xxx lba4 */ mb();
- len = get_fifo(regs) << 24; mb();
- len |= get_fifo(regs) << 16; mb();
- len |= get_fifo(regs) << 8; mb();
- len |= get_fifo(regs); mb();
- if (get_fifo(regs) != 0) ;
- break;
- default:
- panic("asc_selected");
- }
- self->dev_info.cpu.req_len = len;
-/*if (scsi_debug) printf("[L x%x]", len);*/
-
- /* xxx pop the cntrl byte away */
- if (get_fifo(regs) != 0)
- gimmeabreak();
- mb();
-
- /*
- * Setup state
- */
- asc->active_target = self;
- asc->done = SCSI_RET_IN_PROGRESS;
- asc->out_count = 0;
- asc->in_count = 0;
- asc->extra_count = 0;
-
- /*
- * Sync params.
- */
- regs->asc_syn_p = initiator->sync_period;
- regs->asc_syn_o = initiator->sync_offset;
- readback(regs->asc_syn_o);
-
- /*
- * Do the up-call
- */
- LOG(0xB,"tgt-mode-restart");
- (*self->dev_ops->restart)( self, FALSE);
-
- /* The call above has either prepared the data,
- placing an ior on self, or it handled it some
- other way */
- if (self->ior == 0)
- return FALSE;
-
- /* sanity */
- if (fifo_count(regs)) {
- regs->asc_cmd = ASC_CMD_FLUSH;
- readback(regs->asc_cmd);
- }
-
- /* needed by some dma code to align things properly */
- self->transient_state.cmd_count = sizeof(scsi_command_group_0);
- self->transient_state.in_count = len; /* XXX */
-
- (*asc->dma_ops->map)(asc->dma_state, self);
-
- if (asc->wd.nactive++ == 0)
- asc->wd.watchdog_state = SCSI_WD_ACTIVE;
-
-
- {
- register script_t scp;
- unsigned char command;
-
- switch (self->dev_info.cpu.req_cmd) {
- case SCSI_CMD_TEST_UNIT_READY:
- scp = asc_script_t_data_in+1; break;
- case SCSI_CMD_SEND:
- scp = asc_script_t_data_in; break;
- default:
- scp = asc_script_t_data_out; break;
- }
-
- asc->script = scp;
- command = scp->command;
- if (!(*scp->action)(asc, csr, ir))
- return FALSE;
-
-/*if (scsi_debug) printf("[F%x]", fifo_count(regs));*/
-
- asc->script++;
- regs->asc_cmd = command; mb();
-
- }
-
- return FALSE;
-}
-
-
-/*
- * Other utilities
- */
-private void
-pick_up_oddb(
- target_info_t *tgt)
-{
- register char *lastp;
-
- /* State should have been updated before we get here */
- lastp = tgt->dma_ptr + tgt->transient_state.dma_offset;
-
- if ((vm_offset_t) lastp & 1) {
- tgt->transient_state.has_oddb = TRUE;
- tgt->transient_state.the_oddb = lastp[-1];
- } else
- tgt->transient_state.has_oddb = FALSE;
-}
-
-
-/*
- * Error handlers
- */
-
-/*
- * Fall-back error handler.
- */
-asc_err_generic(asc, csr, ir)
- register asc_softc_t asc;
-{
- LOG(0x13,"err_generic");
-
- /* handle non-existant or powered off devices here */
- if ((ir == ASC_INT_DISC) &&
- (asc_isa_select(asc->cmd_was)) &&
- (ASC_SS(asc->ss_was) == 0)) {
- /* Powered off ? */
- target_info_t *tgt = asc->active_target;
-
- tgt->flags = 0;
- tgt->sync_period = 0;
- tgt->sync_offset = 0; mb();
- asc->done = SCSI_RET_DEVICE_DOWN;
- asc_end(asc, csr, ir);
- return;
- }
-
- switch (SCSI_PHASE(csr)) {
- case SCSI_PHASE_STATUS:
- if (asc->script[-1].condition == SCSI_PHASE_STATUS) {
- /* some are just slow to get out.. */
- } else
- asc_err_to_status(asc, csr, ir);
- return;
- break;
- case SCSI_PHASE_DATAI:
- if (asc->script->condition == SCSI_PHASE_STATUS) {
- /*
- * Here is what I know about it. We reconnect to
- * the target (csr 87, ir 0C, cmd 44), start dma in
- * (81 10 12) and then get here with (81 10 90).
- * Dma is rolling and keeps on rolling happily,
- * the value in the counter indicates the interrupt
- * was signalled right away: by the time we get
- * here only 80-90 bytes have been shipped to an
- * rz56 running synchronous at 3.57 Mb/sec.
- */
-/* printf("{P}");*/
- return;
- }
- break;
- case SCSI_PHASE_DATAO:
- if (asc->script->condition == SCSI_PHASE_STATUS) {
- /*
- * See comment above. Actually seen on hitachis.
- */
-/* printf("{P}");*/
- return;
- }
- break;
- case SCSI_PHASE_CMD:
- /* This can be the case with drives that are not
- even scsi-1 compliant and do not like to be
- selected with ATN (to do the synch negot) and
- go stright to command phase, regardless */
-
- if (asc->script == asc_script_try_synch) {
-
- target_info_t *tgt = asc->active_target;
- register asc_padded_regmap_t *regs = asc->regs;
-
- tgt->flags |= TGT_DID_SYNCH; /* only one chance */
- tgt->flags &= ~TGT_TRY_SYNCH;
-
- if (tgt->cur_cmd == SCSI_CMD_INQUIRY)
- tgt->transient_state.script = asc_script_data_in;
- else
- tgt->transient_state.script = asc_script_simple_cmd;
- asc->script = tgt->transient_state.script;
- regs->asc_cmd = ASC_CMD_CLR_ATN;
- readback(regs->asc_cmd);
- asc->regs->asc_cmd = ASC_CMD_XFER_PAD|ASC_CMD_DMA; /*0x98*/ mb();
- printf(" did not like SYNCH xfer ");
- return;
- }
- /* fall through */
- }
- gimmeabreak();
-}
-
-/*
- * Handle generic errors that are reported as
- * an unexpected change to STATUS phase
- */
-asc_err_to_status(asc, csr, ir)
- register asc_softc_t asc;
-{
- script_t scp = asc->script;
-
- LOG(0x14,"err_tostatus");
- while (scp->condition != SCSI_PHASE_STATUS)
- scp++;
- (*scp->action)(asc, csr, ir);
- asc->script = scp + 1;
- asc->regs->asc_cmd = scp->command; mb();
-#if 0
- /*
- * Normally, we would already be able to say the command
- * is in error, e.g. the tape had a filemark or something.
- * But in case we do disconnected mode WRITEs, it is quite
- * common that the following happens:
- * dma_out -> disconnect (xfer complete) -> reconnect
- * and our script might expect at this point that the dma
- * had to be restarted (it didn't notice it was completed).
- * And in any event.. it is both correct and cleaner to
- * declare error iff the STATUS byte says so.
- */
- asc->done = SCSI_RET_NEED_SENSE;
-#endif
-}
-
-/*
- * Handle disconnections as exceptions
- */
-asc_err_disconn(asc, csr, ir)
- register asc_softc_t asc;
- register unsigned char csr, ir;
-{
- register asc_padded_regmap_t *regs;
- register target_info_t *tgt;
- int count;
- boolean_t callback = FALSE;
-
- LOG(0x16,"err_disconn");
-
- /*
- * We only do msg-in cases here
- */
- if (SCSI_PHASE(csr) != SCSI_PHASE_MSG_IN)
- return asc_err_generic(asc, csr, ir);
-
- regs = asc->regs;
- tgt = asc->active_target;
-
- /*
- * What did we expect to happen, and what did happen.
- */
- switch (asc->script->condition) {
- case SCSI_PHASE_DATAO:
- /*
- * A data out phase was either about to be started,
- * or it was in progress but more had to go out later
- * [e.g. a big xfer for instance, or more than the
- * DMA engine can take in one shot].
- */
- LOG(0x1b,"+DATAO");
- if (asc->out_count) {
- register int xferred, offset;
-
- /*
- * Xfer in progress. See where we stopped.
- */
- ASC_TC_GET(regs,xferred); /* temporary misnomer */
- /*
- * Account for prefetching, in its various forms
- */
- xferred += fifo_count(regs);
- xferred -= asc->extra_count;
- /*
- * See how much went out, how much to go.
- */
- xferred = asc->out_count - xferred; /* ok now */
- tgt->transient_state.out_count -= xferred;
- assert(tgt->transient_state.out_count > 0);
-
- callback = (*asc->dma_ops->disconn_1)
- (asc->dma_state, tgt, xferred);
-
- } else {
-
- /*
- * A disconnection before DMA was (re)started.
- */
- callback = (*asc->dma_ops->disconn_2)
- (asc->dma_state, tgt);
-
- }
- asc->extra_count = 0;
- tgt->transient_state.script = asc_script_restart_data_out;
- break;
-
-
- case SCSI_PHASE_DATAI:
- /*
- * Same as above, the other way around
- */
- LOG(0x17,"+DATAI");
- if (asc->in_count) {
- register int offset, xferred;
-
- /*
- * How much did we expect, how much did we get
- */
- ASC_TC_GET(regs,count); mb();
- xferred = asc->in_count - count;
- assert(xferred > 0);
-
-if (regs->asc_flags & 0xf)
-printf("{Xf %x,%x,%x}", xferred, asc->in_count, fifo_count(regs));
- tgt->transient_state.in_count -= xferred;
- assert(tgt->transient_state.in_count > 0);
-
- callback = (*asc->dma_ops->disconn_3)
- (asc->dma_state, tgt, xferred);
-
- /*
- * Handle obb if we have to. DMA code has
- * updated pointers and flushed buffers.
- */
- if (asc->state & ASC_STATE_DO_RFB)
- pick_up_oddb(tgt);
-
- tgt->transient_state.script = asc_script_restart_data_in;
- /*
- * Some silly targets disconnect after they
- * have given us all the data.
- */
- if (tgt->transient_state.in_count == 0)
- tgt->transient_state.script++;
-
- } else
- tgt->transient_state.script = asc_script_restart_data_in;
- break;
-
- case SCSI_PHASE_STATUS:
- /*
- * Either one of the above cases here. Only diff
- * the DMA engine was setup to run to completion
- * and (most likely) did not.
- */
- ASC_TC_GET(regs,count); mb();
- if (asc->state & ASC_STATE_DMA_IN) {
- register int offset, xferred;
-
- LOG(0x1a,"+STATUS+R");
-
-
- /*
- * Handle brain-dead sequence:
- * 1-xfer all data, disconnect
- * 2-reconnect, disconnect immediately ??
- * 3-rept 2
- * 4-reconnect,complete
- */
- if (asc->in_count) {
-
- xferred = asc->in_count - count;
- assert(xferred > 0);
-if (regs->asc_flags & 0xf)
-printf("{Xf %x,%x,%x}", xferred, asc->in_count, fifo_count(regs));
-
- tgt->transient_state.in_count -= xferred;
-
- callback = (*asc->dma_ops->disconn_4)
- (asc->dma_state, tgt, xferred);
- }
- /*
- * Handle obb if we have to. DMA code has
- * updated pointers and flushed buffers.
- */
- if (asc->state & ASC_STATE_DO_RFB)
- pick_up_oddb(tgt);
-
- tgt->transient_state.script = asc_script_restart_data_in;
-
- /* see previous note */
- if (tgt->transient_state.in_count == 0)
- tgt->transient_state.script++;
-
- } else {
-
- /*
- * Outgoing xfer, take care of prefetching.
- */
- /* add what's left in the fifo */
- count += fifo_count(regs);
- /* take back the extra we might have added */
- count -= asc->extra_count;
- /* ..and drop that idea */
- asc->extra_count = 0;
-
- LOG(0x19,"+STATUS+W");
-
- /*
- * All done ? This is less silly than with
- * READs: some disks will only say "done" when
- * the data is down on the platter, and some
- * people like it much better that way.
- */
- if ((count == 0) && (tgt->transient_state.out_count == asc->out_count)) {
- /* all done */
- tgt->transient_state.script = asc->script;
- tgt->transient_state.out_count = 0;
- } else {
- register int xferred, offset;
-
- /* how much we xferred */
- xferred = asc->out_count - count;
-
- /* how much to go */
- tgt->transient_state.out_count -= xferred;
- assert(tgt->transient_state.out_count > 0);
-
- callback = (*asc->dma_ops->disconn_5)
- (asc->dma_state,tgt,xferred);
-
- tgt->transient_state.script = asc_script_restart_data_out;
- }
- asc->out_count = 0;
- }
- break;
- default:
- gimmeabreak();
- return;
- }
- asc_msg_in(asc,csr,ir);
- asc->script = asc_script_disconnect;
- regs->asc_cmd = ASC_CMD_XFER_INFO|ASC_CMD_DMA;
- wbflush();
- /*
- * Prevent a race, now. If the reselection comes quickly
- * the chip will prefetch and reload the transfer counter
- * register. Make sure it will stop, by reloading a zero.
- */
- regs->asc_tc_lsb = 0;
- regs->asc_tc_msb = 0;
- if (callback)
- (*asc->dma_ops->disconn_callback)(asc->dma_state, tgt);
-}
-
-/*
- * Watchdog
- *
- * So far I have only seen the chip get stuck in a
- * select/reselect conflict: the reselection did
- * win and the interrupt register showed it but..
- * no interrupt was generated.
- * But we know that some (name withdrawn) disks get
- * stuck in the middle of dma phases...
- */
-asc_reset_scsibus(asc)
- register asc_softc_t asc;
-{
- register target_info_t *tgt = asc->active_target;
- register asc_padded_regmap_t *regs = asc->regs;
- register int ir;
-
- if (scsi_debug && tgt) {
- int dmalen;
- ASC_TC_GET(asc->regs,dmalen); mb();
- printf("Target %d was active, cmd x%x in x%x out x%x Sin x%x Sou x%x dmalen x%x\n",
- tgt->target_id, tgt->cur_cmd,
- tgt->transient_state.in_count, tgt->transient_state.out_count,
- asc->in_count, asc->out_count,
- dmalen);
- }
- ir = get_reg(regs,asc_intr); mb();
- if ((ir & ASC_INT_RESEL) && (SCSI_PHASE(regs->asc_csr) == SCSI_PHASE_MSG_IN)) {
- /* getting it out of the woods is a bit tricky */
- spl_t s = splbio();
-
- (void) asc_reconnect(asc, get_reg(regs,asc_csr), ir);
- asc_wait(regs, ASC_CSR_INT, 1);
- ir = get_reg(regs,asc_intr); mb();
- regs->asc_cmd = ASC_CMD_MSG_ACPT;
- readback(regs->asc_cmd);
- splx(s);
- } else {
- regs->asc_cmd = ASC_CMD_BUS_RESET; mb();
- delay(35);
- }
-}
-
-#endif NASC > 0
-
diff --git a/scsi/adapters/scsi_7061.h b/scsi/adapters/scsi_7061.h
deleted file mode 100644
index 8969f8b..0000000
--- a/scsi/adapters/scsi_7061.h
+++ /dev/null
@@ -1,230 +0,0 @@
-/*
- * Mach Operating System
- * Copyright (c) 1991,1990,1989 Carnegie Mellon University
- * All Rights Reserved.
- *
- * Permission to use, copy, modify and distribute this software and its
- * documentation is hereby granted, provided that both the copyright
- * notice and this permission notice appear in all copies of the
- * software, derivative works or modified versions, and any portions
- * thereof, and that both notices appear in supporting documentation.
- *
- * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
- * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
- * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
- *
- * Carnegie Mellon requests users of this software to return to
- *
- * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
- * School of Computer Science
- * Carnegie Mellon University
- * Pittsburgh PA 15213-3890
- *
- * any improvements or extensions that they make and grant Carnegie Mellon
- * the rights to redistribute these changes.
- */
-/*
- * File: scsi_7061.h
- * Author: Alessandro Forin, Carnegie Mellon University
- * Date: 9/90
- *
- * Defines for the DEC DC7061 SII gate array (SCSI interface)
- */
-
-/*
- * Register map
- */
-
-typedef struct {
- volatile unsigned short sii_sdb; /* rw: Data bus and parity */
- volatile unsigned short sii_sc1; /* rw: scsi signals 1 */
- volatile unsigned short sii_sc2; /* rw: scsi signals 2 */
- volatile unsigned short sii_csr; /* rw: control and status */
- volatile unsigned short sii_id; /* rw: scsi bus ID */
- volatile unsigned short sii_sel_csr; /* rw: selection status */
- volatile unsigned short sii_destat; /* ro: selection detector status */
- volatile unsigned short sii_dstmo; /* unsupp: dssi timeout */
- volatile unsigned short sii_data; /* rw: data register */
- volatile unsigned short sii_dma_ctrl; /* rw: dma control reg */
- volatile unsigned short sii_dma_len; /* rw: length of transfer */
- volatile unsigned short sii_dma_adr_low;/* rw: low address */
- volatile unsigned short sii_dma_adr_hi; /* rw: high address */
- volatile unsigned short sii_dma_1st_byte;/* rw: initial byte */
- volatile unsigned short sii_stlp; /* unsupp: dssi short trgt list ptr */
- volatile unsigned short sii_ltlp; /* unsupp: dssi long " " " */
- volatile unsigned short sii_ilp; /* unsupp: dssi initiator list ptr */
- volatile unsigned short sii_dssi_csr; /* unsupp: dssi control */
- volatile unsigned short sii_conn_csr; /* rc: connection interrupt control */
- volatile unsigned short sii_data_csr; /* rc: data interrupt control */
- volatile unsigned short sii_cmd; /* rw: command register */
- volatile unsigned short sii_diag_csr; /* rw: disgnostic status */
-} sii_regmap_t;
-
-/*
- * Data bus register (diag)
- */
-
-#define SII_SDB_DATA 0x00ff /* data bits, assert high */
-#define SII_SDB_PARITY 0x0100 /* parity bit */
-
-/*
- * Control signals one (diag)
- */
-
-#define SII_CS1_IO 0x0001 /* I/O bit */
-#define SII_CS1_CD 0x0002 /* Control/Data bit */
-#define SII_CS1_MSG 0x0004 /* Message bit */
-#define SII_CS1_ATN 0x0008 /* Attention bit */
-#define SII_CS1_REQ 0x0010 /* Request bit */
-#define SII_CS1_ACK 0x0020 /* Acknowledge bit */
-#define SII_CS1_RST 0x0040 /* Reset bit */
-#define SII_CS1_SEL 0x0080 /* Selection bit */
-#define SII_CS1_BSY 0x0100 /* Busy bit */
-
-/*
- * Control signals two (diag)
- */
-
-#define SII_CS2_SBE 0x0001 /* Bus enable */
-#define SII_CS2_ARB 0x0002 /* arbitration enable */
-#define SII_CS2_TGS 0x0004 /* Target role steer */
-#define SII_CS2_IGS 0x0008 /* Initiator role steer */
-
-/*
- * Control and status register
- */
-
-#define SII_CSR_IE 0x0001 /* Interrupt enable */
-#define SII_CSR_PCE 0x0002 /* Parity check enable */
-#define SII_CSR_SLE 0x0004 /* Select enable */
-#define SII_CSR_RSE 0x0008 /* Reselect enable */
-#define SII_CSR_HPM 0x0010 /* Arbitration enable */
-
-/*
- * SCSI bus ID register
- */
-
-#define SII_ID_MASK 0x0007 /* The scsi ID */
-#define SII_ID_IO 0x8000 /* ID pins are in/out */
-
-/*
- * Selector control and status register
- */
-
-#define SII_SEL_ID 0x0003 /* Destination ID */
-
-/*
- * Selection detector status register
- */
-
-#define SII_DET_ID 0x0003 /* Selector's ID */
-
-/*
- * Data register (silo)
- */
-
-#define SII_DATA_VAL 0x00ff /* Lower byte */
-
-/*
- * DMA control register
- */
-
-#define SII_DMA_SYN_OFFSET 0x0003 /* 0 -> asynch */
-
-/*
- * DMA counter
- */
-
-#define SII_DMA_COUNT_MASK 0x1fff /* in bytes */
-
-/*
- * DMA address registers
- */
-
-#define SII_DMA_LOW_MASK 0xffff /* all bits */
-#define SII_DMA_HIGH_MASK 0x0003 /* unused ones mbz */
-
-/*
- * DMA initial byte
- */
-
-#define SII_DMA_IBYTE 0x00ff /* for odd address DMAs */
-
-/*
- * Connection status register
- */
-
-#define SII_CON_LST 0x0002 /* ro: lost arbitration */
-#define SII_CON_SIP 0x0004 /* ro: selection InProgress */
-#define SII_CON_SWA 0x0008 /* rc: selected with ATN */
-#define SII_CON_TGT 0x0010 /* ro: target role */
-#define SII_CON_DST 0x0020 /* ro: sii is destination */
-#define SII_CON_CON 0x0040 /* ro: sii is connected */
-#define SII_CON_SCH 0x0080 /* rci: state change */
-#define SII_CON_LDN 0x0100 /* ??i: dssi list elm done */
-#define SII_CON_BUF 0x0200 /* ??i: dssi buffer service */
-#define SII_CON_TZ 0x0400 /* ??: dssi target zero */
-#define SII_CON_OBC 0x0800 /* ??i: dssi outen bit clr */
-#define SII_CON_BERR 0x1000 /* rci: bus error */
-#define SII_CON_RST 0x2000 /* rci: RST asserted */
-#define SII_CON_DI 0x4000 /* ro: data_csr intr */
-#define SII_CON_CI 0x8000 /* ro: con_csr intr */
-
-/*
- * Data transfer status register
- */
-
-#define SII_DTR_IO 0x0001 /* ro: I/O asserted */
-#define SII_DTR_CD 0x0002 /* ro: CD asserted */
-#define SII_DTR_MSG 0x0004 /* ro: MSG asserted */
-#define SII_DTR_ATN 0x0008 /* rc: ATN found asserted */
-#define SII_DTR_MIS 0x0010 /* roi: phase mismatch */
-#define SII_DTR_OBB 0x0100 /* ro: odd byte boundry */
-#define SII_DTR_IPE 0x0200 /* ro: incoming parity err */
-#define SII_DTR_IBF 0x0400 /* roi: input buffer full */
-#define SII_DTR_TBE 0x0800 /* roi: xmt buffer empty */
-#define SII_DTR_TCZ 0x1000 /* ro: xfer counter zero */
-#define SII_DTR_DONE 0x2000 /* rci: xfer complete */
-#define SII_DTR_DI 0x4000 /* ro: data_csr intr */
-#define SII_DTR_CI 0x8000 /* ro: con_csr intr */
-
-#define SII_PHASE(dtr) SCSI_PHASE(dtr)
-
-
-/*
- * Command register
- *
- * Certain bits are only valid in certain roles:
- * I - Initiator D - Destination T - Target
- * Bits 0-3 give the 'expected phase'
- * Bits 4-6 give the 'expected state'
- * Bits 7-11 are the 'command' proper
- */
-
-#define SII_CMD_IO 0x0001 /* rw: (T) assert I/O */
-#define SII_CMD_CD 0x0002 /* rw: (T) assert CD */
-#define SII_CMD_MSG 0x0004 /* rw: (T) assert MSG */
-#define SII_CMD_ATN 0x0008 /* rw: (I) assert ATN */
-
-#define SII_CMD_TGT 0x0010 /* rw: (DIT) target */
-#define SII_CMD_DST 0x0020 /* rw: (DIT) destination */
-#define SII_CMD_CON 0x0040 /* rw: (DIT) connected */
-
-#define SII_CMD_RESET 0x0080 /* rw: (DIT) reset */
-#define SII_CMD_DIS 0x0100 /* rw: (DIT) disconnect */
-#define SII_CMD_REQ 0x0200 /* rw: (T) request data */
-#define SII_CMD_SEL 0x0400 /* rw: (D) select */
-#define SII_CMD_XFER 0x0800 /* rw: (IT) xfer information */
-
-#define SII_CMD_RSL 0x1000 /* rw: reselect target */
-#define SII_CMD_RST 0x4000 /* zw: assert RST */
-#define SII_CMD_DMA 0x8000 /* rw: command uses DMA */
-
-/*
- * Diagnostic control register
- */
-
-#define SII_DIAG_TEST 0x0001 /* rw: test mode */
-#define SII_DIAG_DIA 0x0002 /* rw: ext loopback mode */
-#define SII_DIAG_PORT_ENB 0x0004 /* rw: enable drivers */
-#define SII_DIAG_LPB 0x0008 /* rw: loopback reg writes */
diff --git a/scsi/adapters/scsi_7061_hdw.c b/scsi/adapters/scsi_7061_hdw.c
deleted file mode 100644
index 674e892..0000000
--- a/scsi/adapters/scsi_7061_hdw.c
+++ /dev/null
@@ -1,2603 +0,0 @@
-/*
- * Mach Operating System
- * Copyright (c) 1991,1990,1989 Carnegie Mellon University
- * All Rights Reserved.
- *
- * Permission to use, copy, modify and distribute this software and its
- * documentation is hereby granted, provided that both the copyright
- * notice and this permission notice appear in all copies of the
- * software, derivative works or modified versions, and any portions
- * thereof, and that both notices appear in supporting documentation.
- *
- * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
- * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
- * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
- *
- * Carnegie Mellon requests users of this software to return to
- *
- * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
- * School of Computer Science
- * Carnegie Mellon University
- * Pittsburgh PA 15213-3890
- *
- * any improvements or extensions that they make and grant Carnegie Mellon
- * the rights to redistribute these changes.
- */
-/*
- * File: scsi_7061_hdw.c
- * Author: Alessandro Forin, Carnegie Mellon University
- * Date: 10/90
- *
- * Bottom layer of the SCSI driver: chip-dependent functions
- *
- * This file contains the code that is specific to the DEC DC7061
- * SCSI chip (Host Bus Adapter in SCSI parlance): probing, start
- * operation, and interrupt routine.
- */
-
-/*
- * This layer works based on small simple 'scripts' that are installed
- * at the start of the command and drive the chip to completion.
- * The idea comes from the specs of the NCR 53C700 'script' processor.
- *
- * There are various reasons for this, mainly
- * - Performance: identify the common (successful) path, and follow it;
- * at interrupt time no code is needed to find the current status
- * - Code size: it should be easy to compact common operations
- * - Adaptability: the code skeleton should adapt to different chips without
- * terrible complications.
- * - Error handling: and it is easy to modify the actions performed
- * by the scripts to cope with strange but well identified sequences
- *
- */
-
-#include <sii.h>
-#if NSII > 0
-
-#include <platforms.h>
-
-#ifdef DECSTATION
-#define PAD(n) short n
-#endif
-
-#include <machine/machspl.h> /* spl definitions */
-#include <mach/std_types.h>
-#include <chips/busses.h>
-#include <scsi/compat_30.h>
-#include <machine/machspl.h>
-
-#include <sys/syslog.h>
-
-#include <scsi/scsi.h>
-#include <scsi/scsi2.h>
-#include <scsi/scsi_defs.h>
-
-#define isa_oddbb hba_dep[0]
-#define oddbb hba_dep[1]
-
-#include <scsi/adapters/scsi_7061.h>
-
-#ifdef PAD
-
-typedef struct {
- volatile unsigned short sii_sdb; /* rw: Data bus and parity */
- PAD(pad0);
- volatile unsigned short sii_sc1; /* rw: scsi signals 1 */
- PAD(pad1);
- volatile unsigned short sii_sc2; /* rw: scsi signals 2 */
- PAD(pad2);
- volatile unsigned short sii_csr; /* rw: control and status */
- PAD(pad3);
- volatile unsigned short sii_id; /* rw: scsi bus ID */
- PAD(pad4);
- volatile unsigned short sii_sel_csr; /* rw: selection status */
- PAD(pad5);
- volatile unsigned short sii_destat; /* ro: selection detector status */
- PAD(pad6);
- volatile unsigned short sii_dstmo; /* unsupp: dssi timeout */
- PAD(pad7);
- volatile unsigned short sii_data; /* rw: data register */
- PAD(pad8);
- volatile unsigned short sii_dma_ctrl; /* rw: dma control reg */
- PAD(pad9);
- volatile unsigned short sii_dma_len; /* rw: length of transfer */
- PAD(pad10);
- volatile unsigned short sii_dma_adr_low;/* rw: low address */
- PAD(pad11);
- volatile unsigned short sii_dma_adr_hi; /* rw: high address */
- PAD(pad12);
- volatile unsigned short sii_dma_1st_byte;/* rw: initial byte */
- PAD(pad13);
- volatile unsigned short sii_stlp; /* unsupp: dssi short trgt list ptr */
- PAD(pad14);
- volatile unsigned short sii_ltlp; /* unsupp: dssi long " " " */
- PAD(pad15);
- volatile unsigned short sii_ilp; /* unsupp: dssi initiator list ptr */
- PAD(pad16);
- volatile unsigned short sii_dssi_csr; /* unsupp: dssi control */
- PAD(pad17);
- volatile unsigned short sii_conn_csr; /* rc: connection interrupt control */
- PAD(pad18);
- volatile unsigned short sii_data_csr; /* rc: data interrupt control */
- PAD(pad19);
- volatile unsigned short sii_cmd; /* rw: command register */
- PAD(pad20);
- volatile unsigned short sii_diag_csr; /* rw: disgnostic status */
- PAD(pad21);
-} sii_padded_regmap_t;
-
-#else /*!PAD*/
-
-typedef sii_regmap_t sii_padded_regmap_t;
-
-#endif /*!PAD*/
-
-
-#undef SII_CSR_SLE
-#define SII_CSR_SLE 0 /* for now */
-
-#ifdef DECSTATION
-#include <mips/PMAX/kn01.h>
-#define SII_OFFSET_RAM (KN01_SYS_SII_B_START-KN01_SYS_SII)
-#define SII_RAM_SIZE (KN01_SYS_SII_B_END-KN01_SYS_SII_B_START)
-/* 16 bits in 32 bit envelopes */
-#define SII_DMADR_LO(ptr) ((((unsigned)ptr)>>1)&SII_DMA_LOW_MASK)
-#define SII_DMADR_HI(ptr) ((((unsigned)ptr)>>(16+1))&SII_DMA_HIGH_MASK)
-#endif /* DECSTATION */
-
-#ifndef SII_OFFSET_RAM /* cross compile check */
-#define SII_OFFSET_RAM 0
-#define SII_RAM_SIZE 0x10000
-#define SII_DMADR_LO(ptr) (((unsigned)ptr)>>16)
-#define SII_DMADR_HI(ptr) (((unsigned)ptr)&0xffff)
-#endif
-
-/*
- * Statically partition the DMA buffer between targets.
- * This way we will eventually be able to attach/detach
- * drives on-fly. And 18k/target is enough.
- */
-#define PER_TGT_DMA_SIZE ((SII_RAM_SIZE/7) & ~(sizeof(int)-1))
-
-/*
- * Round to 4k to make debug easier
- */
-#define PER_TGT_BUFF_SIZE ((PER_TGT_DMA_SIZE >> 12) << 12)
-
-/*
- * Macros to make certain things a little more readable
- */
-#define SII_COMMAND(regs,cs,ds,cmd) \
- { \
- (regs)->sii_cmd = ((cs) & 0x70) | \
- ((ds) & 0x07) | (cmd); \
- wbflush(); \
- }
-#define SII_ACK(regs,cs,ds,cmd) \
- { \
- SII_COMMAND(regs,cs,ds,cmd); \
- (regs)->sii_conn_csr = (cs); \
- (regs)->sii_data_csr = (ds); \
- }
-
-/*
- * Deal with bogus pmax dma buffer
- */
-
-static char decent_buffer[NSII*8][256];
-
-/*
- * A script has a three parts: a pre-condition, an action, and
- * an optional command to the chip. The first triggers error
- * handling if not satisfied and in our case it is formed by the
- * values of the sii_conn_csr and sii_data_csr register
- * bits. The action part is just a function pointer, and the
- * command is what the 7061 should be told to do at the end
- * of the action processing. This command is only issued and the
- * script proceeds if the action routine returns TRUE.
- * See sii_intr() for how and where this is all done.
- */
-
-typedef struct script {
- int condition; /* expected state at interrupt */
- int (*action)(); /* extra operations */
- int command; /* command to the chip */
-} *script_t;
-
-#define SCRIPT_MATCH(cs,ds) ((cs)&0x70|SCSI_PHASE((ds)))
-
-#define SII_PHASE_DISC 0x4 /* sort of .. */
-
-/* When no command is needed */
-#define SCRIPT_END -1
-
-/* forward decls of script actions */
-boolean_t
- sii_script_true(), /* when nothing needed */
- sii_identify(), /* send identify msg */
- sii_dosynch(), /* negotiate synch xfer */
- sii_dma_in(), /* get data from target via dma */
- sii_dma_out(), /* send data to target via dma */
- sii_get_status(), /* get status from target */
- sii_end_transaction(), /* all come to an end */
- sii_msg_in(), /* get disconnect message(s) */
- sii_disconnected(); /* current target disconnected */
-/* forward decls of error handlers */
-boolean_t
- sii_err_generic(), /* generic error handler */
- sii_err_disconn(), /* when a target disconnects */
- sii_err_rdp(), /* in reconn, handle rdp mgs */
- gimmeabreak(); /* drop into the debugger */
-
-int sii_reset_scsibus();
-boolean_t sii_probe_target();
-static sii_wait();
-
-/*
- * State descriptor for this layer. There is one such structure
- * per (enabled) SCSI-7061 interface
- */
-struct sii_softc {
- watchdog_t wd;
- sii_padded_regmap_t *regs;
- volatile char *buff;
- script_t script;
- int (*error_handler)();
- int in_count; /* amnt we expect to receive */
- int out_count; /* amnt we are going to ship */
-
- volatile char state;
-#define SII_STATE_BUSY 0x01 /* selecting or currently connected */
-#define SII_STATE_TARGET 0x04 /* currently selected as target */
-#define SII_STATE_COLLISION 0x08 /* lost selection attempt */
-#define SII_STATE_DMA_IN 0x10 /* tgt --> initiator xfer */
-
- unsigned char ntargets; /* how many alive on this scsibus */
- unsigned char done;
- unsigned char cmd_count;
-
- scsi_softc_t *sc;
- target_info_t *active_target;
-
- target_info_t *next_target; /* trying to seize bus */
- queue_head_t waiting_targets;/* other targets competing for bus */
-
-} sii_softc_data[NSII];
-
-typedef struct sii_softc *sii_softc_t;
-
-sii_softc_t sii_softc[NSII];
-
-/*
- * Synch xfer parameters, and timing conversions
- */
-int sii_min_period = 63; /* in 4 ns units */
-int sii_max_offset = 3; /* pure number */
-
-#define sii_to_scsi_period(a) (a)
-#define scsi_period_to_sii(p) (((p) < sii_min_period) ? sii_min_period : (p))
-
-/*
- * Definition of the controller for the auto-configuration program.
- */
-
-int sii_probe(), scsi_slave(), sii_go(), sii_intr();
-extern void scsi_attach();
-
-vm_offset_t sii_std[NSII] = { 0 };
-struct bus_device *sii_dinfo[NSII*8];
-struct bus_ctlr *sii_minfo[NSII];
-struct bus_driver sii_driver =
- { sii_probe, scsi_slave, scsi_attach, sii_go, sii_std, "rz", sii_dinfo,
- "sii", sii_minfo, /*BUS_INTR_B4_PROBE?*/};
-
-/*
- * Scripts
- */
-struct script
-sii_script_data_in[] = {
- { SCSI_PHASE_CMD|SII_CON_CON, sii_script_true,
- (SII_CMD_XFER|SII_CMD_DMA)|SII_CON_CON|SCSI_PHASE_CMD},
- { SCSI_PHASE_DATAI|SII_CON_CON, sii_dma_in,
- (SII_CMD_XFER|SII_CMD_DMA)|SII_CON_CON|SCSI_PHASE_DATAI},
- { SCSI_PHASE_STATUS|SII_CON_CON, sii_get_status,
- SII_CMD_XFER|SII_CON_CON|SCSI_PHASE_STATUS},
- { SCSI_PHASE_MSG_IN|SII_CON_CON, sii_end_transaction, SCRIPT_END}
-},
-
-sii_script_data_out[] = {
- { SCSI_PHASE_CMD|SII_CON_CON, sii_script_true,
- (SII_CMD_XFER|SII_CMD_DMA)|SII_CON_CON|SCSI_PHASE_CMD},
- { SCSI_PHASE_DATAO|SII_CON_CON, sii_dma_out,
- (SII_CMD_XFER|SII_CMD_DMA)|SII_CON_CON|SCSI_PHASE_DATAO},
- { SCSI_PHASE_STATUS|SII_CON_CON, sii_get_status,
- SII_CMD_XFER|SII_CON_CON|SCSI_PHASE_STATUS},
- { SCSI_PHASE_MSG_IN|SII_CON_CON, sii_end_transaction, SCRIPT_END}
-},
-
-sii_script_cmd[] = {
- { SCSI_PHASE_CMD|SII_CON_CON, sii_script_true,
- (SII_CMD_XFER|SII_CMD_DMA)|SII_CON_CON|SCSI_PHASE_CMD},
- { SCSI_PHASE_STATUS|SII_CON_CON, sii_get_status,
- SII_CMD_XFER|SII_CON_CON|SCSI_PHASE_STATUS},
- { SCSI_PHASE_MSG_IN|SII_CON_CON, sii_end_transaction, SCRIPT_END}
-},
-
-/* Same, after a disconnect */
-
-sii_script_restart_data_in[] = {
- { SCSI_PHASE_DATAI|SII_CON_CON|SII_CON_DST, sii_dma_in,
- (SII_CMD_XFER|SII_CMD_DMA)|SII_CON_CON|SII_CON_DST|SCSI_PHASE_DATAI},
- { SCSI_PHASE_STATUS|SII_CON_CON|SII_CON_DST, sii_get_status,
- SII_CMD_XFER|SII_CON_CON|SII_CON_DST|SCSI_PHASE_STATUS},
- { SCSI_PHASE_MSG_IN|SII_CON_CON|SII_CON_DST, sii_end_transaction, SCRIPT_END}
-},
-
-sii_script_restart_data_out[] = {
- { SCSI_PHASE_DATAO|SII_CON_CON|SII_CON_DST, sii_dma_out,
- (SII_CMD_XFER|SII_CMD_DMA)|SII_CON_CON|SII_CON_DST|SCSI_PHASE_DATAO},
- { SCSI_PHASE_STATUS|SII_CON_CON|SII_CON_DST, sii_get_status,
- SII_CMD_XFER|SII_CON_CON|SII_CON_DST|SCSI_PHASE_STATUS},
- { SCSI_PHASE_MSG_IN|SII_CON_CON|SII_CON_DST, sii_end_transaction, SCRIPT_END}
-},
-
-sii_script_restart_cmd[] = {
- { SCSI_PHASE_STATUS|SII_CON_CON|SII_CON_DST, sii_get_status,
- SII_CMD_XFER|SII_CON_CON|SII_CON_DST|SCSI_PHASE_STATUS},
- { SCSI_PHASE_MSG_IN|SII_CON_CON|SII_CON_DST, sii_end_transaction, SCRIPT_END}
-},
-
-/* Synchronous transfer negotiation */
-
-sii_script_try_synch[] = {
- { SCSI_PHASE_MSG_OUT|SII_CON_CON, sii_dosynch, SCRIPT_END}
-},
-
-/* Disconnect sequence */
-
-sii_script_disconnect[] = {
- { SII_PHASE_DISC, sii_disconnected, SCRIPT_END}
-};
-
-
-
-#define u_min(a,b) (((a) < (b)) ? (a) : (b))
-
-
-#define DEBUG
-#ifdef DEBUG
-
-sii_state(regs)
- sii_padded_regmap_t *regs;
-{
- unsigned dmadr;
-
- if (regs == 0)
- regs = (sii_padded_regmap_t*) 0xba000000;
-
- dmadr = regs->sii_dma_adr_low | (regs->sii_dma_adr_hi << 16);
- db_printf("sc %x, dma %x @ x%X, cs %x, ds %x, cmd %x\n",
- (unsigned) regs->sii_sc1,
- (unsigned) regs->sii_dma_len, dmadr,
- (unsigned) regs->sii_conn_csr,
- (unsigned) regs->sii_data_csr,
- (unsigned) regs->sii_cmd);
-
-}
-sii_target_state(tgt)
- target_info_t *tgt;
-{
- if (tgt == 0)
- tgt = sii_softc[0]->active_target;
- if (tgt == 0)
- return 0;
- db_printf("@x%x: fl %X dma %X+%X cmd %x@%X id %X per %X off %X ior %X ret %X\n",
- tgt,
- tgt->flags, tgt->dma_ptr, tgt->transient_state.dma_offset, tgt->cur_cmd,
- tgt->cmd_ptr, tgt->target_id, tgt->sync_period, tgt->sync_offset,
- tgt->ior, tgt->done);
- if (tgt->flags & TGT_DISCONNECTED){
- script_t spt;
-
- spt = tgt->transient_state.script;
- db_printf("disconnected at ");
- db_printsym(spt,1);
- db_printf(": %X %X ", spt->condition, spt->command);
- db_printsym(spt->action,1);
- db_printf(", ");
- db_printsym(tgt->transient_state.handler, 1);
- db_printf("\n");
- }
-
- return 0;
-}
-
-sii_all_targets(unit)
-{
- int i;
- target_info_t *tgt;
- for (i = 0; i < 8; i++) {
- tgt = sii_softc[unit]->sc->target[i];
- if (tgt)
- sii_target_state(tgt);
- }
-}
-
-sii_script_state(unit)
-{
- script_t spt = sii_softc[unit]->script;
-
- if (spt == 0) return 0;
- db_printsym(spt,1);
- db_printf(": %X %X ", spt->condition, spt->command);
- db_printsym(spt->action,1);
- db_printf(", ");
- db_printsym(sii_softc[unit]->error_handler, 1);
- return 0;
-
-}
-
-#define PRINT(x) if (scsi_debug) printf x
-
-#define TRMAX 200
-int tr[TRMAX+3];
-int trpt, trpthi;
-#define TR(x) tr[trpt++] = x
-#define TRWRAP trpthi = trpt; trpt = 0;
-#define TRCHECK if (trpt > TRMAX) {TRWRAP}
-
-#define TRACE
-
-#ifdef TRACE
-
-#define LOGSIZE 256
-int sii_logpt;
-char sii_log[LOGSIZE];
-
-#define MAXLOG_VALUE 0x25
-struct {
- char *name;
- unsigned int count;
-} logtbl[MAXLOG_VALUE];
-
-static LOG(e,f)
- char *f;
-{
- sii_log[sii_logpt++] = (e);
- if (sii_logpt == LOGSIZE) sii_logpt = 0;
- if ((e) < MAXLOG_VALUE) {
- logtbl[(e)].name = (f);
- logtbl[(e)].count++;
- }
-}
-
-sii_print_log(skip)
- int skip;
-{
- register int i, j;
- register unsigned char c;
-
- for (i = 0, j = sii_logpt; i < LOGSIZE; i++) {
- c = sii_log[j];
- if (++j == LOGSIZE) j = 0;
- if (skip-- > 0)
- continue;
- if (c < MAXLOG_VALUE)
- db_printf(" %s", logtbl[c].name);
- else
- db_printf("-x%x", c & 0x7f);
- }
- db_printf("\n");
- return 0;
-}
-
-sii_print_stat()
-{
- register int i;
- register char *p;
- for (i = 0; i < MAXLOG_VALUE; i++) {
- if (p = logtbl[i].name)
- printf("%d %s\n", logtbl[i].count, p);
- }
-}
-
-#else /* TRACE */
-#define LOG(e,f)
-#endif /* TRACE */
-
-struct cnt {
- unsigned int zeroes;
- unsigned int usage;
- unsigned int avg;
- unsigned int min;
- unsigned int max;
-};
-
-static bump(counter, value)
- register struct cnt *counter;
- register unsigned int value;
-{
- register unsigned int n;
-
- if (value == 0) {
- counter->zeroes++;
- return;
- }
- n = counter->usage + 1;
- counter->usage = n;
- if (n == 0) {
- printf("{Counter at x%x overflowed with avg x%x}",
- counter, counter->avg);
- return;
- } else
- if (n == 1)
- counter->min = 0xffffffff;
-
- counter->avg = ((counter->avg * (n - 1)) + value) / n;
- if (counter->min > value)
- counter->min = value;
- if (counter->max < value)
- counter->max = value;
-}
-
-struct cnt
- s_cnt;
-
-#else /* DEBUG */
-#define PRINT(x)
-#define LOG(e,f)
-#define TR(x)
-#define TRCHECK
-#define TRWRAP
-#endif /* DEBUG */
-
-
-/*
- * Probe/Slave/Attach functions
- */
-
-/*
- * Probe routine:
- * Should find out (a) if the controller is
- * present and (b) which/where slaves are present.
- *
- * Implementation:
- * Send an identify msg to each possible target on the bus
- * except of course ourselves.
- */
-sii_probe(reg, ui)
- unsigned reg;
- struct bus_ctlr *ui;
-{
- int unit = ui->unit;
- sii_softc_t sii = &sii_softc_data[unit];
- int target_id, i;
- scsi_softc_t *sc;
- register sii_padded_regmap_t *regs;
- spl_t s;
- boolean_t did_banner = FALSE;
- char *dma_ptr;
- static char *here = "sii_probe";
-
- /*
- * We are only called if the chip is there,
- * but make sure anyways..
- */
- if (check_memory(reg, 0))
- return 0;
-
-#ifdef MACH_KERNEL
- /* Mappable version side */
- SII_probe(reg, ui);
-#endif /*MACH_KERNEL*/
-
- /*
- * Initialize hw descriptor
- */
- sii_softc[unit] = sii;
- sii->regs = (sii_padded_regmap_t *) (reg);
- sii->buff = (volatile char*) (reg + SII_OFFSET_RAM);
-
- queue_init(&sii->waiting_targets);
-
- sc = scsi_master_alloc(unit, sii);
- sii->sc = sc;
-
- sc->go = sii_go;
- sc->watchdog = scsi_watchdog;
- sc->probe = sii_probe_target;
-
- sii->wd.reset = sii_reset_scsibus;
-
-#ifdef MACH_KERNEL
- sc->max_dma_data = -1; /* unlimited */
-#else
- sc->max_dma_data = scsi_per_target_virtual;
-#endif
-
- regs = sii->regs;
-
- /*
- * Clear out dma buffer
- */
- blkclr(sii->buff, SII_RAM_SIZE);
-
- /*
- * Reset chip, fully.
- */
- s = splbio();
- sii_reset(regs, TRUE);
-
- /*
- * Our SCSI id on the bus.
- * The user can set this via the prom on pmaxen/3maxen.
- * If this changes it is easy to fix: make a default that
- * can be changed as boot arg.
- */
-#ifdef unneeded
- regs->sii_id = (scsi_initiator_id[unit] & SII_ID_MASK)|SII_ID_IO;
-#endif
- sc->initiator_id = regs->sii_id & SII_ID_MASK;
- printf("%s%d: my SCSI id is %d", ui->name, unit, sc->initiator_id);
-
- /*
- * For all possible targets, see if there is one and allocate
- * a descriptor for it if it is there.
- */
- for (target_id = 0, dma_ptr = (char*)sii->buff;
- target_id < 8;
- target_id++, dma_ptr += (PER_TGT_DMA_SIZE*2)) {
-
- register unsigned csr, dsr;
- register scsi_status_byte_t status;
-
- /* except of course ourselves */
- if (target_id == sc->initiator_id)
- continue;
-
- regs->sii_sel_csr = target_id;
- wbflush();
-
- /* select */
- regs->sii_cmd = SII_CMD_SEL;
- wbflush();
-
- /* wait for a selection timeout delay, and some more */
- delay(251000);
-
- dsr = regs->sii_data_csr;
- csr = regs->sii_conn_csr;
- if ((csr & SII_CON_CON) == 0) {
-
- regs->sii_conn_csr = csr;/*wtc bits*/
-
- /* abort sel in progress */
- if (csr & SII_CON_SIP) {
- regs->sii_cmd = SII_CMD_DIS;
- wbflush();
- csr = sii_wait(&regs->sii_conn_csr, SII_CON_SCH,1);
- regs->sii_conn_csr = 0xffff;/*wtc bits */
- regs->sii_data_csr = 0xffff;
- regs->sii_cmd = 0;
- wbflush();
- }
- continue;
- }
-
- printf(",%s%d", did_banner++ ? " " : " target(s) at ",
- target_id);
-
- /* should be command phase here */
- if (SCSI_PHASE(dsr) != SCSI_PHASE_CMD)
- panic(here);
-
- /* acknowledge state change */
- SII_ACK(regs,csr,dsr,0);
-
- /* build command in (bogus) dma area */
- {
- unsigned int *p = (unsigned int*) dma_ptr;
-
- p[0] = SCSI_CMD_TEST_UNIT_READY | (0 << 8);
- p[1] = 0 | (0 << 8);
- p[2] = 0 | (0 << 8);
- }
-
- /* set up dma xfer parameters */
- regs->sii_dma_len = 6;
- regs->sii_dma_adr_low = SII_DMADR_LO(dma_ptr);
- regs->sii_dma_adr_hi = SII_DMADR_HI(dma_ptr);
- wbflush();
-
- /* issue dma command */
- SII_COMMAND(regs,csr,dsr,SII_CMD_XFER|SII_CMD_DMA);
-
- /* wait till done */
- dsr = sii_wait(&regs->sii_data_csr, SII_DTR_DONE,1);
- regs->sii_cmd &= ~(SII_CMD_XFER|SII_CMD_DMA);
- regs->sii_data_csr = SII_DTR_DONE;/* clear */
- regs->sii_dma_len = 0;
-
- /* move on to status phase */
- dsr = sii_wait(&regs->sii_data_csr, SCSI_PHASE_STATUS,1);
- csr = regs->sii_conn_csr;
- SII_ACK(regs,csr,dsr,0);
-
- if (SCSI_PHASE(dsr) != SCSI_PHASE_STATUS)
- panic(here);
-
- /* get status byte */
- dsr = sii_wait(&regs->sii_data_csr, SII_DTR_IBF,1);
- csr = regs->sii_conn_csr;
-
- status.bits = regs->sii_data;
- if (status.st.scsi_status_code != SCSI_ST_GOOD)
- scsi_error( 0, SCSI_ERR_STATUS, status.bits, 0);
-
- /* get cmd_complete message */
- SII_ACK(regs,csr,dsr,0);
- SII_COMMAND(regs,csr,dsr,SII_CMD_XFER);
- dsr = sii_wait(&regs->sii_data_csr, SII_DTR_DONE,1);
-
- dsr = sii_wait(&regs->sii_data_csr, SCSI_PHASE_MSG_IN,1);
- csr = regs->sii_conn_csr;
-
-
- SII_ACK(regs,csr,dsr,0);
- i = regs->sii_data;
- SII_COMMAND(regs,csr,dsr,SII_CMD_XFER);
-
- /* check disconnected, clear all intr bits */
- csr = sii_wait(&regs->sii_conn_csr, SII_CON_SCH,1);
- if (regs->sii_conn_csr & SII_CON_CON)
- panic(here);
-
- regs->sii_data_csr = 0xffff;
- regs->sii_conn_csr = 0xffff;
- regs->sii_cmd = 0;
-
- /*
- * Found a target
- */
- sii->ntargets++;
- {
- register target_info_t *tgt;
- tgt = scsi_slave_alloc(sc->masterno, target_id, sii);
-
- tgt->dma_ptr = dma_ptr;
- tgt->cmd_ptr = decent_buffer[unit*8 + target_id];
-#ifdef MACH_KERNEL
-#else /*MACH_KERNEL*/
- fdma_init(&tgt->fdma, scsi_per_target_virtual);
-#endif /*MACH_KERNEL*/
- }
- }
- printf(".\n");
-
- splx(s);
- return 1;
-}
-
-boolean_t
-sii_probe_target(tgt, ior)
- target_info_t *tgt;
- io_req_t ior;
-{
- sii_softc_t sii = sii_softc[tgt->masterno];
- boolean_t newlywed;
- int sii_probe_timeout();
-
- newlywed = (tgt->cmd_ptr == 0);
- if (newlywed) {
- /* desc was allocated afresh */
- char *dma_ptr = (char*)sii->buff;
-
- dma_ptr += (PER_TGT_DMA_SIZE * tgt->target_id)*2;
- tgt->dma_ptr = dma_ptr;
- tgt->cmd_ptr = decent_buffer[tgt->masterno*8 + tgt->target_id];
-#ifdef MACH_KERNEL
-#else /*MACH_KERNEL*/
- fdma_init(&tgt->fdma, scsi_per_target_virtual);
-#endif /*MACH_KERNEL*/
-
- }
-
- /* Unfortunately, the SII chip does not have timeout support
- for selection */
- timeout(sii_probe_timeout, tgt, hz);
-
- if (scsi_inquiry(tgt, SCSI_INQ_STD_DATA) == SCSI_RET_DEVICE_DOWN)
- return FALSE;
-
- untimeout(sii_probe_timeout, tgt);
- tgt->flags = TGT_ALIVE;
- return TRUE;
-}
-
-sii_probe_timeout(tgt)
- target_info_t *tgt;
-{
- sii_softc_t sii = (sii_softc_t)tgt->hw_state;
- register sii_padded_regmap_t *regs = sii->regs;
- int cs, ds;
- spl_t s;
-
- /* cancelled ? */
- if (tgt->done != SCSI_RET_IN_PROGRESS)
- return;
-
- s = splbio();
-
- /* Someone else might be using the bus (rare) */
- switch (regs->sii_conn_csr & (SII_CON_LST|SII_CON_SIP)) {
- case SII_CON_SIP:
- /* We really timed out */
- break;
- case SII_CON_SIP|SII_CON_LST:
- /* Someone else is (still) using the bus */
- sii->wd.watchdog_state = SCSI_WD_ACTIVE;
- /* fall-through */
- default:
- /* Did not get a chance to the bus yet */
- timeout(sii_probe_timeout, tgt, hz);
- goto ret;
- }
- regs->sii_cmd = SII_CMD_DIS;
- wbflush();
- regs->sii_csr |= SII_CSR_RSE;
- regs->sii_cmd = 0;
- wbflush();
-
- sii->done = SCSI_RET_DEVICE_DOWN;
- cs = regs->sii_conn_csr;
- ds = regs->sii_data_csr;
- if (!sii_end(sii, cs, ds))
- (void) sii_reconnect(sii, cs, ds);
-ret:
- splx(s);
-}
-
-
-static sii_wait(preg, until, complain)
- volatile unsigned short *preg;
-{
- int timeo = 1000000;
- while ((*preg & until) != until) {
- delay(1);
- if (!timeo--) {
- if (complain) {
- gimmeabreak();
- printf("sii_wait TIMEO with x%x\n", *preg);
- }
- break;
- }
- }
-#ifdef DEBUG
- bump(&s_cnt, 1000000-timeo);
-#endif
- return *preg;
-}
-
-sii_reset(regs, quickly)
- register sii_padded_regmap_t *regs;
- boolean_t quickly;
-{
- int my_id;
-
- my_id = regs->sii_id & SII_ID_MASK;
-
- regs->sii_cmd = SII_CMD_RESET;
- wbflush();
- delay(30);
-
- /* clear them all random bitsy */
- regs->sii_conn_csr = SII_CON_SWA|SII_CON_SCH|SII_CON_BERR|SII_CON_RST;
- regs->sii_data_csr = SII_DTR_ATN|SII_DTR_DONE;
-
- regs->sii_id = my_id | SII_ID_IO;
-
- regs->sii_dma_ctrl = 0; /* asynch */
-
- regs->sii_dma_len = 0;
- regs->sii_dma_adr_low = 0;
- regs->sii_dma_adr_hi = 0;
-
- regs->sii_csr = SII_CSR_IE|SII_CSR_PCE|SII_CSR_SLE|SII_CSR_HPM;
- /* later: SII_CSR_RSE */
-
- regs->sii_diag_csr = SII_DIAG_PORT_ENB;
- wbflush();
-
- if (quickly)
- return;
-
- /*
- * reset the scsi bus, the interrupt routine does the rest
- * or you can call sii_bus_reset().
- */
- regs->sii_cmd = SII_CMD_RST;
-
-}
-
-/*
- * Operational functions
- */
-
-/*
- * Start a SCSI command on a target
- */
-sii_go(tgt, cmd_count, in_count, cmd_only)
- target_info_t *tgt;
- boolean_t cmd_only;
-{
- sii_softc_t sii;
- register spl_t s;
- boolean_t disconn;
- script_t scp;
- boolean_t (*handler)();
-
- LOG(1,"go");
-
- sii = (sii_softc_t)tgt->hw_state;
-
- /*
- * We cannot do real DMA.
- */
-#ifdef MACH_KERNEL
-#else /*MACH_KERNEL*/
- if (tgt->ior)
- fdma_map(&tgt->fdma, tgt->ior);
-#endif /*MACH_KERNEL*/
-
- copyout_gap16(tgt->cmd_ptr, tgt->dma_ptr, cmd_count);
-
- if ((tgt->cur_cmd == SCSI_CMD_WRITE) ||
- (tgt->cur_cmd == SCSI_CMD_LONG_WRITE)){
- io_req_t ior = tgt->ior;
- register int len = ior->io_count;
-
- tgt->transient_state.out_count = len;
-
- if (len > PER_TGT_BUFF_SIZE)
- len = PER_TGT_BUFF_SIZE;
- copyout_gap16( ior->io_data,
- tgt->dma_ptr + (cmd_count<<1),
- len);
- tgt->transient_state.copy_count = len;
-
- /* avoid leaks */
- if (len < tgt->block_size) {
- bzero_gap16(tgt->dma_ptr + ((cmd_count + len)<<1),
- len - tgt->block_size);
- len = tgt->block_size;
- tgt->transient_state.copy_count = len;
- }
-
- } else {
- tgt->transient_state.out_count = 0;
- tgt->transient_state.copy_count = 0;
- }
-
- tgt->transient_state.cmd_count = cmd_count;
- tgt->transient_state.isa_oddbb = FALSE;
-
- disconn = BGET(scsi_might_disconnect,tgt->masterno,tgt->target_id);
- disconn = disconn && (sii->ntargets > 1);
- disconn |= BGET(scsi_should_disconnect,tgt->masterno,tgt->target_id);
-
- /*
- * Setup target state
- */
- tgt->done = SCSI_RET_IN_PROGRESS;
-
- handler = (disconn) ? sii_err_disconn : sii_err_generic;
-
- switch (tgt->cur_cmd) {
- case SCSI_CMD_READ:
- case SCSI_CMD_LONG_READ:
- LOG(0x13,"readop");
- scp = sii_script_data_in;
- break;
- case SCSI_CMD_WRITE:
- case SCSI_CMD_LONG_WRITE:
- LOG(0x14,"writeop");
- scp = sii_script_data_out;
- break;
- case SCSI_CMD_INQUIRY:
- /* This is likely the first thing out:
- do the synch neg if so */
- if (!cmd_only && ((tgt->flags&TGT_DID_SYNCH)==0)) {
- scp = sii_script_try_synch;
- tgt->flags |= TGT_TRY_SYNCH;
- break;
- }
- case SCSI_CMD_REQUEST_SENSE:
- case SCSI_CMD_MODE_SENSE:
- case SCSI_CMD_RECEIVE_DIAG_RESULTS:
- case SCSI_CMD_READ_CAPACITY:
- case SCSI_CMD_READ_BLOCK_LIMITS:
- case SCSI_CMD_READ_TOC:
- case SCSI_CMD_READ_SUBCH:
- case SCSI_CMD_READ_HEADER:
- case 0xc4: /* despised: SCSI_CMD_DEC_PLAYBACK_STATUS */
- case 0xdd: /* despised: SCSI_CMD_NEC_READ_SUBCH_Q */
- case 0xde: /* despised: SCSI_CMD_NEC_READ_TOC */
- scp = sii_script_data_in;
- LOG(0x1c,"cmdop");
- LOG(0x80+tgt->cur_cmd,0);
- break;
- case SCSI_CMD_MODE_SELECT:
- case SCSI_CMD_REASSIGN_BLOCKS:
- case SCSI_CMD_FORMAT_UNIT:
- case 0xc9: /* vendor-spec: SCSI_CMD_DEC_PLAYBACK_CONTROL */
- tgt->transient_state.cmd_count = sizeof_scsi_command(tgt->cur_cmd);
- tgt->transient_state.out_count =
- cmd_count - tgt->transient_state.cmd_count;
- scp = sii_script_data_out;
- LOG(0x1c,"cmdop");
- LOG(0x80+tgt->cur_cmd,0);
- break;
- case SCSI_CMD_TEST_UNIT_READY:
- /*
- * Do the synch negotiation here, unless done already
- */
- if (tgt->flags & TGT_DID_SYNCH) {
- scp = sii_script_cmd;
- } else {
- scp = sii_script_try_synch;
- tgt->flags |= TGT_TRY_SYNCH;
- }
- LOG(0x1c,"cmdop");
- LOG(0x80+tgt->cur_cmd,0);
- break;
- default:
- LOG(0x1c,"cmdop");
- LOG(0x80+tgt->cur_cmd,0);
- scp = sii_script_cmd;
- }
-
- tgt->transient_state.script = scp;
- tgt->transient_state.handler = handler;
- tgt->transient_state.identify = (cmd_only) ? 0xff :
- (disconn ? SCSI_IDENTIFY|SCSI_IFY_ENABLE_DISCONNECT :
- SCSI_IDENTIFY);
-
- if (in_count)
- tgt->transient_state.in_count =
- (in_count < tgt->block_size) ? tgt->block_size : in_count;
- else
- tgt->transient_state.in_count = 0;
-
- tgt->transient_state.dma_offset = 0;
-
- /*
- * See if another target is currently selected on
- * this SCSI bus, e.g. lock the sii structure.
- * Note that it is the strategy routine's job
- * to serialize ops on the same target as appropriate.
- * XXX here and everywhere, locks!
- */
- /*
- * Protection viz reconnections makes it tricky.
- */
-/* s = splbio();*/
- s = splhigh();
-
- if (sii->wd.nactive++ == 0)
- sii->wd.watchdog_state = SCSI_WD_ACTIVE;
-
- if (sii->state & SII_STATE_BUSY) {
- /*
- * Queue up this target, note that this takes care
- * of proper FIFO scheduling of the scsi-bus.
- */
- LOG(3,"enqueue");
- LOG(0x80+tgt->target_id,0);
- enqueue_tail(&sii->waiting_targets, (queue_entry_t) tgt);
- } else {
- /*
- * It is down to at most two contenders now,
- * we will treat reconnections same as selections
- * and let the scsi-bus arbitration process decide.
- */
- sii->state |= SII_STATE_BUSY;
- sii->next_target = tgt;
- sii_attempt_selection(sii);
- /*
- * Note that we might still lose arbitration..
- */
- }
- splx(s);
-}
-
-sii_attempt_selection(sii)
- sii_softc_t sii;
-{
- target_info_t *tgt;
- register int out_count;
- sii_padded_regmap_t *regs;
- register int cmd;
-
- regs = sii->regs;
- tgt = sii->next_target;
-
- LOG(4,"select");
- LOG(0x80+tgt->target_id,0);
-
- /*
- * Init bus state variables and set registers.
- * [They are intermixed to avoid wbflush()es]
- */
- sii->active_target = tgt;
-
- out_count = tgt->transient_state.cmd_count;
-
- /* set dma pointer and counter */
- regs->sii_dma_len = out_count;
- regs->sii_dma_adr_low = SII_DMADR_LO(tgt->dma_ptr);
- regs->sii_dma_adr_hi = SII_DMADR_HI(tgt->dma_ptr);
-
- sii->error_handler = tgt->transient_state.handler;
-
- regs->sii_sel_csr = tgt->target_id;
-
- sii->done = SCSI_RET_IN_PROGRESS;
-
- regs->sii_dma_ctrl = tgt->sync_offset;
-
- sii->cmd_count = out_count;
-
-/* if (regs->sii_conn_csr & (SII_CON_CON|SII_CON_DST))*/
- if (regs->sii_sc1 & (SII_CS1_BSY|SII_CS1_SEL))
- return;
- regs->sii_csr = SII_CSR_IE|SII_CSR_PCE|SII_CSR_SLE|SII_CSR_HPM;
-
- sii->script = tgt->transient_state.script;
- sii->in_count = 0;
- sii->out_count = 0;
-
- if (tgt->flags & TGT_DID_SYNCH) {
- if (tgt->transient_state.identify == 0xff)
- cmd = SII_CMD_SEL;
- else {
- cmd = SII_CMD_SEL | SII_CMD_ATN |
- SII_CMD_CON | SII_CMD_XFER | SCSI_PHASE_MSG_OUT;
- /* chain select and message out */
-/*??*/ regs->sii_dma_1st_byte = tgt->transient_state.identify;
- }
- } else if (tgt->flags & TGT_TRY_SYNCH)
- cmd = SII_CMD_SEL | SII_CMD_ATN;
- else
- cmd = SII_CMD_SEL;
-
-/* if (regs->sii_conn_csr & (SII_CON_CON|SII_CON_DST)) { */
- if (regs->sii_sc1 & (SII_CS1_BSY|SII_CS1_SEL)) {
- /* let the reconnection attempt proceed */
- regs->sii_csr = SII_CSR_IE|SII_CSR_PCE|SII_CSR_SLE|
- SII_CSR_HPM|SII_CSR_RSE;
- sii->script = 0;
- LOG(0x8c,0);
- } else {
- regs->sii_cmd = cmd;
- wbflush();
- }
-}
-
-/*
- * Interrupt routine
- * Take interrupts from the chip
- *
- * Implementation:
- * Move along the current command's script if
- * all is well, invoke error handler if not.
- */
-boolean_t sii_inside_sii_intr = FALSE;
-
-sii_intr(unit,spllevel)
-{
- register sii_softc_t sii;
- register script_t scp;
- register int cs, ds;
- register sii_padded_regmap_t *regs;
- boolean_t try_match;
-#ifdef MACH_KERNEL
- extern boolean_t rz_use_mapped_interface;
-
- if (rz_use_mapped_interface)
- return SII_intr(unit,spllevel);
-#endif /*MACH_KERNEL*/
-
- /* interrupt code is NOT reentrant */
- if (sii_inside_sii_intr) {
- LOG(0x22,"!!attempted to reenter sii_intr!!");
- return;
- }
- sii_inside_sii_intr = TRUE;
-
- LOG(5,"\n\tintr");
-
- sii = sii_softc[unit];
-
- /* collect status information */
- regs = sii->regs;
- cs = regs->sii_conn_csr;
- ds = regs->sii_data_csr;
-
-TR(cs);
-TR(ds);
-TR(regs->sii_cmd);
-TRCHECK;
-
- if (cs & SII_CON_RST){
- sii_bus_reset(sii);
- goto getout;
- }
-
- /* we got an interrupt allright */
- if (sii->active_target)
- sii->wd.watchdog_state = SCSI_WD_ACTIVE;
-
- /* rid of DONEs */
- if (ds & SII_DTR_DONE) {
- regs->sii_data_csr = SII_DTR_DONE;
- LOG(0x1e,"done");
- ds = regs->sii_data_csr;
- cs = regs->sii_conn_csr;
- }
-
- /* drop spurious calls, note that sometimes
- * ds and cs get out-of-sync */
- if (((cs & SII_CON_CI) | (ds & SII_DTR_DI)) == 0) {
- LOG(2,"SPURIOUS");
- goto getout;
- }
-
- /* clear interrupt flags */
-
- regs->sii_conn_csr = cs;
- regs->sii_data_csr = cs;
-
- /* drop priority */
- splx(spllevel);
-
- if ((sii->state & SII_STATE_TARGET) ||
- (cs & SII_CON_TGT)) {
- sii_target_intr(sii,cs,ds);
- goto getout;
- }
-
- scp = sii->script;
-
- /* check who got the bus */
- if ((scp == 0) || (cs & SII_CON_LST)) {
- if (cs & SII_CON_DST) {
- sii_reconnect(sii, cs, ds);
- goto getout;
- }
- LOG(0x12,"no-script");
- goto getout;
- }
-
- if (SCRIPT_MATCH(cs,ds) != scp->condition) {
- if (try_match = (*sii->error_handler)(sii, cs, ds)) {
- cs = regs->sii_conn_csr;
- ds = regs->sii_data_csr;
- }
- } else
- try_match = TRUE;
-
- /* might have been side effected */
- scp = sii->script;
-
- if (try_match && (SCRIPT_MATCH(cs,ds) == scp->condition)) {
- /*
- * Perform the appropriate operation,
- * then proceed
- */
- if ((*scp->action)(sii, cs, ds)) {
- /* might have been side effected */
- scp = sii->script;
- sii->script = scp + 1;
- regs->sii_cmd = scp->command;
- wbflush();
- }
- }
-getout:
- sii_inside_sii_intr = FALSE;
-}
-
-
-sii_target_intr(sii)
- register sii_softc_t sii;
-{
- panic("SII: TARGET MODE !!!\n");
-}
-
-/*
- * All the many little things that the interrupt
- * routine might switch to
- */
-boolean_t
-sii_script_true(sii, cs, ds)
- register sii_softc_t sii;
-
-{
- SII_COMMAND(sii->regs,cs,ds,SII_CON_CON/*sanity*/);
- LOG(7,"nop");
- return TRUE;
-}
-
-boolean_t
-sii_end_transaction( sii, cs, ds)
- register sii_softc_t sii;
-{
- register sii_padded_regmap_t *regs = sii->regs;
-
- SII_COMMAND(sii->regs,cs,ds,0);
-
- LOG(0x1f,"end_t");
-
- regs->sii_csr &= ~SII_CSR_RSE;
-
- /* is the fifo really clean here ? */
- ds = sii_wait(&regs->sii_data_csr, SII_DTR_IBF,1);
-
- if (regs->sii_data != SCSI_COMMAND_COMPLETE)
- printf("{T%x}", regs->sii_data);
-
- regs->sii_cmd = SII_CMD_XFER | SII_CON_CON | SCSI_PHASE_MSG_IN |
- (cs & SII_CON_DST);
- wbflush();
-
- ds = sii_wait(&regs->sii_data_csr, SII_DTR_DONE,1);
- regs->sii_data_csr = SII_DTR_DONE;
-
- regs->sii_cmd = 0/*SII_PHASE_DISC*/;
- wbflush();
-
- cs = regs->sii_conn_csr;
-
- if ((cs & SII_CON_SCH) == 0)
- cs = sii_wait(&regs->sii_conn_csr, SII_CON_SCH,1);
- regs->sii_conn_csr = SII_CON_SCH;
-
- regs->sii_csr |= SII_CSR_RSE;
-
- cs = regs->sii_conn_csr;
-
- if (!sii_end(sii, cs, ds))
- (void) sii_reconnect(sii, cs, ds);
- return FALSE;
-}
-
-boolean_t
-sii_end( sii, cs, ds)
- register sii_softc_t sii;
-{
- register target_info_t *tgt;
- register io_req_t ior;
- register sii_padded_regmap_t *regs = sii->regs;
-
- LOG(6,"end");
-
- tgt = sii->active_target;
-
- if ((tgt->done = sii->done) == SCSI_RET_IN_PROGRESS)
- tgt->done = SCSI_RET_SUCCESS;
-
- sii->script = 0;
-
- if (sii->wd.nactive-- == 1)
- sii->wd.watchdog_state = SCSI_WD_INACTIVE;
-
- /* check reconnection not pending */
- cs = regs->sii_conn_csr;
- if ((cs & SII_CON_DST) == 0)
- sii_release_bus(sii);
- else {
- sii->active_target = 0;
-/* sii->state &= ~SII_STATE_BUSY; later */
- }
-
- if (ior = tgt->ior) {
- LOG(0xA,"ops->restart");
-#ifdef MACH_KERNEL
-#else /*MACH_KERNEL*/
- fdma_unmap(&tgt->fdma, ior);
-#endif /*MACH_KERNEL*/
- (*tgt->dev_ops->restart)(tgt, TRUE);
- if (cs & SII_CON_DST)
- sii->state &= ~SII_STATE_BUSY;
- }
-
- return ((cs & SII_CON_DST) == 0);
-}
-
-boolean_t
-sii_release_bus(sii)
- register sii_softc_t sii;
-{
- boolean_t ret = FALSE;
-
- LOG(9,"release");
-
- sii->script = 0;
-
- if (sii->state & SII_STATE_COLLISION) {
-
- LOG(0xB,"collided");
- sii->state &= ~SII_STATE_COLLISION;
- sii_attempt_selection(sii);
-
- } else if (queue_empty(&sii->waiting_targets)) {
-
- sii->state &= ~SII_STATE_BUSY;
- sii->active_target = 0;
- ret = TRUE;
-
- } else {
-
- LOG(0xC,"dequeue");
- sii->next_target = (target_info_t *)
- dequeue_head(&sii->waiting_targets);
- sii_attempt_selection(sii);
- }
- return ret;
-}
-
-boolean_t
-sii_get_status( sii, cs, ds)
- register sii_softc_t sii;
-{
- register sii_padded_regmap_t *regs = sii->regs;
- register scsi2_status_byte_t status;
- register target_info_t *tgt;
- unsigned int len;
- unsigned short cmd;
-
- LOG(0xD,"get_status");
-TRWRAP;
-
- sii->state &= ~SII_STATE_DMA_IN;
-
- tgt = sii->active_target;
- sii->error_handler = tgt->transient_state.handler;
-
- if (len = sii->in_count) {
- if ((tgt->cur_cmd != SCSI_CMD_READ) &&
- (tgt->cur_cmd != SCSI_CMD_LONG_READ)){
- len -= regs->sii_dma_len;
- copyin_gap16(tgt->dma_ptr, tgt->cmd_ptr, len);
- if (len & 0x1) /* odd byte, left in silo */
- tgt->cmd_ptr[len - 1] = regs->sii_data;
- } else {
- if (regs->sii_dma_len) {
-#if 0
- this is incorrect and besides..
- tgt->ior->io_residual = regs->sii_dma_len;
-#endif
- len -= regs->sii_dma_len;
- }
- careful_copyin_gap16( tgt, tgt->transient_state.dma_offset,
- len, ds & SII_DTR_OBB,
- regs->sii_dma_1st_byte);
- }
- sii->in_count = 0;
- }
-
- len = regs->sii_dma_len;
- regs->sii_dma_len = 0;/*later?*/
-
- /* if dma is still in progress we have to quiet it down */
- cmd = regs->sii_cmd;
- if (cmd & SII_CMD_DMA) {
- regs->sii_cmd = cmd & ~(SII_CMD_DMA|SII_CMD_XFER);
- wbflush();
- /* DONE might NOT pop up. Sigh. */
- delay(10);
- regs->sii_data_csr = regs->sii_data_csr;
- }
-
- regs->sii_cmd = SCSI_PHASE_STATUS|SII_CON_CON|(cs & SII_CON_DST);
- wbflush();
-
- ds = sii_wait(&regs->sii_data_csr, SII_DTR_IBF,1);
- status.bits = regs->sii_data;
-
- if (status.st.scsi_status_code != SCSI_ST_GOOD) {
- scsi_error(sii->active_target, SCSI_ERR_STATUS, status.bits, 0);
- sii->done = (status.st.scsi_status_code == SCSI_ST_BUSY) ?
- SCSI_RET_RETRY : SCSI_RET_NEED_SENSE;
- } else
- sii->done = SCSI_RET_SUCCESS;
-
- return TRUE;
-}
-
-boolean_t
-sii_dma_in( sii, cs, ds)
- register sii_softc_t sii;
-{
- register target_info_t *tgt;
- register sii_padded_regmap_t *regs = sii->regs;
- char *dma_ptr;
- register int count;
- boolean_t advance_script = TRUE;
-
- SII_COMMAND(regs,cs,ds,0);
- LOG(0xE,"dma_in");
-
- tgt = sii->active_target;
- sii->error_handler = tgt->transient_state.handler;
- sii->state |= SII_STATE_DMA_IN;
-
- if (sii->in_count == 0) {
- /*
- * Got nothing yet: either just sent the command
- * or just reconnected
- */
- register int avail;
-
- if (tgt->transient_state.isa_oddbb) {
- regs->sii_dma_1st_byte = tgt->transient_state.oddbb;
- tgt->transient_state.isa_oddbb = FALSE;
- }
-
- count = tgt->transient_state.in_count;
- count = u_min(count, (SII_DMA_COUNT_MASK+1));
- avail = PER_TGT_BUFF_SIZE - tgt->transient_state.dma_offset;
- count = u_min(count, avail);
-
- /* common case of 8k-or-less read ? */
- advance_script = (tgt->transient_state.in_count == count);
-
- } else {
-
- /*
- * We received some data.
- * Also, take care of bogus interrupts
- */
- register int offset, xferred;
- unsigned char obb = regs->sii_data;
-
- xferred = sii->in_count - regs->sii_dma_len;
- assert(xferred > 0);
- tgt->transient_state.in_count -= xferred;
- assert(tgt->transient_state.in_count > 0);
- offset = tgt->transient_state.dma_offset;
- tgt->transient_state.dma_offset += xferred;
- count = u_min(tgt->transient_state.in_count, (SII_DMA_COUNT_MASK+1));
- if (tgt->transient_state.dma_offset == PER_TGT_BUFF_SIZE) {
- tgt->transient_state.dma_offset = 0;
- } else {
- register int avail;
- avail = PER_TGT_BUFF_SIZE - tgt->transient_state.dma_offset;
- count = u_min(count, avail);
- }
-
- /* get some more */
- dma_ptr = tgt->dma_ptr + (tgt->transient_state.dma_offset << 1);
- sii->in_count = count;
- regs->sii_dma_len = count;
- regs->sii_dma_adr_low = SII_DMADR_LO(dma_ptr);
- regs->sii_dma_adr_hi = SII_DMADR_HI(dma_ptr);
- wbflush();
- regs->sii_cmd = sii->script->command;
- wbflush();
-
- /* copy what we got */
- careful_copyin_gap16( tgt, offset, xferred, ds & SII_DTR_OBB, obb);
-
- /* last chunk ? */
- if (count == tgt->transient_state.in_count) {
- sii->script++;
- }
- return FALSE;
- }
-quickie:
- sii->in_count = count;
- dma_ptr = tgt->dma_ptr + (tgt->transient_state.dma_offset << 1);
- regs->sii_dma_len = count;
- regs->sii_dma_adr_low = SII_DMADR_LO(dma_ptr);
- regs->sii_dma_adr_hi = SII_DMADR_HI(dma_ptr);
- wbflush();
-
- if (!advance_script) {
- regs->sii_cmd = sii->script->command;
- wbflush();
- }
- return advance_script;
-}
-
-/* send data to target. Called in three different ways:
- (a) to start transfer (b) to restart a bigger-than-8k
- transfer (c) after reconnection
- */
-boolean_t
-sii_dma_out( sii, cs, ds)
- register sii_softc_t sii;
-{
- register sii_padded_regmap_t *regs = sii->regs;
- register char *dma_ptr;
- register target_info_t *tgt;
- boolean_t advance_script = TRUE;
- int count = sii->out_count;
-
- SII_COMMAND(regs,cs,ds,0);
- LOG(0xF,"dma_out");
-
- tgt = sii->active_target;
- sii->error_handler = tgt->transient_state.handler;
- sii->state &= ~SII_STATE_DMA_IN;
-
- if (sii->out_count == 0) {
- /*
- * Nothing committed: either just sent the
- * command or reconnected
- */
- register int remains;
-
- count = tgt->transient_state.out_count;
- count = u_min(count, (SII_DMA_COUNT_MASK+1));
- remains = PER_TGT_BUFF_SIZE - tgt->transient_state.dma_offset;
- count = u_min(count, remains);
-
- /* common case of 8k-or-less write ? */
- advance_script = (tgt->transient_state.out_count == count);
- } else {
- /*
- * We sent some data.
- * Also, take care of bogus interrupts
- */
- register int offset, xferred;
-
- xferred = sii->out_count - regs->sii_dma_len;
- assert(xferred > 0);
- tgt->transient_state.out_count -= xferred;
- assert(tgt->transient_state.out_count > 0);
- offset = tgt->transient_state.dma_offset;
- tgt->transient_state.dma_offset += xferred;
- count = u_min(tgt->transient_state.out_count, (SII_DMA_COUNT_MASK+1));
- if (tgt->transient_state.dma_offset == PER_TGT_BUFF_SIZE) {
- tgt->transient_state.dma_offset = 0;
- } else {
- register int remains;
- remains = PER_TGT_BUFF_SIZE - tgt->transient_state.dma_offset;
- count = u_min(count, remains);
- }
- /* last chunk ? */
- if (tgt->transient_state.out_count == count)
- goto quickie;
-
- /* ship some more */
- dma_ptr = tgt->dma_ptr +
- ((tgt->transient_state.cmd_count + tgt->transient_state.dma_offset) << 1);
- sii->out_count = count;
- regs->sii_dma_len = count;
- regs->sii_dma_adr_low = SII_DMADR_LO(dma_ptr);
- regs->sii_dma_adr_hi = SII_DMADR_HI(dma_ptr);
- wbflush();
- regs->sii_cmd = sii->script->command;
-
- /* copy some more data */
- careful_copyout_gap16(tgt, offset, xferred);
- return FALSE;
- }
-
-quickie:
- sii->out_count = count;
- dma_ptr = tgt->dma_ptr +
- ((tgt->transient_state.cmd_count + tgt->transient_state.dma_offset) << 1);
- regs->sii_dma_len = count;
- regs->sii_dma_adr_low = SII_DMADR_LO(dma_ptr);
- regs->sii_dma_adr_hi = SII_DMADR_HI(dma_ptr);
- wbflush();
-
- if (!advance_script) {
- regs->sii_cmd = sii->script->command;
- wbflush();
- }
- return advance_script;
-}
-
-/* disconnect-reconnect ops */
-
-/* get the message in via dma */
-boolean_t
-sii_msg_in(sii, cs, ds)
- register sii_softc_t sii;
- register unsigned char cs, ds;
-{
- register target_info_t *tgt;
- char *dma_ptr;
- register sii_padded_regmap_t *regs = sii->regs;
-
- LOG(0x15,"msg_in");
-
- tgt = sii->active_target;
-
- dma_ptr = tgt->dma_ptr;
- /* We would clobber the data for READs */
- if (sii->state & SII_STATE_DMA_IN) {
- register int offset;
- offset = tgt->transient_state.cmd_count + tgt->transient_state.dma_offset;
- if (offset & 1) offset++;
- dma_ptr += (offset << 1);
- }
-
- regs->sii_dma_adr_low = SII_DMADR_LO(dma_ptr);
- regs->sii_dma_adr_hi = SII_DMADR_HI(dma_ptr);
- /* We only really expect two bytes */
- regs->sii_dma_len = sizeof(scsi_command_group_0);
- wbflush();
-
- return TRUE;
-}
-
-/* check the message is indeed a DISCONNECT */
-boolean_t
-sii_disconnect(sii, cs, ds)
- register sii_softc_t sii;
- register unsigned char cs, ds;
-
-{
- register target_info_t *tgt;
- register int len;
- boolean_t ok = FALSE;
- unsigned int dmsg = 0;
-
- tgt = sii->active_target;
-
- len = sizeof(scsi_command_group_0) - sii->regs->sii_dma_len;
- PRINT(("{G%d}",len));
-
-/* if (len == 0) ok = FALSE; */
- if (len == 1) {
- dmsg = sii->regs->sii_dma_1st_byte;
- ok = (dmsg == SCSI_DISCONNECT);
- } else if (len == 2) {
- register char *msgs;
- register unsigned int offset;
- register sii_padded_regmap_t *regs = sii->regs;
-
- /* wherever it was, take it from there */
- offset = regs->sii_dma_adr_low | ((regs->sii_dma_adr_hi&3)<<16);
- msgs = (char*)sii->buff + (offset << 1);
- dmsg = *((unsigned short *)msgs);
-
- /* A SDP message preceeds it in non-completed READs */
- ok = (((dmsg & 0xff) == SCSI_DISCONNECT) ||
- (dmsg == ((SCSI_DISCONNECT<<8)|SCSI_SAVE_DATA_POINTER)));
- }
- if (!ok)
- printf("[tgt %d bad msg (%d): %x]", tgt->target_id, len, dmsg);
-
- return TRUE;
-}
-
-/* save all relevant data, free the BUS */
-boolean_t
-sii_disconnected(sii, cs, ds)
- register sii_softc_t sii;
- register unsigned char cs, ds;
-
-{
- register target_info_t *tgt;
-
- SII_COMMAND(sii->regs,cs,ds,0);
-
- sii->regs->sii_csr = SII_CSR_IE|SII_CSR_PCE|SII_CSR_SLE|
- SII_CSR_HPM|SII_CSR_RSE;
-
- LOG(0x16,"disconnected");
-
- sii_disconnect(sii,cs,ds);
-
- tgt = sii->active_target;
- tgt->flags |= TGT_DISCONNECTED;
- tgt->transient_state.handler = sii->error_handler;
- /* the rest has been saved in sii_err_disconn() */
-
- PRINT(("{D%d}", tgt->target_id));
-
- sii_release_bus(sii);
-
- return FALSE;
-}
-
-/* get reconnect message, restore BUS */
-boolean_t
-sii_reconnect(sii, cs, ds)
- register sii_softc_t sii;
- register unsigned char cs, ds;
-
-{
- register target_info_t *tgt;
- sii_padded_regmap_t *regs;
- int id;
-
- regs = sii->regs;
- regs->sii_conn_csr = SII_CON_SCH;
- regs->sii_cmd = SII_CON_CON|SII_CON_DST|SCSI_PHASE_MSG_IN;
- wbflush();
-
- LOG(0x17,"reconnect");
-
- /*
- * See if this reconnection collided with a selection attempt
- */
- if (sii->state & SII_STATE_BUSY)
- sii->state |= SII_STATE_COLLISION;
-
- sii->state |= SII_STATE_BUSY;
-
- cs = regs->sii_conn_csr;
-
- /* tk50s are slow */
- if ((cs & SII_CON_CON) == 0)
- cs = sii_wait(&regs->sii_conn_csr, SII_CON_CON,1);
-
- /* ?? */
- if (regs->sii_conn_csr & SII_CON_BERR)
- regs->sii_conn_csr = SII_CON_BERR;
-
- if ((ds & SII_DTR_IBF) == 0)
- ds = sii_wait(&regs->sii_data_csr, SII_DTR_IBF,1);
-
- if (regs->sii_data != SCSI_IDENTIFY)
- printf("{I%x %x}", regs->sii_data, regs->sii_dma_1st_byte);
-
- /* find tgt: id is in sii_destat */
- id = regs->sii_destat;
-
- tgt = sii->sc->target[id];
- if (id > 7 || tgt == 0) panic("sii_reconnect");
-
- PRINT(("{R%d}", id));
- if (sii->state & SII_STATE_COLLISION)
- PRINT(("[B %d-%d]", sii->active_target->target_id, id));
-
- LOG(0x80+id,0);
-
- sii->active_target = tgt;
- tgt->flags &= ~TGT_DISCONNECTED;
-
- /* synch params */
- regs->sii_dma_ctrl = tgt->sync_offset;
- regs->sii_dma_len = 0;
-
- sii->script = tgt->transient_state.script;
- sii->error_handler = sii_err_rdp;
- sii->in_count = 0;
- sii->out_count = 0;
-
- regs->sii_cmd = SII_CMD_XFER|SII_CMD_CON|SII_CMD_DST|SCSI_PHASE_MSG_IN;
- wbflush();
-
- (void) sii_wait(&regs->sii_data_csr, SII_DTR_DONE,1);
- regs->sii_data_csr = SII_DTR_DONE;
-
- return TRUE;
-}
-
-
-/* do the synch negotiation */
-boolean_t
-sii_dosynch( sii, cs, ds)
- register sii_softc_t sii;
-{
- /*
- * Phase is MSG_OUT here, cmd has not been xferred
- */
- int *p, len;
- unsigned short dmalo, dmahi, dmalen;
- register target_info_t *tgt;
- register sii_padded_regmap_t *regs = sii->regs;
- unsigned char off;
-
- regs->sii_cmd = SCSI_PHASE_MSG_OUT|SII_CMD_ATN|SII_CON_CON;
- wbflush();
-
- LOG(0x11,"dosync");
-
- tgt = sii->active_target;
-
- tgt->flags |= TGT_DID_SYNCH; /* only one chance */
- tgt->flags &= ~TGT_TRY_SYNCH;
-
- p = (int*) (tgt->dma_ptr + (((regs->sii_dma_len<<1) + 2) & ~3));
- p[0] = SCSI_IDENTIFY | (SCSI_EXTENDED_MESSAGE<<8);
- p[1] = 3 | (SCSI_SYNC_XFER_REQUEST<<8);
- if (BGET(scsi_no_synchronous_xfer,tgt->masterno,tgt->target_id))
- off = 0;
- else
- off = sii_max_offset;
- /* but we'll ship "off" manually */
- p[2] = sii_to_scsi_period(sii_min_period) |(off << 8);
-
- dmalen = regs->sii_dma_len;
- dmalo = regs->sii_dma_adr_low;
- dmahi = regs->sii_dma_adr_hi;
- regs->sii_dma_len = sizeof(scsi_synch_xfer_req_t) /* + 1 */;
- regs->sii_dma_adr_low = SII_DMADR_LO(p);
- regs->sii_dma_adr_hi = SII_DMADR_HI(p);
- wbflush();
-
- regs->sii_cmd = SII_CMD_DMA|SII_CMD_XFER|SII_CMD_ATN|
- SII_CON_CON|SCSI_PHASE_MSG_OUT;
- wbflush();
-
- /* wait for either DONE or MIS */
- ds = sii_wait(&regs->sii_data_csr, SII_DTR_DI,1);
-
- /* TK50s do not like xtended messages */
- /* and some others just ignore the standard */
- if (SCSI_PHASE(ds) != SCSI_PHASE_MSG_OUT) {
- /* disentangle FIFO */
- regs->sii_cmd = SII_CON_CON|SCSI_PHASE_MSG_OUT;
- ds = sii_wait(&regs->sii_data_csr, SII_DTR_DONE,1);
- if (SCSI_PHASE(ds) == SCSI_PHASE_MSG_IN)
- goto msgin;
- goto got_answer;
- }
-
- /* ack and stop dma */
- regs->sii_cmd = SII_CON_CON|SCSI_PHASE_MSG_OUT|SII_CMD_ATN;
- wbflush();
- ds = sii_wait(&regs->sii_data_csr, SII_DTR_DONE,1);
- regs->sii_data_csr = SII_DTR_DONE;
- wbflush();
-
- /* last byte of message */
- regs->sii_data = off;
- wbflush();
- regs->sii_cmd = SII_CMD_XFER|SII_CON_CON|SCSI_PHASE_MSG_OUT;
- wbflush();
-
- /* Race here: who will interrupt first, the DMA
- controller or the status watching machine ? */
- delay(1000);
- regs->sii_cmd = SII_CON_CON|SCSI_PHASE_MSG_OUT;
- wbflush();
-
- ds = sii_wait(&regs->sii_data_csr, SII_DTR_DONE,1);
- regs->sii_data_csr = SII_DTR_DONE;
-
- /* The standard sez there nothing else the target can do but.. */
- ds = sii_wait(&regs->sii_data_csr, SCSI_PHASE_MSG_IN,0);
-
- /* Of course, what are standards for ? */
- if (SCSI_PHASE(ds) == SCSI_PHASE_CMD)
- goto cmdp;
-msgin:
- /* ack */
- regs->sii_cmd = SII_CON_CON|SCSI_PHASE_MSG_IN;
- wbflush();
-
- /* set up dma to receive answer */
- regs->sii_dma_adr_low = SII_DMADR_LO(p);
- regs->sii_dma_adr_hi = SII_DMADR_HI(p);
- regs->sii_dma_len = sizeof(scsi_synch_xfer_req_t);
- wbflush();
- regs->sii_cmd = SII_CMD_DMA|SII_CMD_XFER|SII_CON_CON|SCSI_PHASE_MSG_IN;
- wbflush();
-
- /* wait for the answer, and look at it */
- ds = sii_wait(&regs->sii_data_csr, SII_DTR_MIS,1);
-
- regs->sii_cmd = SII_CON_CON|SCSI_PHASE_MSG_IN;
- wbflush();
- ds = sii_wait(&regs->sii_data_csr, SII_DTR_DONE,1);
-
-got_answer:
- /* do not cancel the phase mismatch */
- regs->sii_data_csr = SII_DTR_DONE;
-
- if (regs->sii_dma_len || ((p[0] & 0xff) != SCSI_EXTENDED_MESSAGE)) {
- /* did not like it */
- printf(" did not like SYNCH xfer ");
- } else {
- /* will do synch */
- tgt->sync_period = scsi_period_to_sii((p[1]>>8)&0xff);
- tgt->sync_offset = regs->sii_data; /* odd xfer, in silo */
- /* sanity */
- if (tgt->sync_offset > sii_max_offset)
- tgt->sync_offset = sii_max_offset;
- regs->sii_dma_ctrl = tgt->sync_offset;
- }
-
-cmdp:
- /* phase should be command now */
- regs->sii_dma_len = dmalen;
- regs->sii_dma_adr_low = dmalo;
- regs->sii_dma_adr_hi = dmahi;
- wbflush();
-
- /* continue with simple command script */
- sii->error_handler = sii_err_generic;
-
- sii->script = (tgt->cur_cmd == SCSI_CMD_INQUIRY) ?
- sii_script_data_in : sii_script_cmd;
- if (SCSI_PHASE(ds) == SCSI_PHASE_CMD )
- return TRUE;
-
- sii->script++;
- if (SCSI_PHASE(ds) == SCSI_PHASE_STATUS )
- return TRUE;
-
- sii->script++; /* msgin? */
- sii->script++;
- if (SCSI_PHASE(ds) == SII_PHASE_DISC)
- return TRUE;
-
-gimmeabreak();
- panic("sii_dosynch");
- return FALSE;
-}
-
-/*
- * The bus was reset
- */
-sii_bus_reset(sii)
- register sii_softc_t sii;
-{
- register sii_padded_regmap_t *regs = sii->regs;
-
- LOG(0x21,"bus_reset");
-
- /*
- * Clear interrupt bits
- */
- regs->sii_conn_csr = 0xffff;
- regs->sii_data_csr = 0xffff;
-
- /*
- * Clear bus descriptor
- */
- sii->script = 0;
- sii->error_handler = 0;
- sii->active_target = 0;
- sii->next_target = 0;
- sii->state = 0;
- queue_init(&sii->waiting_targets);
- sii->wd.nactive = 0;
- sii_reset(regs, TRUE);
-
- log(LOG_KERN, "sii: (%d) bus reset ", ++sii->wd.reset_count);
- delay(scsi_delay_after_reset); /* some targets take long to reset */
-
- if (sii->sc == 0) /* sanity */
- return;
-
- sii_inside_sii_intr = FALSE;
-
- scsi_bus_was_reset(sii->sc);
-}
-
-/*
- * Error handlers
- */
-
-/*
- * Generic, default handler
- */
-boolean_t
-sii_err_generic(sii, cs, ds)
- register sii_softc_t sii;
-{
- register int cond = sii->script->condition;
-
- LOG(0x10,"err_generic");
-
- /*
- * Note to DEC hardware people.
- * Dropping the notion of interrupting on
- * DMA completions (or at least make it optional)
- * would save TWO interrupts out of the SEVEN that
- * are currently requested for a non-disconnecting
- * READ or WRITE operation.
- */
- if (ds & SII_DTR_DONE)
- return TRUE;
-
- /* this is a band-aid */
- if ((SCSI_PHASE(cond) == SII_PHASE_DISC) &&
- (cs & SII_CON_SCH)) {
- ds &= ~7;
- ds |= SII_PHASE_DISC;
- (void) (*sii->script->action)(sii,cs,ds);
- return FALSE;
- }
-
- /* TK50s are slow to connect, forgive em */
- if ((SCSI_PHASE(ds) == SCSI_PHASE_MSG_OUT) ||
- (SCSI_PHASE(cond) == SCSI_PHASE_MSG_OUT))
- return TRUE;
- if ((SCSI_PHASE(cond) == SCSI_PHASE_CMD) &&
- ((SCSI_PHASE(ds) == 0) || (SCSI_PHASE(ds) == 4) || (SCSI_PHASE(ds) == 5)))
- return TRUE;
-
- /* transition to status ? */
- if (SCSI_PHASE(ds) == SCSI_PHASE_STATUS)
- return sii_err_to_status(sii, cs, ds);
-
- return sii_err_phase_mismatch(sii,cs,ds);
-}
-
-/*
- * Handle generic errors that are reported as
- * an unexpected change to STATUS phase
- */
-sii_err_to_status(sii, cs, ds)
- register sii_softc_t sii;
-{
- script_t scp = sii->script;
-
- LOG(0x20,"err_tostatus");
- while (SCSI_PHASE(scp->condition) != SCSI_PHASE_STATUS)
- scp++;
- sii->script = scp;
-#if 0
- /*
- * Normally, we would already be able to say the command
- * is in error, e.g. the tape had a filemark or something.
- * But in case we do disconnected mode WRITEs, it is quite
- * common that the following happens:
- * dma_out -> disconnect -> reconnect
- * and our script might expect at this point that the dma
- * had to be restarted (it didn't know it was completed
- * because the tape record is shorter than we asked for).
- * And in any event.. it is both correct and cleaner to
- * declare error iff the STATUS byte says so.
- */
- sii->done = SCSI_RET_NEED_SENSE;
-#endif
- return TRUE;
-}
-
-/*
- * Watch for a disconnection
- */
-boolean_t
-sii_err_disconn(sii, cs, ds)
- register sii_softc_t sii;
- register unsigned cs, ds;
-{
- register sii_padded_regmap_t *regs;
- register target_info_t *tgt;
- int count;
- int from;
- unsigned char obb;
- int delayed_copy = 0;
-
- LOG(0x18,"err_disconn");
-
- if (SCSI_PHASE(ds) != SCSI_PHASE_MSG_IN)
- return sii_err_generic(sii, cs, ds);
-
- regs = sii->regs;
-
- if ((regs->sii_cmd & (SII_CMD_DMA|SII_CMD_XFER)) ==
- (SII_CMD_DMA|SII_CMD_XFER)) {
- /* stop dma and wait */
- regs->sii_cmd &= ~(SII_CMD_DMA|SII_CMD_XFER);
- (void) sii_wait(&regs->sii_data_csr, SII_DTR_DONE,1);
-/* later: regs->sii_data_csr = SII_DTR_DONE; */
- }
-
- SII_COMMAND(regs,cs,ds,0);
-
- tgt = sii->active_target;
- switch (SCSI_PHASE(sii->script->condition)) {
- case SCSI_PHASE_DATAO:
- LOG(0x1b,"+DATAO");
- if (sii->out_count) {
- register int xferred, offset;
-
- xferred = sii->out_count - regs->sii_dma_len;
- tgt->transient_state.out_count -= xferred;
- assert(tgt->transient_state.out_count > 0);
- offset = tgt->transient_state.dma_offset;
- tgt->transient_state.dma_offset += xferred;
- if (tgt->transient_state.dma_offset == PER_TGT_BUFF_SIZE)
- tgt->transient_state.dma_offset = 0;
-
- delayed_copy = 1;
- from = offset;
- count = xferred;
-
- }
- tgt->transient_state.script = sii_script_restart_data_out;
- break;
-
- case SCSI_PHASE_DATAI:
- LOG(0x19,"+DATAI");
- if (sii->in_count) {
- register int offset, xferred;
-
- obb = regs->sii_dma_1st_byte;
-
- xferred = sii->in_count - regs->sii_dma_len;
- assert(xferred > 0);
- if (ds & SII_DTR_OBB) {
- tgt->transient_state.isa_oddbb = TRUE;
- tgt->transient_state.oddbb = obb;
- }
- tgt->transient_state.in_count -= xferred;
- assert(tgt->transient_state.in_count > 0);
- offset = tgt->transient_state.dma_offset;
- tgt->transient_state.dma_offset += xferred;
- if (tgt->transient_state.dma_offset == PER_TGT_BUFF_SIZE)
- tgt->transient_state.dma_offset = 0;
-
- /* copy what we got */
-
- delayed_copy = 2;
- from = offset;
- count = xferred;
-
- }
- tgt->transient_state.script = sii_script_restart_data_in;
- break;
-
- case SCSI_PHASE_STATUS:
- /* will have to restart dma */
- if (count = regs->sii_dma_len) {
- (void) sii_wait(&regs->sii_data_csr, SII_DTR_DONE,1);
- regs->sii_data_csr = SII_DTR_DONE;
- }
- if (sii->state & SII_STATE_DMA_IN) {
- register int offset, xferred;
-
- obb = regs->sii_dma_1st_byte;
-
- LOG(0x1a,"+STATUS+R");
-
- xferred = sii->in_count - count;
- assert(xferred > 0);
- if (ds & SII_DTR_OBB) {
- tgt->transient_state.isa_oddbb = TRUE;
- tgt->transient_state.oddbb = obb;
- }
- tgt->transient_state.in_count -= xferred;
-/* assert(tgt->transient_state.in_count > 0);*/
- offset = tgt->transient_state.dma_offset;
- tgt->transient_state.dma_offset += xferred;
- if (tgt->transient_state.dma_offset == PER_TGT_BUFF_SIZE)
- tgt->transient_state.dma_offset = 0;
-
- /* copy what we got */
-
- delayed_copy = 2;
- from = offset;
- count = xferred;
-
- tgt->transient_state.script = sii_script_restart_data_in;
- if (tgt->transient_state.in_count == 0)
- tgt->transient_state.script++;
-
- } else {
-
- LOG(0x1d,"+STATUS+W");
-
- if ((count == 0) && (tgt->transient_state.out_count == sii->out_count)) {
- /* all done */
- tgt->transient_state.script = &sii_script_restart_data_out[1];
- tgt->transient_state.out_count = 0;
- } else {
- register int xferred, offset;
-
- /* how much we xferred */
- xferred = sii->out_count - count;
-
- tgt->transient_state.out_count -= xferred;
- assert(tgt->transient_state.out_count > 0);
- offset = tgt->transient_state.dma_offset;
- tgt->transient_state.dma_offset += xferred;
- if (tgt->transient_state.dma_offset == PER_TGT_BUFF_SIZE)
- tgt->transient_state.dma_offset = 0;
-
- delayed_copy = 1;
- from = offset;
- count = xferred;
-
- tgt->transient_state.script = sii_script_restart_data_out;
- }
- sii->out_count = 0;
- }
- break;
- case SII_PHASE_DISC: /* sometimes disconnects and phase remains */
- return sii_err_generic(sii, cs, ds);
- default:
- gimmeabreak();
- }
- regs->sii_csr &= ~SII_CSR_RSE;
- sii_msg_in(sii,cs,ds);
- sii->script = sii_script_disconnect;
- regs->sii_cmd = SII_CMD_DMA|SII_CMD_XFER|SCSI_PHASE_MSG_IN|
- SII_CON_CON|(regs->sii_conn_csr & SII_CON_DST);
- wbflush();
- if (delayed_copy == 2)
- careful_copyin_gap16( tgt, from, count, ds & SII_DTR_OBB, obb);
- else if (delayed_copy == 1)
- careful_copyout_gap16( tgt, from, count);
-
- return FALSE;
-}
-
-/*
- * Suppose someone reads the specs as they read the Bible.
- * They would send these unnecessary restore-pointer msgs
- * in reconnect phases. If this was a SCSI-2 modify-pointer
- * I could understand, but. Oh well.
- */
-sii_err_rdp(sii, cs, ds)
- register sii_softc_t sii;
-{
- register sii_padded_regmap_t *regs;
- register target_info_t *tgt;
-
- LOG(0x24,"err_drp");
-
- /* One chance */
- sii->error_handler = sii->active_target->transient_state.handler;
-
- if (SCSI_PHASE(ds) != SCSI_PHASE_MSG_IN)
- return sii_err_generic(sii, cs, ds);
-
- regs = sii->regs;
-
- if ((ds & SII_DTR_IBF) == 0)
- ds = sii_wait(&regs->sii_data_csr, SII_DTR_IBF,1);
-
- if (regs->sii_data != SCSI_RESTORE_POINTERS)
- return sii_err_disconn(sii, cs, ds);
-
- regs->sii_cmd = SII_CMD_XFER|SII_CMD_CON|SII_CMD_DST|SCSI_PHASE_MSG_IN;
- wbflush();
-
- (void) sii_wait(&regs->sii_data_csr, SII_DTR_DONE,1);
- regs->sii_data_csr = SII_DTR_DONE;
-
- return FALSE;
-}
-
-/*
- * Handle strange, yet unexplained interrupts and error
- * situations which eventually I will be old and wise
- * enough to deal with properly with preventive care.
- */
-sii_err_phase_mismatch(sii, cs, ds)
- register sii_softc_t sii;
-{
- register sii_padded_regmap_t *regs = sii->regs;
- register int match;
-
- LOG(0x23,"err_mismatch");
-
- match = SCSI_PHASE(sii->script->condition);
-
- /* dmain interrupted */
- if ((match == SCSI_PHASE_STATUS) && (SCSI_PHASE(ds) == SCSI_PHASE_DATAI)) {
- register int xferred;
- register char *p;
-
- if (regs->sii_dma_len <= 1) {
-/*if (scsi_debug)*/
-printf("[DMAINZERO %x %x %x]", cs, ds, regs->sii_dma_len);
- if (regs->sii_dma_len == 0) {
- regs->sii_dma_len = sii->in_count;
- wbflush();
- regs->sii_cmd = sii->script[-1].command;
- }
- return FALSE;
- }
-
- /* This happens when you do not "init" the prom
- and the fifo is screwed up */
- xferred = sii->in_count - regs->sii_dma_len;
- p = (char*)( regs->sii_dma_adr_low | ((regs->sii_dma_adr_hi&3)<<16) );
- p += xferred;
-if (scsi_debug)
-printf("[DMAIN %x %x %x]", cs, ds, xferred);
- /* odd bytes are not xferred */
- if (((unsigned)p) & 0x1){
- register short *oddb;
- oddb = (short*)(sii->buff) + ((unsigned)p-1);/*shifts*/
- *oddb = regs->sii_dma_1st_byte;
- }
- regs->sii_dma_adr_low = ((unsigned)p);
- regs->sii_dma_adr_hi = ((unsigned)p) << 16;
- wbflush();
- regs->sii_cmd = sii->script[-1].command;
- wbflush();
- return FALSE;
- } else
- /* dmaout interrupted */
- if ((match == SCSI_PHASE_STATUS) && (SCSI_PHASE(ds) == SCSI_PHASE_DATAO)) {
- register int xferred;
- register char *p;
-
- if (regs->sii_dma_len <= 1) {
-/*if (scsi_debug)*/
-printf("[DMAOUTZERO %x %x %x]", cs, ds, regs->sii_dma_len);
-gimmeabreak();
- if (regs->sii_dma_len == 0) {
- regs->sii_dma_len = sii->out_count;
- wbflush();
- regs->sii_cmd = sii->script[-1].command;
- }
- return FALSE;
- }
-
- xferred = sii->out_count - regs->sii_dma_len;
-/*if (scsi_debug)*/
-printf("[DMAOUT %x %x %x %x]", cs, ds, regs->sii_dma_len, sii->out_count);
- sii->out_count -= xferred;
- p = (char*)( regs->sii_dma_adr_low | ((regs->sii_dma_adr_hi&3)<<16) );
- p += xferred;
- regs->sii_dma_adr_low = ((unsigned)p);
- regs->sii_dma_adr_hi = ((unsigned)p) << 16;
- wbflush();
- regs->sii_cmd = sii->script[-1].command;
- wbflush();
- return FALSE;
- }
-#if 1 /* ?? */
- /* stuck in cmd phase */
- else if ((SCSI_PHASE(ds) == SCSI_PHASE_CMD) &&
- ((match == SCSI_PHASE_DATAI) || (match == SCSI_PHASE_DATAO))) {
-/*if (scsi_debug)*/
-printf("[CMD %x %x %x %x]", cs, ds, sii->cmd_count, regs->sii_dma_len);
- if (regs->sii_dma_len != 0) {
- /* ouch, this hurts */
- register int xferred;
- register char *p;
-
- xferred = sii->cmd_count - regs->sii_dma_len;
- sii->cmd_count -= xferred;
- p = (char*)( regs->sii_dma_adr_low | ((regs->sii_dma_adr_hi&3)<<16) );
- p += xferred;
- regs->sii_dma_adr_low = ((unsigned)p);
- regs->sii_dma_adr_hi = ((unsigned)p) << 16;
- wbflush();
- regs->sii_cmd = 0x8842;
- wbflush();
- return FALSE;;
-
- }
- SII_ACK(regs,cs,ds,0/*match*/);
- wbflush();
- return FALSE;;
- }
-#endif
- else {
- printf("{D%x %x}", cs, ds);
-/* if (scsi_debug)*/ gimmeabreak();
- }
- return FALSE;
-}
-
-/*
- * Watchdog
- *
- * There are two ways in which I have seen the chip
- * get stuck: a target never reconnected, or the
- * selection deadlocked. Both cases involved a tk50,
- * but elsewhere it showed up with hitachi disks too.
- */
-sii_reset_scsibus(sii)
- register sii_softc_t sii;
-{
- register target_info_t *tgt = sii->active_target;
- register sii_padded_regmap_t *regs = sii->regs;
-
- /* see if SIP still --> device down or non-existant */
- if ((regs->sii_conn_csr & (SII_CON_LST|SII_CON_SIP)) == SII_CON_SIP){
- if (tgt) {
- log(LOG_KERN, "Target %d went offline\n",
- tgt->target_id);
- tgt->flags = 0;
- return sii_probe_timeout(tgt);
- }
- /* else fall through */
- }
-
- if (tgt)
- log(LOG_KERN, "Target %d was active, cmd x%x in x%x out x%x Sin x%x Sou x%x dmalen x%x\n",
- tgt->target_id, tgt->cur_cmd,
- tgt->transient_state.in_count, tgt->transient_state.out_count,
- sii->in_count, sii->out_count,
- sii->regs->sii_dma_len);
-
- sii->regs->sii_cmd = SII_CMD_RST;
- delay(25);
-}
-
-/*
- * Copy routines that avoid odd pointers
- */
-boolean_t nocopyin = FALSE;
-careful_copyin_gap16(tgt, offset, len, isaobb, obb)
- register target_info_t *tgt;
- unsigned char obb;
-{
- register char *from, *to;
- register int count;
-
- count = tgt->transient_state.copy_count;
-
- from = tgt->dma_ptr + (offset << 1);
- to = tgt->ior->io_data + count;
- tgt->transient_state.copy_count = count + len;
- if (count & 1) {
- from -= (1 << 1);
- to -= 1;
- len += 1;
- }
-if (nocopyin) return;/*timing*/
- copyin_gap16( from, to, len);
- /* check for last, poor little odd byte */
- if (isaobb) {
- to += len;
- to[-1] = obb;
- }
-}
-
-careful_copyout_gap16( tgt, offset, len)
- register target_info_t *tgt;
-{
- register char *from, *to;
- register int count, olen;
- unsigned char c;
- char *p;
-
- count = tgt->ior->io_count - tgt->transient_state.copy_count;
- if (count > 0) {
-
- len = u_min(count, len);
- offset += tgt->transient_state.cmd_count;
-
- count = tgt->transient_state.copy_count;
- tgt->transient_state.copy_count = count + len;
-
- from = tgt->ior->io_data + count;
- to = tgt->dma_ptr + (offset << 1);
-
- /* the scsi buffer acts weirdo at times */
- if ((olen=len) & 1) {
- p = tgt->dma_ptr + ((offset + olen - 1)<<1);
- c = (*(unsigned short*)p) >> 8;/*!MSF*/
- }
-
- if (count & 1) {
- from -= 1;
- to -= (1 << 1);
- len += 1;
- }
-
- count = copyout_gap16(from, to, len);
-
- /* the scsi buffer acts weirdo at times */
- if (olen & 1) {
- unsigned char cv;
- cv = (*(unsigned short*)p) >> 8;/*!MSF*/
- if (c != cv) {
- /*
- * Scott Fahlman would say
- * "Use a big plier!"
- */
- unsigned short s;
- volatile unsigned short *pp;
- pp = (volatile unsigned short*)p;
- s = (c << 8) | (from[len-1] & 0xff);
- do {
- *pp = s;
- } while (*pp != s);
- }
- }
- }
-}
-
-#endif NSII > 0
-
diff --git a/scsi/adapters/scsi_89352.h b/scsi/adapters/scsi_89352.h
deleted file mode 100644
index 85c579f..0000000
--- a/scsi/adapters/scsi_89352.h
+++ /dev/null
@@ -1,231 +0,0 @@
-/*
- * Mach Operating System
- * Copyright (c) 1991 Carnegie Mellon University
- * All Rights Reserved.
- *
- * Permission to use, copy, modify and distribute this software and its
- * documentation is hereby granted, provided that both the copyright
- * notice and this permission notice appear in all copies of the
- * software, derivative works or modified versions, and any portions
- * thereof, and that both notices appear in supporting documentation.
- *
- * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
- * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
- * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
- *
- * Carnegie Mellon requests users of this software to return to
- *
- * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
- * School of Computer Science
- * Carnegie Mellon University
- * Pittsburgh PA 15213-3890
- *
- * any improvements or extensions that they make and grant Carnegie Mellon
- * the rights to redistribute these changes.
- */
-/*
- * File: scsi_89352.h
- * Author: Daniel Stodolsky, Carnegie Mellon University
- * Date: 06/91
- *
- * Defines for the Fujitsu MB89352 SCSI Protocol Controller (HBA)
- * The definitions herein also cover the 89351, 87035/36, 87033B
- */
-
-/*
- * Register map, padded as needed. Matches Hardware, do not screw up.
- */
-
-#define vuc volatile unsigned char
-
-typedef struct
-{
- vuc spc_bdid; /* Bus Device ID (R/W) */
-#define spc_myid spc_bdid
- char pad0[3];
- vuc spc_sctl; /* SPC Control register (R/W) */
- char pad1[3];
- vuc spc_scmd; /* Command Register (R/W) */
- char pad2[3];
- vuc spc_tmod; /* Transmit Mode Register (synch models) */
- char pad3[3];
- vuc spc_ints; /* Interrupt sense (R); Interrupt Reset (w) */
- char pad4[3];
- vuc spc_psns; /* Phase Sense (R); SPC Diagnostic Control (w) */
-#define spc_phase spc_psns
- char pad5[3];
- vuc spc_ssts; /* SPC status (R/O) */
- char pad6[3];
- vuc spc_serr; /* SPC error status (R/O) */
- char pad7[3];
- vuc spc_pctl; /* Phase Control (R/W) */
- char pad8[3];
- vuc spc_mbc; /* Modifed Byte Counter (R/O) */
- char pad9[3];
- vuc spc_dreg; /* Data Register (R/W) */
- char pad10[3];
- vuc spc_temp; /* Temporary Register (R/W) */
- char pad11[3];
- vuc spc_tch; /* Transfer Counter High (R/W) */
- char pad12[3];
- vuc spc_tcm; /* Transfer Counter Middle (R/W) */
- char pad13[3];
- vuc spc_tcl; /* Transfer Counter Low (R/W) */
- char pad14[3];
- vuc spc_exbf; /* External Buffer (synch models) */
- char pad15[3];
-} spc_regmap_t;
-
-#undef vuc
-
-/*
- * Control register
- */
-
-#define SPC_SCTL_DISABLE 0x80
-#define SPC_SCTL_RESET 0x40
-#define SPC_SCTL_DIAGMODE 0x20
-#define SPC_SCTL_ARB_EBL 0x10
-#define SPC_SCTL_PAR_EBL 0x08
-#define SPC_SCTL_SEL_EBL 0x04
-#define SPC_SCTL_RSEL_EBL 0x02
-#define SPC_SCTL_IE 0x01
-
-/*
- * Command register
- */
-
-#define SPC_SCMD_CMDMASK 0xe0
-# define SPC_SCMD_C_ACKREQ_S 0xe0
-# define SPC_SCMD_C_ACKREQ_C 0xc0
-# define SPC_SCMD_C_STOP_X 0xa0
-# define SPC_SCMD_C_XFER 0x80
-# define SPC_SCMD_C_ATN_S 0x60
-# define SPC_SCMD_C_ATN_C 0x40
-# define SPC_SCMD_C_SELECT 0x20
-# define SPC_SCMD_C_BUS_RLSE 0x00
-#define SPC_SCMD_BUSRST 0x10
-#define SPC_SCMD_INTERCEPT_X 0x08
-#define SPC_SCMD_PROGRAMMED_X 0x04
-#define SPC_SCMD_PAD_X 0x01
-
-/*
- * Transfer mode register (MB87033B/35/36)
- */
-
-#define SPC_TMOD_SYNC_X 0x80
-#define SPC_TMOD_OFFSET_MASK 0x70
-# define SPC_OFFSET(x) (((x)<<4)&SPC_TMOD_OFFSET_MASK)
-#define SPC_TMOD_PERIOD_MASK 0xc0
-# define SPC_PERIOD(x) (((x)<<2)&SPC_TMOD_PERIOD_MASK)
-#define SPC_TMOD_EXP_COUNTER 0x01
-
-/*
- * Interrupt cause register
- */
-
-#define SPC_INTS_SELECTED 0x80
-#define SPC_INTS_RESELECTED 0x40
-#define SPC_INTS_DISC 0x20
-#define SPC_INTS_DONE 0x10
-#define SPC_INTS_BUSREQ 0x08
-#define SPC_INTS_TIMEOUT 0x04
-#define SPC_INTS_ERROR 0x02
-#define SPC_INTS_RESET 0x01
-
-/*
- * SCSI Bus signals ("phase")
- */
-
-#define SPC_BUS_REQ 0x80 /* rw */
-#define SPC_BUS_ACK 0x40 /* rw */
-#define SPC_BUS_ATN 0x20 /* ro */
-# define SPC_DIAG_ENBL_XFER 0x20 /* wo */
-#define SPC_BUS_SEL 0x10 /* ro */
-#define SPC_BUS_BSY 0x08 /* rw */
-#define SPC_BUS_MSG 0x04 /* rw */
-#define SPC_BUS_CD 0x02 /* rw */
-#define SPC_BUS_IO 0x01 /* rw */
-
-#define SPC_CUR_PHASE(x) SCSI_PHASE(x)
-
-#define SPC_BSY(r) (r->spc_phase & SPC_BUS_BSY)
-
-/*
- * Chip status register
- */
-
-#define SPC_SSTS_INI_CON 0x80
-#define SPC_SSTS_TGT_CON 0x40
-#define SPC_SSTS_BUSY 0x20
-#define SPC_SSTS_XIP 0x10
-#define SPC_SSTS_RST 0x08
-#define SPC_SSTS_TC0 0x04
-#define SPC_SSTS_FIFO_FULL 0x02
-#define SPC_SSTS_FIFO_EMPTY 0x01
-
-/*
- * Error register
- */
-
-#define SPC_SERR_SEL 0x80 /* Selected */
-#define SPC_SERR_RSEL 0x40 /* Reselected */
-#define SPC_SERR_DISC 0x20 /* Disconnected */
-#define SPC_SERR_CMDC 0x10 /* Command Complete */
-#define SPC_SERR_SRVQ 0x08 /* Service Required */
-#define SPC_SERR_TIMO 0x04 /* Timeout */
-#define SPC_SERR_HARDERR 0x02 /* SPC Hard Error */
-#define SPC_SERR_RSTC 0x01 /* Reset Condition */
-
-/*
- * Phase control register
- *
- * [use SPC_CUR_PHASE() here too]
- */
-
-#define SPC_PCTL_BFREE_IE 0x80 /* Bus free (disconnected) */
-#define SPC_PCTL_LST_IE 0x40 /* lost arbit (87033) */
-#define SPC_PCTL_ATN_IE 0x20 /* ATN set (87033) */
-#define SPC_PCTL_RST_DIS 0x10 /* RST asserted */
-
-/*
- * Modified byte counter register
- */
-
-#define SPC_MBC_ECNT_MASK 0xf0 /* 87033 only */
-# define SPC_MBC_ECNT_GET(x) (((x)&SPC_MBC_ECNT_MASK)>>4)
-# define SPC_MBC_ECNT_PUT(x) (((x)<<4)&SPC_MBC_ECNT_MASK)
-#define SPC_MBC_MBC_MASK 0x0f
-# define SPC_MBC_GET(x) ((x)&SPC_MBC_MBC_MASK)
-# define SPC_MBC_PUT(x) ((x)&SPC_MBC_MBC_MASK)
-
-/*
- * Transfer counter register(s)
- */
-
-#define SPC_TC_PUT(ptr,val) { \
- (ptr)->spc_tch = (((val)>>16)&0xff); \
- (ptr)->spc_tcm = (((val)>> 8)&0xff); \
- (ptr)->spc_tcl = (((val) )&0xff); \
- }
-
-#define SPC_TC_GET(ptr,val) { \
- (val) = (((ptr)->spc_tch & 0xff )<<16) |\
- (((ptr)->spc_tcm 0 0xff )<<8) |\
- ((ptr)->spc_tcl 0xff);\
- }
-
-/* 87033 in expanded mode */
-#define SPC_XTC_PUT(ptr,val) { \
- (ptr)->spc_mbc = SPC_MBC_ECNT_PUT(((val)>>24));\
- (ptr)->spc_tch = (((val)>>16)&0xff); \
- (ptr)->spc_tcm = (((val)>> 8)&0xff); \
- (ptr)->spc_tcl = (((val) )&0xff); \
- }
-
-#define SPC_XTC_GET(ptr,val) { \
- (val) = (SPC_MBC_ECNT_GET((ptr)->spc_mbc)<<24)|\
- (((ptr)->spc_tch)<<16)|(((ptr)->spc_tcm)<<8)|\
- ((ptr)->spc_tcl);\
- }
-
diff --git a/scsi/adapters/scsi_89352_hdw.c b/scsi/adapters/scsi_89352_hdw.c
deleted file mode 100644
index 5672cb6..0000000
--- a/scsi/adapters/scsi_89352_hdw.c
+++ /dev/null
@@ -1,2192 +0,0 @@
-/*
- * Mach Operating System
- * Copyright (c) 1992,1991 Carnegie Mellon University
- * All Rights Reserved.
- *
- * Permission to use, copy, modify and distribute this software and its
- * documentation is hereby granted, provided that both the copyright
- * notice and this permission notice appear in all copies of the
- * software, derivative works or modified versions, and any portions
- * thereof, and that both notices appear in supporting documentation.
- *
- * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
- * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
- * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
- *
- * Carnegie Mellon requests users of this software to return to
- *
- * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
- * School of Computer Science
- * Carnegie Mellon University
- * Pittsburgh PA 15213-3890
- *
- * any improvements or extensions that they make and grant Carnegie Mellon
- * the rights to redistribute these changes.
- */
-/*
- * File: scsi_89352_hdw.c
- * Author: Daniel Stodolsky, Carnegie Mellon University
- * Date: 06/91
- *
- * Bottom layer of the SCSI driver: chip-dependent functions
- *
- * This file contains the code that is specific to the Fujitsu MB89352
- * SCSI chip (Host Bus Adapter in SCSI parlance): probing, start
- * operation, and interrupt routine.
- */
-
-/*
- * This layer works based on small simple 'scripts' that are installed
- * at the start of the command and drive the chip to completion.
- * The idea comes from the specs of the NCR 53C700 'script' processor.
- *
- * There are various reasons for this, mainly
- * - Performance: identify the common (successful) path, and follow it;
- * at interrupt time no code is needed to find the current status
- * - Code size: it should be easy to compact common operations
- * - Adaptability: the code skeleton should adapt to different chips without
- * terrible complications.
- * - Error handling: and it is easy to modify the actions performed
- * by the scripts to cope with strange but well identified sequences
- *
- */
-
-/*
- *
- *
- * Known Headaches/Features with this chip.
- *
- * (1) After the interrupt raised by select, the phase sense (psns)
- * and SPC status (ssts) registers do not display the correct values
- * until the REQ line (via psns) is high. (danner@cs.cmu.edu 6/11/91)
- *
- * (2) After a data in phase, the command complete interrupt may be raised
- * before the psns, ssts, and transfer counter registers settle. The reset
- * acknowledge or request command should not be issued until they settle.
- * (danner@cs.cmu.edu 6/14/91)
- *
- * (3) In general, an interrupt can be raised before the psns and ssts have
- * meaningful values. One should wait for the psns to show the REQ bit (0x80)
- * set before expecting meaningful values, with the exception of (2) above.
- * Currently this is handled by spc_err_generic ("Late REQ"). (This problem
- * is really a refinement of (1)). (danner@cs.cmu.edu 6/14/91)
- *
- * (4) When issuing a multibyte command after a select with attention,
- * The chip will automatically drop ATN before sending the last byte of the
- * message, in accordance with the ANSI SCSI standard. This requires, of course,
- * the transfer counter be an accurate representation of the amount of data to be
- * transfered. (danner@cs.cmu.edu 6/14/91)
- *
- */
-
-#if 0
-
-#include <platforms.h>
-
-#include <scsi.h>
-
-#if NSCSI > 0
-
-#include <mach/std_types.h>
-#include <sys/types.h>
-#include <chips/busses.h>
-#include <scsi/compat_30.h>
-#include <sys/syslog.h>
-#include <scsi/scsi.h>
-#include <scsi/scsi2.h>
-#include <scsi/scsi_defs.h>
-#include <scsi/adapters/scsi_89352.h>
-
-#include <machine/db_machdep.h> /*4proto*/
-#include <ddb/db_sym.h> /*4proto*/
-
-#ifdef LUNA88K
-#include <luna88k/board.h>
-#define SPC_DEFAULT_ADDRESS (caddr_t) SCSI_ADDR
-#endif
-
-#ifndef SPC_DEFAULT_ADDRESS /* cross compile check */
-#define SPC_DEFAULT_ADDRESS (caddr_t) 0
-#endif
-
-
-/* external/forward declarations */
-int spc_probe(), spc_slave(), spc_attach(), scsi_go();
-void spc_reset(), spc_attempt_selection(), spc_target_intr(), spc_bus_reset();
-/*
- * Statically allocated command & temp buffers
- * This way we can attach/detach drives on-fly
- */
-#define PER_TGT_BUFF_DATA 256
-
-static char spc_buffer[NSCSI * 8 * PER_TGT_BUFF_DATA];
-
-/*
- * Macros to make certain things a little more readable
- */
-
-/*
- wait for the desired phase to appear, but make sure the REQ bit set in the psns
- (otherwise the values tend to float/be garbage.
-*/
-
-#define SPC_WAIT_PHASE(p) while(((regs->spc_psns & (SPC_BUS_REQ|SCSI_PHASE_MASK))) \
- != (SPC_BUS_REQ|(p)))
-
-/*
- wait until a phase different than p appears in the psns. Since it is only valid
- when the REQ bit is set, don't test unless REQ bit is set. So spin until
- REQ is high or the phase is not p.
-*/
-
-#define SPC_WAIT_PHASE_VANISH(p) while(1) { int _psns_ = regs->spc_psns; \
- if ((_psns_ & SPC_BUS_REQ) && (_psns_ & SCSI_PHASE_MASK)!=p) break; }
-
-
-
-/* ?? */
-/* #define SPC_ACK(ptr,phase) (ptr)->spc_pctl = (phase) */
-
-/*
- * A script has a two parts: a pre-condition and an action.
- * The first triggers error handling if not satisfied and in
- * our case it is formed by the current bus phase and connected
- * condition as per bus status bits. The action part is just a
- * function pointer, invoked in a standard way. The script
- * pointer is advanced only if the action routine returns TRUE.
- * See spc_intr() for how and where this is all done.
- */
-
-typedef struct script {
- char condition; /* expected state at interrupt */
- int (*action)(); /* action routine */
-} *script_t;
-
-#define SCRIPT_MATCH(psns) (SPC_CUR_PHASE((psns))|((psns) & SPC_BUS_BSY))
-
-/* ?? */
-#define SPC_PHASE_DISC 0x0 /* sort of .. */
-
-/* The active script is in the state expected right after the issue of a select */
-
-#define SCRIPT_SELECT(scp) (scp->action == spc_issue_command || \
- scp->action == spc_issue_ident_and_command)
-
-/* forward decls of script actions */
-boolean_t
- spc_dosynch(), /* negotiate synch xfer */
- spc_xfer_in(), /* get data from target via dma */
- spc_xfer_out(), /* send data to target via dma */
- spc_get_status(), /* get status from target */
- spc_end_transaction(), /* all come to an end */
- spc_msg_in(), /* get disconnect message(s) */
- spc_issue_command(), /* spit on the bus */
- spc_issue_ident_and_command(), /* spit on the bus (with ATN) */
- spc_disconnected(); /* current target disconnected */
-/* forward decls of error handlers */
-boolean_t
- spc_err_generic(), /* generic error handler */
- spc_err_disconn(); /* when a target disconnects */
-void gimmeabreak(); /* drop into the debugger */
-
-void spc_reset_scsibus();
-boolean_t spc_probe_target();
-
-scsi_ret_t spc_select_target();
-
-/*
- * State descriptor for this layer. There is one such structure
- * per (enabled) 89352 chip
- */
-struct spc_softc {
- watchdog_t wd;
- spc_regmap_t *regs; /* 5380 registers */
- char *buff; /* scratch buffer memory */
- char *data_ptr; /* orig/dest memory */
- script_t script;
- int (*error_handler)();
- int in_count; /* amnt we expect to receive */
- int out_count; /* amnt we are going to ship */
-
- volatile char state;
-#define SPC_STATE_BUSY 0x01 /* selecting or currently connected */
-#define SPC_STATE_TARGET 0x04 /* currently selected as target */
-#define SPC_STATE_COLLISION 0x08 /* lost selection attempt */
-#define SPC_STATE_DMA_IN 0x10 /* tgt --> initiator xfer */
-
- unsigned char ntargets; /* how many alive on this scsibus */
- unsigned char done;
- unsigned char xxxx;
-
- scsi_softc_t *sc;
- target_info_t *active_target;
-
- target_info_t *next_target; /* trying to seize bus */
- queue_head_t waiting_targets;/* other targets competing for bus */
- decl_simple_lock_data(,chiplock) /* Interlock */
-} spc_softc_data[NSCSI];
-
-typedef struct spc_softc *spc_softc_t;
-
-spc_softc_t spc_softc[NSCSI];
-
-/*
- * Definition of the controller for the auto-configuration program.
- */
-
-int spc_probe(), scsi_slave(), spc_go();
-void spc_intr();
-void scsi_attach();
-
-vm_offset_t spc_std[NSCSI] = { SPC_DEFAULT_ADDRESS };
-
-struct bus_device *spc_dinfo[NSCSI*8];
-struct bus_ctlr *spc_minfo[NSCSI];
-struct bus_driver spc_driver =
- { spc_probe, scsi_slave, scsi_attach, spc_go, spc_std, "rz", spc_dinfo,
- "spc", spc_minfo, BUS_INTR_B4_PROBE};
-
-/*
- * Scripts
- */
-
-struct script
-spc_script_data_in[] = {
- { SCSI_PHASE_CMD|SPC_BUS_BSY, spc_issue_command},
- { SCSI_PHASE_DATAI|SPC_BUS_BSY, spc_xfer_in},
- { SCSI_PHASE_STATUS|SPC_BUS_BSY, spc_get_status},
- { SCSI_PHASE_MSG_IN|SPC_BUS_BSY, spc_end_transaction}
-},
-
-spc_script_late_data_in[] = {
- { SCSI_PHASE_MSG_OUT|SPC_BUS_BSY, spc_issue_ident_and_command},
- { SCSI_PHASE_DATAI|SPC_BUS_BSY, spc_xfer_in},
- { SCSI_PHASE_STATUS|SPC_BUS_BSY, spc_get_status},
- { SCSI_PHASE_MSG_IN|SPC_BUS_BSY, spc_end_transaction}
-},
-
-spc_script_data_out[] = {
- { SCSI_PHASE_CMD|SPC_BUS_BSY, spc_issue_command},
- { SCSI_PHASE_DATAO|SPC_BUS_BSY, spc_xfer_out},
- { SCSI_PHASE_STATUS|SPC_BUS_BSY, spc_get_status},
- { SCSI_PHASE_MSG_IN|SPC_BUS_BSY, spc_end_transaction}
-},
-
-
-spc_script_late_data_out[] = {
- { SCSI_PHASE_MSG_OUT|SPC_BUS_BSY, spc_issue_ident_and_command},
- { SCSI_PHASE_DATAO|SPC_BUS_BSY, spc_xfer_out},
- { SCSI_PHASE_STATUS|SPC_BUS_BSY, spc_get_status},
- { SCSI_PHASE_MSG_IN|SPC_BUS_BSY, spc_end_transaction}
-},
-
-
-spc_script_cmd[] = {
- { SCSI_PHASE_CMD|SPC_BUS_BSY, spc_issue_command},
- { SCSI_PHASE_STATUS|SPC_BUS_BSY, spc_get_status},
- { SCSI_PHASE_MSG_IN|SPC_BUS_BSY, spc_end_transaction}
-},
-
-spc_script_late_cmd[] = {
- { SCSI_PHASE_MSG_OUT|SPC_BUS_BSY, spc_issue_ident_and_command},
- { SCSI_PHASE_STATUS|SPC_BUS_BSY, spc_get_status},
- { SCSI_PHASE_MSG_IN|SPC_BUS_BSY, spc_end_transaction}
-},
-
-/* Synchronous transfer neg(oti)ation */
-
-spc_script_try_synch[] = {
- { SCSI_PHASE_MSG_OUT|SPC_BUS_BSY, spc_dosynch}
-},
-
-/* Disconnect sequence */
-
-spc_script_disconnect[] = {
- { SPC_PHASE_DISC, spc_disconnected}
-};
-
-
-
-#define u_min(a,b) (((a) < (b)) ? (a) : (b))
-
-
-#define DEBUG
-#ifdef DEBUG
-
-int spc_state(base)
- vm_offset_t base;
-{
- register spc_regmap_t *regs;
-
- if (base == 0)
- base = (vm_offset_t) SPC_DEFAULT_ADDRESS;
-
- regs = (spc_regmap_t*) (base);
-
- db_printf("spc_bdid (bus device #): %x\n",regs->spc_bdid);
- db_printf("spc_sctl (spc internal control): %x\n",regs->spc_sctl);
- db_printf("spc_scmd (scp command): %x\n",regs->spc_scmd);
- db_printf("spc_ints (spc interrupt): %x\n",regs->spc_ints);
- db_printf("spc_psns (scsi bus phase): %x\n",regs->spc_psns);
- db_printf("spc_ssts (spc internal status): %x\n",regs->spc_ssts);
- db_printf("spc_serr (spc internal err stat): %x\n",regs->spc_serr);
- db_printf("spc_pctl (scsi transfer phase): %x\n",regs->spc_pctl);
- db_printf("spc_mbc (spc transfer data ct): %x\n",regs->spc_mbc);
-/* db_printf("spc_dreg (spc transfer data r/w): %x\n",regs->spc_dreg);*/
- db_printf("spc_temp (scsi data bus control): %x\n",regs->spc_temp);
- db_printf("spc_tch (transfer byte ct (MSB): %x\n",regs->spc_tch);
- db_printf("spc_tcm (transfer byte ct (2nd): %x\n",regs->spc_tcm);
- db_printf("spc_tcl (transfer byte ct (LSB): %x\n",regs->spc_tcl);
-
- return 0;
-}
-
-int spc_target_state(tgt)
- target_info_t *tgt;
-{
- if (tgt == 0)
- tgt = spc_softc[0]->active_target;
- if (tgt == 0)
- return 0;
- db_printf("fl %x dma %x+%x cmd %x id %x per %x off %x ior %x ret %x\n",
- tgt->flags, tgt->dma_ptr, tgt->transient_state.dma_offset,
- tgt->cmd_ptr, tgt->target_id, tgt->sync_period, tgt->sync_offset,
- tgt->ior, tgt->done);
- if (tgt->flags & TGT_DISCONNECTED){
- script_t spt;
-
- spt = tgt->transient_state.script;
- db_printf("disconnected at ");
- db_printsym((db_expr_t)spt,1);
- db_printf(": %x ", spt->condition);
- db_printsym((db_expr_t)spt->action,1);
- db_printf(", ");
- db_printsym((db_expr_t)tgt->transient_state.handler, 1);
- db_printf("\n");
- }
-
- return 0;
-}
-
-void spc_all_targets(unit)
-int unit;
-{
- int i;
- target_info_t *tgt;
- for (i = 0; i < 8; i++) {
- tgt = spc_softc[unit]->sc->target[i];
- if (tgt)
- spc_target_state(tgt);
- }
-}
-
-int spc_script_state(unit)
-int unit;
-{
- script_t spt = spc_softc[unit]->script;
-
- if (spt == 0) return 0;
- db_printsym((db_expr_t)spt,1);
- db_printf(": %x ", spt->condition);
- db_printsym((db_expr_t)spt->action,1);
- db_printf(", ");
- db_printsym((db_expr_t)spc_softc[unit]->error_handler, 1);
- return 0;
-}
-
-#define PRINT(x) if (scsi_debug) printf x
-
-#define TRMAX 200
-int tr[TRMAX+3];
-int trpt, trpthi;
-#define TR(x) tr[trpt++] = x
-#define TRWRAP trpthi = trpt; trpt = 0;
-#define TRCHECK if (trpt > TRMAX) {TRWRAP}
-
-#define TRACE
-
-#ifdef TRACE
-
-#define LOGSIZE 256
-int spc_logpt;
-int spc_log[LOGSIZE];
-
-#define MAXLOG_VALUE 0x30
-struct {
- char *name;
- unsigned int count;
-} logtbl[MAXLOG_VALUE];
-
-static void LOG(e,f)
- int e;
- char *f;
-{
- spc_log[spc_logpt++] = (e);
- if (spc_logpt == LOGSIZE) spc_logpt = 0;
- if ((e) < MAXLOG_VALUE) {
- logtbl[(e)].name = (f);
- logtbl[(e)].count++;
- }
-}
-
-int spc_print_log(skip)
- int skip;
-{
- register int i, j;
- register unsigned int c;
-
- for (i = 0, j = spc_logpt; i < LOGSIZE; i++) {
- c = spc_log[j];
- if (++j == LOGSIZE) j = 0;
- if (skip-- > 0)
- continue;
- if (c < MAXLOG_VALUE)
- db_printf(" %s", logtbl[c].name);
- else
- db_printf("-0x%x", c - 0x80);
- }
- db_printf("\n");
- return 0;
-}
-
-void spc_print_stat()
-{
- register int i;
- register char *p;
- for (i = 0; i < MAXLOG_VALUE; i++) {
- if (p = logtbl[i].name)
- printf("%d %s\n", logtbl[i].count, p);
- }
-}
-
-#else /* TRACE */
-#define LOG(e,f)
-#endif /* TRACE */
-
-#else /* DEBUG */
-#define PRINT(x)
-#define LOG(e,f)
-#define TR(x)
-#define TRCHECK
-#define TRWRAP
-#endif /* DEBUG */
-
-
-/*
- * Probe/Slave/Attach functions
- */
-
-/*
- * Probe routine:
- * Should find out (a) if the controller is
- * present and (b) which/where slaves are present.
- *
- * Implementation:
- * Send an identify msg to each possible target on the bus
- * except of course ourselves.
- */
-int spc_probe(reg, ui)
- char *reg;
- struct bus_ctlr *ui;
-{
- int tmp;
- int unit = ui->unit;
- spc_softc_t spc = &spc_softc_data[unit];
- int target_id, i;
- scsi_softc_t *sc;
- register spc_regmap_t *regs;
- int s;
- boolean_t did_banner = FALSE;
- char *cmd_ptr;
-
- /*
- * We are only called if the chip is there,
- * but make sure anyways..
- */
- regs = (spc_regmap_t *) (reg);
- if (check_memory((unsigned)regs, 0))
- return 0;
-
-#if notyet
- /* Mappable version side */
- SPC_probe(reg, ui);
-#endif
-
- /*
- * Initialize hw descriptor
- */
- spc_softc[unit] = spc;
- spc->regs = regs;
- spc->buff = spc_buffer;
-
- queue_init(&spc->waiting_targets);
-
- simple_lock_init(&spc->chiplock);
-
- sc = scsi_master_alloc(unit, (char*)spc);
- spc->sc = sc;
-
- sc->go = spc_go;
- sc->probe = spc_probe_target;
- sc->watchdog = scsi_watchdog;
- spc->wd.reset = spc_reset_scsibus;
-
-#ifdef MACH_KERNEL
- sc->max_dma_data = -1; /* unlimited */
-#else
- sc->max_dma_data = scsi_per_target_virtual;
-#endif
-
- scsi_might_disconnect[unit] = 0; /* XXX for now */
-
- /*
- * Reset chip
- */
- s = splbio();
- spc_reset(regs, TRUE);
- tmp = regs->spc_ints = regs->spc_ints;
-
- /*
- * Our SCSI id on the bus.
- */
-
- sc->initiator_id = bdid_to_id(regs->spc_bdid);
- printf("%s%d: my SCSI id is %d", ui->name, unit, sc->initiator_id);
-
- /*
- * For all possible targets, see if there is one and allocate
- * a descriptor for it if it is there.
- */
- cmd_ptr = spc_buffer;
- for (target_id = 0; target_id < 8; target_id++, cmd_ptr += PER_TGT_BUFF_DATA) {
-
- register unsigned csr, ints;
- scsi_status_byte_t status;
-
- /* except of course ourselves */
- if (target_id == sc->initiator_id)
- continue;
-
- if (spc_select_target( regs, sc->initiator_id, target_id, FALSE)
- == SCSI_RET_DEVICE_DOWN) {
- tmp = regs->spc_ints = regs->spc_ints;
- continue;
- }
-
- printf(",%s%d", did_banner++ ? " " : " target(s) at ",
- target_id);
-
- /* should be command phase here: we selected wo ATN! */
- SPC_WAIT_PHASE(SCSI_PHASE_CMD);
-
- SPC_ACK(regs,SCSI_PHASE_CMD);
-
- /* build command in buffer */
- {
- unsigned char *p = (unsigned char*) cmd_ptr;
-
- p[0] = SCSI_CMD_TEST_UNIT_READY;
- p[1] =
- p[2] =
- p[3] =
- p[4] =
- p[5] = 0;
- }
-
- spc_data_out(regs, SCSI_PHASE_CMD, 6, cmd_ptr);
-
- SPC_WAIT_PHASE(SCSI_PHASE_STATUS);
-
- /* should have recieved a Command Complete Interrupt */
- while (!(regs->spc_ints))
- delay(1);
- ints = regs->spc_ints;
- if (ints != (SPC_INTS_DONE))
- gimmeabreak();
- regs->spc_ints = ints;
-
- SPC_ACK(regs,SCSI_PHASE_STATUS);
-
- csr = spc_data_in(regs, SCSI_PHASE_STATUS, 1, &status.bits);
- LOG(0x25,"din_count");
- LOG(0x80+csr,0);
-
- if (status.st.scsi_status_code != SCSI_ST_GOOD)
- scsi_error( 0, SCSI_ERR_STATUS, status.bits, 0);
-
- /* expect command complete interupt */
- while (!(regs->spc_ints & SPC_INTS_DONE))
- delay(1);
-
- /* clear all intr bits */
- tmp = regs->spc_ints;
- LOG(0x26,"ints");
- LOG(0x80+tmp,0);
- regs->spc_ints = SPC_INTS_DONE;
-
- /* get cmd_complete message */
- SPC_WAIT_PHASE(SCSI_PHASE_MSG_IN);
-
- SPC_ACK(regs,SCSI_PHASE_MSG_IN);
-
- csr = spc_data_in(regs,SCSI_PHASE_MSG_IN, 1,(unsigned char*)&i);
- LOG(0x25,"din_count");
- LOG(0x80+csr,0);
-
- while (!(regs->spc_ints & SPC_INTS_DONE))
- delay(1);
-
- /* clear all done intr */
- tmp = regs->spc_ints;
- LOG(0x26,"ints");
- LOG(0x80+tmp,0);
- regs->spc_ints = SPC_INTS_DONE;
-
- SPC_ACK(regs,SPC_PHASE_DISC);
-
- /* release the bus */
- regs->spc_pctl = ~SPC_PCTL_BFREE_IE & SPC_PHASE_DISC;
- /* regs->spc_scmd = 0; only in TARGET mode */
-
- /* wait for disconnected interrupt */
- while (!(regs->spc_ints & SPC_INTS_DISC))
- delay(1);
-
- tmp = regs->spc_ints;
- LOG(0x26,"ints");
- LOG(0x80+tmp,0);
- regs->spc_ints = tmp;
- LOG(0x29,"Probed\n");
-
- /*
- * Found a target
- */
- spc->ntargets++;
- {
- register target_info_t *tgt;
-
- tgt = scsi_slave_alloc(unit, target_id, (char*)spc);
-
- /* "virtual" address for our use */
- tgt->cmd_ptr = cmd_ptr;
- /* "physical" address for dma engine (??) */
- tgt->dma_ptr = 0;
-#ifdef MACH_KERNEL
-#else /*MACH_KERNEL*/
- fdma_init(&tgt->fdma, scsi_per_target_virtual);
-#endif /*MACH_KERNEL*/
- }
- }
- printf(".\n");
-
- splx(s);
- return 1;
-}
-
-boolean_t
-spc_probe_target(tgt, ior)
- target_info_t *tgt;
- io_req_t ior;
-{
- boolean_t newlywed;
-
- newlywed = (tgt->cmd_ptr == 0);
- if (newlywed) {
- /* desc was allocated afresh */
-
- /* "virtual" address for our use */
- tgt->cmd_ptr = &spc_buffer[PER_TGT_BUFF_DATA*tgt->target_id +
- (tgt->masterno*8*PER_TGT_BUFF_DATA) ];
- /* "physical" address for dma engine */
- tgt->dma_ptr = 0;
-#ifdef MACH_KERNEL
-#else /*MACH_KERNEL*/
- fdma_init(&tgt->fdma, scsi_per_target_virtual);
-#endif /*MACH_KERNEL*/
-
- }
-
- if (scsi_inquiry(tgt, SCSI_INQ_STD_DATA) == SCSI_RET_DEVICE_DOWN)
- return FALSE;
-
- tgt->flags = TGT_ALIVE;
- return TRUE;
-}
-
-int bdid_to_id(bdid)
- register int bdid;
-{
- register int i;
- for (i = 0; i < 8; i++)
- if (bdid == (1 << i)) break;
- return i;
-}
-
-scsi_ret_t
-spc_select_target(regs, myid, id, with_atn)
- register spc_regmap_t *regs;
- unsigned myid, id;
- boolean_t with_atn;
-{
- scsi_ret_t ret = SCSI_RET_RETRY;
- int mask;
-
- if ((regs->spc_phase & (SPC_BUS_BSY|SPC_BUS_SEL))
-#ifdef MIPS
- && (regs->spc_phase & (SPC_BUS_BSY|SPC_BUS_SEL))
- && (regs->spc_phase & (SPC_BUS_BSY|SPC_BUS_SEL))
-#endif
- )
- return ret;
-
- /* setup for for select:
-
-#if 0
- (1) Toggle the Enable transfer bit (turning on the chips
- SCSI bus drivers).
-#endif
- (2) Enable arbitration, parity, reselect display, but
- disable interrupt generation to the CPU (we are polling).
- (3) Disable the bus free interrupt and set I/O direction
- (4) If doing a select with attention, write the Set attention command.
- Then delay 1 microsecond to avoid command races.
-
- (5) Temp register gets 1<<target | 1<<initiator ids
- (6) Timeout clocked into transfer registers
- (7) Drive select (and optionally attention) onto the bus
- (8) Wait 1/4 second for timeout.
- */
-
-#if 0
- regs->spc_psns = SPC_DIAG_ENBL_XFER; /* (1) */
-#endif
-
- regs->spc_sctl = SPC_SCTL_ARB_EBL|
- SPC_SCTL_PAR_EBL|
- SPC_SCTL_RSEL_EBL; /* (2) */
-
-
-
- mask = ~SPC_PCTL_BFREE_IE & regs->spc_pctl;
- mask &= ~1; /* set I/O direction to be out */
-
- regs->spc_pctl = mask; /* (3) */
-
- if (with_atn)
- {
- regs->spc_scmd = SPC_SCMD_C_ATN_S; /* (4) */
- delay(1);
- }
-
- regs->spc_temp = (1<<myid) | (1<<id); /* (5) */
-
- SPC_TC_PUT(regs,0xfa004); /* (6) */
-
- regs->spc_scmd = (SPC_SCMD_C_SELECT | SPC_SCMD_PROGRAMMED_X); /* (7) */
-
- {
- int count = 2500;
-
- /* wait for an interrupt */
- while ((regs->spc_ints)==0)
- {
- if (--count > 0)
- delay(100);
- else
- {
- goto nodev;
- }
- }
-
- count = regs->spc_ints;
- if (count & SPC_INTS_TIMEOUT)
- {
- /* sanity check. The ssts should have the busy bit set */
- if (regs->spc_ssts & SPC_SSTS_BUSY)
- goto nodev;
- else
- panic("spc_select_target: timeout");
- }
-
- /* otherwise, we should have received a
- command complete interrupt */
-
- if (count & ~SPC_INTS_DONE)
- panic("spc_select_target");
-
- } /* (8) */
-
- /* we got a response - now connected; bus is in COMMAND phase */
-
- regs->spc_ints = regs->spc_ints;
- /* regs->spc_scmd = 0; target only */
- return SCSI_RET_SUCCESS;
-nodev:
- SPC_TC_PUT(regs,0); /* play it safe */
- regs->spc_ints = regs->spc_ints;
- /* regs->spc_scmd = 0; target only */
- ret = SCSI_RET_DEVICE_DOWN;
- return ret;
-}
-
-int spc_data_out(regs, phase, count, data)
- int phase, count;
- register spc_regmap_t *regs;
- unsigned char *data;
-{
- /* This is the one that sends data out. returns how many
- bytes it did NOT xfer: */
-
- if (SPC_CUR_PHASE(regs->spc_phase) != phase)
- return count;
-
- /* check that the fifo is empty. If not, cry */
- if (!(regs->spc_ssts & SPC_SSTS_FIFO_EMPTY))
- panic("spc_data_out: junk in fifo\n");
-
- SPC_TC_PUT(regs,count);
- regs->spc_scmd = SPC_SCMD_C_XFER | SPC_SCMD_PROGRAMMED_X;
-
- /* wait for the SPC to start processing the command */
- while ((regs->spc_ssts & (SPC_SSTS_INI_CON|SPC_SSTS_TGT_CON|SPC_SSTS_BUSY|SPC_SSTS_XIP))
- != (SPC_SSTS_INI_CON|SPC_SSTS_BUSY|SPC_SSTS_XIP))
- delay(1);
-
- /* shovel out the data */
-
- while (count)
- {
- /* check if interrupt is pending */
- int ints = regs->spc_ints;
- int ssts;
-
- if (ints) /* something has gone wrong */
- break;
-
- ssts = regs->spc_ssts;
- if (ssts & SPC_SSTS_FIFO_FULL) /* full fifo - can't write */
- delay(1);
- else
- { /* spit out a byte */
- regs->spc_dreg = *data;
- data++;
- count--;
- }
- }
-
-
- if (count != 0)
- {
- /* need some sort of fifo cleanup if failed */
- gimmeabreak(); /* Bytes stranded in the fifo */
- }
-
- return count;
-}
-
-int spc_data_in(regs, phase, count, data)
- int phase, count;
- register spc_regmap_t *regs;
- unsigned char *data;
-{
- if (SPC_CUR_PHASE(regs->spc_phase) != phase)
- return count;
-
- SPC_TC_PUT(regs,count);
- regs->spc_scmd = SPC_SCMD_C_XFER | SPC_SCMD_PROGRAMMED_X;
-
- /* The Fujistu code sample suggests waiting for the top nibble of the SSTS to
- become 0xb (ssts & 0xf0) = 0xb. This state, however is transient. If the
- message is short (say , 1 byte), it can get sucked into the fifo before
- we ever get to look at the state. So instead, we are going to wait for
- the fifo to become nonempty.
- */
-
- while ((regs->spc_ssts & SPC_SSTS_FIFO_EMPTY))
- delay(1);
-
- while (count)
- {
- int ints = regs->spc_ints;
- int ssts;
-
- /* If there is an interrupt pending besides command complete or
- phase mismatch, give up */
-
- if (ints & ~(SPC_INTS_DONE|SPC_INTS_BUSREQ))
- break;
-
- /* see if there is any data in the fifo */
- ssts = regs->spc_ssts;
- if ((ssts & SPC_SSTS_FIFO_EMPTY) == 0)
- {
- *data = regs->spc_dreg;
- data++;
- count--;
- continue;
- }
-
- /* if empty, check if phase has changed */
- if (SPC_CUR_PHASE(regs->spc_phase) != phase)
- break;
-
- }
-
- if ((count==0) && (phase == SCSI_PHASE_MSG_IN))
- {
- while (!(regs->spc_ints & SPC_INTS_DONE))
- delay(1);
-
- /*
- So the command complete interrupt has arrived. Now check that the
- other two conditions we expect - The psns to be in ack|busy|message_in phase
- and ssts to indicate connected|xfer in progress|busy|xfer counter 0|empty fifo
- are true.
- */
- while (1)
- {
- register int psns = regs->spc_psns;
- register int ssts = regs->spc_ssts;
- register int sscon = ssts & (SPC_SSTS_INI_CON | SPC_SSTS_TGT_CON);
- register int ssncon = ssts & ~(SPC_SSTS_INI_CON | SPC_SSTS_TGT_CON);
-
- if (psns == (SPC_BUS_ACK | SPC_BUS_BSY | SCSI_PHASE_MSG_IN) &&
- ssncon == (SPC_SSTS_BUSY | SPC_SSTS_XIP | SPC_SSTS_TC0 | SPC_SSTS_FIFO_EMPTY) &&
- sscon)
- break;
- }
-
- regs->spc_scmd = SPC_SCMD_C_ACKREQ_C;
- }
-
- return count;
-}
-
-void spc_reset(regs, quickly)
- register spc_regmap_t *regs;
- boolean_t quickly;
-{
- register char myid;
-
- /* save our id across reset */
- myid = bdid_to_id(regs->spc_bdid);
-
- /* wait for Reset In signal to go low */
- while (regs->spc_ssts & SPC_SSTS_RST)
- delay(1);
-
- /* reset chip */
- regs->spc_sctl = SPC_SCTL_RESET;
- delay(25);
-
- regs->spc_myid = myid;
- regs->spc_sctl = SPC_SCTL_ARB_EBL|SPC_SCTL_PAR_EBL|SPC_SCTL_SEL_EBL|
- SPC_SCTL_RSEL_EBL|SPC_SCTL_IE;
- regs->spc_scmd = SPC_SCMD_C_BUS_RLSE;
- /* regs->spc_tmod = 0; - SANDRO ? */
- regs->spc_ints = 0xff;/* clear off any pending */
-#if 0
- regs->spc_pctl = SPC_PCTL_LST_IE; /* useful only on 87033 */
-#else
- regs->spc_pctl = 0;
-#endif
- regs->spc_mbc = 0;
- SPC_TC_PUT(regs,0);
-
- if (quickly)
- return;
-
- /*
- * reset the scsi bus, the interrupt routine does the rest
- * or you can call spc_bus_reset().
- */
- regs->spc_scmd = SPC_SCMD_BUSRST|SPC_SCMD_C_STOP_X;/*?*/
-}
-
-/*
- * Operational functions
- */
-
-/*
- * Start a SCSI command on a target
- */
-spc_go(tgt, cmd_count, in_count, cmd_only)
- int cmd_count, in_count;
- target_info_t *tgt;
- boolean_t cmd_only;
-{
- spc_softc_t spc;
- register int s;
- boolean_t disconn;
- script_t scp;
- boolean_t (*handler)();
- int late;
-
- LOG(1,"\n\tgo");
-
- spc = (spc_softc_t)tgt->hw_state;
-
- /*
- * We cannot do real DMA.
- */
-#ifdef MACH_KERNEL
-#else /*MACH_KERNEL*/
- if (tgt->ior)
- fdma_map(&tgt->fdma, tgt->ior);
-#endif /*MACH_KERNEL*/
-
- if ((tgt->cur_cmd == SCSI_CMD_WRITE) ||
- (tgt->cur_cmd == SCSI_CMD_LONG_WRITE)){
- io_req_t ior = tgt->ior;
- register int len = ior->io_count;
-
- tgt->transient_state.out_count = len;
- tgt->transient_state.copy_count = 0;
-
- if (len < tgt->block_size) {
- gimmeabreak();
-
- /* avoid leaks */
-#if 0
-you`ll have to special case this
-#endif
- tgt->transient_state.out_count = tgt->block_size;
- }
- } else {
- tgt->transient_state.out_count = 0;
- tgt->transient_state.copy_count = 0;
- }
-
- tgt->transient_state.cmd_count = cmd_count;
-
- disconn =
- BGET(scsi_might_disconnect,(unsigned)tgt->masterno, tgt->target_id);
- disconn = disconn && (spc->ntargets > 1);
- disconn |=
- BGET(scsi_should_disconnect,(unsigned)tgt->masterno, tgt->target_id);
-
- /*
- * Setup target state
- */
- tgt->done = SCSI_RET_IN_PROGRESS;
-
- handler = (disconn) ? spc_err_disconn : spc_err_generic;
-
- /* determine wether or not to use the late forms of the scripts */
- late = cmd_only ? FALSE : (tgt->flags & TGT_DID_SYNCH);
-
- switch (tgt->cur_cmd) {
- case SCSI_CMD_READ:
- case SCSI_CMD_LONG_READ:
- LOG(0x13,"readop");
- scp = late ? spc_script_late_data_in : spc_script_data_in;
- break;
- case SCSI_CMD_WRITE:
- case SCSI_CMD_LONG_WRITE:
- LOG(0x14,"writeop");
- scp = late ? spc_script_late_data_out : spc_script_data_out;
- break;
- case SCSI_CMD_INQUIRY:
- /* This is likely the first thing out:
- do the synch neg if so */
- if (!cmd_only && ((tgt->flags&TGT_DID_SYNCH)==0)) {
- scp = spc_script_try_synch;
- tgt->flags |= TGT_TRY_SYNCH;
- break;
- }
- case SCSI_CMD_REQUEST_SENSE:
- case SCSI_CMD_MODE_SENSE:
- case SCSI_CMD_RECEIVE_DIAG_RESULTS:
- case SCSI_CMD_READ_CAPACITY:
- case SCSI_CMD_READ_BLOCK_LIMITS:
- case SCSI_CMD_READ_TOC:
- case SCSI_CMD_READ_SUBCH:
- case SCSI_CMD_READ_HEADER:
- case 0xc4: /* despised: SCSI_CMD_DEC_PLAYBACK_STATUS */
- case 0xc6: /* despised: SCSI_CMD_TOSHIBA_READ_SUBCH_Q */
- case 0xc7: /* despised: SCSI_CMD_TOSHIBA_READ_TOC_ENTRY */
- case 0xdd: /* despised: SCSI_CMD_NEC_READ_SUBCH_Q */
- case 0xde: /* despised: SCSI_CMD_NEC_READ_TOC */
- scp = late ? spc_script_late_data_in : spc_script_data_in;
- LOG(0x1c,"cmdop");
- LOG(0x80+tgt->cur_cmd,0);
- break;
- case SCSI_CMD_MODE_SELECT:
- case SCSI_CMD_REASSIGN_BLOCKS:
- case SCSI_CMD_FORMAT_UNIT:
- case 0xc9: /* vendor-spec: SCSI_CMD_DEC_PLAYBACK_CONTROL */
- tgt->transient_state.cmd_count = sizeof_scsi_command(tgt->cur_cmd);
- tgt->transient_state.out_count =
- cmd_count - tgt->transient_state.cmd_count;
- scp = late ? spc_script_late_data_out : spc_script_data_out;
- LOG(0x1c,"cmdop");
- LOG(0x80+tgt->cur_cmd,0);
- break;
- case SCSI_CMD_TEST_UNIT_READY:
- /*
- * Do the synch negotiation here, unless prohibited
- * or done already
- */
- if (tgt->flags & TGT_DID_SYNCH) {
- scp = late ? spc_script_late_cmd : spc_script_cmd;
- } else {
- scp = spc_script_try_synch;
- tgt->flags |= TGT_TRY_SYNCH;
- cmd_only = FALSE;
- }
- LOG(0x1c,"cmdop");
- LOG(0x80+tgt->cur_cmd,0);
- break;
- default:
- LOG(0x1c,"cmdop");
- LOG(0x80+tgt->cur_cmd,0);
- scp = late ? spc_script_late_cmd : spc_script_cmd;
- }
-
- tgt->transient_state.script = scp;
- tgt->transient_state.handler = handler;
- tgt->transient_state.identify = (cmd_only) ? 0xff :
- (disconn ? SCSI_IDENTIFY|SCSI_IFY_ENABLE_DISCONNECT :
- SCSI_IDENTIFY);
-
- if (in_count)
- tgt->transient_state.in_count =
- (in_count < tgt->block_size) ? tgt->block_size : in_count;
- else
- tgt->transient_state.in_count = 0;
- tgt->transient_state.dma_offset = 0;
-
- /*
- * See if another target is currently selected on
- * this SCSI bus, e.g. lock the spc structure.
- * Note that it is the strategy routine's job
- * to serialize ops on the same target as appropriate.
- */
-#if 0
-locking code here
-#endif
- s = splbio();
-
- if (spc->wd.nactive++ == 0)
- spc->wd.watchdog_state = SCSI_WD_ACTIVE;
-
- if (spc->state & SPC_STATE_BUSY) {
- /*
- * Queue up this target, note that this takes care
- * of proper FIFO scheduling of the scsi-bus.
- */
- LOG(3,"enqueue");
- enqueue_tail(&spc->waiting_targets, (queue_entry_t) tgt);
- } else {
- /*
- * It is down to at most two contenders now,
- * we will treat reconnections same as selections
- * and let the scsi-bus arbitration process decide.
- */
- spc->state |= SPC_STATE_BUSY;
- spc->next_target = tgt;
- spc_attempt_selection(spc);
- /*
- * Note that we might still lose arbitration..
- */
- }
- splx(s);
-}
-
-void spc_attempt_selection(spc)
- spc_softc_t spc;
-{
- target_info_t *tgt;
- spc_regmap_t *regs;
- register int cmd;
- int atn=0;
-
- /* This is about your select code */
-
- regs = spc->regs;
- tgt = spc->next_target;
-
- LOG(4,"select");
- LOG(0x80+tgt->target_id,0);
-
- /*
- * Init bus state variables and set registers.
- */
- spc->active_target = tgt;
-
- /* reselection pending ? */
- if ((regs->spc_phase & (SPC_BUS_BSY|SPC_BUS_SEL))
-#ifdef MIPS
- && (regs->spc_phase & (SPC_BUS_BSY|SPC_BUS_SEL))
- && (regs->spc_phase & (SPC_BUS_BSY|SPC_BUS_SEL))
-#endif
- )
- return;
-
- spc->script = tgt->transient_state.script;
- spc->error_handler = tgt->transient_state.handler;
- spc->done = SCSI_RET_IN_PROGRESS;
-
- spc->in_count = 0;
- spc->out_count = 0;
-
- cmd = SPC_SCMD_C_SELECT | SPC_SCMD_PROGRAMMED_X;
- if (tgt->flags & TGT_DID_SYNCH)
- {
- if (tgt->transient_state.identify != 0xff)
- atn = 1;
- }
- else
- if (tgt->flags & TGT_TRY_SYNCH)
- atn = 1;
-
-#if 0
- regs->spc_psns = SPC_DIAG_ENBL_XFER;
-#endif
-
- regs->spc_sctl = SPC_SCTL_ARB_EBL | SPC_SCTL_PAR_EBL |
- SPC_SCTL_RSEL_EBL | SPC_SCTL_IE;
-
-
- { int mask;
- mask = ~SPC_PCTL_BFREE_IE & regs->spc_pctl;
- regs->spc_pctl = mask;
- }
-
- regs->spc_temp = (1<<(spc->sc->initiator_id)) | (1<<(tgt->target_id));
-
- SPC_TC_PUT(regs,0xfa004);
-
- if (atn)
- {
- regs->spc_scmd = SPC_SCMD_C_ATN_S;
- /* delay 1us to avoid races */
- delay(1);
- }
-
- regs->spc_scmd = cmd;
- return;
-}
-
-/*
- * Interrupt routine
- * Take interrupts from the chip
- *
- * Implementation:
- * Move along the current command's script if
- * all is well, invoke error handler if not.
- */
-void spc_intr(unit)
-int unit;
-{
- register spc_softc_t spc;
- register script_t scp;
- register unsigned ints, psns, ssts;
- register spc_regmap_t *regs;
- boolean_t try_match;
-#if notyet
- extern boolean_t rz_use_mapped_interface;
-
- if (rz_use_mapped_interface)
- {
- SPC_intr(unit);
- return;
- }
-#endif
-
- spc = spc_softc[unit];
- regs = spc->regs;
-
- /* read the interrupt status register */
- ints = regs->spc_ints;
-
- LOG(5,"\n\tintr");
- LOG(0x80+ints,0);
-
-TR(ints);
-TRCHECK;
-
- if (ints & SPC_INTS_RESET)
- {
- /* does its own interrupt reset when ready */
- spc_bus_reset(spc);
- return;
- }
-
- /* we got an interrupt allright */
- if (spc->active_target)
- spc->wd.watchdog_state = SCSI_WD_ACTIVE;
-
-
- if (ints == 0)
- { /* no obvious cause */
- LOG(2,"SPURIOUS");
- gimmeabreak();
- return;
- }
-
-
- /* reset the interrupt */
- regs->spc_ints = ints;
-
- /* go get the phase, and status. We can't trust the
- phase until REQ is asserted in the psns. Only do
- this is we received a command complete or service
- required interrupt. Otherwise, just read them once
- and trust. */
-
-
-
- if (ints & (SPC_INTS_DONE|SPC_INTS_BUSREQ))
- while(1)
- {
- psns = regs->spc_psns;
- if (psns & SPC_BUS_REQ)
- break;
- delay(1); /* don't hog the bus */
- }
- else
- psns = regs->spc_psns;
-
- ssts = regs->spc_psns;
-
-TR(psns);
-TR(ssts);
-TRCHECK;
-
- if ((spc->state & SPC_STATE_TARGET) ||
- (ints & SPC_INTS_SELECTED))
- spc_target_intr(spc /**, ints, psns, ssts **/);
-
- scp = spc->script;
-
- if ((scp == 0) || (ints & SPC_INTS_RESELECTED))
- {
- gimmeabreak();
- spc_reconnect(spc, ints, psns, ssts);
- return;
- }
-
- if (SCRIPT_MATCH(psns) != scp->condition) {
- if (try_match = (*spc->error_handler)(spc, ints, psns, ssts)) {
- psns = regs->spc_psns;
- ssts = regs->spc_ssts;
- }
- } else
- try_match = TRUE;
-
-
- /* might have been side effected */
- scp = spc->script;
-
- if (try_match && (SCRIPT_MATCH(psns) == scp->condition)) {
- /*
- * Perform the appropriate operation,
- * then proceed
- */
- if ((*scp->action)(spc, ints, psns, ssts)) {
- /* might have been side effected */
- scp = spc->script;
- spc->script = scp + 1;
- }
- }
-}
-
-void spc_target_intr(spc)
- register spc_softc_t spc;
-{
- panic("SPC: TARGET MODE !!!\n");
-}
-
-/*
- * All the many little things that the interrupt
- * routine might switch to
- */
-boolean_t
-spc_issue_command(spc, ints, psns, ssts)
- spc_softc_t spc;
- int ints, psns, ssts;
-{
- register spc_regmap_t *regs = spc->regs;
-
- LOG(0x12, "cmd_issue");
- /* we have just done a select;
- Bus is in CMD phase;
- need to phase match */
- SPC_ACK(regs, SCSI_PHASE_CMD);
-
- return spc_data_out(regs, SCSI_PHASE_CMD,
- spc->active_target->transient_state.cmd_count,
- spc->active_target->cmd_ptr) ? FALSE : TRUE;
-}
-
-boolean_t
-spc_issue_ident_and_command(spc, ints, psns, ssts)
- spc_softc_t spc;
- int ints, psns, ssts;
-{
- register spc_regmap_t *regs = spc->regs;
-
- LOG(0x22, "ident_and_cmd");
- /* we have just done a select with atn Bus is in MSG_OUT phase;
- need to phase match */
- SPC_ACK(regs, SCSI_PHASE_MSG_OUT);
-
- spc_data_out(regs, SCSI_PHASE_MSG_OUT, 1,
- &spc->active_target->transient_state.identify);
-
- /* wait to go to command phase */
- SPC_WAIT_PHASE(SCSI_PHASE_CMD);
-
- /* ack */
- SPC_ACK(regs, SCSI_PHASE_CMD);
-
- /* should be a command complete intr pending. Eat it */
- if (regs->spc_ints != SPC_INTS_DONE)
- gimmeabreak();
- regs->spc_ints = SPC_INTS_DONE;
-
- /* spit */
- return spc_data_out(regs, SCSI_PHASE_CMD,
- spc->active_target->transient_state.cmd_count,
- spc->active_target->cmd_ptr) ? FALSE : TRUE;
-}
-
-
-boolean_t
-spc_end_transaction( spc, ints, psns, serr)
- register spc_softc_t spc;
- int ints, psns, serr;
-{
- register spc_regmap_t *regs = spc->regs;
- char cmc;
- int tmp;
-
- LOG(0x1f,"end_t");
-
- SPC_ACK(regs,SCSI_PHASE_MSG_IN /*,1*/);
-
- spc_data_in(regs, SCSI_PHASE_MSG_IN, 1, &cmc);
-
- if (cmc != SCSI_COMMAND_COMPLETE)
- printf("{T%x}", cmc);
-
- while (regs->spc_ints != (SPC_INTS_DONE|SPC_INTS_DISC));
-
- SPC_ACK(regs,SPC_PHASE_DISC);
-
- /* going to disconnect */
- regs->spc_pctl = ~SPC_PCTL_BFREE_IE & SPC_PHASE_DISC;
- /* regs->spc_scmd = 0; */
-
- /* clear all intr bits? */
- tmp = regs->spc_ints;
- regs->spc_ints = tmp;
-
-
- if (!spc_end(spc, ints, psns, serr))
- (void) spc_reconnect(spc, ints, psns, serr);
- return FALSE;
-}
-
-boolean_t
-spc_end( spc, ints, psns, serr)
- register spc_softc_t spc;
- int ints, psns, serr;
-{
- register target_info_t *tgt;
- register io_req_t ior;
- register spc_regmap_t *regs = spc->regs;
- int csr;
-
- LOG(6,"end");
-
- tgt = spc->active_target;
-
- if ((tgt->done = spc->done) == SCSI_RET_IN_PROGRESS)
- tgt->done = SCSI_RET_SUCCESS;
-
- spc->script = 0;
-
- if (spc->wd.nactive-- == 1)
- spc->wd.watchdog_state = SCSI_WD_INACTIVE;
-
- /* check reconnection not pending */
- csr = SPC_INTS_RESELECTED & regs->spc_ints;
- if (!csr)
- spc_release_bus(spc);
- else
- {
- spc->active_target = 0;
- /* spc->state &= ~SPC_STATE_BUSY; later */
- }
- if (ior = tgt->ior) {
-#ifdef MACH_KERNEL
-#else /*MACH_KERNEL*/
- fdma_unmap(&tgt->fdma, ior);
-#endif /*MACH_KERNEL*/
- LOG(0xA,"ops->restart");
- (*tgt->dev_ops->restart)( tgt, TRUE);
- if (csr)
- spc->state &= ~SPC_STATE_BUSY;
- }
-
- /* return not reselected */
- return (csr & SPC_INTS_RESELECTED) ? 0 : 1;
-}
-
-boolean_t
-spc_release_bus(spc)
- register spc_softc_t spc;
-{
- boolean_t ret = FALSE;
-
- LOG(9,"release");
-
- spc->script = 0;
-
- if (spc->state & SPC_STATE_COLLISION) {
-
- LOG(0xB,"collided");
- spc->state &= ~SPC_STATE_COLLISION;
- spc_attempt_selection(spc);
-
- } else if (queue_empty(&spc->waiting_targets)) {
-
- spc->state &= ~SPC_STATE_BUSY;
- spc->active_target = 0;
- ret = TRUE;
-
- } else {
-
- LOG(0xC,"dequeue");
- spc->next_target = (target_info_t *)
- dequeue_head(&spc->waiting_targets);
- spc_attempt_selection(spc);
- }
- return ret;
-}
-
-boolean_t
-spc_get_status( spc, ints, psns, serr)
- register spc_softc_t spc;
- int ints, psns, serr;
-{
- register spc_regmap_t *regs = spc->regs;
- scsi2_status_byte_t status;
- register target_info_t *tgt;
-
- LOG(0xD,"get_status");
-TRWRAP;
-
- spc->state &= ~SPC_STATE_DMA_IN;
-
- tgt = spc->active_target;
-
- SPC_ACK(regs,SCSI_PHASE_STATUS /*,1*/);
-
- spc_data_in(regs, SCSI_PHASE_STATUS, 1, &status.bits);
-
- if (status.st.scsi_status_code != SCSI_ST_GOOD) {
- scsi_error(spc->active_target, SCSI_ERR_STATUS, status.bits, 0);
- spc->done = (status.st.scsi_status_code == SCSI_ST_BUSY) ?
- SCSI_RET_RETRY : SCSI_RET_NEED_SENSE;
- } else
- spc->done = SCSI_RET_SUCCESS;
-
- return TRUE;
-}
-
-boolean_t
-spc_xfer_in( spc, ints, psns, ssts)
- register spc_softc_t spc;
- int ints, psns, ssts;
-{
- register target_info_t *tgt;
- register spc_regmap_t *regs = spc->regs;
- register int count;
- boolean_t advance_script = TRUE;
-
- LOG(0xE,"xfer_in");
-
- tgt = spc->active_target;
- spc->state |= SPC_STATE_DMA_IN;
-
- count = tgt->transient_state.in_count;
-
- SPC_ACK(regs, SCSI_PHASE_DATAI);
-
- if ((tgt->cur_cmd != SCSI_CMD_READ) &&
- (tgt->cur_cmd != SCSI_CMD_LONG_READ))
- spc_data_in(regs, SCSI_PHASE_DATAI, count, tgt->cmd_ptr);
- else
- {
- spc_data_in(regs, SCSI_PHASE_DATAI, count, tgt->ior->io_data);
- }
-
- return advance_script;
-}
-
-boolean_t
-spc_xfer_out( spc, ints, psns, ssts)
- register spc_softc_t spc;
- int ints, psns, ssts;
-{
- register spc_regmap_t *regs = spc->regs;
- register target_info_t *tgt;
- boolean_t advance_script = TRUE;
- int count = spc->out_count;
-
- LOG(0xF,"xfer_out");
-
- tgt = spc->active_target;
- spc->state &= ~SPC_STATE_DMA_IN;
-
- count = tgt->transient_state.out_count;
-
- SPC_ACK(regs, SCSI_PHASE_DATAO);
-
- if ((tgt->cur_cmd != SCSI_CMD_WRITE) &&
- (tgt->cur_cmd != SCSI_CMD_LONG_WRITE))
- spc_data_out(regs, SCSI_PHASE_DATAO, count,
- tgt->cmd_ptr + tgt->transient_state.cmd_count);
- else
- spc_data_out(regs, SCSI_PHASE_DATAO, count, tgt->ior->io_data);
-
- return advance_script;
-}
-
-/* disconnect-reconnect ops */
-
-/* get the message in via dma ?? */
-boolean_t
-spc_msg_in(spc, ints, psns, ssts)
- register spc_softc_t spc;
- int ints, psns, ssts;
-{
- register target_info_t *tgt;
-
- LOG(0x15,"msg_in");
- gimmeabreak();
-
- tgt = spc->active_target;
-
-#if 0
-You can do this by hand, just leave an interrupt pending at the end
-#endif
-
- /* We only really expect two bytes */
-#if 0
- SPC_PUT(dmar,sizeof(scsi_command_group_0));
- ....
-#endif
- return TRUE;
-}
-
-/* check the message is indeed a DISCONNECT */
-boolean_t
-spc_disconnect(spc, ints, psns, ssts)
- register spc_softc_t spc;
- int ints, psns, ssts;
-{
- register int len = 0;
- boolean_t ok = FALSE;
- register char *msgs = 0;
-
-
-/* SPC_TC_GET(dmar,len); */
- len = sizeof(scsi_command_group_0) - len;
-
-/* msgs = tgt->cmd_ptr; */ /* I think */
-
- if ((len == 0) || (len > 2) || msgs == 0)
- ok = FALSE;
- else {
- /* A SDP message preceeds it in non-completed READs */
- ok = ((msgs[0] == SCSI_DISCONNECT) || /* completed op */
- ((msgs[0] == SCSI_SAVE_DATA_POINTER) && /* incomplete */
- (msgs[1] == SCSI_DISCONNECT)));
- }
- if (!ok)
- printf("[tgt %d bad msg (%d): %x]",
- spc->active_target->target_id, len, *msgs);
-
- return TRUE;
-}
-
-/* save all relevant data, free the BUS */
-boolean_t
-spc_disconnected(spc, ints, psns, ssts)
- register spc_softc_t spc;
- int ints, psns, ssts;
-{
- register target_info_t *tgt;
-
-/* make sure reselects will work */
-
- LOG(0x16,"disconnected");
-
- spc_disconnect(spc,ints, psns, ssts);
-
- tgt = spc->active_target;
- tgt->flags |= TGT_DISCONNECTED;
- tgt->transient_state.handler = spc->error_handler;
- /* the rest has been saved in spc_err_disconn() */
-
- PRINT(("{D%d}", tgt->target_id));
-
- spc_release_bus(spc);
-
- return FALSE;
-}
-
-/* get reconnect message, restore BUS */
-boolean_t
-spc_reconnect(spc, ints, psns, ssts)
- register spc_softc_t spc;
- int ints, psns, ssts;
-{
-
- LOG(0x17,"reconnect");
-
- if (spc->wd.nactive == 0) {
- LOG(2,"SPURIOUS");
- return FALSE;
- }
-
-#if 0
-This is the 5380 code, for reference:
- spc_regmap_t *regs = spc->regs;
- register target_info_t *tgt;
- register int id;
- int msg;
-
-
- id = regs->spc_data;/*parity?*/
- /* xxx check our id is in there */
-
- id &= ~(1 << spc->sc->initiator_id);
- {
- register int i;
- for (i = 0; i < 8; i++)
- if (id & (1 << i)) break;
-if (i == 8) {printf("{P%x}", id);return;}
- id = i;
- }
- regs->spc_icmd = SPC_ICMD_BSY;
- while (regs->spc_bus_csr & SPC_BUS_SEL)
- ;
- regs->spc_icmd = 0;
- delay_1p2_us();
- while ( ((regs->spc_bus_csr & SPC_BUS_BSY) == 0) &&
- ((regs->spc_bus_csr & SPC_BUS_BSY) == 0) &&
- ((regs->spc_bus_csr & SPC_BUS_BSY) == 0))
- ;
-
- /* Now should wait for correct phase: REQ signals it */
- while ( ((regs->spc_bus_csr & SPC_BUS_REQ) == 0) &&
- ((regs->spc_bus_csr & SPC_BUS_REQ) == 0) &&
- ((regs->spc_bus_csr & SPC_BUS_REQ) == 0))
- ;
-
- regs->spc_mode |= SPC_MODE_MONBSY;
-
- /*
- * See if this reconnection collided with a selection attempt
- */
- if (spc->state & SPC_STATE_BUSY)
- spc->state |= SPC_STATE_COLLISION;
-
- spc->state |= SPC_STATE_BUSY;
-
- /* Get identify msg */
- bs = regs->spc_phase;
-if (SPC_CUR_PHASE(bs) != SCSI_PHASE_MSG_IN) gimmeabreak();
- SPC_ACK(regs,SCSI_PHASE_MSG_IN /*,1*/);
- msg = 0;
- spc_data_in(regs, SCSI_PHASE_MSG_IN, 1, &msg);
- regs->spc_mode = SPC_MODE_PAR_CHK|SPC_MODE_DMA|SPC_MODE_MONBSY;
-
- if (msg != SCSI_IDENTIFY)
- printf("{I%x %x}", id, msg);
-
- tgt = spc->sc->target[id];
- if (id > 7 || tgt == 0) panic("spc_reconnect");
-
- PRINT(("{R%d}", id));
- if (spc->state & SPC_STATE_COLLISION)
- PRINT(("[B %d-%d]", spc->active_target->target_id, id));
-
- LOG(0x80+id,0);
-
- spc->active_target = tgt;
- tgt->flags &= ~TGT_DISCONNECTED;
-
- spc->script = tgt->transient_state.script;
- spc->error_handler = tgt->transient_state.handler;
- spc->in_count = 0;
- spc->out_count = 0;
-
- /* Should get a phase mismatch when tgt changes phase */
-#endif
- return TRUE;
-}
-
-
-
-/* do the synch negotiation */
-boolean_t
-spc_dosynch( spc, ints, psns, ssts)
- register spc_softc_t spc;
- int ints, psns, ssts;
-{
- /*
- * Phase is MSG_OUT here, cmd has not been xferred
- */
- int len;
- register target_info_t *tgt;
- register spc_regmap_t *regs = spc->regs;
- unsigned char off;
- unsigned char p[6];
-
- LOG(0x11,"dosync");
-
- /* ATN still asserted */
- SPC_ACK(regs,SCSI_PHASE_MSG_OUT);
-
- tgt = spc->active_target;
-
- tgt->flags |= TGT_DID_SYNCH; /* only one chance */
- tgt->flags &= ~TGT_TRY_SYNCH;
-
- /*p = some scratch buffer, on the stack */
-
- p[0] = SCSI_IDENTIFY;
- p[1] = SCSI_EXTENDED_MESSAGE;
- p[2] = 3;
- p[3] = SCSI_SYNC_XFER_REQUEST;
- /* We cannot run synchronous */
-#define spc_to_scsi_period(x) 0x7
-#define scsi_period_to_spc(x) (x)
- off = 0;
- p[4] = spc_to_scsi_period(spc_min_period);
- p[5] = off;
-
- /* The transfer is started with ATN still set. The
- chip will automagically drop ATN before it transfers the
- last byte. Pretty neat. */
- spc_data_out(regs, SCSI_PHASE_MSG_OUT,
- sizeof(scsi_synch_xfer_req_t)+1, p);
-
- /* wait for phase change to status phase */
- SPC_WAIT_PHASE_VANISH(SCSI_PHASE_MSG_OUT);
-
-
- psns = regs->spc_phase;
-
- /* The standard sez there nothing else the target can do but.. */
- if (SPC_CUR_PHASE(psns) != SCSI_PHASE_MSG_IN)
- panic("spc_dosync");/* XXX put offline */
-
- /*
- msgin:
- */
- /* ack */
- SPC_ACK(regs,SCSI_PHASE_MSG_IN);
-
- /* clear any pending interrupts */
- regs->spc_ints = regs->spc_ints;
-
- /* get answer */
- len = sizeof(scsi_synch_xfer_req_t);
- len = spc_data_in(regs, SCSI_PHASE_MSG_IN, len, p);
-
- /* do not cancel the phase mismatch interrupt ! */
-
- /* look at the answer and see if we like it */
- if (len || (p[0] != SCSI_EXTENDED_MESSAGE)) {
- /* did not like it at all */
- printf(" did not like SYNCH xfer ");
- } else {
- /* will NOT do synch */
- printf(" but we cannot do SYNCH xfer ");
- tgt->sync_period = scsi_period_to_spc(p[3]);
- tgt->sync_offset = p[4];
- /* sanity */
- if (tgt->sync_offset != 0)
- printf(" ?OFFSET %x? ", tgt->sync_offset);
- }
-
- /* wait for phase change */
- SPC_WAIT_PHASE_VANISH(SCSI_PHASE_MSG_IN);
-
- psns = regs->spc_phase;
-
- /* phase should be command now */
- /* continue with simple command script */
- spc->error_handler = spc_err_generic;
- spc->script = spc_script_cmd;
-
-/* Make sure you get out right here, esp the script pointer and/or pending intr */
-
- if (SPC_CUR_PHASE(psns) == SCSI_PHASE_CMD )
- return FALSE;
-
- if (SPC_CUR_PHASE(psns) == SCSI_PHASE_STATUS ) /* jump to get_status */
- return TRUE; /* intr is pending */
-
- spc->script++;
- if (SPC_CUR_PHASE(psns) == SCSI_PHASE_MSG_IN )
- return TRUE;
-
- if ((psns & SPC_BUS_BSY) == 0) /* uhu? disconnected */
- return TRUE;
-
- gimmeabreak();
- return FALSE;
-}
-
-/*
- * The bus was reset
- */
-void spc_bus_reset(spc)
- register spc_softc_t spc;
-{
- register spc_regmap_t *regs = spc->regs;
-
- LOG(0x21,"bus_reset");
-
- /*
- * Clear bus descriptor
- */
- spc->script = 0;
- spc->error_handler = 0;
- spc->active_target = 0;
- spc->next_target = 0;
- spc->state = 0;
- queue_init(&spc->waiting_targets);
- spc->wd.nactive = 0;
- spc_reset(regs, TRUE);
-
- printf("spc%d: (%d) bus reset ", spc->sc->masterno, ++spc->wd.reset_count);
- delay(scsi_delay_after_reset); /* some targets take long to reset */
-
- if (spc->sc == 0) /* sanity */
- return;
-
- scsi_bus_was_reset(spc->sc);
-}
-
-/*
- * Error handlers
- */
-
-/*
- * Generic, default handler
- */
-boolean_t
-spc_err_generic(spc, ints, psns, ssts)
- register spc_softc_t spc;
- int ints, psns, ssts;
-{
- register spc_regmap_t *regs = spc->regs;
- LOG(0x10,"err_generic");
-
- if (ints & SPC_INTS_TIMEOUT) /* we timed out */
- if ((regs->spc_scmd & SPC_SCMD_CMDMASK) == SPC_SCMD_C_SELECT)
- {
- /* Powered off ? */
- if (spc->active_target->flags & TGT_FULLY_PROBED)
- {
- spc->active_target->flags = 0;
- LOG(0x1e,"Device Down");
- }
- spc->done = SCSI_RET_DEVICE_DOWN;
- spc_end(spc, ints, psns, ssts);
- return FALSE; /* don't retry - just report missing device */
- }
- else
- { /* timed out - but not on a select. What is going on? */
- gimmeabreak();
- }
-
- if (SPC_CUR_PHASE(psns) == SCSI_PHASE_STATUS)
- return spc_err_to_status(spc, ints, psns, ssts);
- gimmeabreak();
- return FALSE;
-}
-
-/*
- * Handle generic errors that are reported as
- * an unexpected change to STATUS phase
- */
-boolean_t
-spc_err_to_status(spc, ints, psns, ssts)
- register spc_softc_t spc;
- int ints, psns, ssts;
-{
- script_t scp = spc->script;
-
- LOG(0x20,"err_tostatus");
- while (SCSI_PHASE(scp->condition) != SCSI_PHASE_STATUS)
- scp++;
- spc->script = scp;
-#if 0
- /*
- * Normally, we would already be able to say the command
- * is in error, e.g. the tape had a filemark or something.
- * But in case we do disconnected mode WRITEs, it is quite
- * common that the following happens:
- * dma_out -> disconnect -> reconnect
- * and our script might expect at this point that the dma
- * had to be restarted (it didn't know it was completed
- * because the tape record is shorter than we asked for).
- * And in any event.. it is both correct and cleaner to
- * declare error iff the STATUS byte says so.
- */
- spc->done = SCSI_RET_NEED_SENSE;
-#endif
- return TRUE;
-}
-
-/*
- * Watch for a disconnection
- */
-boolean_t
-spc_err_disconn(spc, ints, psns, ssts)
- register spc_softc_t spc;
- int ints, psns, ssts;
-{
-#if 1
-/*
- * THIS ROUTINE CAN'T POSSIBLY WORK...
- * FOR EXAMPLE, THE VARIABLE 'xferred' IS NEVER INITIALIZED.
- */
- return FALSE;
-#else
- register spc_regmap_t *regs;
- register target_info_t *tgt;
- int xferred;
-
- LOG(0x18,"err_disconn");
-
- if (SPC_CUR_PHASE(ints) != SCSI_PHASE_MSG_IN)
- return spc_err_generic(spc, ints, psns, ssts);
-
- regs = spc->regs;
-
- tgt = spc->active_target;
-
- switch (SCSI_PHASE(spc->script->condition)) {
- case SCSI_PHASE_DATAO:
- LOG(0x1b,"+DATAO");
-/*updatecounters:*/
- tgt->transient_state.out_count -= xferred;
- assert(tgt->transient_state.out_count > 0);
- tgt->transient_state.dma_offset += xferred;
-
- tgt->transient_state.script = spc_script_data_out;
- break;
-
- case SCSI_PHASE_DATAI:
- LOG(0x19,"+DATAI");
-
-/*update counters: */
- assert(xferred > 0);
- tgt->transient_state.in_count -= xferred;
- assert(tgt->transient_state.in_count > 0);
- tgt->transient_state.dma_offset += xferred;
-
- tgt->transient_state.script = spc_script_data_in;
- break;
-
- case SCSI_PHASE_STATUS:
-
- if (spc->state & SPC_STATE_DMA_IN) {
-
- LOG(0x1a,"+STATUS+R");
-
-/*same as above.. */
- assert(xferred > 0);
- tgt->transient_state.in_count -= xferred;
-/* assert(tgt->transient_state.in_count > 0);*/
- tgt->transient_state.dma_offset += xferred;
-
- tgt->transient_state.script = spc_script_data_in;
- if (tgt->transient_state.in_count == 0)
- tgt->transient_state.script++;
-
- } else {
-
- LOG(0x1d,"+STATUS+W");
-
- if ((tgt->transient_state.out_count == spc->out_count)) {
- /* all done */
- tgt->transient_state.script = &spc_script_data_out[1];
- tgt->transient_state.out_count = 0;
- } else {
-
-/*.. */
- tgt->transient_state.out_count -= xferred;
- assert(tgt->transient_state.out_count > 0);
- tgt->transient_state.dma_offset += xferred;
-
- tgt->transient_state.script = spc_script_data_out;
- }
- spc->out_count = 0;
- }
- break;
- default:
- gimmeabreak();
- }
- /* spc->xxx = 0; */
-
-/* SPC_ACK(regs,SCSI_PHASE_MSG_IN); later */
- (void) spc_msg_in(spc, ints, psns, ssts);
-
- spc->script = spc_script_disconnect;
-
- return FALSE;
-#endif
-}
-
-/*
- * Watchdog
- *
- */
-void spc_reset_scsibus(spc)
- register spc_softc_t spc;
-{
- register target_info_t *tgt = spc->active_target;
- if (tgt) {
- int cnt = 0;
- /* SPC_TC_GET(spc->dmar,cnt); */
- log( LOG_KERN,
- "Target %d was active, cmd x%x in x%x out x%x Sin x%x Sou x%x dmalen x%x\n",
- tgt->target_id, tgt->cur_cmd,
- tgt->transient_state.in_count, tgt->transient_state.out_count,
- spc->in_count, spc->out_count, cnt);
- }
-#if 0
- spc->regs->.....
-#endif
- delay(25);
-}
-
-int SPC_ACK(regs, phase)
-register spc_regmap_t *regs;
-unsigned phase;
-{
- /* we want to switch into the specified phase -
-
- The calling routine should already dismissed
- any pending interrupts (spc_ints)
- */
-
- regs->spc_psns = 0;
- regs->spc_pctl = phase | SPC_PCTL_BFREE_IE;
- return 0;
-}
-#endif /*NSCSI > 0*/
-
-#endif 0
diff --git a/scsi/adapters/scsi_aha15.h b/scsi/adapters/scsi_aha15.h
deleted file mode 100644
index 52cd936..0000000
--- a/scsi/adapters/scsi_aha15.h
+++ /dev/null
@@ -1,347 +0,0 @@
-/*
- * Mach Operating System
- * Copyright (c) 1991,1990 Carnegie Mellon University
- * All Rights Reserved.
- *
- * Permission to use, copy, modify and distribute this software and its
- * documentation is hereby granted, provided that both the copyright
- * notice and this permission notice appear in all copies of the
- * software, derivative works or modified versions, and any portions
- * thereof, and that both notices appear in supporting documentation.
- *
- * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
- * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
- * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
- *
- * Carnegie Mellon requests users of this software to return to
- *
- * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
- * School of Computer Science
- * Carnegie Mellon University
- * Pittsburgh PA 15213-3890
- *
- * any improvements or extensions that they make and grant Carnegie Mellon
- * the rights to redistribute these changes.
- */
-/*
- * File: scsi_aha15.h
- * Author: Alessandro Forin, Carnegie Mellon University
- * Date: 6/91
- *
- * Definitions for the Adaptec AHA-15xx family
- * of Intelligent SCSI Host Adapter boards
- */
-
-#ifndef _SCSI_AHA15_H_
-#define _SCSI_AHA15_H_
-
-/*
- * Addresses/length in 24 bits
- *
- * BEWARE: your compiler must pack these correctly,
- * e.g. without gaps between two such contiguous structs
- * (GCC does)
- */
-typedef struct {
- unsigned char msb;
- unsigned char mid;
- unsigned char lsb;
-} aha_address_t;
-
-#define AHA_ADDRESS_SET(addr,val) {\
- (addr).msb = ((val) >> 16);\
- (addr).mid = ((val) >> 8);\
- (addr).lsb = (val) ;\
- }
-#define AHA_ADDRESS_GET(addr,val) {\
- (val) = ((addr).msb << 16) |\
- ((addr).mid << 8) |\
- ((addr).lsb ) ;\
- }
-
-#define aha_length_t aha_address_t
-#define AHA_LENGTH_SET AHA_ADDRESS_SET
-#define AHA_LENGTH_GET AHA_ADDRESS_GET
-
-/*
- * Register map
- */
-
-typedef struct {
- volatile unsigned char aha_status; /* r: Status Register */
-#define aha_ctl aha_status /* w: Control Register */
-
- volatile unsigned char aha_data; /* rw: Data Port */
-#define aha_cmd aha_data /* w: Command register */
-
- volatile unsigned char aha_intr; /* ro: Interrupt Register */
-} aha_regmap_t;
-
-/* ..but on the 386 I/O is not memory mapped */
-#define AHA_STATUS_PORT(port) ((port))
-#define AHA_CONTROL_PORT(port) ((port))
-#define AHA_COMMAND_PORT(port) ((port)+1)
-#define AHA_DATA_PORT(port) ((port)+1)
-#define AHA_INTR_PORT(port) ((port)+2)
-
-/* Status Register */
-#define AHA_CSR_CMD_ERR 0x01 /* Invalid command */
-#define AHA_CSR_xxx 0x02 /* undefined */
-#define AHA_CSR_DATAI_FULL 0x04 /* In-port full */
-#define AHA_CSR_DATAO_FULL 0x08 /* Out-port full */
-#define AHA_CSR_IDLE 0x10 /* doin nuthin */
-#define AHA_CSR_INIT_REQ 0x20 /* initialization required */
-#define AHA_CSR_DIAG_FAIL 0x40 /* selftest failed */
-#define AHA_CSR_SELF_TEST 0x80 /* selftesting */
-
-/* Control Register */
-#define AHA_CTL_xxx 0x0f /* undefined */
-#define AHA_CTL_SCSI_RST 0x10 /* reset SCSIbus */
-#define AHA_CTL_INTR_CLR 0x20 /* Clear interrupt reg */
-#define AHA_CTL_SOFT_RESET 0x40 /* Board only, no selftest */
-#define AHA_CTL_HARD_RESET 0x80 /* Full reset, and SCSIbus */
-
-/* Interrupt Flags register */
-#define AHA_INTR_MBI_FULL 0x01 /* scan the In mboxes */
-#define AHA_INTR_MBO_AVAIL 0x02 /* scan the Out mboxes */
-#define AHA_INTR_DONE 0x04 /* command complete */
-#define AHA_INTR_RST 0x08 /* saw a SCSIbus reset */
-#define AHA_INTR_xxx 0x70 /* undefined */
-#define AHA_INTR_PENDING 0x80 /* Any interrupt bit set */
-
-/*
- * Command register
- */
-#define AHA_CMD_NOP 0x00 /* */
-#define AHA_CMD_INIT 0x01 /* mbox initialization */
- /* 4 bytes follow: # of Out mboxes (x2->total), and
- msb, mid, lsb of mbox address */
-struct aha_init {
- unsigned char mb_count;
- aha_address_t mb_ptr;
-};
-#define AHA_CMD_START 0x02 /* start SCSI cmd */
-#define AHA_CMD_BIOS 0x03
-#define AHA_CMD_INQUIRY 0x04
- /* returns 4 bytes: */
-struct aha_inq {
- unsigned char board_id;
-# define AHA_BID_1540_B16 0x00
-# define AHA_BID_1540_B64 0x30
-# define AHA_BID_1540B 0x41
-# define AHA_BID_1640 0x42
-# define AHA_BID_1740 0x43
-# define AHA_BID_1542C 0x44
-# define AHA_BID_1542CF 0x45 /* BIOS v2.0x */
-
- unsigned char options;
-# define AHA_BOPT_STD 0x41 /* in 154x, standard model */
-
- unsigned char frl_1; /* rev level */
- unsigned char frl_2;
-};
-#define AHA_CMD_MBO_IE 0x05
- /* 1 byte follows: */
-# define AHA_MBO_DISABLE 0x00
-# define AHA_MBO_ENABLE 0x01
-
-#define AHA_CMD_SET_SELTO 0x06 /* select timeout */
- /* 4 bytes follow: */
-struct aha_selto {
- unsigned char enable;
- char xxx;
- unsigned char timeo_msb;
- unsigned char timeo_lsb;
-};
-#define AHA_CMD_SET_BUSON 0x07
- /* 1 byte value follows: 2..15 default 11 usecs */
-#define AHA_CMD_SET_BUSOFF 0x08
- /* 1 byte value follows: 1..64 default 4 usecs */
-#define AHA_CMD_SET_XSPEED 0x09
- /* 1 byte value follows: */
-# define AHA_DMASPEED_5Mb 0x00
-# define AHA_DMASPEED_7Mb 0x01
-# define AHA_DMASPEED_8Mb 0x02
-# define AHA_DMASPEED_10Mb 0x03
-# define AHA_DMASPEED_6Mb 0x04
- /* values in the range 80..ff encoded as follows:
- bit 7 on --> custom speed
- bits 6..4 read pulse width
- 0 100ns
- 1 150
- 2 200
- 3 250
- 4 300
- 5 350
- 6 400
- 7 450
- bit 3 strobe off time
- 0 100ns
- 1 150ns
- bits 2..0 write pulse width
- <same as read pulse>
- */
-#define AHA_CMD_FIND_DEVICES 0x0a
- /* returns 8 bytes, each one is a bitmask of the LUNs
- available for the given target ID */
-struct aha_devs {
- unsigned char tgt_luns[8];
-};
-#define AHA_CMD_GET_CONFIG 0x0b
- /* returns 3 bytes: */
-struct aha_conf {
- unsigned char dma_arbitration;/* bit N -> channel N */
- unsigned char intr_ch;/* bit N -> intr 9+N (but 13,16)*/
- unsigned char my_scsi_id; /* both of I and T role */
-};
-#define AHA_CMD_ENB_TGT_MODE 0x0c
- /* 2 bytes follow: */
-struct aha_tgt {
- unsigned char enable;
- unsigned char luns; /* bitmask */
-};
-
-#define AHA_CMD_GET_SETUP 0x0d
- /* 1 byte follows: allocation len (N) */
- /* returns N bytes, 17 significant: */
-struct aha_setup {
- BITFIELD_3( unsigned char,
- initiate_SDT:1,
- enable_parity:1,
- res:6);
- unsigned char xspeed; /* see above */
- unsigned char buson;
- unsigned char busoff;
- unsigned char n_mboxes;/* 0 if not initialized */
- aha_address_t mb_ptr; /* garbage if not inited */
- struct {
- BITFIELD_3( unsigned char,
- offset: 4,
- period: 3, /* 200 + 50 * N */
- negotiated: 1);
- } SDT_params[8];
- unsigned char no_disconnect; /* bitmask */
-};
-
-#define AHA_CMD_WRITE_CH2 0x1a
- /* 3 bytes (aha_address_t) follow for the buffer pointer */
-#define AHA_CMD_READ_CH2 0x1b
- /* 3 bytes (aha_address_t) follow for the buffer pointer */
-#define AHA_CMD_WRITE_FIFO 0x1c
- /* 3 bytes (aha_address_t) follow for the buffer pointer */
-#define AHA_CMD_READ_FIFO 0x1d
- /* 3 bytes (aha_address_t) follow for the buffer pointer */
-#define AHA_CMD_ECHO 0x1f
- /* 1 byte follows, which should then be read back */
-#define AHA_CMD_DIAG 0x20
-#define AHA_CMD_SET_OPT 0x21
- /* 2+ bytes follow: */
-struct aha_diag {
- unsigned char parmlen; /* bytes to follow */
- unsigned char no_disconnect; /* bitmask */
- /* rest is undefined */
-};
-
-#define AHA_EXT_BIOS 0x28 /* return extended bios info */
-#define AHA_MBX_ENABLE 0x29 /* enable mail box interface */
-struct aha_extbios {
- unsigned char flags; /* Bit 3 == 1 extended bios enabled */
- unsigned char mailboxlock; /* mail box lock code to unlock it */
-};
-
-/*
- * Command Control Block
- */
-typedef struct {
- unsigned char ccb_code;
-# define AHA_CCB_I_CMD 0x00
-# define AHA_CCB_T_CMD 0x01
-# define AHA_CCB_I_CMD_SG 0x02
-# define AHA_CCB_ICMD_R 0x03
-# define AHA_CCB_ICMD_SG_R 0x04
-# define AHA_CCB_BDEV_RST 0x81
- BITFIELD_4( unsigned char,
- ccb_lun:3,
- ccb_in:1,
- ccb_out:1,
- ccb_scsi_id:3);
- unsigned char ccb_cmd_len;
- unsigned char ccb_reqsns_len; /* if 1 no automatic reqsns*/
- aha_length_t ccb_datalen;
- aha_address_t ccb_dataptr;
- aha_address_t ccb_linkptr;
- unsigned char ccb_linkid;
- unsigned char ccb_hstatus;
-# define AHA_HST_SUCCESS 0x00
-# define AHA_HST_SEL_TIMEO 0x11
-# define AHA_HST_DATA_OVRUN 0x12
-# define AHA_HST_BAD_DISCONN 0x13
-# define AHA_HST_BAD_PHASE_SEQ 0x14
-# define AHA_HST_BAD_OPCODE 0x16
-# define AHA_HST_BAD_LINK_LUN 0x17
-# define AHA_HST_INVALID_TDIR 0x18
-# define AHA_HST_DUPLICATED_CCB 0x19
-# define AHA_HST_BAD_PARAM 0x1a
-
- scsi2_status_byte_t ccb_status;
- unsigned char ccb_xxx;
- unsigned char ccb_xxx1;
- scsi_command_group_5 ccb_scsi_cmd; /* cast as needed */
-} aha_ccb_t;
-
-/* For scatter/gather use a list of (len,ptr) segments, each field
- is 3 bytes (aha_address_t) long. Max 17 segments, min 1 */
-
-/*
- * Ring descriptor, aka Mailbox
- */
-typedef union {
-
- struct {
- volatile unsigned char mb_cmd; /* Out mbox */
-# define mb_status mb_cmd /* In mbox */
-
- aha_address_t mb_ptr;
-#define AHA_MB_SET_PTR(mbx,val) AHA_ADDRESS_SET((mbx)->mb.mb_ptr,(val))
-#define AHA_MB_GET_PTR(mbx,val) AHA_ADDRESS_GET((mbx)->mb.mb_ptr,(val))
-
- } mb;
-
- struct { /* ccb required In mbox */
- volatile unsigned char mb_cmd;
- BITFIELD_4( unsigned char,
- mb_lun : 3,
- mb_isa_send : 1,
- mb_isa_recv : 1,
- mb_initiator_id : 3);
- unsigned char mb_data_len_msb;
- unsigned char mb_data_len_mid;
- } mbt;
-
- unsigned int bits; /* quick access */
-
-} aha_mbox_t;
-
-/* Out mbox, values for the mb_cmd field */
-#define AHA_MBO_FREE 0x00
-#define AHA_MBO_START 0x01
-#define AHA_MBO_ABORT 0x02
-
-/* In mbox, values for the mb_status field */
-#define AHA_MBI_FREE 0x00
-#define AHA_MBI_SUCCESS 0x01
-#define AHA_MBI_ABORTED 0x02
-#define AHA_MBI_NOT_FOUND 0x03
-#define AHA_MBI_ERROR 0x04
-#define AHA_MBI_NEED_CCB 0x10
-
-/*
- * Scatter/gather segment lists
- */
-typedef struct {
- aha_length_t len;
- aha_address_t ptr;
-} aha_seglist_t;
-
-#define AHA_MAX_SEGLIST 17 /* which means max 64Kb */
-#endif /*_SCSI_AHA15_H_*/
diff --git a/scsi/adapters/scsi_aha15_hdw.c b/scsi/adapters/scsi_aha15_hdw.c
deleted file mode 100644
index 5514bc5..0000000
--- a/scsi/adapters/scsi_aha15_hdw.c
+++ /dev/null
@@ -1,1467 +0,0 @@
-/*
- * Mach Operating System
- * Copyright (c) 1993,1992,1991,1990 Carnegie Mellon University
- * All Rights Reserved.
- *
- * Permission to use, copy, modify and distribute this software and its
- * documentation is hereby granted, provided that both the copyright
- * notice and this permission notice appear in all copies of the
- * software, derivative works or modified versions, and any portions
- * thereof, and that both notices appear in supporting documentation.
- *
- * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
- * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
- * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
- *
- * Carnegie Mellon requests users of this software to return to
- *
- * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
- * School of Computer Science
- * Carnegie Mellon University
- * Pittsburgh PA 15213-3890
- *
- * any improvements or extensions that they make and grant Carnegie Mellon
- * the rights to redistribute these changes.
- */
-/*
- * File: scsi_aha15_hdw.c
- * Author: Alessandro Forin, Carnegie Mellon University
- * Date: 6/91
- *
- * Bottom layer of the SCSI driver: chip-dependent functions
- *
- * This file contains the code that is specific to the Adaptec
- * AHA-15xx family of Intelligent SCSI Host Adapter boards:
- * probing, start operation, and interrupt routine.
- */
-
-/*
- * Since the board is "Intelligent" we do not need scripts like
- * other simpler HBAs. Maybe.
- */
-#include <cpus.h>
-#include <platforms.h>
-
-#include <aha.h>
-#if NAHA > 0
-
-#include <mach/std_types.h>
-#include <machine/machspl.h>
-#include <sys/types.h>
-#include <chips/busses.h>
-#include <scsi/compat_30.h>
-
-/* #include <sys/syslog.h> */
-
-#include <scsi/scsi.h>
-#include <scsi/scsi2.h>
-#include <scsi/scsi_defs.h>
-
-#include <scsi/adapters/scsi_aha15.h>
-
-#ifdef AT386
-#define MACHINE_PGBYTES I386_PGBYTES
-#define MAPPABLE 0
-#define gimmeabreak() asm("int3")
-#include <i386/pio.h> /* inlining of outb and inb */
-#endif /*AT386*/
-
-#ifdef CBUS /* For the Corollary machine, physical */
-#include <i386at/mp/mp.h>
-#include <cbus/cbus.h>
-
-#define aha_cbus_window transient_state.hba_dep[0]
- /* must use windows for phys addresses */
- /* greater than 16 megs */
-
-#define kvtoAT cbus_kvtoAT
-#else /* CBUS */
-#define kvtoAT kvtophys
-#endif /* CBUS */
-
-#ifndef MACHINE_PGBYTES /* cross compile check */
-#define MACHINE_PGBYTES 0x1000
-#define MAPPABLE 1
-#define gimmeabreak() Debugger("gimmeabreak");
-#endif
-
-/*
- * Data structures: ring, ccbs, a per target buffer
- */
-
-#define AHA_NMBOXES 2 /* no need for more, I think */
-struct aha_mb_ctl {
- aha_mbox_t omb[AHA_NMBOXES];
- aha_mbox_t imb[AHA_NMBOXES];
- unsigned char iidx, oidx; /* roving ptrs into */
-};
-#define next_mbx_idx(i) ((((i)+1)==AHA_NMBOXES)?0:((i)+1))
-
-#define AHA_NCCB 8 /* for now */
-struct aha_ccb_raw {
- target_info_t *active_target;
- aha_ccb_t ccb;
- char buffer[256]; /* separate out this ? */
-};
-#define rccb_to_cmdptr(rccb) ((char*)&((rccb)->ccb.ccb_scsi_cmd))
-
-/* forward decls */
-int aha_reset_scsibus();
-boolean_t aha_probe_target();
-
-/*
- * State descriptor for this layer. There is one such structure
- * per (enabled) board
- */
-struct aha_softc {
- watchdog_t wd;
- decl_simple_lock_data(, aha_lock)
- unsigned int port; /* I/O port */
-
- int ntargets; /* how many alive on this scsibus */
-
- scsi_softc_t *sc; /* HBA-indep info */
-
- struct aha_mb_ctl mb; /* mailbox structures */
-
- /* This chicanery is for mapping back the phys address
- of a CCB (which we get in an MBI) to its virtual */
- /* [we could use phystokv(), but it isn't standard] */
- vm_offset_t I_hold_my_phys_address;
- struct aha_ccb_raw aha_ccbs[AHA_NCCB];
-
-} aha_softc_data[NAHA];
-
-typedef struct aha_softc *aha_softc_t;
-
-aha_softc_t aha_softc[NAHA];
-
-struct aha_ccb_raw *
-mb_to_rccb(aha, mbi)
- aha_softc_t aha;
- aha_mbox_t mbi;
-{
- vm_offset_t addr;
-
- AHA_MB_GET_PTR(&mbi,addr); /* phys address of ccb */
-
- /* make virtual */
- addr = ((vm_offset_t)&aha->I_hold_my_phys_address) +
- (addr - aha->I_hold_my_phys_address);
-
- /* adjust by proper offset to get base */
- addr -= (vm_offset_t)&(((struct aha_ccb_raw *)0)->ccb);
-
- return (struct aha_ccb_raw *)addr;
-}
-
-target_info_t *
-aha_tgt_alloc(aha, id, sns_len, tgt)
- aha_softc_t aha;
- target_info_t *tgt;
-{
- struct aha_ccb_raw *rccb;
-
- aha->ntargets++;
-
- if (tgt == 0)
- tgt = scsi_slave_alloc(aha - aha_softc_data, id, aha);
-
- rccb = &(aha->aha_ccbs[id]);
- rccb->ccb.ccb_reqsns_len = sns_len;
- tgt->cmd_ptr = rccb_to_cmdptr(rccb);
- tgt->dma_ptr = 0;
-#ifdef CBUS
- tgt->aha_cbus_window = 0;
-#endif /* CBUS */
- return tgt;
-}
-
-/*
- * Synch xfer timing conversions
- */
-#define aha_to_scsi_period(a) ((200 + ((a) * 50)) >> 2)
-#define scsi_period_to_aha(p) ((((p) << 2) - 200) / 50)
-
-/*
- * Definition of the controller for the auto-configuration program.
- */
-
-/* DOCUMENTATION */
-/* base ports can be:
- 0x334, 0x330 (default), 0x234, 0x230, 0x134, 0x130
- possible interrupt channels are:
- 9, 10, 11 (default), 12, 14, 15
- DMA channels can be:
- 7, 6, 5 (default), 0
-/* DOCUMENTATION */
-
-int aha_probe(), scsi_slave(), aha_go(), aha_intr();
-void scsi_attach();
-
-vm_offset_t aha_std[NAHA] = { 0 };
-struct bus_device *aha_dinfo[NAHA*8];
-struct bus_ctlr *aha_minfo[NAHA];
-struct bus_driver aha_driver =
- { aha_probe, scsi_slave, scsi_attach, aha_go, aha_std, "rz", aha_dinfo,
- "ahac", aha_minfo, BUS_INTR_B4_PROBE};
-
-#define DEBUG 1
-#if DEBUG
-
-#define PRINT(x) if (scsi_debug) printf x
-
-aha_state(port)
-{
- register unsigned char st, intr;
-
- if (port == 0)
- port = 0x330;
- st = inb(AHA_STATUS_PORT(port));
- intr = inb(AHA_INTR_PORT(port));
-
- printf("status %x intr %x\n", st, intr);
- return 0;
-}
-
-aha_target_state(tgt)
- target_info_t *tgt;
-{
- if (tgt == 0)
- tgt = aha_softc[0]->sc->target[0];
- if (tgt == 0)
- return 0;
- printf("fl %x dma %X+%x cmd %x@%X id %x per %x off %x ior %X ret %X\n",
- tgt->flags, tgt->dma_ptr, tgt->transient_state.dma_offset, tgt->cur_cmd,
- tgt->cmd_ptr, tgt->target_id, tgt->sync_period, tgt->sync_offset,
- tgt->ior, tgt->done);
-
- return 0;
-}
-
-aha_all_targets(unit)
-{
- int i;
- target_info_t *tgt;
- for (i = 0; i < 8; i++) {
- tgt = aha_softc[unit]->sc->target[i];
- if (tgt)
- aha_target_state(tgt);
- }
-}
-
-#define TRMAX 200
-int tr[TRMAX+3];
-int trpt, trpthi;
-#define TR(x) tr[trpt++] = x
-#define TRWRAP trpthi = trpt; trpt = 0;
-#define TRCHECK if (trpt > TRMAX) {TRWRAP}
-
-#define TRACE
-
-#ifdef TRACE
-
-#define LOGSIZE 256
-#define LOG_KERN 0<<3 /* from syslog.h */
-
-int aha_logpt;
-char aha_log[LOGSIZE];
-
-#define MAXLOG_VALUE 0x1e
-struct {
- char *name;
- unsigned int count;
-} logtbl[MAXLOG_VALUE];
-
-static LOG(e,f)
- char *f;
-{
- aha_log[aha_logpt++] = (e);
- if (aha_logpt == LOGSIZE) aha_logpt = 0;
- if ((e) < MAXLOG_VALUE) {
- logtbl[(e)].name = (f);
- logtbl[(e)].count++;
- }
-}
-
-aha_print_log(skip)
- int skip;
-{
- register int i, j;
- register unsigned char c;
-
- for (i = 0, j = aha_logpt; i < LOGSIZE; i++) {
- c = aha_log[j];
- if (++j == LOGSIZE) j = 0;
- if (skip-- > 0)
- continue;
- if (c < MAXLOG_VALUE)
- printf(" %s", logtbl[c].name);
- else
- printf("-%x", c & 0x7f);
- }
- return 0;
-}
-
-aha_print_stat()
-{
- register int i;
- register char *p;
- for (i = 0; i < MAXLOG_VALUE; i++) {
- if (p = logtbl[i].name)
- printf("%d %s\n", logtbl[i].count, p);
- }
-}
-
-#else /*TRACE*/
-#define LOG(e,f)
-#define LOGSIZE
-#endif /*TRACE*/
-
-#else /*DEBUG*/
-#define PRINT(x)
-#define LOG(e,f)
-#define LOGSIZE
-#define TRCHECK
-#define TR(a)
-
-#endif /*DEBUG*/
-
-/* Utility functions at end */
-
-
-/*
- * Probe/Slave/Attach functions
- */
-
-int aha_dotarget = 1; /* somehow on some boards this is trouble */
-
-/*
- * Probe routine:
- * Should find out (a) if the controller is
- * present and (b) which/where slaves are present.
- *
- * Implementation:
- * Just ask the board to do it
- */
-aha_probe(port, ui)
- register port;
- struct bus_ctlr *ui;
-{
- int unit = ui->unit;
- aha_softc_t aha = &aha_softc_data[unit];
- int target_id;
- scsi_softc_t *sc;
- spl_t s;
- boolean_t did_banner = FALSE;
- struct aha_devs installed;
- struct aha_conf conf;
-
- /* No interrupts yet */
- s = splbio();
-
- /*
- * We should be called with a sensible port, but you never know.
- * Send an echo command and see that we get it back properly
- */
- {
- register unsigned char st;
-
- st = inb(AHA_STATUS_PORT(port));
-
- /*
- * There is no board reset in case of reboot with
- * no power-on/power-off sequence. Test it and do
- * the reset if necessary.
- */
-
- if (!(st & AHA_CSR_INIT_REQ)) {
- outb(AHA_CONTROL_PORT(port),
- AHA_CTL_SOFT_RESET|AHA_CTL_HARD_RESET);
- while ((st = inb(AHA_STATUS_PORT(port))) &
- AHA_CSR_SELF_TEST);
- }
- if ((st & AHA_CSR_DATAO_FULL) ||
- !(st & AHA_CSR_INIT_REQ))
- goto fail;
-
- outb(AHA_COMMAND_PORT(port), AHA_CMD_ECHO);
- delay(1000);/*?*/
- st = inb(AHA_STATUS_PORT(port));
- if (st & (AHA_CSR_CMD_ERR|AHA_CSR_DATAO_FULL))
- goto fail;
-
- outb(AHA_COMMAND_PORT(port), 0x5e);
- delay(1000);
-
- st = inb(AHA_STATUS_PORT(port));
- if ((st & AHA_CSR_CMD_ERR) ||
- ((st & AHA_CSR_DATAI_FULL) == 0))
- goto fail;
-
- st = inb(AHA_DATA_PORT(port));
- if (st != 0x5e) {
-fail: splx(s);
- return 0;
- }
- /*
- * augment test with check for echoing inverse and with
- * test for enhanced adapter with standard ports enabled.
- */
-
- /* Check that 0xa1 echoed as well as 0x5e */
-
- outb(AHA_COMMAND_PORT(port), AHA_CMD_ECHO);
- delay(1000);/*?*/
- st = inb(AHA_STATUS_PORT(port));
- if (st & (AHA_CSR_CMD_ERR|AHA_CSR_DATAO_FULL))
- goto fail;
-
- outb(AHA_COMMAND_PORT(port), 0xa1);
- delay(1000);
-
- st = inb(AHA_STATUS_PORT(port));
- if ((st & AHA_CSR_CMD_ERR) ||
- ((st & AHA_CSR_DATAI_FULL) == 0))
- goto fail;
-
- st = inb(AHA_DATA_PORT(port));
- if (st != 0xa1)
- goto fail ;
-
- { /* Check that port isn't 174x in enhanced mode
- with standard mode ports enabled. This should be
- ignored because it will be caught and correctly
- handled by eaha_probe(). See TRM4-11..13.
- dph
- */
- unsigned z ;
- static unsigned port_table[] =
- {0,0,0x130,0x134,0x230,0x234,0x330,0x334};
- for (z= 0x1000; z<= 0xF000; z+= 0x1000)
- if (inb(z+0xC80) == 0x04 &&
- inb(z+0xC81) == 0x90 &&
- inb(z+0xCC0) & 0x80 == 0x80 &&
- port_table [inb(z+0xCC0) & 0x07] == port)
- goto fail ;
- }
- outb(AHA_CONTROL_PORT(port), AHA_CTL_INTR_CLR);
- }
-
-#if MAPPABLE
- /* Mappable version side */
- AHA_probe(port, ui);
-#endif /*MAPPABLE*/
-
- /*
- * Initialize hw descriptor, cache some pointers
- */
- aha_softc[unit] = aha;
- aha->port = port;
-
- sc = scsi_master_alloc(unit, aha);
- aha->sc = sc;
-
- simple_lock_init(&aha->aha_lock);
- sc->go = aha_go;
- sc->watchdog = scsi_watchdog;
- sc->probe = aha_probe_target;
- aha->wd.reset = aha_reset_scsibus;
-
- /* Stupid limitation, no way around it */
- sc->max_dma_data = (AHA_MAX_SEGLIST-1) * MACHINE_PGBYTES;
-
-
- /* XXX
- * I'm not sure how much use this bit of code is really.
- * On the 1542CF we don't really want to try and initialize
- * the mailboxes before unlocking them in any case, and
- * resetting the card is done above.
- */
-#if 0
-#if 0
- /*
- * Reset board.
- */
- aha_reset(port, TRUE);
-#else
- /*
- * Initialize mailboxes
- */
- aha_init_1(aha);
-#endif
-#endif
-
- /*
- * Who are we ?
- */
- {
- struct aha_inq inq;
- struct aha_extbios extbios;
- char *id;
-
- aha_command(port, AHA_CMD_INQUIRY, 0, 0, &inq, sizeof(inq), TRUE);
-
- switch (inq.board_id) {
- case AHA_BID_1540_B16:
- case AHA_BID_1540_B64:
- id = "1540"; break;
- case AHA_BID_1540B:
- id = "1540B/1542B"; break;
- case AHA_BID_1640:
- id = "1640"; break;
- case AHA_BID_1740:
- id = "1740 Unsupported!!"; break;
- case AHA_BID_1542C:
- id = "1542C"; aha_dotarget = 0; break;
- case AHA_BID_1542CF:
- id = "1542CF"; break;
- default:
- id = 0; break;
- }
-
- printf("Adaptec %s [id %x], rev %c%c, options x%x\n",
- id ? id : "Board",
- inq.board_id, inq.frl_1, inq.frl_2, inq.options);
-
- /*
- * If we are a 1542C or 1542CF disable the extended bios
- * so that the mailbox interface is unlocked.
- * No need to check the extended bios flags as some of the
- * extensions that cause us problems are not flagged in
- * that byte.
- */
- if (inq.board_id == 0x44 || inq.board_id == 0x45) {
- aha_command(port, AHA_EXT_BIOS, 0, 0, &extbios,
- sizeof(extbios), TRUE);
-#ifdef AHADEBUG
- printf("aha: extended bios flags 0x%x\n", extbios.flags);
- printf("aha: mailboxlock 0x%x\n", extbios.mblock);
-#endif /* AHADEBUG */
-
- printf("aha: 1542C/CF detected, unlocking mailbox\n");
-
- /* XXX - This sends the mailboxlock code out to the
- * controller. We need to output a 0, then the
- * code...so since we don't care about the flags
- * anyway, we just zero out that field and re-use
- * the struct.
- */
- extbios.flags = 0;
- aha_command(port, AHA_MBX_ENABLE, &extbios,
- sizeof(extbios), 0, 0, TRUE);
- }
-
- }
-doconf:
- /*
- * Readin conf data
- */
- aha_command(port, AHA_CMD_GET_CONFIG, 0, 0, &conf, sizeof(conf), TRUE);
-
- {
- unsigned char args;
-
- /*
- * Change the bus on/off times to not clash with
- * other dma users.
- */
- args = 7;
- aha_command(port, AHA_CMD_SET_BUSON, &args, 1, 0, 0, TRUE);
- args = 5;
- aha_command(port, AHA_CMD_SET_BUSOFF, &args, 1, 0, 0, TRUE);
- }
-
- /* XXX - This is _REALLY_ sickening. */
- /*
- * Set up the DMA channel we'll be using.
- */
- {
- register int d, i;
- static struct {
- unsigned char port;
- unsigned char init_data;
- } aha_dma_init[8][2] = {
- {{0x0b,0x0c}, {0x0a,0x00}}, /* channel 0 */
- {{0,0},{0,0}},
- {{0,0},{0,0}},
- {{0,0},{0,0}},
- {{0,0},{0,0}},
- {{0xd6,0xc1}, {0xd4,0x01}}, /* channel 5 (def) */
- {{0xd6,0xc2}, {0xd4,0x02}}, /* channel 6 */
- {{0xd6,0xc3}, {0xd4,0x03}} /* channel 7 */
- };
-
-
- for (i = 0; i < 8; i++)
- if ((1 << i) & conf.intr_ch) break;
- i += 9;
-
-#if there_was_a_way
- /*
- * On second unit, avoid clashes with first
- */
- if ((unit > 0) && (ui->sysdep1 != i)) {
- printf("Reprogramming irq and dma ch..\n");
- ....
- goto doconf;
- }
-#endif
-
- /*
- * Initialize the DMA controller viz the channel we'll use
- */
- for (d = 0; d < 8; d++)
- if ((1 << d) & conf.dma_arbitration) break;
-
- outb(aha_dma_init[d][0].port, aha_dma_init[d][0].init_data);
- outb(aha_dma_init[d][1].port, aha_dma_init[d][1].init_data);
-
- /* make mapping phys->virt possible for CCBs */
- aha->I_hold_my_phys_address =
- kvtoAT((vm_offset_t)&aha->I_hold_my_phys_address);
-
- /*
- * Our SCSI ID. (xxx) On some boards this is SW programmable.
- */
- sc->initiator_id = conf.my_scsi_id;
-
- printf("%s%d: [dma ch %d intr ch %d] my SCSI id is %d",
- ui->name, unit, d, i, sc->initiator_id);
-
- /* Interrupt vector setup */
- ui->sysdep1 = i;
- take_ctlr_irq(ui);
- }
-
- /*
- * More initializations
- */
- {
- register target_info_t *tgt;
-
- aha_init(aha);
-
- /* allocate a desc for tgt mode role */
- tgt = aha_tgt_alloc(aha, sc->initiator_id, 1, 0);
- sccpu_new_initiator(tgt, tgt); /* self */
-
- }
-
- /* Now we could take interrupts, BUT we do not want to
- be selected as targets by some other host just yet */
-
- /*
- * For all possible targets, see if there is one and allocate
- * a descriptor for it if it is there.
- * This includes ourselves, when acting as target
- */
- aha_command( port, AHA_CMD_FIND_DEVICES, 0, 0, &installed, sizeof(installed), TRUE);
- for (target_id = 0; target_id < 8; target_id++) {
-
- if (target_id == sc->initiator_id) /* done already */
- continue;
-
- if (installed.tgt_luns[target_id] == 0)
- continue;
-
- printf(",%s%d", did_banner++ ? " " : " target(s) at ",
- target_id);
-
- /* Normally, only LUN 0 */
- if (installed.tgt_luns[target_id] != 1)
- printf("(%x)", installed.tgt_luns[target_id]);
- /*
- * Found a target
- */
- (void) aha_tgt_alloc(aha, target_id, 1/*no REQSNS*/, 0);
-
- }
- printf(".\n");
- splx(s);
-
- return 1;
-}
-
-boolean_t
-aha_probe_target(tgt, ior)
- target_info_t *tgt;
- io_req_t ior;
-{
- aha_softc_t aha = aha_softc[tgt->masterno];
- boolean_t newlywed;
-
- newlywed = (tgt->cmd_ptr == 0);
- if (newlywed) {
- /* desc was allocated afresh */
- (void) aha_tgt_alloc(aha,tgt->target_id, 1/*no REQSNS*/, tgt);
- }
-
- if (scsi_inquiry(tgt, SCSI_INQ_STD_DATA) == SCSI_RET_DEVICE_DOWN)
- return FALSE;
-
- tgt->flags = TGT_ALIVE;
- return TRUE;
-}
-
-aha_reset(port, quick)
-{
- register unsigned char st;
-
- /*
- * Reset board and wait till done
- */
- outb(AHA_CONTROL_PORT(port), AHA_CTL_SOFT_RESET);
- do {
- delay(25);
- st = inb(AHA_STATUS_PORT(port));
- } while ((st & (AHA_CSR_IDLE|AHA_CSR_INIT_REQ)) == 0);
-
- if (quick) return;
-
- /*
- * reset the scsi bus. Does NOT generate an interrupt (bozos)
- */
- outb(AHA_CONTROL_PORT(port), AHA_CTL_SCSI_RST);
-}
-
-aha_init_1(aha)
- aha_softc_t aha;
-{
- struct aha_init a;
- vm_offset_t phys;
-
- bzero(&aha->mb, sizeof(aha->mb)); /* also means all free */
- a.mb_count = AHA_NMBOXES;
- phys = kvtoAT((vm_offset_t)&aha->mb);
- AHA_ADDRESS_SET(a.mb_ptr, phys);
- aha_command(aha->port, AHA_CMD_INIT, &a, sizeof(a), 0, 0, TRUE);
-}
-
-aha_init_2(port)
-{
- unsigned char disable = AHA_MBO_DISABLE;
- struct aha_tgt role;
-
- /* Disable MBO available interrupt */
- aha_command(port, AHA_CMD_MBO_IE, &disable, 1, 0,0, FALSE);
-
- if (aha_dotarget) {
- /* Enable target mode role */
- role.enable = 1;
- role.luns = 1; /* only LUN 0 */
- aha_command(port, AHA_CMD_ENB_TGT_MODE, &role, sizeof(role), 0, 0, TRUE);
- }
-}
-
-aha_init(aha)
- aha_softc_t aha;
-{
- aha_init_1(aha);
- aha_init_2(aha->port);
-}
-
-/*
- * Operational functions
- */
-
-/*
- * Start a SCSI command on a target
- */
-aha_go(tgt, cmd_count, in_count, cmd_only)
- target_info_t *tgt;
- boolean_t cmd_only;
-{
- aha_softc_t aha;
- spl_t s;
- struct aha_ccb_raw *rccb;
- int len;
- vm_offset_t virt, phys;
-
-#if CBUS
- at386_io_lock_state();
-#endif
-
- LOG(1,"go");
-
- aha = (aha_softc_t)tgt->hw_state;
-
-/* XXX delay the handling of the ccb till later */
- rccb = &(aha->aha_ccbs[tgt->target_id]);
- rccb->active_target = tgt;
-
- /*
- * We can do real DMA.
- */
-/* tgt->transient_state.copy_count = 0; unused */
-/* tgt->transient_state.dma_offset = 0; unused */
-
- tgt->transient_state.cmd_count = cmd_count;
-
- if ((tgt->cur_cmd == SCSI_CMD_WRITE) ||
- (tgt->cur_cmd == SCSI_CMD_LONG_WRITE)){
- io_req_t ior = tgt->ior;
- register int len = ior->io_count;
-
- tgt->transient_state.out_count = len;
-
- /* How do we avoid leaks here ? Trust the board
- will do zero-padding, for now. XXX CHECKME */
-#if 0
- if (len < tgt->block_size) {
- bzero(to + len, tgt->block_size - len);
- len = tgt->block_size;
- tgt->transient_state.out_count = len;
- }
-#endif
- } else {
- tgt->transient_state.out_count = 0;
- }
-
- /* See above for in_count < block_size */
- tgt->transient_state.in_count = in_count;
-
- /*
- * Setup CCB state
- */
- tgt->done = SCSI_RET_IN_PROGRESS;
-
- switch (tgt->cur_cmd) {
- case SCSI_CMD_READ:
- case SCSI_CMD_LONG_READ:
- LOG(9,"readop");
- virt = (vm_offset_t)tgt->ior->io_data;
- len = tgt->transient_state.in_count;
- rccb->ccb.ccb_in = 1; rccb->ccb.ccb_out = 0;
- break;
- case SCSI_CMD_WRITE:
- case SCSI_CMD_LONG_WRITE:
- LOG(0x1a,"writeop");
- virt = (vm_offset_t)tgt->ior->io_data;
- len = tgt->transient_state.out_count;
- rccb->ccb.ccb_in = 0; rccb->ccb.ccb_out = 1;
- break;
- case SCSI_CMD_INQUIRY:
- case SCSI_CMD_REQUEST_SENSE:
- case SCSI_CMD_MODE_SENSE:
- case SCSI_CMD_RECEIVE_DIAG_RESULTS:
- case SCSI_CMD_READ_CAPACITY:
- case SCSI_CMD_READ_BLOCK_LIMITS:
- case SCSI_CMD_READ_TOC:
- case SCSI_CMD_READ_SUBCH:
- case SCSI_CMD_READ_HEADER:
- case 0xc4: /* despised: SCSI_CMD_DEC_PLAYBACK_STATUS */
- case 0xc6: /* despised: SCSI_CMD_TOSHIBA_READ_SUBCH_Q */
- case 0xc7: /* despised: SCSI_CMD_TOSHIBA_READ_TOC_ENTRY */
- case 0xdd: /* despised: SCSI_CMD_NEC_READ_SUBCH_Q */
- case 0xde: /* despised: SCSI_CMD_NEC_READ_TOC */
- LOG(0x1c,"cmdop");
- LOG(0x80+tgt->cur_cmd,0);
- virt = (vm_offset_t)tgt->cmd_ptr;
- len = tgt->transient_state.in_count;
- rccb->ccb.ccb_in = 1; rccb->ccb.ccb_out = 0;
- break;
- case SCSI_CMD_MODE_SELECT:
- case SCSI_CMD_REASSIGN_BLOCKS:
- case SCSI_CMD_FORMAT_UNIT:
- case 0xc9: /* vendor-spec: SCSI_CMD_DEC_PLAYBACK_CONTROL */
- { register int cs = sizeof_scsi_command(tgt->cur_cmd);
- tgt->transient_state.cmd_count = cs;
- len =
- tgt->transient_state.out_count = cmd_count - cs;
- virt = (vm_offset_t)tgt->cmd_ptr + cs;
- rccb->ccb.ccb_in = 0; rccb->ccb.ccb_out = 1;
- LOG(0x1c,"cmdop");
- LOG(0x80+tgt->cur_cmd,0);
- }
- break;
- default:
- LOG(0x1c,"cmdop");
- LOG(0x80+tgt->cur_cmd,0);
- virt = 0;
- len = 0;
- rccb->ccb.ccb_in = 0; rccb->ccb.ccb_out = 0;
- }
-
-#if CBUS
- at386_io_lock(MP_DEV_WAIT);
-#endif
- aha_prepare_rccb(tgt, rccb, virt, len);
-
- rccb->ccb.ccb_lun = tgt->lun;
- rccb->ccb.ccb_scsi_id = tgt->target_id;
-
-/* AHA_LENGTH_SET(rccb->ccb.ccb_linkptr, 0); unused */
-/* rccb->ccb.ccb_linkid = 0; unused */
-
-#if !CBUS
- s = splbio();
-#endif
-
- LOG(3,"enqueue");
-
- aha_start_scsi(aha, &rccb->ccb);
-
-#if CBUS
- at386_io_unlock();
-#else
- splx(s);
-#endif
-}
-
-aha_prepare_rccb(tgt, rccb, virt, len)
- target_info_t *tgt;
- struct aha_ccb_raw *rccb;
- vm_offset_t virt;
- vm_size_t len;
-{
- vm_offset_t phys;
-#ifdef CBUS
- int cbus_window;
-#endif /* CBUS */
-
- rccb->ccb.ccb_cmd_len = tgt->transient_state.cmd_count;
-
- /* this opcode is refused, grrrr. */
-/* rccb->ccb.ccb_code = AHA_CCB_I_CMD_R; /* default common case */
- rccb->ccb.ccb_code = AHA_CCB_I_CMD; /* default common case */
- AHA_LENGTH_SET(rccb->ccb.ccb_datalen, len);/* default common case */
-
-#ifdef CBUS
- if (tgt->aha_cbus_window == 0)
- tgt->aha_cbus_window = cbus_alloc_win(AHA_MAX_SEGLIST+1);
- cbus_window = tgt->aha_cbus_window;
-#endif /* CBUS */
-
- if (virt == 0) {
- /* no xfers */
- AHA_ADDRESS_SET(rccb->ccb.ccb_dataptr, 0);
- } else if (len <= MACHINE_PGBYTES) {
-/* INCORRECT: what if across two pages :INCORRECT */
- /* simple xfer */
-#ifdef CBUS
- phys = cbus_kvtoAT_ww(virt, cbus_window);
-#else /* CBUS */
- phys = kvtophys(virt);
-#endif /* CBUS */
- AHA_ADDRESS_SET(rccb->ccb.ccb_dataptr, phys);
- } else {
- /* messy xfer */
- aha_seglist_t *seglist;
- vm_offset_t ph1, off;
- vm_size_t l1;
-
- /* this opcode does not work, grrrrr */
-/* rccb->ccb.ccb_code = AHA_CCB_I_CMD_SG_R;*/
- rccb->ccb.ccb_code = AHA_CCB_I_CMD_SG;
-
- if (tgt->dma_ptr == 0)
- aha_alloc_segment_list(tgt);
- seglist = (aha_seglist_t *) tgt->dma_ptr;
-#ifdef CBUS
- phys = cbus_kvtoAT_ww(seglist, cbus_window);
- cbus_window++;
-#else /* CBUS */
- phys = kvtophys((vm_offset_t) seglist);
-#endif /* CBUS */
- AHA_ADDRESS_SET(rccb->ccb.ccb_dataptr, phys);
-
- ph1 = /*i386_trunc_page*/ virt & ~(MACHINE_PGBYTES - 1);
- off = virt & (MACHINE_PGBYTES - 1);
-#ifdef CBUS
- ph1 = cbus_kvtoAT_ww(ph1, cbus_window) + off;
- cbus_window++;
-#else /* CBUS */
- ph1 = kvtophys(ph1) + off;
-#endif /* CBUS */
- l1 = MACHINE_PGBYTES - off;
-
- off = 1;/* now #pages */
- while (1) {
- AHA_ADDRESS_SET(seglist->ptr, ph1);
- AHA_LENGTH_SET(seglist->len, l1);
- seglist++;
-
- if ((len -= l1) <= 0)
- break;
- virt += l1; off++;
-
-#ifdef CBUS
- ph1 = cbus_kvtoAT_ww(virt, cbus_window);
- cbus_window++;
-#else /* CBUS */
- ph1 = kvtophys(virt);
-#endif /* CBUS */
- l1 = (len > MACHINE_PGBYTES) ? MACHINE_PGBYTES : len;
- }
- l1 = off * sizeof(*seglist);
- AHA_LENGTH_SET(rccb->ccb.ccb_datalen, l1);
- }
-}
-
-aha_start_scsi(aha, ccb)
- aha_softc_t aha;
- aha_ccb_t *ccb;
-{
- register aha_mbox_t *mb;
- register idx;
- vm_offset_t phys;
- aha_mbox_t mbo;
- spl_t s;
-
- LOG(4,"start");
- LOG(0x80+ccb->ccb_scsi_id,0);
-
- /*
- * Get an MBO, spin if necessary (takes little time)
- */
- s = splbio();
- phys = kvtoAT((vm_offset_t)ccb);
- /* might cross pages, but should be ok (kernel is contig) */
- AHA_MB_SET_PTR(&mbo,phys);
- mbo.mb.mb_cmd = AHA_MBO_START;
-
- simple_lock(&aha->aha_lock);
- if (aha->wd.nactive++ == 0)
- aha->wd.watchdog_state = SCSI_WD_ACTIVE;
- idx = aha->mb.oidx;
- aha->mb.oidx = next_mbx_idx(idx);
- mb = &aha->mb.omb[idx];
- while (mb->mb.mb_status != AHA_MBO_FREE)
- delay(1);
- mb->bits = mbo.bits;
- simple_unlock(&aha->aha_lock);
-
- /*
- * Start the board going
- */
- aha_command(aha->port, AHA_CMD_START, 0, 0, 0, 0, FALSE);
- splx(s);
-}
-
-/*
- * Interrupt routine
- * Take interrupts from the board
- *
- * Implementation:
- * TBD
- */
-aha_intr(unit)
-{
- register aha_softc_t aha;
- register port;
- register csr, intr;
-#if MAPPABLE
- extern boolean_t rz_use_mapped_interface;
-
- if (rz_use_mapped_interface)
- return AHA_intr(unit);
-#endif /*MAPPABLE*/
-
- aha = aha_softc[unit];
- port = aha->port;
-
- LOG(5,"\n\tintr");
-gotintr:
- /* collect ephemeral information */
- csr = inb(AHA_STATUS_PORT(port));
- intr = inb(AHA_INTR_PORT(port));
-
- /*
- * Check for errors
- */
- if (csr & (AHA_CSR_DIAG_FAIL|AHA_CSR_CMD_ERR)) {
-/* XXX */ gimmeabreak();
- }
-
- /* drop spurious interrupts */
- if ((intr & AHA_INTR_PENDING) == 0) {
- LOG(2,"SPURIOUS");
- return;
- }
- outb(AHA_CONTROL_PORT(port), AHA_CTL_INTR_CLR);
-
-TR(csr);TR(intr);TRCHECK
-
- if (intr & AHA_INTR_RST)
- return aha_bus_reset(aha);
-
- /* we got an interrupt allright */
- if (aha->wd.nactive)
- aha->wd.watchdog_state = SCSI_WD_ACTIVE;
-
- if (intr == AHA_INTR_DONE) {
- /* csr & AHA_CSR_CMD_ERR --> with error */
- LOG(6,"done");
- return;
- }
-
-/* if (intr & AHA_INTR_MBO_AVAIL) will not happen */
-
- /* Some real work today ? */
- if (intr & AHA_INTR_MBI_FULL) {
- register int idx;
- register aha_mbox_t *mb;
- int nscan = 0;
- aha_mbox_t mbi;
-rescan:
- simple_lock(&aha->aha_lock);
- idx = aha->mb.iidx;
- aha->mb.iidx = next_mbx_idx(idx);
- mb = &aha->mb.imb[idx];
- mbi.bits = mb->bits;
- mb->mb.mb_status = AHA_MBI_FREE;
- simple_unlock(&aha->aha_lock);
-
- nscan++;
-
- switch (mbi.mb.mb_status) {
-
- case AHA_MBI_FREE:
- if (nscan >= AHA_NMBOXES)
- return;
- goto rescan;
- break;
-
- case AHA_MBI_SUCCESS:
- case AHA_MBI_ERROR:
- aha_initiator_intr(aha, mbi);
- break;
-
- case AHA_MBI_NEED_CCB:
- aha_target_intr(aha, mbi);
- break;
-
-/* case AHA_MBI_ABORTED: /* this we wont see */
-/* case AHA_MBI_NOT_FOUND: /* this we wont see */
- default:
- log( LOG_KERN,
- "aha%d: Bogus status (x%x) in MBI\n",
- unit, mbi.mb.mb_status);
- break;
- }
-
- /* peek ahead */
- if (aha->mb.imb[aha->mb.iidx].mb.mb_status != AHA_MBI_FREE)
- goto rescan;
- }
-
- /* See if more work ready */
- if (inb(AHA_INTR_PORT(port)) & AHA_INTR_PENDING) {
- LOG(7,"\n\tre-intr");
- goto gotintr;
- }
-}
-
-/*
- * The interrupt routine turns to one of these two
- * functions, depending on the incoming mbi's role
- */
-aha_target_intr(aha, mbi)
- aha_softc_t aha;
- aha_mbox_t mbi;
-{
- target_info_t *initiator; /* this is the caller */
- target_info_t *self; /* this is us */
- int len;
-
- if (mbi.mbt.mb_cmd != AHA_MBI_NEED_CCB)
- gimmeabreak();
-
- /* If we got here this is not zero .. */
- self = aha->sc->target[aha->sc->initiator_id];
-
- initiator = aha->sc->target[mbi.mbt.mb_initiator_id];
- /* ..but initiators are not required to answer to our inquiry */
- if (initiator == 0) {
- /* allocate */
- initiator = aha_tgt_alloc(aha, mbi.mbt.mb_initiator_id,
- sizeof(scsi_sense_data_t) + 5, 0);
-
- /* We do not know here wether the host was down when
- we inquired, or it refused the connection. Leave
- the decision on how we will talk to it to higher
- level code */
- LOG(0xC, "new_initiator");
- sccpu_new_initiator(self, initiator);
- }
-
- /* The right thing to do would be build an ior
- and call the self->dev_ops->strategy routine,
- but we cannot allocate it at interrupt level.
- Also note that we are now disconnected from the
- initiator, no way to do anything else with it
- but reconnect and do what it wants us to do */
-
- /* obviously, this needs both spl and MP protection */
- self->dev_info.cpu.req_pending = TRUE;
- self->dev_info.cpu.req_id = mbi.mbt.mb_initiator_id;
- self->dev_info.cpu.req_lun = mbi.mbt.mb_lun;
- self->dev_info.cpu.req_cmd =
- mbi.mbt.mb_isa_send ? SCSI_CMD_SEND: SCSI_CMD_RECEIVE;
- len = (mbi.mbt.mb_data_len_msb << 16) |
- (mbi.mbt.mb_data_len_mid << 8 );
- len += 0x100;/* truncation problem */
- self->dev_info.cpu.req_len = len;
-
- LOG(0xB,"tgt-mode-restart");
- (*self->dev_ops->restart)( self, FALSE);
-
- /* The call above has either prepared the data,
- placing an ior on self, or it handled it some
- other way */
- if (self->ior == 0)
- return; /* I guess we'll do it later */
-
- {
- struct aha_ccb_raw *rccb;
-
- rccb = &(aha->aha_ccbs[initiator->target_id]);
- rccb->active_target = initiator;
- if (self->dev_info.cpu.req_cmd == SCSI_CMD_SEND) {
- rccb->ccb.ccb_in = 1;
- rccb->ccb.ccb_out = 0;
- } else {
- rccb->ccb.ccb_in = 0;
- rccb->ccb.ccb_out = 1;
- }
-
- aha_prepare_rccb(initiator, rccb,
- (vm_offset_t)self->ior->io_data, self->ior->io_count);
- rccb->ccb.ccb_code = AHA_CCB_T_CMD;
- rccb->ccb.ccb_lun = initiator->lun;
- rccb->ccb.ccb_scsi_id = initiator->target_id;
-
- simple_lock(&aha->aha_lock);
- if (aha->wd.nactive++ == 0)
- aha->wd.watchdog_state = SCSI_WD_ACTIVE;
- simple_unlock(&aha->aha_lock);
-
- aha_start_scsi(aha, &rccb->ccb);
- }
-}
-
-aha_initiator_intr(aha, mbi)
- aha_softc_t aha;
- aha_mbox_t mbi;
-{
- struct aha_ccb_raw *rccb;
- scsi2_status_byte_t status;
- target_info_t *tgt;
-
- rccb = mb_to_rccb(aha,mbi);
- tgt = rccb->active_target;
- rccb->active_target = 0;
-
- /* shortcut (sic!) */
- if (mbi.mb.mb_status == AHA_MBI_SUCCESS)
- goto allok;
-
- switch (rccb->ccb.ccb_hstatus) {
- case AHA_HST_SUCCESS:
-allok:
- status = rccb->ccb.ccb_status;
- if (status.st.scsi_status_code != SCSI_ST_GOOD) {
- scsi_error(tgt, SCSI_ERR_STATUS, status.bits, 0);
- tgt->done = (status.st.scsi_status_code == SCSI_ST_BUSY) ?
- SCSI_RET_RETRY : SCSI_RET_NEED_SENSE;
- } else
- tgt->done = SCSI_RET_SUCCESS;
- break;
- case AHA_HST_SEL_TIMEO:
- if (tgt->flags & TGT_FULLY_PROBED)
- tgt->flags = 0; /* went offline */
- tgt->done = SCSI_RET_DEVICE_DOWN;
- break;
- case AHA_HST_DATA_OVRUN:
- /* BUT we don't know if this is an underrun.
- It is ok if we get less data than we asked
- for, in a number of cases. Most boards do not
- seem to generate this anyways, but some do. */
- { register int cmd = tgt->cur_cmd;
- switch (cmd) {
- case SCSI_CMD_INQUIRY:
- case SCSI_CMD_REQUEST_SENSE:
- break;
- default:
- printf("%sx%x\n",
- "aha: U/OVRUN on scsi command x%x\n",
- cmd);
- gimmeabreak();
- }
- }
- goto allok;
- case AHA_HST_BAD_DISCONN:
- printf("aha: bad disconnect\n");
- tgt->done = SCSI_RET_ABORTED;
- break;
- case AHA_HST_BAD_PHASE_SEQ:
- /* we'll get an interrupt soon */
- printf("aha: bad PHASE sequencing\n");
- tgt->done = SCSI_RET_ABORTED;
- break;
- case AHA_HST_BAD_OPCODE: /* fall through */
- case AHA_HST_BAD_PARAM:
-printf("aha: BADCCB\n");gimmeabreak();
- tgt->done = SCSI_RET_RETRY;
- break;
- case AHA_HST_BAD_LINK_LUN: /* these should not happen */
- case AHA_HST_INVALID_TDIR:
- case AHA_HST_DUPLICATED_CCB:
- printf("aha: bad hstatus (x%x)\n", rccb->ccb.ccb_hstatus);
- tgt->done = SCSI_RET_ABORTED;
- break;
- }
-
- LOG(8,"end");
-
- simple_lock(&aha->aha_lock);
- if (aha->wd.nactive-- == 1)
- aha->wd.watchdog_state = SCSI_WD_INACTIVE;
- simple_unlock(&aha->aha_lock);
-
- if (tgt->ior) {
- LOG(0xA,"ops->restart");
- (*tgt->dev_ops->restart)( tgt, TRUE);
- }
-
- return FALSE;
-}
-
-/*
- * The bus was reset
- */
-aha_bus_reset(aha)
- register aha_softc_t aha;
-{
- register port = aha->port;
-
- LOG(0x1d,"bus_reset");
-
- /*
- * Clear bus descriptor
- */
- aha->wd.nactive = 0;
- aha_reset(port, TRUE);
- aha_init(aha);
-
- printf("aha: (%d) bus reset ", ++aha->wd.reset_count);
- delay(scsi_delay_after_reset); /* some targets take long to reset */
-
- if (aha->sc == 0) /* sanity */
- return;
-
- scsi_bus_was_reset(aha->sc);
-}
-
-/*
- * Watchdog
- *
- * We know that some (name withdrawn) disks get
- * stuck in the middle of dma phases...
- */
-aha_reset_scsibus(aha)
- register aha_softc_t aha;
-{
- register target_info_t *tgt;
- register port = aha->port;
- register int i;
-
- for (i = 0; i < AHA_NCCB; i++) {
- tgt = aha->aha_ccbs[i].active_target;
- if (/*scsi_debug &&*/ tgt)
- printf("Target %d was active, cmd x%x in x%x out x%x\n",
- tgt->target_id, tgt->cur_cmd,
- tgt->transient_state.in_count,
- tgt->transient_state.out_count);
- }
- aha_reset(port, FALSE);
- delay(35);
- /* no interrupt will come */
- aha_bus_reset(aha);
-}
-
-/*
- * Utilities
- */
-
-/*
- * Send a command to the board along with some
- * optional parameters, optionally receive the
- * results at command completion, returns how
- * many bytes we did NOT get back.
- */
-aha_command(port, cmd, outp, outc, inp, inc, clear_interrupt)
- unsigned char *outp, *inp;
-{
- register unsigned char st;
- boolean_t failed = TRUE;
-
- do {
- st = inb(AHA_STATUS_PORT(port));
- } while (st & AHA_CSR_DATAO_FULL);
-
- /* Output command and any data */
- outb(AHA_COMMAND_PORT(port), cmd);
- while (outc--) {
- do {
- st = inb(AHA_STATUS_PORT(port));
- if (st & AHA_CSR_CMD_ERR) goto out;
- } while (st & AHA_CSR_DATAO_FULL);
-
- outb(AHA_COMMAND_PORT(port), *outp++);
- }
-
- /* get any data */
- while (inc--) {
- do {
- st = inb(AHA_STATUS_PORT(port));
- if (st & AHA_CSR_CMD_ERR) goto out;
- } while ((st & AHA_CSR_DATAI_FULL) == 0);
-
- *inp++ = inb(AHA_DATA_PORT(port));
- }
- ++inc;
- failed = FALSE;
-
- /* wait command complete */
- if (clear_interrupt) do {
- delay(1);
- st = inb(AHA_INTR_PORT(port));
- } while ((st & AHA_INTR_DONE) == 0);
-
-out:
- if (clear_interrupt)
- outb(AHA_CONTROL_PORT(port), AHA_CTL_INTR_CLR);
- if (failed)
- printf("aha_command: error on (%x %x %x %x %x %x), status %x\n",
- port, cmd, outp, outc, inp, inc, st);
- return inc;
-}
-
-#include <vm/vm_kern.h>
-
-/*
- * Allocate dynamically segment lists to
- * targets (for scatter/gather)
- * Its a max of 17*6=102 bytes per target.
- */
-vm_offset_t aha_seglist_next, aha_seglist_end;
-
-aha_alloc_segment_list(tgt)
- target_info_t *tgt;
-{
-#define ALLOC_SIZE (AHA_MAX_SEGLIST * sizeof(aha_seglist_t))
-
-/* XXX locking */
- if ((aha_seglist_next + ALLOC_SIZE) > aha_seglist_end) {
- (void) kmem_alloc_wired(kernel_map, &aha_seglist_next, PAGE_SIZE);
- aha_seglist_end = aha_seglist_next + PAGE_SIZE;
- }
- tgt->dma_ptr = (char *)aha_seglist_next;
- aha_seglist_next += ALLOC_SIZE;
-/* XXX locking */
-}
-
-#endif /* NAHA > 0 */
-
diff --git a/scsi/adapters/scsi_aha17_hdw.c b/scsi/adapters/scsi_aha17_hdw.c
deleted file mode 100644
index d8afe6a..0000000
--- a/scsi/adapters/scsi_aha17_hdw.c
+++ /dev/null
@@ -1,1371 +0,0 @@
-/*
- * Mach Operating System
- * Copyright (c) 1993 Carnegie Mellon University
- * Copyright (c) 1993 University of Dublin
- * All Rights Reserved.
- *
- * Permission to use, copy, modify and distribute this software and its
- * documentation is hereby granted, provided that both the copyright
- * notice and the following permission notice appear in all copies of the
- * software, derivative works or modified versions, and any portions
- * thereof, and that both notices appear in supporting documentation.
- *
- * CARNEGIE MELLON AND THE UNIVERSITY OF DUBLIN ALLOW FREE USE OF
- * THIS SOFTWARE IN ITS "AS IS" CONDITION. CARNEGIE MELLON AND THE
- * UNIVERSITY OF DUBLIN DISCLAIM ANY LIABILITY OF ANY KIND FOR
- * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
- *
- * Carnegie Mellon requests users of this software to return to
- *
- * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
- * School of Computer Science
- * Carnegie Mellon University
- * Pittsburgh PA 15213-3890
- *
- * any improvements or extensions that they make and grant Carnegie Mellon
- * the rights to redistribute these changes.
- */
-/*
- * Support for AHA-174x in enhanced mode. Dominic Herity (dherity@cs.tcd.ie)
- * Will refer to "Adaptec AHA-1740A/1742A/1744 Technical Reference Manual"
- * page x-y as TRMx-y in comments below.
- */
-
-#include <eaha.h>
-#if NEAHA > 0
-
-#define db_printf printf
-
-#include <cpus.h>
-#include <platforms.h>
-#include <aha.h>
-
-#ifdef OSF
-#include <eisa.h>
-#else
-#include <i386at/eisa.h>
-#endif
-
-#include <mach/std_types.h>
-#include <sys/types.h>
-#include <chips/busses.h>
-#include <scsi/compat_30.h>
-
-#include <scsi/scsi.h>
-#include <scsi/scsi2.h>
-#include <scsi/scsi_defs.h>
-
-#include <scsi/adapters/scsi_aha15.h>
-#include <vm/vm_kern.h>
-
-#ifdef AT386
-#define MACHINE_PGBYTES I386_PGBYTES
-#define MAPPABLE 0
-#define gimmeabreak() asm("int3")
-
-
-#include <i386/pio.h> /* inlining of outb and inb */
-#ifdef OSF
-#include <machine/mp/mp.h>
-#endif
-#endif /*AT386*/
-
-#ifdef CBUS
-#include <cbus/cbus.h>
-#endif
-
-
-#ifndef MACHINE_PGBYTES /* cross compile check */
-#define MACHINE_PGBYTES 0x1000
-#define MAPPABLE 1
-#define gimmeabreak() Debugger("gimmeabreak");
-#endif
-
-int eaha_probe(), scsi_slave(), eaha_go(), eaha_intr();
-void scsi_attach();
-
-vm_offset_t eaha_std[NEAHA] = { 0 };
-struct bus_device *eaha_dinfo[NEAHA*8];
-struct bus_ctlr *eaha_minfo[NEAHA];
-struct bus_driver eaha_driver =
- { eaha_probe, scsi_slave, scsi_attach, eaha_go, eaha_std, "rz",
- eaha_dinfo, "eahac", eaha_minfo, BUS_INTR_B4_PROBE};
-
-
-#define TRACE
-#ifdef TRACE
-
-#define LOGSIZE 256
-int eaha_logpt;
-char eaha_log[LOGSIZE];
-
-#define MAXLOG_VALUE 0x1e
-struct {
- char *name;
- unsigned int count;
-} logtbl[MAXLOG_VALUE];
-
-static LOG(
- int e,
- char *f)
-{
- eaha_log[eaha_logpt++] = (e);
- if (eaha_logpt == LOGSIZE) eaha_logpt = 0;
- if ((e) < MAXLOG_VALUE) {
- logtbl[(e)].name = (f);
- logtbl[(e)].count++;
- }
-}
-
-eaha_print_log(
- int skip)
-{
- register int i, j;
- register unsigned char c;
-
- for (i = 0, j = eaha_logpt; i < LOGSIZE; i++) {
- c = eaha_log[j];
- if (++j == LOGSIZE) j = 0;
- if (skip-- > 0)
- continue;
- if (c < MAXLOG_VALUE)
- db_printf(" %s", logtbl[c].name);
- else
- db_printf("-%x", c & 0x7f);
- }
- return 0;
-}
-
-eaha_print_stat()
-{
- register int i;
- register char *p;
- for (i = 0; i < MAXLOG_VALUE; i++) {
- if (p = logtbl[i].name)
- printf("%d %s\n", logtbl[i].count, p);
- }
-}
-
-#else /*TRACE*/
-#define LOG(e,f)
-#define LOGSIZE
-#endif /*TRACE*/
-
-#ifdef DEBUG
-#define ASSERT(x) { if (!(x)) gimmeabreak() ; }
-#define MARK() gimmeabreak()
-#else
-#define ASSERT(x)
-#define MARK()
-#endif
-
-/*
- * Notes :
- *
- * do each host command TRM6-4
- * find targets in probe
- * disable SCSI writes
- * matching port with structs, eaha_go with port, eaha_intr with port
- *
- */
-
-/* eaha registers. See TRM4-11..23. dph */
-
-#define HID0(z) ((z)+0xC80)
-#define HID1(z) ((z)+0xC81)
-#define HID2(z) ((z)+0xC82)
-#define HID3(z) ((z)+0xC83)
-#define EBCTRL(z) ((z)+0xC84)
-#define PORTADDR(z) ((z)+0xCC0)
-#define BIOSADDR(z) ((z)+0xCC1)
-#define INTDEF(z) ((z)+0xCC2)
-#define SCSIDEF(z) ((z)+0xCC3)
-#define MBOXOUT0(z) ((z)+0xCD0)
-#define MBOXOUT1(z) ((z)+0xCD1)
-#define MBOXOUT2(z) ((z)+0xCD2)
-#define MBOXOUT3(z) ((z)+0xCD3)
-#define MBOXIN0(z) ((z)+0xCD8)
-#define MBOXIN1(z) ((z)+0xCD9)
-#define MBOXIN2(z) ((z)+0xCDA)
-#define MBOXIN3(z) ((z)+0xCDB)
-#define ATTN(z) ((z)+0xCD4)
-#define G2CNTRL(z) ((z)+0xCD5)
-#define G2INTST(z) ((z)+0xCD6)
-#define G2STAT(z) ((z)+0xCD7)
-#define G2STAT2(z) ((z)+0xCDC)
-
-/*
- * Enhanced mode data structures: ring, enhanced ccbs, a per target buffer
- */
-
-#define SCSI_TARGETS 8 /* Allow for SCSI-2 */
-
-
-/* Extended Command Control Block Format. See TRM6-3..12. */
-
-typedef struct {
- unsigned short command ;
-# define EAHA_CMD_NOP 0
-# define EAHA_CMD_INIT_CMD 1
-# define EAHA_CMD_DIAG 5
-# define EAHA_CMD_INIT_SCSI 6
-# define EAHA_CMD_READ_SENS 8
-# define EAHA_CMD_DOWNLOAD 9
-# define EAHA_CMD_HOST_INQ 0x0a
-# define EAHA_CMD_TARG_CMD 0x10
-
- /*
- * It appears to be customary to tackle the endian-ness of
- * bit fields as follows, so I won't deviate. However, nothing in
- * K&R implies that bit fields are implemented so that the fields
- * of an unsigned char are allocated lsb first. Indeed, K&R _warns_
- * _against_ using bit fields to describe storage allocation.
- * This issue is separate from endian-ness. dph
- * And this is exactly the reason macros are used. If your compiler
- * is weird just override the macros and we will all be happy. af
- */
- BITFIELD_3(unsigned char,
- cne:1,
- xxx0:6,
- di:1) ;
- BITFIELD_7(unsigned char,
- xxx1:2,
- ses:1,
- xxx2:1,
- sg:1,
- xxx3:1,
- dsb:1,
- ars:1) ;
-
- BITFIELD_5(unsigned char,
- lun:3,
- tag:1,
- tt:2,
- nd:1,
- xxx4:1) ;
- BITFIELD_7(unsigned char,
- dat:1,
- dir:1,
- st:1,
- chk:1,
- xxx5:2,
- rec:1,
- nbr:1) ;
-
- unsigned short xxx6 ;
-
- vm_offset_t scather ; /* scatter/gather */
- unsigned scathlen ;
- vm_offset_t status ;
- vm_offset_t chain ;
- int xxx7 ;
-
- vm_offset_t sense_p ;
- unsigned char sense_len ;
- unsigned char cdb_len ;
- unsigned short checksum ;
- scsi_command_group_5 cdb ;
- unsigned char buffer[256] ; /* space for data returned. */
-
-} eccb ;
-
-#define NTARGETS (8)
-#define NECCBS (NTARGETS+2) /* Targets + 2 to allow for temporaries. */
- /* Can be up to 64 (TRM6-2), but that entails lots of bss usage */
-
-typedef struct { /* Status Block Format. See TRM6-13..19. */
- BITFIELD_8(unsigned char,
- don:1,
- du:1,
- xxx0:1,
- qf:1,
- sc:1,
- dover:1,
- ch:1,
- inti:1) ;
- BITFIELD_8(unsigned char,
- asa:1, /* Error in TRM6-15..16 says both asa and sns */
- sns:1, /* bit 9. Bits 8 and 10 are not mentioned. */
- xxx1:1,
- ini:1,
- me:1,
- xxx2:1,
- eca:1,
- xxx3:1) ;
-
- unsigned char ha_status ;
-# define HA_STATUS_SUCCESS 0x00
-# define HA_STATUS_HOST_ABORTED 0x04
-# define HA_STATUS_ADP_ABORTED 0x05
-# define HA_STATUS_NO_FIRM 0x08
-# define HA_STATUS_NOT_TARGET 0x0a
-# define HA_STATUS_SEL_TIMEOUT 0x11
-# define HA_STATUS_OVRUN 0x12
-# define HA_STATUS_BUS_FREE 0x13
-# define HA_STATUS_PHASE_ERROR 0x14
-# define HA_STATUS_BAD_OPCODE 0x16
-# define HA_STATUS_INVALID_LINK 0x17
-# define HA_STATUS_BAD_CBLOCK 0x18
-# define HA_STATUS_DUP_CBLOCK 0x19
-# define HA_STATUS_BAD_SCATHER 0x1a
-# define HA_STATUS_RSENSE_FAIL 0x1b
-# define HA_STATUS_TAG_REJECT 0x1c
-# define HA_STATUS_HARD_ERROR 0x20
-# define HA_STATUS_TARGET_NOATTN 0x21
-# define HA_STATUS_HOST_RESET 0x22
-# define HA_STATUS_OTHER_RESET 0x23
-# define HA_STATUS_PROG_BAD_SUM 0x80
-
- scsi2_status_byte_t target_status ;
-
- unsigned residue ;
- vm_offset_t residue_buffer ;
- unsigned short add_stat_len ;
- unsigned char sense_len ;
- char xxx4[9] ;
- unsigned char cdb[6] ;
-
-} status_block ;
-
-typedef struct {
- vm_offset_t ptr ;
- unsigned len ;
-} scather_entry ;
-
-#define SCATHER_ENTRIES 128 /* TRM 6-11 */
-
-struct erccbx {
- target_info_t *active_target;
- eccb _eccb;
- status_block status ;
- struct erccbx *next ;
-} ;
-
-typedef struct erccbx erccb ;
-
-/* forward decls */
-int eaha_reset_scsibus();
-boolean_t eaha_probe_target();
-
-/*
- * State descriptor for this layer. There is one such structure
- * per (enabled) board
- */
-typedef struct {
- watchdog_t wd;
- decl_simple_lock_data(, aha_lock)
- int port; /* I/O port */
-
- int has_sense_info [NTARGETS];
- int sense_info_lun [NTARGETS];
- /* 1742 enhanced mode will hang if target has
- * sense info and host doesn't request it (TRM6-34).
- * This sometimes happens in the scsi driver.
- * These flags indicate when a target has sense
- * info to disgorge.
- * If set, eaha_go reads and discards sense info
- * before running any command except request sense.
- * dph
- */
-
- scsi_softc_t *sc; /* HBA-indep info */
-
- erccb _erccbs[NECCBS] ; /* mailboxes */
- erccb *toperccb ;
-
- /* This chicanery is for mapping back the phys address
- of a CCB (which we get in an MBI) to its virtual */
- /* [we could use phystokv(), but it isn't standard] */
- vm_offset_t I_hold_my_phys_address;
-
- char host_inquiry_data[256] ; /* Check out ../scsi2.h */
-
-} eaha_softc ;
-
-eaha_softc eaha_softc_data[NEAHA];
-
-typedef eaha_softc *eaha_softc_t;
-
-eaha_softc_t eaha_softc_pool[NEAHA];
-
-int eaha_quiet ;
-
-erccb *erccb_alloc(
- eaha_softc *eaha)
-{
- erccb *e ;
- int x ;
-
- do {
- while (eaha->toperccb == 0) ;/* Shouldn't be often or long, */
- /* BUT should use a semaphore */
- x = splbio() ;
- e = eaha->toperccb ;
- if (e == 0)
- splx(x) ;
- } while (!e) ;
- eaha->toperccb = e->next ;
- splx(x) ;
- bzero(e,sizeof(*e)) ;
- e->_eccb.status = kvtophys((vm_offset_t)&e->status) ;
- return e ;
-}
-
-void erccb_free(
- eaha_softc *eaha,
- erccb *e)
-{
- int x ;
- ASSERT ( e >= eaha->_erccbs && e < eaha->_erccbs+NECCBS) ;
- x = splbio() ;
- e->next = eaha->toperccb ;
- eaha->toperccb = e ;
- splx(x) ;
-}
-
-void eaha_mboxout(
- int port,
- vm_offset_t phys)
-{
- outb(MBOXOUT0(port),phys) ;
- outb(MBOXOUT1(port),phys>>8) ;
- outb(MBOXOUT2(port),phys>>16) ;
- outb(MBOXOUT3(port),phys>>24) ;
-}
-
-void eaha_command( /* start a command */
- int port,
- erccb *_erccb)
-{
- int s ;
- vm_offset_t phys = kvtophys((vm_offset_t) &_erccb->_eccb) ;
- while ((inb(G2STAT(port)) & 0x04)==0); /*While MBO busy. TRM6-1 */
- s = splbio() ;
- eaha_mboxout(port,phys) ;
- while (inb(G2STAT(port)) & 1) ; /* While adapter busy. TRM6-2 */
- outb(ATTN(port),0x40 | _erccb->active_target->target_id) ; /* TRM6-20 */
- /* (Should use target id for intitiator command) */
- splx(s) ;
-}
-
-eaha_reset(
- eaha_softc_t eaha,
- boolean_t quick)
-{
- /*
- * Reset board and wait till done
- */
- unsigned st ;
- int target_id ;
- int port = eaha->port ;
-
- /* Reset adapter, maybe with SCSIbus */
- eaha_mboxout(port, quick ? 0x00080080 : 0x00000080 ) ; /* TRM 6-43..45 */
- outb(ATTN(port), 0x10 | inb(SCSIDEF(port)) & 0x0f) ;
- outb(G2CNTRL(port),0x20) ; /* TRM 4-22 */
-
- do {
- st = inb(G2INTST(port)) >> 4 ;
- } while (st == 0) ;
- /* TRM 4-22 implies that 1 should not be returned in G2INTST, but
- in practise, it is. So this code takes 0 to mean non-completion. */
-
- for (target_id = 0 ; target_id < NTARGETS; target_id++)
- eaha->has_sense_info[target_id] = FALSE ;
-
-}
-
-void eaha_init(
- eaha_softc_t eaha)
-{
- /* Do nothing - I guess */
-}
-
-void eaha_bus_reset(
- eaha_softc_t eaha)
-
-{
- LOG(0x1d,"bus_reset");
-
- /*
- * Clear bus descriptor
- */
- eaha->wd.nactive = 0;
- eaha_reset(eaha, TRUE);
- eaha_init(eaha);
-
- printf("eaha: (%d) bus reset ", ++eaha->wd.reset_count);
- delay(scsi_delay_after_reset); /* some targets take long to reset */
-
- if (eaha->sc == 0) /* sanity */
- return;
-
- scsi_bus_was_reset(eaha->sc);
-}
-
-#ifdef notdef
- /* functions added to complete 1742 support, but not used. Untested. */
-
- void eaha_download(port, data, len)
- int port ;
- char *data ;
- unsigned len ;
- {
- /* 1744 firmware download. Not implemented. TRM6-21 */
- }
-
- void eaha_initscsi(data, len)
- char *data ;
- unsigned len ;
- {
- /* initialize SCSI subsystem. Presume BIOS does it.
- Not implemented. TRM6-23 */
- }
-
- void eaha_noop()
- {
- /* Not implemented. TRM6-27 */
- }
-
- erccb *eaha_host_adapter_inquiry(eaha) /* Returns a promise */
- eaha_softc *eaha ; /* TRM6-31..33 */
- {
- erccb *_erccb = erccb_alloc(eaha) ;
- _erccb->_eccb.scather = (vm_offset_t) kvtophys(eaha->host_inquiry_data) ;
- _erccb->_eccb.scathlen = sizeof(eaha->host_inquiry_data) ;
- _erccb->_eccb.ses = 1 ;
- _erccb->_eccb.command = EAHA_CMD_HOST_INQ ;
- eaha_command(eaha->port,_erccb->_eccb,0) ; /* Is scsi_id used */
- return _erccb ;
- }
-
- erccb *eaha_read_sense_info(eaha, target, lun) /* TRM 6-33..35 */
- eaha_softc *eaha ;
- unsigned target, lun ;
- { /* Don't think we need this because its done in scsi_alldevs.c */
- #ifdef notdef
- erccb *_erccb = erccb_alloc(eaha) ;
- _erccb->_eccb.command = EAHA_CMD_READ_SENS ;
- _erccb->_eccb.lun = lun ;
- eaha_command(eaha->port,_erccb->_eccb, target) ;/*Wrong # args*/
- return _erccb ;
- #else
- return 0 ;
- #endif
- }
-
- void eaha_diagnostic(eaha)
- eaha_softc *eaha ;
- {
- /* Not implemented. TRM6-36..37 */
- }
-
- erccb *eaha_target_cmd(eaha, target, lun, data, len) /* TRM6-38..39 */
- eaha_softc *eaha ;
- unsigned target, lun ;
- char *data ;
- unsigned len ;
- {
- erccb *_erccb = erccb_alloc(eaha) ;
- _erccb->_eccb.command = EAHA_CMD_TARG_CMD ;
- _erccb->_eccb.lun = lun ;
- eaha_command(eaha->port,_erccb->_eccb,target);/*Wrong # args*/
- return _erccb ;
- }
-
- erccb *eaha_init_cmd(port) /* SHOULD RETURN TOKEN. i.e. ptr to eccb */
- /* Need list of free eccbs */
- { /* to be continued,. possibly. */
- }
-
-#endif /* notdef */
-
-target_info_t *
-eaha_tgt_alloc(
- eaha_softc_t eaha,
- int id,
- target_info_t *tgt)
-{
- erccb *_erccb;
-
- if (tgt == 0)
- tgt = scsi_slave_alloc(eaha - eaha_softc_data, id, eaha);
-
- _erccb = erccb_alloc(eaha) ; /* This is very dodgy */
- tgt->cmd_ptr = (char *)& _erccb->_eccb.cdb ;
- tgt->dma_ptr = 0;
- return tgt;
-}
-
-
-struct {
- scsi_sense_data_t sns ;
- unsigned char extra
- [254-sizeof(scsi_sense_data_t)] ;
-} eaha_xsns [NTARGETS] ;/*must be bss to be contiguous*/
-
-
-/* Enhanced adapter probe routine */
-
-eaha_probe(
- register int port,
- struct bus_ctlr *ui)
-{
- int unit = ui->unit;
- eaha_softc_t eaha = &eaha_softc_data[unit] ;
- int target_id ;
- scsi_softc_t *sc ;
- int s;
- boolean_t did_banner = FALSE ;
- struct aha_devs installed;
- unsigned char my_scsi_id, my_interrupt ;
-
- if (unit >= NEAHA)
- return(0);
-
- /* No interrupts yet */
- s = splbio();
-
- /*
- * Detect prescence of 174x in enhanced mode. Ignore HID2 and HID3
- * on the assumption that compatibility will be preserved. dph
- */
- if (inb(HID0(port)) != 0x04 || inb(HID1(port)) != 0x90 ||
- (inb(PORTADDR(port)) & 0x80) != 0x80) {
- splx(s);
- return 0 ;
- }
-
- /* Issue RESET in case this is a reboot */
-
- outb(EBCTRL(port),0x04) ; /* Disable board. TRM4-12 */
- outb(PORTADDR(port),0x80) ; /* Disable standard mode ports. TRM4-13. */
- my_interrupt = inb(INTDEF(port)) & 0x07 ;
- outb(INTDEF(port), my_interrupt | 0x00) ;
- /* Disable interrupts. TRM4-15 */
- my_scsi_id = inb(SCSIDEF(port)) & 0x0f ;
- outb(SCSIDEF(port), my_scsi_id | 0x10) ;
- /* Force SCSI reset on hard reset. TRM4-16 */
- outb(G2CNTRL(port),0xe0) ; /* Reset board, clear interrupt */
- /* and set 'host ready'. */
- delay(10*10) ; /* HRST must remain set for 10us. TRM4-22 */
- /* (I don't believe the delay loop is slow enough.) */
- outb(G2CNTRL(port),0x60);/*Un-reset board, set 'host ready'. TRM4-22*/
-
- printf("Adaptec 1740A/1742A/1744 enhanced mode\n");
-
- /* Get host inquiry data */
-
- eaha_softc_pool[unit] = eaha ;
- bzero(eaha,sizeof(*eaha)) ;
- eaha->port = port ;
-
- sc = scsi_master_alloc(unit, eaha) ;
- eaha->sc = sc ;
- sc->go = eaha_go ;
- sc->watchdog = scsi_watchdog ;
- sc->probe = eaha_probe_target ;
- eaha->wd.reset = eaha_reset_scsibus ;
- sc->max_dma_data = -1 ; /* Lets be optimistic */
- sc->initiator_id = my_scsi_id ;
- eaha_reset(eaha,TRUE) ;
- eaha->I_hold_my_phys_address =
- kvtophys((vm_offset_t)&eaha->I_hold_my_phys_address) ;
- {
- erccb *e ;
- eaha->toperccb = eaha->_erccbs ;
- for (e=eaha->_erccbs; e < eaha->_erccbs+NECCBS; e++) {
- e->next = e+1 ;
- e->_eccb.status =
- kvtophys((vm_offset_t) &e->status) ;
- }
- eaha->_erccbs[NECCBS-1].next = 0 ;
-
- }
-
- ui->sysdep1 = my_interrupt + 9 ;
- take_ctlr_irq(ui) ;
-
- printf("%s%d: [port 0x%x intr ch %d] my SCSI id is %d",
- ui->name, unit, port, my_interrupt + 9, my_scsi_id) ;
-
- outb(INTDEF(port), my_interrupt | 0x10) ;
- /* Enable interrupts. TRM4-15 */
- outb(EBCTRL(port),0x01) ; /* Enable board. TRM4-12 */
-
- { target_info_t *t = eaha_tgt_alloc(eaha, my_scsi_id, 0) ;
- /* Haven't enabled target mode a la standard mode, because */
- /* it doesn't seem to be necessary. */
- sccpu_new_initiator(t, t) ;
- }
-
- /* Find targets, incl. ourselves. */
-
- for (target_id=0; target_id < SCSI_TARGETS; target_id++)
- if (target_id != sc->initiator_id) {
- scsi_cmd_test_unit_ready_t *cmd;
- erccb *_erccb = erccb_alloc(eaha) ;
- unsigned attempts = 0 ;
-#define MAX_ATTEMPTS 2
- target_info_t temp_targ ;
-
- temp_targ.ior = 0 ;
- temp_targ.hw_state = (char *) eaha ;
- temp_targ.cmd_ptr = (char *) &_erccb->_eccb.cdb ;
- temp_targ.target_id = target_id ;
- temp_targ.lun = 0 ;
- temp_targ.cur_cmd = SCSI_CMD_TEST_UNIT_READY;
-
- cmd = (scsi_cmd_test_unit_ready_t *) temp_targ.cmd_ptr;
-
- do {
- cmd->scsi_cmd_code = SCSI_CMD_TEST_UNIT_READY;
- cmd->scsi_cmd_lun_and_lba1 = 0; /*assume 1 lun?*/
- cmd->scsi_cmd_lba2 = 0;
- cmd->scsi_cmd_lba3 = 0;
- cmd->scsi_cmd_ss_flags = 0;
- cmd->scsi_cmd_ctrl_byte = 0; /* not linked */
-
- eaha_go( &temp_targ,
- sizeof(scsi_cmd_test_unit_ready_t),0,0);
- /* ints disabled, so call isr yourself. */
- while (temp_targ.done == SCSI_RET_IN_PROGRESS)
- if (inb(G2STAT(eaha->port)) & 0x02) {
- eaha_quiet = 1 ;
- eaha_intr(unit) ;
- eaha_quiet = 0 ;
- }
- if (temp_targ.done == SCSI_RET_NEED_SENSE) {
- /* MUST get sense info : TRM6-34 */
- if (eaha_retrieve_sense_info(
- eaha, temp_targ.target_id,
- temp_targ.lun) &&
- attempts == MAX_ATTEMPTS-1) {
-
- printf(
- "\nTarget %d Check Condition : "
- ,temp_targ.target_id) ;
- scsi_print_sense_data(&eaha_xsns
- [temp_targ.target_id]);
- printf("\n") ;
- }
- }
- } while (temp_targ.done != SCSI_RET_SUCCESS &&
- temp_targ.done != SCSI_RET_ABORTED &&
- ++attempts < MAX_ATTEMPTS) ;
-
- /*
- * Recognize target which is present, whether or not
- * it is ready, e.g. drive with removable media.
- */
- if (temp_targ.done == SCSI_RET_SUCCESS ||
- temp_targ.done == SCSI_RET_NEED_SENSE &&
- _erccb->status.target_status.bits != 0) { /* Eureka */
- installed.tgt_luns[target_id]=1;/*Assume 1 lun?*/
- printf(", %s%d",
- did_banner++ ? "" : "target(s) at ",
- target_id);
-
- erccb_free(eaha, _erccb) ;
-
- /* Normally, only LUN 0 */
- if (installed.tgt_luns[target_id] != 1)
- printf("(%x)", installed.tgt_luns[target_id]);
- /*
- * Found a target
- */
- (void) eaha_tgt_alloc(eaha, target_id, 0);
- /* Why discard ? */
- } else
- installed.tgt_luns[target_id]=0;
- }
-
- printf(".\n") ;
- splx(s);
- return 1 ;
-}
-
-int eaha_retrieve_sense_info (
- eaha_softc_t eaha,
- int tid,
- int lun)
-{
- int result ;
- int s ;
- target_info_t dummy_target ; /* Keeps eaha_command() happy. HACK */
- erccb *_erccb1 = erccb_alloc(eaha) ;
-
- _erccb1->active_target = &dummy_target ;
- dummy_target.target_id = tid ;
- _erccb1->_eccb.command =
- EAHA_CMD_READ_SENS ;
- _erccb1->_eccb.lun = lun ;
- _erccb1->_eccb.sense_p = kvtophys((vm_offset_t) &eaha_xsns [tid]);
- _erccb1->_eccb.sense_len = sizeof(eaha_xsns [tid]);
- _erccb1->_eccb.ses = 1 ;
- s = splbio() ;
- eaha_command(eaha->port,_erccb1) ;
- while ((inb(G2STAT(eaha->port)) & 0x02) == 0) ;
- outb(G2CNTRL(eaha->port),0x40);/* Clear int */
- splx(s) ;
- result = _erccb1->status.target_status.bits != 0 ;
- erccb_free(eaha,_erccb1) ;
- return result ;
-}
-
-/*
- * Start a SCSI command on a target (enhanced mode)
- */
-eaha_go(
- target_info_t *tgt,
- int cmd_count,
- int in_count,
- boolean_t cmd_only)/*lint: unused*/
-{
- eaha_softc_t eaha;
- int s;
- erccb *_erccb;
- int len;
- vm_offset_t virt;
- int tid = tgt->target_id ;
-
-#ifdef CBUS
- at386_io_lock_state();
-#endif
- LOG(1,"go");
-
-#ifdef CBUS
- at386_io_lock(MP_DEV_WAIT);
-#endif
- eaha = (eaha_softc_t)tgt->hw_state;
-
- if(eaha->has_sense_info[tid]) {
- (void) eaha_retrieve_sense_info
- (eaha, tid, eaha->sense_info_lun[tid]) ;
- eaha->has_sense_info[tid] = FALSE ;
- if (tgt->cur_cmd == SCSI_CMD_REQUEST_SENSE) {
- bcopy(&eaha_xsns[tid],tgt->cmd_ptr,in_count) ;
- tgt->done = SCSI_RET_SUCCESS;
- tgt->transient_state.cmd_count = cmd_count;
- tgt->transient_state.out_count = 0;
- tgt->transient_state.in_count = in_count;
- /* Fake up interrupt */
- /* Highlights from eaha_initiator_intr(), */
- /* ignoring errors */
- if (tgt->ior)
- (*tgt->dev_ops->restart)( tgt, TRUE);
-#ifdef CBUS
- at386_io_unlock();
-#endif
- return ;
- }
- }
-
-/* XXX delay the handling of the ccb till later */
- _erccb = (erccb *)
- ((unsigned)tgt->cmd_ptr - (unsigned) &((erccb *) 0)->_eccb.cdb);
- /* Tell *rccb about target, eg. id ? */
- _erccb->active_target = tgt;
-
- /*
- * We can do real DMA.
- */
-/* tgt->transient_state.copy_count = 0; unused */
-/* tgt->transient_state.dma_offset = 0; unused */
-
- tgt->transient_state.cmd_count = cmd_count;
-
- if ((tgt->cur_cmd == SCSI_CMD_WRITE) ||
- (tgt->cur_cmd == SCSI_CMD_LONG_WRITE)){
- io_req_t ior = tgt->ior;
- register int len = ior->io_count;
-
- tgt->transient_state.out_count = len;
-
- /* How do we avoid leaks here ? Trust the board
- will do zero-padding, for now. XXX CHECKME */
-#if 0
- if (len < tgt->block_size) {
- bzero(to + len, tgt->block_size - len);
- len = tgt->block_size;
- tgt->transient_state.out_count = len;
- }
-#endif
- } else {
- tgt->transient_state.out_count = 0;
- }
-
- /* See above for in_count < block_size */
- tgt->transient_state.in_count = in_count;
-
- /*
- * Setup CCB state
- */
- tgt->done = SCSI_RET_IN_PROGRESS;
-
- switch (tgt->cur_cmd) {
- case SCSI_CMD_READ:
- case SCSI_CMD_LONG_READ:
- LOG(9,"readop");
- virt = (vm_offset_t)tgt->ior->io_data;
- len = tgt->transient_state.in_count;
- break;
- case SCSI_CMD_WRITE:
- case SCSI_CMD_LONG_WRITE:
- LOG(0x1a,"writeop");
- virt = (vm_offset_t)tgt->ior->io_data;
- len = tgt->transient_state.out_count;
- break;
- case SCSI_CMD_INQUIRY:
- case SCSI_CMD_REQUEST_SENSE:
- case SCSI_CMD_MODE_SENSE:
- case SCSI_CMD_RECEIVE_DIAG_RESULTS:
- case SCSI_CMD_READ_CAPACITY:
- case SCSI_CMD_READ_BLOCK_LIMITS:
- LOG(0x1c,"cmdop");
- LOG(0x80+tgt->cur_cmd,0);
- virt = (vm_offset_t)tgt->cmd_ptr;
- len = tgt->transient_state.in_count;
- break;
- case SCSI_CMD_MODE_SELECT:
- case SCSI_CMD_REASSIGN_BLOCKS:
- case SCSI_CMD_FORMAT_UNIT:
- tgt->transient_state.cmd_count = sizeof(scsi_command_group_0);
- len =
- tgt->transient_state.out_count = cmd_count - sizeof(scsi_command_group_0);
- virt = (vm_offset_t)tgt->cmd_ptr+sizeof(scsi_command_group_0);
- LOG(0x1c,"cmdop");
- LOG(0x80+tgt->cur_cmd,0);
- break;
- default:
- LOG(0x1c,"cmdop");
- LOG(0x80+tgt->cur_cmd,0);
- virt = 0;
- len = 0;
- }
-
- eaha_prepare_rccb(tgt, _erccb, virt, len);
-
- _erccb->_eccb.lun = tgt->lun;
-
- /*
- * XXX here and everywhere, locks!
- */
- s = splbio();
-
- simple_lock(&eaha->aha_lock);
- if (eaha->wd.nactive++ == 0)
- eaha->wd.watchdog_state = SCSI_WD_ACTIVE;
- simple_unlock(&eaha->aha_lock);
-
- LOG(3,"enqueue");
-
- eaha_command(eaha->port, _erccb) ;
-
- splx(s);
-#ifdef CBUS
- at386_io_unlock();
-#endif
-}
-
-eaha_prepare_rccb(
- target_info_t *tgt,
- erccb *_erccb,
- vm_offset_t virt,
- vm_size_t len)
-{
- _erccb->_eccb.cdb_len = tgt->transient_state.cmd_count;
-
- _erccb->_eccb.command = EAHA_CMD_INIT_CMD;/* default common case */
-
- if (virt == 0) {
- /* no xfers */
- _erccb->_eccb.scather = 0 ;
- _erccb->_eccb.scathlen = 0 ;
- _erccb->_eccb.sg = 0 ;
- } else {
- /* messy xfer */
- scather_entry *seglist;
- vm_size_t l1, off;
-
- _erccb->_eccb.sg = 1 ;
-
- if (tgt->dma_ptr == 0)
- eaha_alloc_segment_list(tgt);
- seglist = (scather_entry *) tgt->dma_ptr;
-
- _erccb->_eccb.scather = kvtophys((vm_offset_t) seglist);
-
- l1 = MACHINE_PGBYTES - (virt & (MACHINE_PGBYTES - 1));
- if (l1 > len)
- l1 = len ;
-
- off = 1;/* now #pages */
- while (1) {
- seglist->ptr = kvtophys(virt) ;
- seglist->len = l1 ;
- seglist++;
-
- if (len <= l1)
- break ;
- len-= l1 ;
- virt += l1; off++;
-
- l1 = (len > MACHINE_PGBYTES) ? MACHINE_PGBYTES : len;
- }
- _erccb->_eccb.scathlen = off * sizeof(*seglist);
- }
-}
-
-/*
- * Allocate dynamically segment lists to
- * targets (for scatter/gather)
- */
-vm_offset_t eaha_seglist_next = 0, eaha_seglist_end = 0 ;
-#define EALLOC_SIZE (SCATHER_ENTRIES * sizeof(scather_entry))
-
-eaha_alloc_segment_list(
- target_info_t *tgt)
-{
-
-/* XXX locking */
-/* ? Can't spl() for unknown duration */
- if ((eaha_seglist_next + EALLOC_SIZE) > eaha_seglist_end) {
- (void)kmem_alloc_wired(kernel_map,&eaha_seglist_next,PAGE_SIZE);
- eaha_seglist_end = eaha_seglist_next + PAGE_SIZE;
- }
- tgt->dma_ptr = (char *)eaha_seglist_next;
- eaha_seglist_next += EALLOC_SIZE;
-/* XXX locking */
-}
-
-/*
- *
- * shameless copy from above
- */
-eaha_reset_scsibus(
- register eaha_softc_t eaha)
-{
- register target_info_t *tgt;
- register port = eaha->port;
- register int i;
-
- for (i = 0; i < NECCBS; i++) {
- tgt = eaha->_erccbs[i].active_target;
- if (/*scsi_debug &&*/ tgt)
- printf("Target %d was active, cmd x%x in x%x out x%x\n",
- tgt->target_id, tgt->cur_cmd,
- tgt->transient_state.in_count,
- tgt->transient_state.out_count);
- }
- eaha_reset(eaha, FALSE);
- delay(35);
- /* no interrupt will come */
- eaha_bus_reset(eaha);
-}
-
-boolean_t
-eaha_probe_target(
- target_info_t *tgt,
- io_req_t ior)
-{
- eaha_softc_t eaha = eaha_softc_pool[tgt->masterno];
- boolean_t newlywed;
-
- newlywed = (tgt->cmd_ptr == 0);
- if (newlywed) {
- /* desc was allocated afresh */
- (void) eaha_tgt_alloc(eaha,tgt->target_id, tgt);
- }
-
- if (scsi_inquiry(tgt, SCSI_INQ_STD_DATA) == SCSI_RET_DEVICE_DOWN)
- return FALSE;
-
- tgt->flags = TGT_ALIVE;
- return TRUE;
-}
-
-
-/*
- * Interrupt routine (enhanced mode)
- * Take interrupts from the board
- *
- * Implementation:
- * TBD
- */
-eaha_intr(
- int unit)
-{
- register eaha_softc_t eaha;
- register port;
- unsigned g2intst, g2stat, g2stat2 ;
- vm_offset_t mbi ;
- erccb *_erccb ;
- status_block *status ;
-
-#if MAPPABLE
- extern boolean_t rz_use_mapped_interface;
-
- if (rz_use_mapped_interface) {
- EAHA_intr(unit);
- return ;
- }
-#endif /*MAPPABLE*/
-
- eaha = eaha_softc_pool[unit];
- port = eaha->port;
-
- LOG(5,"\n\tintr");
-gotintr:
- /* collect ephemeral information */
-
- g2intst = inb(G2INTST(port)) ; /* See TRM4-22..23 */
- g2stat = inb(G2STAT(port)) ; /*lint:set,not used*/
- g2stat2 = inb(G2STAT2(port)) ; /*lint:set,not used*/
- mbi = (vm_offset_t) inb(MBOXIN0(port)) + (inb(MBOXIN1(port))<<8) +
- (inb(MBOXIN2(port))<<16) + (inb(MBOXIN3(port))<<24) ;
-
- /* we got an interrupt allright */
- if (eaha->wd.nactive)
- eaha->wd.watchdog_state = SCSI_WD_ACTIVE;
-
- outb(G2CNTRL(port),0x40) ; /* Clear EISA interrupt */
-
- switch(g2intst>>4) {
- case 0x07 : /* hardware error ? */
- case 0x0a : /* immediate command complete - don't expect */
- case 0x0e : /* ditto with failure */
- default :
- printf( "aha%d: Bogus status (x%x) in MBI\n",
- unit, mbi);
- gimmeabreak() ; /* Any of above is disaster */
- break;
-
- case 0x0d : /* Asynchronous event TRM6-41 */
- if ((g2intst & 0x0f) == (inb(SCSIDEF(eaha->port)) & 0x0f))
- eaha_reset_scsibus(eaha) ;
- else
- eaha_target_intr(eaha, mbi, g2intst & 0x0f);
- break;
-
- case 0x0c : /* ccb complete with error */
- case 0x01 : /* ccb completed with success */
- case 0x05 : /* ccb complete with success after retry */
-
- _erccb = (erccb *)
- ( ((vm_offset_t)&eaha->I_hold_my_phys_address) +
- (mbi - eaha->I_hold_my_phys_address) -
- (vm_offset_t)&(((erccb *)0)->_eccb) ) ;
- /* That ain't necessary. As kernel (must be) */
- /* contiguous, only need delta to translate */
-
- status = &_erccb->status ;
-
-#ifdef NOTDEF
- if (!eaha_quiet && (!status->don || status->qf ||
- status->sc || status->dover ||
- status->ini || status->me)) {
- printf("\nccb complete error G2INTST=%02X\n",
- g2intst) ;
- DUMP(*_erccb) ;
- gimmeabreak() ;
- }
-#endif
-
- eaha_initiator_intr(eaha, _erccb);
- break;
- }
-
- /* See if more work ready */
- if (inb(G2STAT(port)) & 0x02) {
- LOG(7,"\n\tre-intr");
- goto gotintr;
- }
-}
-
-/*
- * The interrupt routine turns to one of these two
- * functions, depending on the incoming mbi's role
- */
-eaha_target_intr(
- eaha_softc_t eaha,
- unsigned int mbi,
- unsigned int peer)
-{
- target_info_t *initiator; /* this is the caller */
- target_info_t *self; /* this is us */
- int len;
-
- self = eaha->sc->target[eaha->sc->initiator_id];
-
- initiator = eaha->sc->target[peer];
-
- /* ..but initiators are not required to answer to our inquiry */
- if (initiator == 0) {
- /* allocate */
- initiator = eaha_tgt_alloc(eaha, peer, 0);
-
- /* We do not know here wether the host was down when
- we inquired, or it refused the connection. Leave
- the decision on how we will talk to it to higher
- level code */
- LOG(0xC, "new_initiator");
- sccpu_new_initiator(self, initiator);
- /* Bug fix: was (aha->sc, self, initiator); dph */
- }
-
- /* The right thing to do would be build an ior
- and call the self->dev_ops->strategy routine,
- but we cannot allocate it at interrupt level.
- Also note that we are now disconnected from the
- initiator, no way to do anything else with it
- but reconnect and do what it wants us to do */
-
- /* obviously, this needs both spl and MP protection */
- self->dev_info.cpu.req_pending = TRUE;
- self->dev_info.cpu.req_id = peer ;
- self->dev_info.cpu.req_lun = (mbi>>24) & 0x07 ;
- self->dev_info.cpu.req_cmd =
- (mbi & 0x80000000) ? SCSI_CMD_SEND: SCSI_CMD_RECEIVE;
- len = mbi & 0x00ffffff ;
-
- self->dev_info.cpu.req_len = len;
-
- LOG(0xB,"tgt-mode-restart");
- (*self->dev_ops->restart)( self, FALSE);
-
- /* The call above has either prepared the data,
- placing an ior on self, or it handled it some
- other way */
- if (self->ior == 0)
- return; /* I guess we'll do it later */
-
- {
- erccb *_erccb ;
-
- _erccb = erccb_alloc(eaha) ;
- _erccb->active_target = initiator;
- _erccb->_eccb.command = EAHA_CMD_TARG_CMD ;
- _erccb->_eccb.ses = 1 ;
- _erccb->_eccb.dir = (self->cur_cmd == SCSI_CMD_SEND) ? 1 : 0 ;
-
- eaha_prepare_rccb(initiator, _erccb,
- (vm_offset_t)self->ior->io_data, self->ior->io_count);
- _erccb->_eccb.lun = initiator->lun;
-
- simple_lock(&eaha->aha_lock);
- if (eaha->wd.nactive++ == 0)
- eaha->wd.watchdog_state = SCSI_WD_ACTIVE;
- simple_unlock(&eaha->aha_lock);
-
- eaha_command(eaha->port, _erccb);
- }
-}
-
-eaha_initiator_intr(
- eaha_softc_t eaha,
- erccb *_erccb)
-{
- scsi2_status_byte_t status;
- target_info_t *tgt;
-
- tgt = _erccb->active_target;
- _erccb->active_target = 0;
-
- /* shortcut (sic!) */
- if (_erccb->status.ha_status == HA_STATUS_SUCCESS)
- goto allok;
-
- switch (_erccb->status.ha_status) { /* TRM6-17 */
- case HA_STATUS_SUCCESS :
-allok:
- status = _erccb->status.target_status ;
- if (status.st.scsi_status_code != SCSI_ST_GOOD) {
- scsi_error(tgt, SCSI_ERR_STATUS, status.bits, 0);
- tgt->done = (status.st.scsi_status_code == SCSI_ST_BUSY) ?
- SCSI_RET_RETRY : SCSI_RET_NEED_SENSE;
- } else
- tgt->done = SCSI_RET_SUCCESS;
- break;
-
- case HA_STATUS_SEL_TIMEOUT :
- if (tgt->flags & TGT_FULLY_PROBED)
- tgt->flags = 0; /* went offline */
- tgt->done = SCSI_RET_DEVICE_DOWN;
- break;
-
- case HA_STATUS_OVRUN :
- /* BUT we don't know if this is an underrun.
- It is ok if we get less data than we asked
- for, in a number of cases. Most boards do not
- seem to generate this anyways, but some do. */
- { register int cmd = tgt->cur_cmd;
- switch (cmd) {
- case SCSI_CMD_INQUIRY:
- case SCSI_CMD_REQUEST_SENSE:
- case SCSI_CMD_RECEIVE_DIAG_RESULTS:
- case SCSI_CMD_MODE_SENSE:
- if (_erccb->status.du) /*Ignore underrun only*/
- break;
- default:
- printf("eaha: U/OVRUN on scsi command x%x\n",cmd);
- gimmeabreak();
- }
- }
- goto allok;
- case HA_STATUS_BUS_FREE :
- printf("aha: bad disconnect\n");
- tgt->done = SCSI_RET_ABORTED;
- break;
- case HA_STATUS_PHASE_ERROR :
- /* we'll get an interrupt soon */
- printf("aha: bad PHASE sequencing\n");
- tgt->done = SCSI_RET_ABORTED;
- break;
- case HA_STATUS_BAD_OPCODE :
-printf("aha: BADCCB\n");gimmeabreak();
- tgt->done = SCSI_RET_RETRY;
- break;
-
- case HA_STATUS_HOST_ABORTED :
- case HA_STATUS_ADP_ABORTED :
- case HA_STATUS_NO_FIRM :
- case HA_STATUS_NOT_TARGET :
- case HA_STATUS_INVALID_LINK : /* These aren't expected. */
- case HA_STATUS_BAD_CBLOCK :
- case HA_STATUS_DUP_CBLOCK :
- case HA_STATUS_BAD_SCATHER :
- case HA_STATUS_RSENSE_FAIL :
- case HA_STATUS_TAG_REJECT :
- case HA_STATUS_HARD_ERROR :
- case HA_STATUS_TARGET_NOATTN :
- case HA_STATUS_HOST_RESET :
- case HA_STATUS_OTHER_RESET :
- case HA_STATUS_PROG_BAD_SUM :
- default :
- printf("aha: bad ha_status (x%x)\n", _erccb->status.ha_status);
- tgt->done = SCSI_RET_ABORTED;
- break;
- }
-
- eaha->has_sense_info [tgt->target_id] =
- (tgt->done == SCSI_RET_NEED_SENSE) ;
- if (eaha->has_sense_info [tgt->target_id])
- eaha->sense_info_lun [tgt->target_id] = tgt->lun ;
-
- LOG(8,"end");
-
- simple_lock(&eaha->aha_lock);
- if (eaha->wd.nactive-- == 1)
- eaha->wd.watchdog_state = SCSI_WD_INACTIVE;
- simple_unlock(&eaha->aha_lock);
-
- if (tgt->ior) {
- LOG(0xA,"ops->restart");
- (*tgt->dev_ops->restart)( tgt, TRUE);
- }
-
- return FALSE;/*lint: Always returns FALSE. ignored. */
-}
-
-#endif /* NEAHA > 0 */
diff --git a/scsi/adapters/scsi_dma.h b/scsi/adapters/scsi_dma.h
deleted file mode 100644
index 9401a16..0000000
--- a/scsi/adapters/scsi_dma.h
+++ /dev/null
@@ -1,150 +0,0 @@
-/*
- * Mach Operating System
- * Copyright (c) 1991,1990,1989 Carnegie Mellon University
- * All Rights Reserved.
- *
- * Permission to use, copy, modify and distribute this software and its
- * documentation is hereby granted, provided that both the copyright
- * notice and this permission notice appear in all copies of the
- * software, derivative works or modified versions, and any portions
- * thereof, and that both notices appear in supporting documentation.
- *
- * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS AS-IS
- * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
- * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
- *
- * Carnegie Mellon requests users of this software to return to
- *
- * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
- * School of Computer Science
- * Carnegie Mellon University
- * Pittsburgh PA 15213-3890
- *
- * any improvements or extensions that they make and grant Carnegie Mellon
- * the rights to redistribute these changes.
- */
-/*
- * File: scsi_dma.h
- * Author: Alessandro Forin, Carnegie Mellon University
- * Date: 7/91
- *
- * DMA operations that an HBA driver might invoke.
- *
- */
-
-/*
- * This defines much more than usually needed, mainly
- * to cover for the case of no DMA at all and/or only
- * DMA from/to a specialized buffer ( which means the
- * CPU has to copy data into/outof it ).
- */
-
-typedef struct {
- opaque_t (*init)(
- int dev_unit,
- vm_offset_t base,
- int *dma_bsizep,
- boolean_t *oddbp);
-
- void (*new_target)(
- opaque_t dma_state,
- target_info_t *tgt);
-
- void (*map)(
- opaque_t dma_state,
- target_info_t *tgt);
-
- int (*start_cmd)(
- opaque_t dma_state,
- target_info_t *tgt);
-
- void (*end_xfer)(
- opaque_t dma_state,
- target_info_t *tgt,
- int xferred);
-
- void (*end_cmd)(
- opaque_t dma_state,
- target_info_t *tgt,
- io_req_t ior);
-
- int (*start_datain)(
- opaque_t dma_state,
- target_info_t *tgt);
-
- int (*start_msgin)(
- opaque_t dma_state,
- target_info_t *tgt);
-
- void (*end_msgin)(
- opaque_t dma_state,
- target_info_t *tgt);
-
- boolean_t (*start_dataout)(
- opaque_t dma_state,
- target_info_t *tgt,
- volatile unsigned *regp,
- unsigned value,
- unsigned char *prefetch_count);
-
- int (*restart_datain_1)(
- opaque_t dma_state,
- target_info_t *tgt);
-
- int (*restart_datain_2)(
- opaque_t dma_state,
- target_info_t *tgt,
- int xferred);
-
- void (*restart_datain_3)(
- opaque_t dma_state,
- target_info_t *tgt);
-
- int (*restart_dataout_1)(
- opaque_t dma_state,
- target_info_t *tgt);
-
- int (*restart_dataout_2)(
- opaque_t dma_state,
- target_info_t *tgt,
- int xferred);
-
- int (*restart_dataout_3)(
- opaque_t dma_state,
- target_info_t *tgt,
- volatile unsigned *regp);
-
- void (*restart_dataout_4)(
- opaque_t dma_state,
- target_info_t *tgt);
-
- boolean_t (*disconn_1)(
- opaque_t dma_state,
- target_info_t *tgt,
- int xferred);
-
- boolean_t (*disconn_2)(
- opaque_t dma_state,
- target_info_t *tgt);
-
- boolean_t (*disconn_3)(
- opaque_t dma_state,
- target_info_t *tgt,
- int xferred);
-
- boolean_t (*disconn_4)(
- opaque_t dma_state,
- target_info_t *tgt,
- int xferred);
-
- boolean_t (*disconn_5)(
- opaque_t dma_state,
- target_info_t *tgt,
- int xferred);
-
- void (*disconn_callback)(
- opaque_t dma_state,
- target_info_t *tgt);
-
-} scsi_dma_ops_t;
-
diff --git a/scsi/adapters/scsi_user_dma.c b/scsi/adapters/scsi_user_dma.c
deleted file mode 100644
index 5fb98d6..0000000
--- a/scsi/adapters/scsi_user_dma.c
+++ /dev/null
@@ -1,171 +0,0 @@
-/*
- * Mach Operating System
- * Copyright (c) 1991,1990 Carnegie Mellon University
- * All Rights Reserved.
- *
- * Permission to use, copy, modify and distribute this software and its
- * documentation is hereby granted, provided that both the copyright
- * notice and this permission notice appear in all copies of the
- * software, derivative works or modified versions, and any portions
- * thereof, and that both notices appear in supporting documentation.
- *
- * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS
- * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
- * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
- *
- * Carnegie Mellon requests users of this software to return to
- *
- * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
- * School of Computer Science
- * Carnegie Mellon University
- * Pittsburgh PA 15213-3890
- *
- * any improvements or extensions that they make and grant Carnegie the
- * rights to redistribute these changes.
- */
-/*
- * File: scsi_user_dma.c
- * Author: Alessandro Forin, Carnegie Mellon University
- * Date: 4/91
- *
- * Mach 2.5 compat file, to handle case of DMA to user space
- * [e.g. fsck and other raw device accesses]
- */
-
-#ifdef MACH_KERNEL
-/* We do not need this in 3.0 */
-#else /*MACH_KERNEL*/
-
-#include <mach/std_types.h>
-#include <scsi/adapters/scsi_user_dma.h>
-
-#include <kern/assert.h>
-
-#include <vm/vm_kern.h>
-#include <mach/vm_param.h> /* round_page() */
-
-/* bp -> pmap */
-#include <sys/buf.h>
-#include <sys/proc.h>
-
-/*
- * Initialization, called once per device
- */
-fdma_init(fdma, size)
- fdma_t fdma;
- vm_size_t size;
-{
- vm_offset_t addr;
-
- size = round_page(size);
- addr = kmem_alloc_pageable(kernel_map, size);
- if (addr == 0) panic("fdma_init");
-
- fdma->kernel_virtual = addr;
- fdma->max_data = size;
- fdma->user_virtual = -1;
-
-}
-
-/*
- * Remap a buffer from user space to kernel space.
- * Note that physio() has already validated
- * and wired the user's address range.
- */
-fdma_map(fdma, bp)
- fdma_t fdma;
- struct buf *bp;
-{
- pmap_t pmap;
- vm_offset_t user_addr;
- vm_size_t size;
- vm_offset_t kernel_addr;
- vm_offset_t off;
- vm_prot_t prot;
-
- /*
- * If this is not to user space, or no data xfer is
- * involved, no need to do anything.
- */
- user_addr = (vm_offset_t)bp->b_un.b_addr;
- if (!(bp->b_flags & B_PHYS) || (user_addr == 0)) {
- fdma->user_virtual = -1;
- return;
- }
- /*
- * We are going to clobber the buffer pointer, so
- * remember what it was to restore it later.
- */
- fdma->user_virtual = user_addr;
-
- /*
- * Account for initial offset into phys page
- */
- off = user_addr - trunc_page(user_addr);
-
- /*
- * Check xfer size makes sense, note how many pages we'll remap
- */
- size = bp->b_bcount + off;
- assert((size <= fdma->max_data));
- fdma->xfer_size_rnd = round_page(size);
-
- pmap = bp->b_proc->task->map->pmap;
-
- /*
- * Use minimal protection possible
- */
- prot = VM_PROT_READ;
- if (bp->b_flags & B_READ)
- prot |= VM_PROT_WRITE;
-
- /*
- * Loop through all phys pages, taking them from the
- * user pmap (they are wired) and inserting them into
- * the kernel pmap.
- */
- user_addr -= off;
- kernel_addr = fdma->kernel_virtual;
- bp->b_un.b_addr = (char *)kernel_addr + off;
-
- for (size = fdma->xfer_size_rnd; size; size -= PAGE_SIZE) {
- register vm_offset_t phys;
-
- phys = pmap_extract(pmap, user_addr);
- pmap_enter(kernel_pmap, kernel_addr, phys, prot, TRUE);
- user_addr += PAGE_SIZE;
- kernel_addr += PAGE_SIZE;
- }
-}
-
-/*
- * Called at end of xfer, to restore the buffer
- */
-fdma_unmap(fdma, bp)
- fdma_t fdma;
- struct buf *bp;
-{
- register vm_offset_t end_addr;
-
- /*
- * Check we actually did remap it
- */
- if (fdma->user_virtual == -1)
- return;
-
- /*
- * Restore the buffer
- */
- bp->b_un.b_addr = (char *)fdma->user_virtual;
- fdma->user_virtual = -1;
-
- /*
- * Eliminate the mapping, pmap module might mess up
- * the pv list otherwise. Some might actually tolerate it.
- */
- end_addr = fdma->kernel_virtual + fdma->xfer_size_rnd;
- pmap_remove(kernel_pmap, fdma->kernel_virtual, end_addr);
-
-}
-
-#endif /*MACH_KERNEL*/
diff --git a/scsi/adapters/scsi_user_dma.h b/scsi/adapters/scsi_user_dma.h
deleted file mode 100644
index ff2682c..0000000
--- a/scsi/adapters/scsi_user_dma.h
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * Mach Operating System
- * Copyright (c) 1991,1990 Carnegie Mellon University
- * All Rights Reserved.
- *
- * Permission to use, copy, modify and distribute this software and its
- * documentation is hereby granted, provided that both the copyright
- * notice and this permission notice appear in all copies of the
- * software, derivative works or modified versions, and any portions
- * thereof, and that both notices appear in supporting documentation.
- *
- * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS
- * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
- * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
- *
- * Carnegie Mellon requests users of this software to return to
- *
- * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
- * School of Computer Science
- * Carnegie Mellon University
- * Pittsburgh PA 15213-3890
- *
- * any improvements or extensions that they make and grant Carnegie the
- * rights to redistribute these changes.
- */
-/*
- * File: scsi_user_dma.h
- * Author: Alessandro Forin, Carnegie Mellon University
- * Date: 4/91
- *
- * Defines for Mach 2.5 compat, user-space DMA routines
- */
-
-/* There is one such structure per I/O device
- that needs to xfer data to/from user space */
-
-typedef struct fdma {
- vm_offset_t kernel_virtual;
- vm_size_t max_data;
- vm_offset_t user_virtual;
- int xfer_size_rnd;
-} *fdma_t;
-
-extern int
- fdma_init(/* fdma_t, vm_size_t */),
- fdma_map(/* fdma_t, struct buf* */),
- fdma_unmap(/* fdma_t, struct buf* */);
diff --git a/scsi/compat_30.h b/scsi/compat_30.h
deleted file mode 100644
index 988aed7..0000000
--- a/scsi/compat_30.h
+++ /dev/null
@@ -1,163 +0,0 @@
-/*
- * Mach Operating System
- * Copyright (c) 1991,1990 Carnegie Mellon University
- * All Rights Reserved.
- *
- * Permission to use, copy, modify and distribute this software and its
- * documentation is hereby granted, provided that both the copyright
- * notice and this permission notice appear in all copies of the
- * software, derivative works or modified versions, and any portions
- * thereof, and that both notices appear in supporting documentation.
- *
- * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
- * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
- * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
- *
- * Carnegie Mellon requests users of this software to return to
- *
- * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
- * School of Computer Science
- * Carnegie Mellon University
- * Pittsburgh PA 15213-3890
- *
- * any improvements or extensions that they make and grant Carnegie Mellon
- * the rights to redistribute these changes.
- */
-/*
- * File: compat_30.h
- * Author: Alessandro Forin, Carnegie Mellon University
- * Date: 4/91
- *
- * Compatibility defs to retrofit Mach 3.0 drivers
- * into Mach 2.6.
- */
-
-#ifndef _SCSI_COMPAT_30_
-#define _SCSI_COMPAT_30_
-
-#include <kern/assert.h>
-
-#ifdef MACH_KERNEL
-/*
- * Mach 3.0 compiles with these definitions
- */
-
-#include <device/param.h>
-#include <device/io_req.h>
-#include <device/device_types.h>
-#include <device/disk_status.h>
-
-/*
- * Scratch temporary in io_req structure (for error handling)
- */
-#define io_temporary io_error
-
-#else /*MACH_KERNEL*/
-/*
- * Mach 2.x compiles with these definitions
- */
-
-/* ??? */
-typedef int dev_mode_t;
-typedef int *dev_status_t; /* Variable-length array of integers */
-/* ??? */
-
-/* Buffer structures */
-
-typedef int io_return_t;
-
-#include <sys/param.h>
-#include <sys/buf.h>
-
-#define io_req buf
-typedef struct buf *io_req_t;
-
-#define io_req_alloc(ior,size) ior = geteblk(size)
-#define io_req_free(ior) brelse(ior)
-
-/*
- * Redefine fields for drivers using new names
- */
-#define io_op b_flags
-#define io_count b_bcount
-#define io_error b_error
-#define io_unit b_dev
-#define io_recnum b_blkno
-#define io_residual b_resid
-#define io_data b_un.b_addr
-#define io_done b_iodone
-
-/*
- * Redefine fields for driver request list heads, using new names.
- */
-#define io_next av_forw
-#define io_prev av_back
-/*#define io_next b_actf*/
-/*#define io_prev b_actl*/
-#define io_link b_forw
-#define io_rlink b_back
-/*#define io_count b_active*/
-/*#define io_residual b_errcnt*/
-#define io_alloc_size b_bufsize
-
-/*
- * Scratch temporary in io_req structure (for error handling)
- */
-#define io_temporary b_pfcent
-
-/*
- * Redefine flags
- */
-#define IO_WRITE B_WRITE
-#define IO_READ B_READ
-#define IO_OPEN B_OPEN
-#define IO_DONE B_DONE
-#define IO_ERROR B_ERROR
-#define IO_BUSY B_BUSY
-#define IO_WANTED B_WANTED
-#define IO_BAD B_BAD
-#define IO_CALL B_CALL
-#define IO_INTERNAL B_MD1
-
-#define IO_SPARE_START B_MD1
-
-#include <sys/disklabel.h>
-
-/* Error codes */
-
-#include <sys/errno.h>
-
-#define D_SUCCESS ESUCCESS
-#define D_IO_ERROR EIO
-#define D_NO_SUCH_DEVICE ENXIO
-#define D_INVALID_SIZE EINVAL
-#define D_ALREADY_OPEN EBUSY
-#define D_INVALID_OPERATION EINVAL
-#define D_NO_MEMORY ENOMEM
-#define D_WOULD_BLOCK EWOULDBLOCK
-#define D_DEVICE_DOWN EIO
-#define D_READ_ONLY EROFS
-
-/*
- * Debugging support
- */
-#define db_printf kdbprintf
-#define db_printsym(s,m) kdbpsymoff(s,1,"")
-
-/*
- * Miscellaneous utils
- */
-
-#define check_memory(addr,dow) ((dow) ? wbadaddr(addr,4) : badaddr(addr,4))
-
-#include <sys/kernel.h> /* for hz */
-#include <scsi/adapters/scsi_user_dma.h>
-
-#ifdef DECSTATION
-#include <mach/mips/vm_param.h> /* for page size */
-#define ULTRIX_COMPAT 1 /* support for rzdisk disk formatter */
-#endif /*DECSTATION*/
-
-#endif /*MACH_KERNEL*/
-
-#endif /*_SCSI_COMPAT_30_*/
diff --git a/scsi/disk_label.c b/scsi/disk_label.c
deleted file mode 100644
index ab20378..0000000
--- a/scsi/disk_label.c
+++ /dev/null
@@ -1,692 +0,0 @@
-/*
- * Copyright (c) 1996 The University of Utah and
- * the Computer Systems Laboratory at the University of Utah (CSL).
- * All rights reserved.
- *
- * Permission to use, copy, modify and distribute this software is hereby
- * granted provided that (1) source code retains these copyright, permission,
- * and disclaimer notices, and (2) redistributions including binaries
- * reproduce the notices in supporting documentation, and (3) all advertising
- * materials mentioning features or use of this software display the following
- * acknowledgement: ``This product includes software developed by the
- * Computer Systems Laboratory at the University of Utah.''
- *
- * THE UNIVERSITY OF UTAH AND CSL ALLOW FREE USE OF THIS SOFTWARE IN ITS "AS
- * IS" CONDITION. THE UNIVERSITY OF UTAH AND CSL DISCLAIM ANY LIABILITY OF
- * ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
- *
- * CSL requests users of this software to return to csl-dist@cs.utah.edu any
- * improvements that they make and grant CSL redistribution rights.
- *
- * Author: Kevin T. Van Maren, University of Utah CSL
- */
-
-/*
- * Mach Operating System
- * Copyright (c) 1991,1990 Carnegie Mellon University
- * All Rights Reserved.
- *
- * Permission to use, copy, modify and distribute this software and its
- * documentation is hereby granted, provided that both the copyright
- * notice and this permission notice appear in all copies of the
- * software, derivative works or modified versions, and any portions
- * thereof, and that both notices appear in supporting documentation.
- *
- * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
- * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
- * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
- *
- * Carnegie Mellon requests users of this software to return to
- *
- * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
- * School of Computer Science
- * Carnegie Mellon University
- * Pittsburgh PA 15213-3890
- *
- * any improvements or extensions that they make and grant Carnegie Mellon
- * the rights to redistribute these changes.
- */
-
-/*
- * Copyright (c) 1994 Shantanu Goel
- * All Rights Reserved.
- *
- * Permission to use, copy, modify and distribute this software and its
- * documentation is hereby granted, provided that both the copyright
- * notice and this permission notice appear in all copies of the
- * software, derivative works or modified versions, and any portions
- * thereof, and that both notices appear in supporting documentation.
- *
- * THE AUTHOR ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
- * CONDITION. THE AUTHOR DISCLAIMS ANY LIABILITY OF ANY KIND FOR
- * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
- *
- */
-
-/* This file contains the partition code that is used by the Mach
- * device drivers (ide & scsi). */
-
-#include <scsi/compat_30.h>
-#include <sys/types.h>
-
-#include <scsi/rz_labels.h>
-#include <i386at/disk.h> /* combine & rename these... */
-
-#define SECTOR_SIZE 512 /* BAD!!! */
-
-#define DSLICE(dev) ((dev >> 4) & 0x3f)
-#define DPART(dev) (dev & 0xf)
-
-/* note: 0 will supress ALL output;
- 1 is 'normal' output; 2 is verbose; 3 is Very verbose */
-#define PARTITION_DEBUG 1
-
-#define min(x,y) (x<y?x:y)
-
-/*
- * Label that is filled in with extra info
- */
-struct disklabel default_label =
-{
- DISKMAGIC, DTYPE_SCSI, 0,
- "SCSI", "",
- DEV_BSIZE, 1, 1, 1, 1, 1, 0, 0, 0,
- 3600, 1, 1, 1, 0, 0, 0,
- {0,}, {0,},
- DISKMAGIC, 0,
- 8, 8192, 8192,
- {{ -1, 0, 1024, FS_BSDFFS, 8, 3 },
- { -1, 0, 1024, FS_BSDFFS, 8, 3 },
- { -1, 0, 1024, FS_BSDFFS, 8, 3 },
- { -1, 0, 1024, FS_BSDFFS, 8, 3 },
- { -1, 0, 1024, FS_BSDFFS, 8, 3 },
- { -1, 0, 1024, FS_BSDFFS, 8, 3 },
- { -1, 0, 1024, FS_BSDFFS, 8, 3 },
- { -1, 0, 1024, FS_BSDFFS, 8, 3 }}
-};
-
-
-
-/* the device driver calls this just to save some info it got from the HW */
-/* This is a bad holdover from the disklabel days, and needs to go */
-fudge_bsd_label(struct disklabel *label, int type, int total_secs, int heads, int sectors, int sectorsize, int n)
-{
- *label=default_label;
-
- label->d_ncylinders = total_secs/(heads*sectors);
- label->d_ntracks = heads;
- label->d_nsectors = sectors;
-
- label->d_secpercyl = heads*sectors;
- label->d_secperunit = total_secs;
-
- /* this is never used, but ... */
- label->d_partitions[MAXPARTITIONS].p_offset = 0;
- label->d_partitions[MAXPARTITIONS].p_size = total_secs;
-
- /* ??
- */
- label->d_secsize = sectorsize;
- label->d_type = type;
- label->d_subtype = 0xa; /* ??? */
-
- label->d_npartitions = n; /* up to 'c' */
- label->d_checksum = 0;
-
- /* should do a checksum on it now */
-}
-
-
-
-/* This is placed here to
- a. provide comparability with existing servers
- b. allow the use of FreeBSD-style slices to access ANY disk partition
- c. provide an easy migration path to lites-based partition code
- by only passing the drive name to get the entire disk (sd0).
-
- This will be called by every routine that needs to access partition info
- based on a device number. It is slower than the old method of indexing
- into a disklabel, but is more flexible, and reasonably fast in the (future)
- case where Lites will access the whole disk. An array of disklabels
- could have been used, but this is more compact and general. The underlying
- structure does not limit it to 2-levels, but keeping the kernel interface
- simple does. */
-
-
-/* this code and data structure based on conversation with Bryan Ford */
-/* Note: this is called ON EVERY read or write. It makes sense to
- optimize this for the common case. Hopefully the common case
- will become the '0,0' case, as partitioning is moved out of the
- kernel. (Downside is kernel can't protect filesystems from each other).
- It is slower than indexing into a 1-D array, but not much. */
-
-struct diskpart *lookup_part(struct diskpart *array, int dev_number)
-{
-/* Note: 10 bit encoding to get partitions 0-15 (0,a-h typically), and slices
- * 0-63
- */
-
- int slice = DSLICE(dev_number);
- int part = DPART(dev_number);
- struct diskpart *s;
-
- if (slice == 0) /* compatability slice */
- {
- if (part == 0) /* whole disk */
- return &array[0];
-
- if (array[0].type == DISKPART_DOS)
- {
- int i;
- for (i = 0; i < array[0].nsubs; i++)
- {
- s = &array[0].subs[i];
- if ( s->type == DISKPART_BSD
- || s->type == DISKPART_VTOC)
- {
- if (part > s->nsubs)
- return 0;
- return (&s->subs[part-1]);
- }
- }
- }
-
- if (part > array[0].nsubs)
- return 0;
- return(&array[0].subs[part-1]);
- }
- else
- {
- if ( array[0].type != DISKPART_DOS
- || slice > array[0].nsubs)
- return 0;
-
- s = &array[0].subs[slice-1];
-
- if (part == 0) /* whole slice */
- return (s);
- if (part > s->nsubs)
- return 0;
-
- return (&s->subs[part-1]);
- }
-}
-
-
-
-
-static inline void fill_array(struct diskpart *array, int start, int size,
- struct diskpart *subs, int nsubs, short type, short fsys)
-{
- array->start=start;
- array->size=size;
- array->subs=subs;
- array->nsubs=nsubs;
- array->type=type;
- array->fsys=fsys;
-#if (PARTITION_DEBUG > 2)
- printf("fill: type %d:%d, start %d, size %d, %d parts\n",type,fsys,
- start,size,nsubs);
-#endif
-}
-
-
-
-
-void print_array(struct diskpart *array, int level)
-{
- int i,j;
- struct diskpart *subs;
-
-#if (PARTITION_DEBUG)
- subs=array[0].subs;
-
- for (i=0;i<array[0].nsubs;i++) {
- for (j=0;j<level;j++)
- printf(" ");
- printf("%c: %d, %d, %d, %d (%d subparts)\n",'a'+i,
- subs[i].start, subs[i].size, subs[i].fsys,
- subs[i].type, subs[i].nsubs);
- if (subs[i].nsubs>0)
- print_array(&subs[i], level+1);
- }
-#endif
-}
-
-
-
-/* individual routines to find the drive labels.
- There needs to be a function for every different method for partitioning
- much of the following code is derived from the SCSI/IDE drivers */
-
-int get_dos(struct diskpart *array, char *buff, int start,
- void *driver_info, int (*bottom_read_fun)(),
- char *name, int max_part)
-{
-
- bios_label_t *mp;
- struct bios_partition_info *pp;
-
- int count, i, j;
- int pstart, psize;
- int ext=-1, mystart=start, mybase;
- int first=1;
-
- /* note: start is added, although a start != 0 is meaningless
- to DOS and anything else... */
-
- /* check the boot sector for a partition table. */
- (*bottom_read_fun)(driver_info, start, buff); /* always in sector 0 */
-
- /*
- * Check for valid partition table.
- */
- mp = (bios_label_t *)&buff[BIOS_LABEL_BYTE_OFFSET];
- if (mp->magic != BIOS_LABEL_MAGIC) {
-#if (PARTITION_DEBUG>1)
- printf("%s invalid partition table\n", name);
-#endif
- return(0); /* didn't add any partitions */
- }
-#if (PARTITION_DEBUG>1)
- printf("DOS partition table found\n");
-#endif
-
- count=min(4,max_part); /* always 4 (primary) partitions */
-#if (PARTITION_DEBUG)
- if (count<4) printf("More partitions than space!\n");
-#endif
-
-
- /* fill the next 4 entries in the array */
- for (i=0, pp=(struct bios_partition_info *)mp->partitions;
- i<count; i++,pp++) {
-
- fill_array(&array[i], pp->offset, pp->n_sectors, NULL, 0,
- DISKPART_NONE, pp->systid);
- if ((pp->systid == DOS_EXTENDED) &&(ext<0)) {
- mystart+=pp->offset;
- ext=i;
- }
- }
-
- /* if there is an extended partition, find all the logical partitions */
- /* note: logical start at '5' (extended is one of the numbered 1-4) */
-
- /* logical partitions 'should' be nested inside the primary, but
- then it would be impossible to NAME a disklabel inside a logical
- partition, which would be nice to do */
-#if (PARTITION_DEBUG>1)
- if (ext>=0)
- printf("extended partition found: %d\n",ext);
-#endif 0
-
- while (ext>=0) {
- pp = &(((struct bios_partition_info *)mp->partitions)[ext]);
-
- /* read the EXTENDED partition table */
- if (first) {
- mybase=mystart;
- first=0;
- } else {
- mybase=mystart+pp->offset;
- }
-
- (*bottom_read_fun)(driver_info, mybase, buff);
-
- if (mp->magic != BIOS_LABEL_MAGIC) {
-#if (PARTITION_DEBUG>1)
- printf("%s invalid expanded magic\n", name);
-#endif
- return(count);/*don't add any more partitions*/
- }
-
- /* just in case more than one partition is there...*/
- /* search the EXTENDED partition table */
- ext=-1;
- for (j=0,pp=(struct bios_partition_info *)mp->partitions;
- j<4; j++,pp++) {
-
- if (pp->systid && (pp->systid!=DOS_EXTENDED)) {
- if (count<max_part) {
- fill_array(&array[count],
- mybase +pp->offset,
- pp->n_sectors, NULL, 0, DISKPART_NONE,
- pp->systid);
- count++; }
- else {
-#if (PARTITION_DEBUG)
- printf("More partitions than space!\n");
-#endif
- return(count);
- }
- } else if ((ext<0) &&(pp->systid==DOS_EXTENDED)) {
- ext=j;
- /* recursivly search the chain here */
- }
- }
- }
-#if (PARTITION_DEBUG>1)
- printf("%d dos partitions\n",count);
-#endif 0
- return(count); /* number dos partitions found */
-
-}
-
-
-
-/* this should work on the bare drive, or in a dos partition */
-int get_disklabel(struct diskpart *array, char *buff, int start,
- void *driver_info, int (*bottom_read_fun)(),
- char *name, int max_part)
-{
- struct disklabel *dlp;
- int mybase = start + (512 * LBLLOC)/SECTOR_SIZE, i;
- int count;
-
- (*bottom_read_fun)(driver_info, mybase, buff);
-
- dlp = (struct disklabel *)buff;
- if (dlp->d_magic != DISKMAGIC || dlp->d_magic2 != DISKMAGIC) {
-#if (PARTITION_DEBUG>1)
- printf("%s no BSD label found\n",name);
-#endif
- return(0); /* no partitions added */
- }
-#if (PARTITION_DEBUG>1)
- printf(" BSD LABEL\n");
-#endif 0
- /* note: BSD disklabel offsets are from start of DRIVE -- uuggh */
-
- count=min(8,max_part); /* always 8 in a disklabel */
-#if (PARTITION_DEBUG)
- if (count<8) printf("More partitions than space!\n");
-#endif
- /* COPY into the array */
- for (i=0;i<count;i++)
- fill_array(&array[i], /* mybase + */
- dlp->d_partitions[i].p_offset,
- dlp->d_partitions[i].p_size,
- NULL, 0, DISKPART_NONE, dlp->d_partitions[i].p_fstype);
-
- /* note: p_fstype is not the same set as the DOS types */
-
- return(count); /* 'always' 8 partitions in disklabel -- if space */
-
-/* UNREACHED CODE FOLLOWS: (alternative method in scsi) */
-#if 0
- (*bottom_read_fun)(driver_info, (start)+LABELSECTOR, buff);
-
- register int j;
- boolean_t found;
-
- for (j = LABELOFFSET, found = FALSE;
- j < (SECTOR_SIZE-sizeof(struct disklabel));
- j += sizeof(int)) {
- search = (struct disklabel *)&buff[j];
- if (search->d_magic == DISKMAGIC &&
- search->d_magic2 == DISKMAGIC) {
- found = TRUE;
- break;
- }
- }
- if (found) {
-#if (PARTITION_DEBUG>1)
- printf("Label found in LABELSECTOR\n");
-#endif
- } else {
- search = 0;
- }
-
-
-#endif 0
-
-}
-
-
-/* NOT TESTED! */
-/* VTOC in sector 29 */
-int get_vtoc(struct diskpart *array, char *buff, int start,
- void *driver_info, int (*bottom_read_fun)(),
- char *name, int max_part)
-{
- struct evtoc *evp;
- int n,i;
- struct disklabel lpl;
- struct disklabel *lp = &lpl;
-
-#if (PARTITION_DEBUG)
- printf("Read VTOC.\n");
-#endif
- (*bottom_read_fun)(driver_info, start +PDLOCATION, buff);
- evp = (struct evtoc *)buff;
- if (evp->sanity != VTOC_SANE) {
-#if (PARTITION_DEBUG)
- printf("%s evtoc corrupt or not found\n", name);
-#endif
- return(0);
- }
- n = min(evp->nparts,max_part); /* no longer DISKLABEL limitations... */
-#if 0
- n = (evp->nparts > MAXPARTITIONS) ? MAXPARTITIONS : evp->nparts;
-#endif 0
-
- for (i = 0; i < n; i++)
- fill_array(&array[i], /* mybase + */
- evp->part[i].p_start,
- evp->part[i].p_size,
- NULL, 0, DISKPART_NONE, FS_BSDFFS);
-
- return(n); /* (evp->nparts) */
-}
-
-
-/* NOT TESTED! */
-int get_omron(struct diskpart *array, char *buff, int start,
- void *driver_info, int (*bottom_read_fun)(),
- char *name, int max_part)
-{
-
- struct disklabel *label;
-
- /* here look for an Omron label */
- register omron_label_t *part;
- int i;
-
-#if (PARTITION_DEBUG)
- printf("Looking for Omron label...\n");
-#endif
-
- (*bottom_read_fun)(driver_info, start+
- OMRON_LABEL_BYTE_OFFSET/SECTOR_SIZE, buff);
-
- part = (omron_label_t*)&buff[OMRON_LABEL_BYTE_OFFSET%SECTOR_SIZE];
- if (part->magic == OMRON_LABEL_MAGIC) {
-#if (PARTITION_DEBUG)
- printf("{Using OMRON label}");
-#endif
- for (i = 0; i < 8; i++) {
- label->d_partitions[i].p_size = part->partitions[i].n_sectors;
- label->d_partitions[i].p_offset = part->partitions[i].offset;
- }
- bcopy(part->packname, label->d_packname, 16);
- label->d_ncylinders = part->ncyl;
- label->d_acylinders = part->acyl;
- label->d_ntracks = part->nhead;
- label->d_nsectors = part->nsect;
- /* Many disks have this wrong, therefore.. */
-#if 0
- label->d_secperunit = part->maxblk;
-#else
- label->d_secperunit = label->d_ncylinders * label->d_ntracks *
- label->d_nsectors;
-#endif 0
-
- return(8);
- }
-#if (PARTITION_DEBUG)
- printf("No Omron label found.\n");
-#endif
- return(0);
-}
-
-
-/* NOT TESTED! */
-int get_dec(struct diskpart *array, char *buff, int start,
- void *driver_info, int (*bottom_read_fun)(),
- char *name, int max_part)
-{
- struct disklabel *label;
-
- /* here look for a DEC label */
- register dec_label_t *part;
- int i;
-
-#if (PARTITION_DEBUG)
- printf("Checking for dec_label...\n");
-#endif
-
- (*bottom_read_fun)(driver_info, start +
- DEC_LABEL_BYTE_OFFSET/SECTOR_SIZE, buff);
-
- if (part->magic == DEC_LABEL_MAGIC) {
-#if (PARTITION_DEBUG)
- printf("{Using DEC label}");
-#endif
- for (i = 0; i < 8; i++) {
- label->d_partitions[i].p_size = part->partitions[i].n_sectors;
- label->d_partitions[i].p_offset = part->partitions[i].offset;
- }
- return(8);
- }
-#if (PARTITION_DEBUG)
- printf("No dec label found.\n");
-#endif
-
- return(0);
-}
-
-
-
-
-/* array is a pointer to an array of partition_info structures */
-/* array_size is the number of pre-allocated entries there are */
-int get_only_partition(void *driver_info, int (*bottom_read_fun)(),
- struct diskpart *array, int array_size,
- int disk_size, char *drive_name)
-{
- char buff[SECTOR_SIZE];
- int i,n,cnt;
- int arrsize;
- struct diskpart *res;
-
- /* first fill in the entire disk stuff */
- /* or should the calling routine do that already? */
-
- fill_array(array, 0, disk_size, NULL, 0, -1, -1);
-
- /* while the structure does not preclude additional nestings,
- additional ones make no sense currently, so they are not
- checked (Mach can't handle them anyway). It might be nice
- if for all partitions found, all types of sub-partitions
- were looked for (unnecessary). This will be done when this
- is moved out of ther kernel, and there is some way to name them */
-
- arrsize = array_size -1; /* 1 for whole disk */
-
- /* search for dos partition table */
- /* find all the partitions (including logical) */
- n=get_dos(&array[1], buff, 0,
- driver_info, (bottom_read_fun), drive_name,
- arrsize);
-
- if (n>0) {
- fill_array(array, 0, disk_size, &array[1], n,
- DISKPART_DOS, 256+DISKPART_DOS);
- arrsize-=n;
-
-
- /* search each one for a BSD disklabel (iff BSDOS) */
- /* note: searchine extended and logical partitions */
- for (i=0;i<n;i++)
- if (array[i+1].fsys==BSDOS) {
-#if (PARTITION_DEBUG)
- printf("BSD OS slice: %d\n",i+1);
-#endif
- cnt=get_disklabel(&array[n+1], buff,
- array[i+1].start,
- driver_info, (bottom_read_fun),
- drive_name,arrsize);
-
- if (cnt>0) {
- arrsize-=cnt;
- fill_array(&array[i+1],array[i+1].start,
- array[i+1].size, &array[n+1],
- cnt, DISKPART_BSD,
- array[i+1].fsys);
- }
- n+=cnt;
- }
-
- /* search for VTOC -- in a DOS partition as well */
- for (i=0;i<n;i++)
- if (array[i+1].fsys==UNIXOS) {
-#if (PARTITION_DEBUG)
- printf("UNIXOS (vtoc) partition\n");
-#endif
- cnt=get_vtoc(&array[n+1], buff,
- array[i+1].start,
- driver_info, (bottom_read_fun),
- drive_name,arrsize);
-
- if (cnt>0) {
- arrsize-=cnt;
- fill_array(&array[i+1],array[i+1].start,
- array[i+1].size, &array[n+1],
- cnt, DISKPART_VTOC,
- array[i+1].fsys);
- }
- n+=cnt;
- }
- }
-
- /* search for only disklabel */
- if (n==0) {
- fill_array(array, 0, disk_size, &array[1], n, DISKPART_BSD,
- 256+DISKPART_BSD);
- n=get_disklabel(&array[1], buff, 0, driver_info,
- (bottom_read_fun), drive_name,arrsize);
- }
-
- /* search for only VTOC -- NOT TESTED! */
- if (n==0) {
- fill_array(array, 0, disk_size, &array[1], n, DISKPART_VTOC,
- 256+DISKPART_VTOC);
- n=get_vtoc(&array[1], buff, 0, driver_info, (bottom_read_fun),
- drive_name,arrsize);
- }
-#if 0
- /* search for only omron -- NOT TESTED! */
- if (n==0) {
- fill_array(array, 0, disk_size, &array[1], n, DISKPART_OMRON,
- 256+DISKPART_OMRON);
- n=get_omron(&array[1], buff, 0,driver_info, (bottom_read_fun),
- drive_name,arrsize);
- }
-
- /* search for only dec -- NOT TESTED! */
- if (n==0) {
- fill_array(array, 0, disk_size, &array[1], n, DISKPART_DEC,
- 256+DISKPART_DEC);
- n=get_dec(&array[1], buff, 0, driver_info, (bottom_read_fun),
- drive_name,arrsize);
- }
-#endif 0
-
-#if (PARTITION_DEBUG) /* print out what we found */
- print_array(array,0);
-#endif
-
-}
-
-
diff --git a/scsi/mapped_scsi.c b/scsi/mapped_scsi.c
deleted file mode 100644
index fe3dd77..0000000
--- a/scsi/mapped_scsi.c
+++ /dev/null
@@ -1,586 +0,0 @@
-/*
- * Mach Operating System
- * Copyright (c) 1991,1990 Carnegie Mellon University
- * All Rights Reserved.
- *
- * Permission to use, copy, modify and distribute this software and its
- * documentation is hereby granted, provided that both the copyright
- * notice and this permission notice appear in all copies of the
- * software, derivative works or modified versions, and any portions
- * thereof, and that both notices appear in supporting documentation.
- *
- * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
- * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
- * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
- *
- * Carnegie Mellon requests users of this software to return to
- *
- * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
- * School of Computer Science
- * Carnegie Mellon University
- * Pittsburgh PA 15213-3890
- *
- * any improvements or extensions that they make and grant Carnegie Mellon
- * the rights to redistribute these changes.
- */
-/*
- * File: mapped_scsi.c
- * Author: Alessandro Forin, Carnegie Mellon University
- * Date: 9/90
- *
- * In-kernel side of the user-mapped SCSI driver.
- */
-
-#include <asc.h>
-#include <sii.h>
-#define NRZ (NASC+NSII)
-#if NRZ > 0
-#include <platforms.h>
-
-#include <machine/machspl.h> /* spl definitions */
-
-#include <device/device_types.h>
-#include <device/io_req.h>
-#include <chips/busses.h>
-
-#include <vm/vm_kern.h>
-#include <kern/eventcount.h>
-
-#include <scsi/mapped_scsi.h>
-
-#include <machine/machspl.h>
-
-#ifdef DECSTATION
-
-#define machine_btop mips_btop
-
-#define kvctophys(v) K0SEG_TO_PHYS((v)) /* kernel virtual cached */
-#define phystokvc(p) PHYS_TO_K0SEG((p)) /* and back */
-#define kvutophys(v) K1SEG_TO_PHYS((v)) /* kernel virtual uncached */
-#define phystokvu(p) PHYS_TO_K1SEG((p)) /* and back */
-
-#include <mips/mips_cpu.h>
-#include <mips/PMAX/kn01.h>
-#include <mips/PMAX/pmaz_aa.h>
-
-#define SII_REG_PHYS(self) kvutophys(self->registers.any)
-#define SII_RAM_PHYS(self) (SII_REG_PHYS((self))+(KN01_SYS_SII_B_START-KN01_SYS_SII))
-#define SII_RAM_SIZE (KN01_SYS_SII_B_END-KN01_SYS_SII_B_START)
-
-#define ASC_REG_PHYS(self) kvutophys(self->registers.any)
-#define ASC_DMAR_PHYS(self) (ASC_REG_PHYS((self))+ ASC_OFFSET_DMAR)
-#define ASC_RAM_PHYS(self) (ASC_REG_PHYS((self))+ ASC_OFFSET_RAM)
-
-#define PAD_7061(n) short n
-#define PAD_53C94(n) char n[3]
-
-#endif /*DECSTATION*/
-
-#ifdef VAXSTATION
-#define machine_btop vax_btop
-#endif /*VAXSTATION*/
-
-#ifdef P40
-
-#define machine_btop mips_btop
-
-#define kvctophys(v) K0SEG_TO_PHYS((v)) /* kernel virtual cached */
-#define phystokvc(p) PHYS_TO_K0SEG((p)) /* and back */
-#define kvutophys(v) K1SEG_TO_PHYS((v)) /* kernel virtual uncached */
-#define phystokvu(p) PHYS_TO_K1SEG((p)) /* and back */
-
-#include <mips/mips_cpu.h>
-
-#define ASC_RAM_SIZE 0
-#define ASC_OFFSET_DMAR 0
-#define ASC_OFFSET_RAM 0
-
-#define ASC_REG_PHYS(self) kvutophys(self->registers.any)
-#define ASC_DMAR_PHYS(self) (ASC_REG_PHYS((self))+ ASC_OFFSET_DMAR)
-#define ASC_RAM_PHYS(self) (ASC_REG_PHYS((self))+ ASC_OFFSET_RAM)
-#endif /* P40 */
-
-/*
- * Phys defines for the various supported HBAs
- */
-
-/* DEC7061 */
-#include <scsi/adapters/scsi_7061.h>
-
-#ifdef PAD_7061
-
-typedef struct {
- volatile unsigned short sii_sdb; /* rw: Data bus and parity */
- PAD_7061(pad0);
- volatile unsigned short sii_sc1; /* rw: scsi signals 1 */
- PAD_7061(pad1);
- volatile unsigned short sii_sc2; /* rw: scsi signals 2 */
- PAD_7061(pad2);
- volatile unsigned short sii_csr; /* rw: control and status */
- PAD_7061(pad3);
- volatile unsigned short sii_id; /* rw: scsi bus ID */
- PAD_7061(pad4);
- volatile unsigned short sii_sel_csr; /* rw: selection status */
- PAD_7061(pad5);
- volatile unsigned short sii_destat; /* ro: selection detector status */
- PAD_7061(pad6);
- volatile unsigned short sii_dstmo; /* unsupp: dssi timeout */
- PAD_7061(pad7);
- volatile unsigned short sii_data; /* rw: data register */
- PAD_7061(pad8);
- volatile unsigned short sii_dma_ctrl; /* rw: dma control reg */
- PAD_7061(pad9);
- volatile unsigned short sii_dma_len; /* rw: length of transfer */
- PAD_7061(pad10);
- volatile unsigned short sii_dma_adr_low;/* rw: low address */
- PAD_7061(pad11);
- volatile unsigned short sii_dma_adr_hi; /* rw: high address */
- PAD_7061(pad12);
- volatile unsigned short sii_dma_1st_byte;/* rw: initial byte */
- PAD_7061(pad13);
- volatile unsigned short sii_stlp; /* unsupp: dssi short trgt list ptr */
- PAD_7061(pad14);
- volatile unsigned short sii_ltlp; /* unsupp: dssi long " " " */
- PAD_7061(pad15);
- volatile unsigned short sii_ilp; /* unsupp: dssi initiator list ptr */
- PAD_7061(pad16);
- volatile unsigned short sii_dssi_csr; /* unsupp: dssi control */
- PAD_7061(pad17);
- volatile unsigned short sii_conn_csr; /* rc: connection interrupt control */
- PAD_7061(pad18);
- volatile unsigned short sii_data_csr; /* rc: data interrupt control */
- PAD_7061(pad19);
- volatile unsigned short sii_cmd; /* rw: command register */
- PAD_7061(pad20);
- volatile unsigned short sii_diag_csr; /* rw: disgnostic status */
- PAD_7061(pad21);
-} sii_padded_regmap_t;
-
-#else /*!PAD_7061*/
-
-typedef sii_regmap_t sii_padded_regmap_t;
-
-#endif /*!PAD_7061*/
-
-/* NCR 53C94 */
-#include <scsi/adapters/scsi_53C94.h>
-
-#ifdef PAD_53C94
-typedef struct {
- volatile unsigned char asc_tc_lsb; /* rw: Transfer Counter LSB */
- PAD_53C94(pad0);
- volatile unsigned char asc_tc_msb; /* rw: Transfer Counter MSB */
- PAD_53C94(pad1);
- volatile unsigned char asc_fifo; /* rw: FIFO top */
- PAD_53C94(pad2);
- volatile unsigned char asc_cmd; /* rw: Command */
- PAD_53C94(pad3);
- volatile unsigned char asc_csr; /* r: Status */
-/*#define asc_dbus_id asc_csr /* w: Destination Bus ID */
- PAD_53C94(pad4);
- volatile unsigned char asc_intr; /* r: Interrupt */
-/*#define asc_sel_timo asc_intr /* w: (re)select timeout */
- PAD_53C94(pad5);
- volatile unsigned char asc_ss; /* r: Sequence Step */
-/*#define asc_syn_p asc_ss /* w: synchronous period */
- PAD_53C94(pad6);
- volatile unsigned char asc_flags; /* r: FIFO flags + seq step */
-/*#define asc_syn_o asc_flags /* w: synchronous offset */
- PAD_53C94(pad7);
- volatile unsigned char asc_cnfg1; /* rw: Configuration 1 */
- PAD_53C94(pad8);
- volatile unsigned char asc_ccf; /* w: Clock Conv. Factor */
- PAD_53C94(pad9);
- volatile unsigned char asc_test; /* w: Test Mode */
- PAD_53C94(pad10);
- volatile unsigned char asc_cnfg2; /* rw: Configuration 2 */
- PAD_53C94(pad11);
- volatile unsigned char asc_cnfg3; /* rw: Configuration 3 */
- PAD_53C94(pad12);
- volatile unsigned char asc_rfb; /* w: Reserve FIFO byte */
- PAD_53C94(pad13);
-} asc_padded_regmap_t;
-
-#else /* !PAD_53C94 */
-
-typedef asc_regmap_t asc_padded_regmap_t;
-
-#endif /* !PAD_53C94 */
-
-/*
- * Co-existency with in-kernel drivers
- */
-boolean_t rz_use_mapped_interface = FALSE;
-
-/*
- * Status information for all HBAs
- */
-/*static*/ struct RZ_status {
- union {
- unsigned long any;
- asc_padded_regmap_t *asc;
- sii_padded_regmap_t *sii;
- } registers;
- int (*stop)();
- vm_offset_t (*mmap)();
- mapped_scsi_info_t info;
- struct evc eventcounter;
-} RZ_statii[NRZ];
-
-typedef struct RZ_status *RZ_status_t;
-
-
-/*
- * Probe routine for all HBAs
- */
-RZ_probe(regbase, ui, hba)
- unsigned long regbase;
- register struct bus_device *ui;
-{
- int unit = ui->unit;
- vm_offset_t addr;
- mapped_scsi_info_t info;
- struct RZ_status *self;
-
- printf("[mappable] ");
-
- self = &RZ_statii[unit];
-
- self->registers.any = regbase;
-
- /*
- * Grab a page to be mapped later to users
- */
- (void) kmem_alloc_wired(kernel_map, &addr, PAGE_SIZE); /* kseg2 */
- bzero(addr, PAGE_SIZE);
- addr = pmap_extract(pmap_kernel(), addr); /* phys */
- info = (mapped_scsi_info_t) (phystokvc(addr));
- self->info = info;
-
- /*
- * Set permanent info
- */
- info->interrupt_count = 0;
-/*XXX*/ info->ram_size = ASC_RAM_SIZE;
- info->hba_type = hba;
-
- evc_init(&self->eventcounter);
- info->wait_event = self->eventcounter.ev_id;
-
- return 1;
-}
-
-/*
- * Device open procedure
- */
-RZ_open(dev, flag, ior)
- io_req_t ior;
-{
- int unit = dev;
- register RZ_status_t self = &RZ_statii[unit];
-
-
- if (unit >= NRZ)
- return D_NO_SUCH_DEVICE;
-
- /*
- * Silence interface, just in case
- */
- (*self->stop)(unit);
-
- /*
- * Reset eventcounter
- */
- evc_signal(&self->eventcounter);
-
- rz_use_mapped_interface = TRUE;
-
- /*
- * Do not turn interrupts on. The user can do it when ready
- * to take them.
- */
-
- return 0;
-}
-
-/*
- * Device close procedure
- */
-RZ_close(dev, flag)
-{
- int unit = dev;
- register RZ_status_t self = &RZ_statii[unit];
-
- if (unit >= NRZ)
- return D_NO_SUCH_DEVICE;
-
- /*
- * Silence interface, in case user forgot
- */
- (*self->stop)(unit);
-
- evc_signal(&self->eventcounter);
-
- rz_use_mapped_interface = FALSE;
-
- /* XXX rz_kernel_mode(); XXX */
-
- return 0;
-}
-
-
-/*
- * Get status procedure.
- * We need to tell that we are mappable.
- */
-io_return_t
-RZ_get_status(dev, flavor, status, status_count)
- int dev;
- int flavor;
- dev_status_t status;
- unsigned int status_count;
-{
- return (D_SUCCESS);
-}
-
-/*
- * Should not refuse this either
- */
-RZ_set_status(dev, flavor, status, status_count)
- int dev;
- int flavor;
- dev_status_t status;
- unsigned int status_count;
-{
- return (D_SUCCESS);
-}
-
-/*
- * Port death notification routine
- */
-RZ_portdeath(dev, dead_port)
-{
-}
-
-/*
- * Page mapping, switch off to HBA-specific for regs&ram
- */
-vm_offset_t
-RZ_mmap(dev, off, prot)
- int dev;
-{
- int unit = dev;
- register RZ_status_t self = &RZ_statii[unit];
- vm_offset_t page;
- vm_offset_t addr;
- io_return_t ret;
-
- if (off < SCSI_INFO_SIZE) {
- addr = kvctophys (self->info) + off;
- ret = D_SUCCESS;
- } else
- ret = (*self->mmap)(self, off, prot, &addr);
-
- if (ret != D_SUCCESS)
- return ret;
-
- page = machine_btop(addr);
-
- return (page);
-}
-
-
-/*
- *---------------------------------------------------------------
- * The rest of the file contains HBA-specific routines
- *---------------------------------------------------------------
- */
-
-#if NASC > 0
-/*
- * Routines for the NCR 53C94
- */
-static
-ASC_stop(unit)
-{
- register RZ_status_t self = &RZ_statii[unit];
- register asc_padded_regmap_t *regs = self->registers.asc;
- int ack;
-
- ack = regs->asc_intr; /* Just acknowledge pending interrupts */
-}
-
-ASC_probe(reg, ui)
- unsigned long reg;
- register struct bus_device *ui;
-{
- register RZ_status_t self = &RZ_statii[ui->unit];
- static vm_offset_t ASC_mmap();
-
- self->stop = ASC_stop;
- self->mmap = ASC_mmap;
- return RZ_probe(reg, ui, HBA_NCR_53c94);
-}
-
-
-ASC_intr(unit,spllevel)
- spl_t spllevel;
-{
- register RZ_status_t self = &RZ_statii[unit];
- register asc_padded_regmap_t *regs = self->registers.asc;
- register csr, intr, seq_step, cmd;
-
- /*
- * Acknowledge interrupt request
- *
- * This clobbers some two other registers, therefore
- * we read them beforehand. It also clears the intr
- * request bit, silencing the interface for now.
- */
- csr = regs->asc_csr;
-
- /* drop spurious interrupts */
- if ((csr & ASC_CSR_INT) == 0)
- return;
- seq_step = regs->asc_ss;
- cmd = regs->asc_cmd;
-
- intr = regs->asc_intr; /* ack */
-
- splx(spllevel); /* drop priority */
-
- if (self->info) {
- self->info->interrupt_count++; /* total interrupts */
- self->info->saved_regs.asc.csr = csr;
- self->info->saved_regs.asc.isr = intr;
- self->info->saved_regs.asc.seq = seq_step;
- self->info->saved_regs.asc.cmd = cmd;
- }
-
- /* Awake user thread */
- evc_signal(&self->eventcounter);
-}
-
-/*
- * Virtual->physical mapping routine for PMAZ-AA
- */
-static vm_offset_t
-ASC_mmap(self, off, prot, addr)
- RZ_status_t self;
- vm_offset_t off;
- vm_prot_t prot;
- vm_offset_t *addr;
-{
- /*
- * The offset (into the VM object) defines the following layout
- *
- * off size what
- * 0 1pg mapping information (csr & #interrupts)
- * 1pg 1pg ASC registers
- * 2pg 1pg ASC dma
- * 3pg 128k ASC ram buffers
- */
-
-#define ASC_END (ASC_RAM_BASE+ASC_RAM_SIZE)
-
- if (off < ASC_DMAR_BASE)
- *addr = (vm_offset_t) ASC_REG_PHYS(self) + (off - SCSI_INFO_SIZE);
- else if (off < ASC_RAM_BASE)
- *addr = (vm_offset_t) ASC_DMAR_PHYS(self) + (off - ASC_REGS_BASE);
- else if (off < ASC_END)
- *addr = (vm_offset_t) ASC_RAM_PHYS(self) + (off - ASC_RAM_BASE);
- else
- return D_INVALID_SIZE;
-
- return D_SUCCESS;
-}
-#endif NASC > 0
-
-#if NSII > 0
-SII_stop(unit)
-{
- register RZ_status_t self = &RZ_statii[unit];
- register sii_padded_regmap_t *regs = self->registers.sii;
-
- regs->sii_csr &= ~SII_CSR_IE; /* disable interrupts */
- /* clear all wtc bits */
- regs->sii_conn_csr = regs->sii_conn_csr;
- regs->sii_data_csr = regs->sii_data_csr;
-}
-
-SII_probe(reg, ui)
- unsigned long reg;
- register struct bus_device *ui;
-{
- register RZ_status_t self = &RZ_statii[ui->unit];
- static vm_offset_t SII_mmap();
-
- self->stop = SII_stop;
- self->mmap = SII_mmap;
- return RZ_probe(reg, ui, HBA_DEC_7061);
-}
-
-SII_intr(unit,spllevel)
- spl_t spllevel;
-{
- register RZ_status_t self = &RZ_statii[unit];
- register sii_padded_regmap_t *regs = self->registers.sii;
- register unsigned short conn, data;
-
- /*
- * Disable interrupts, saving cause(s) first.
- */
- conn = regs->sii_conn_csr;
- data = regs->sii_data_csr;
-
- /* drop spurious calls */
- if (((conn|data) & (SII_DTR_DI|SII_DTR_CI)) == 0)
- return;
-
- regs->sii_csr &= ~SII_CSR_IE;
-
- regs->sii_conn_csr = conn;
- regs->sii_data_csr = data;
-
- splx(spllevel);
-
- if (self->info) {
- self->info->interrupt_count++; /* total interrupts */
- self->info->saved_regs.sii.sii_conn_csr = conn;
- self->info->saved_regs.sii.sii_data_csr = data;
- }
-
- /* Awake user thread */
- evc_signal(&self->eventcounter);
-}
-
-static vm_offset_t
-SII_mmap(self, off, prot, addr)
- RZ_status_t self;
- vm_offset_t off;
- vm_prot_t prot;
- vm_offset_t *addr;
-{
- /*
- * The offset (into the VM object) defines the following layout
- *
- * off size what
- * 0 1pg mapping information (csr & #interrupts)
- * 1pg 1pg SII registers
- * 2pg 128k SII ram buffer
- */
-
-#define SII_END (SII_RAM_BASE+SII_RAM_SIZE)
-
- if (off < SII_RAM_BASE)
- *addr = (vm_offset_t) SII_REG_PHYS(self) + (off - SCSI_INFO_SIZE);
- else if (off < SII_END)
- *addr = (vm_offset_t) SII_RAM_PHYS(self) + (off - SII_RAM_BASE);
- else
- return D_INVALID_SIZE;
-
- return D_SUCCESS;
-}
-#endif NSII > 0
-
-#endif NRZ > 0
diff --git a/scsi/mapped_scsi.h b/scsi/mapped_scsi.h
deleted file mode 100644
index b9c6528..0000000
--- a/scsi/mapped_scsi.h
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
- * Mach Operating System
- * Copyright (c) 1991,1990,1989 Carnegie Mellon University
- * All Rights Reserved.
- *
- * Permission to use, copy, modify and distribute this software and its
- * documentation is hereby granted, provided that both the copyright
- * notice and this permission notice appear in all copies of the
- * software, derivative works or modified versions, and any portions
- * thereof, and that both notices appear in supporting documentation.
- *
- * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
- * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
- * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
- *
- * Carnegie Mellon requests users of this software to return to
- *
- * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
- * School of Computer Science
- * Carnegie Mellon University
- * Pittsburgh PA 15213-3890
- *
- * any improvements or extensions that they make and grant Carnegie Mellon
- * the rights to redistribute these changes.
- */
-/*
- * File: mapped_scsi.h
- * Author: Alessandro Forin, Carnegie Mellon University
- * Date: 11/90
- *
- * Definitions for the User-level SCSI Driver
- */
-
-/*
- * HBA chips of various sorts
- */
-
-/* DEC 7061 used on pmaxen */
-
-typedef struct sii_volatile_regs {
- unsigned short sii_conn_csr;
- unsigned short sii_data_csr;
-} *sii_reg_t;
-
-#define HBA_DEC_7061 0x00000001
-
- /* layout of mapped stuff */
-#define SII_REGS_BASE (SCSI_INFO_BASE+SCSI_INFO_SIZE)
-#define SII_REGS_SIZE PAGE_SIZE
-#define SII_RAM_BASE (SII_REGS_BASE+SII_REGS_SIZE)
-
-
-/* National 53C94, used on 3maxen' PMAZ-AA boards */
-
-typedef struct asc_volatile_regs {
- unsigned char csr;
- unsigned char isr;
- unsigned char seq;
- unsigned char cmd;
-} *asc_reg_t;
-
-#define HBA_NCR_53c94 0x00000002
-
- /* layout of mapped stuff */
-#define ASC_REGS_BASE (SCSI_INFO_BASE+SCSI_INFO_SIZE)
-#define ASC_REGS_SIZE PAGE_SIZE
-#define ASC_DMAR_BASE (ASC_REGS_BASE+ASC_REGS_SIZE)
-#define ASC_DMAR_SIZE PAGE_SIZE
-#define ASC_RAM_BASE (ASC_DMAR_BASE+ASC_DMAR_SIZE)
-
-/*
- * User-mapped information block, common to all
- */
-#define SCSI_INFO_BASE 0
-#define SCSI_INFO_SIZE PAGE_SIZE
-
-#define SCSI_MAX_MAPPED_SIZE (ASC_RAM_BASE+128*1024)
-
-typedef struct {
- int interrupt_count;/* Counter kept by kernel */
- unsigned int wait_event; /* To wait for interrupts */
- unsigned ram_size;
- int hba_type; /* Tag for regs union */
- union { /* Space for regs saved on
- * intr. Only few used */
- struct asc_volatile_regs asc;
- struct sii_volatile_regs sii;
- } saved_regs;
-} *mapped_scsi_info_t;
-
diff --git a/scsi/pc_scsi_label.c b/scsi/pc_scsi_label.c
deleted file mode 100644
index 9bbcbbf..0000000
--- a/scsi/pc_scsi_label.c
+++ /dev/null
@@ -1,196 +0,0 @@
-/*
- * Mach Operating System
- * Copyright (c) 1993,1991,1990,1989 Carnegie Mellon University
- * All Rights Reserved.
- *
- * Permission to use, copy, modify and distribute this software and its
- * documentation is hereby granted, provided that both the copyright
- * notice and this permission notice appear in all copies of the
- * software, derivative works or modified versions, and any portions
- * thereof, and that both notices appear in supporting documentation.
- *
- * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
- * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
- * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
- *
- * Carnegie Mellon requests users of this software to return to
- *
- * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
- * School of Computer Science
- * Carnegie Mellon University
- * Pittsburgh PA 15213-3890
- *
- * any improvements or extensions that they make and grant Carnegie Mellon
- * the rights to redistribute these changes.
- */
-/* This goes away as soon as we move it in the Ux server */
-
-
-
-#include <mach/std_types.h>
-#include <scsi/compat_30.h>
-#include <scsi/scsi.h>
-#include <scsi/scsi_defs.h>
-#include <scsi/rz.h>
-#include <scsi/rz_labels.h>
-#include <sys/types.h>
-#include <sys/ioctl.h>
-
-#if (NSCSI > 0)
-#define LABEL_DEBUG(x,y) if (label_flag&x) y
-
-#include <i386at/disk.h>
-#include <device/device_types.h>
-#include <device/disk_status.h>
-
-
-int scsi_abs_sec = -1;
-int scsi_abs_count = -1;
-
-scsi_rw_abs(dev, data, rw, sec, count)
- dev_t dev;
-{
- io_req_t ior;
- io_return_t error;
-
- io_req_alloc(ior,0);
- ior->io_next = 0;
- ior->io_unit = dev & (~(MAXPARTITIONS-1)); /* sort of */
- ior->io_unit |= PARTITION_ABSOLUTE;
- ior->io_data = (io_buf_ptr_t)data;
- ior->io_count = count;
- ior->io_recnum = sec;
- ior->io_error = 0;
- if (rw == IO_READ)
- ior->io_op = IO_READ;
- else
- ior->io_op = IO_WRITE;
- scdisk_strategy(ior);
- iowait(ior);
- error = ior->io_error;
- io_req_free(ior);
- return(error);
-}
-
-io_return_t
-scsi_i386_get_status(dev, tgt, flavor, status, status_count)
-int dev;
-target_info_t *tgt;
-int flavor;
-dev_status_t status;
-unsigned int *status_count;
-{
-
- switch (flavor) {
- case V_GETPARMS: {
- struct disklabel *lp = &tgt->dev_info.disk.l;
- struct disk_parms *dp = (struct disk_parms *)status;
- extern struct disklabel default_label;
- int part = rzpartition(dev);
-
- if (*status_count < sizeof (struct disk_parms)/sizeof(int))
- return (D_INVALID_OPERATION);
- dp->dp_type = DPT_WINI;
- dp->dp_secsiz = lp->d_secsize;
- if (lp->d_nsectors == default_label.d_nsectors &&
- lp->d_ntracks == default_label.d_ntracks &&
- lp->d_ncylinders == default_label.d_ncylinders) {
- /* I guess there is nothing there */
- /* Well, then, Adaptec's like ... */
- dp->dp_sectors = 32;
- dp->dp_heads = 64;
- dp->dp_cyls = lp->d_secperunit / 64 / 32 ;
- } else {
- dp->dp_sectors = lp->d_nsectors;
- dp->dp_heads = lp->d_ntracks;
- dp->dp_cyls = lp->d_ncylinders;
- }
-
- dp->dp_dossectors = 32;
- dp->dp_dosheads = 64;
- dp->dp_doscyls = lp->d_secperunit / 64 / 32;
- dp->dp_ptag = 0;
- dp->dp_pflag = 0;
-/* !!! partition changes */
-printf("USING PARTIOION TABLE\n");
- dp->dp_pstartsec = lp->d_partitions[part].p_offset;
- dp->dp_pnumsec = lp->d_partitions[part].p_size;
- *status_count = sizeof(struct disk_parms)/sizeof(int);
- break;
- }
- case V_RDABS:
- if (*status_count < DEV_BSIZE/sizeof (int)) {
- printf("RDABS bad size %x", *status_count);
- return (D_INVALID_OPERATION);
- }
- if (scsi_rw_abs(dev, status, IO_READ, scsi_abs_sec, DEV_BSIZE) != D_SUCCESS)
- return(D_INVALID_OPERATION);
- *status_count = DEV_BSIZE/sizeof(int);
- break;
- case V_VERIFY: {
- int count = scsi_abs_count * DEV_BSIZE;
- int sec = scsi_abs_sec;
- char *scsi_verify_buf;
-#include "vm/vm_kern.h"
-
- (void) kmem_alloc(kernel_map, &scsi_verify_buf, PAGE_SIZE);
-
- *status = 0;
- while (count > 0) {
- int xcount = (count < PAGE_SIZE) ? count : PAGE_SIZE;
- if (scsi_rw_abs(dev, scsi_verify_buf, IO_READ, sec, xcount) != D_SUCCESS) {
- *status = BAD_BLK;
- break;
- } else {
- count -= xcount;
- sec += xcount / DEV_BSIZE;
- }
- }
- (void) kmem_free(kernel_map, scsi_verify_buf, PAGE_SIZE);
- *status_count = 1;
- break;
- }
- default:
- return(D_INVALID_OPERATION);
- }
- return D_SUCCESS;
-}
-
-io_return_t
-scsi_i386_set_status(dev, tgt, flavor, status, status_count)
-int dev;
-target_info_t *tgt;
-int flavor;
-int *status;
-unsigned int status_count;
-{
- io_req_t ior;
-
- switch (flavor) {
- case V_SETPARMS:
- printf("scsdisk_set_status: invalid flavor V_SETPARMS\n");
- return(D_INVALID_OPERATION);
- break;
- case V_REMOUNT:
- tgt->flags &= ~TGT_ONLINE;
- break;
- case V_ABS:
- scsi_abs_sec = status[0];
- if (status_count == 2)
- scsi_abs_count = status[1];
- break;
- case V_WRABS:
- if (status_count < DEV_BSIZE/sizeof (int)) {
- printf("RDABS bad size %x", status_count);
- return (D_INVALID_OPERATION);
- }
- if (scsi_rw_abs(dev, status, IO_WRITE, scsi_abs_sec, DEV_BSIZE) != D_SUCCESS)
- return(D_INVALID_OPERATION);
- break;
- default:
- return(D_INVALID_OPERATION);
- }
- return D_SUCCESS;
-}
-#endif /* NSCSI > 0 */
-
diff --git a/scsi/rz.c b/scsi/rz.c
deleted file mode 100644
index febf629..0000000
--- a/scsi/rz.c
+++ /dev/null
@@ -1,462 +0,0 @@
-/*
- * Mach Operating System
- * Copyright (c) 1993-1990 Carnegie Mellon University
- * All Rights Reserved.
- *
- * Permission to use, copy, modify and distribute this software and its
- * documentation is hereby granted, provided that both the copyright
- * notice and this permission notice appear in all copies of the
- * software, derivative works or modified versions, and any portions
- * thereof, and that both notices appear in supporting documentation.
- *
- * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
- * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
- * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
- *
- * Carnegie Mellon requests users of this software to return to
- *
- * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
- * School of Computer Science
- * Carnegie Mellon University
- * Pittsburgh PA 15213-3890
- *
- * any improvements or extensions that they make and grant Carnegie Mellon
- * the rights to redistribute these changes.
- */
-/*
- * File: rz.c
- * Author: Alessandro Forin, Carnegie Mellon University
- * Date: 10/90
- *
- * Top layer of the SCSI driver: interface with the MI side.
- */
-
-/*
- * This file contains the code that is common to all scsi devices,
- * operations and/or behaviours specific to certain devices live
- * in the corresponding rz_mumble files.
- */
-
-#include <scsi.h>
-
-#if (NSCSI>0)
-
-#include <mach/std_types.h>
-#include <machine/machspl.h> /* spl definitions */
-#include <scsi/compat_30.h>
-
-#ifdef MACH_KERNEL
-#include <kern/time_out.h>
-#else /*MACH_KERNEL*/
-#include <sys/kernel.h> /* for hz */
-
-static io_req_t getbp();
-#endif /*MACH_KERNEL*/
-
-#include <scsi/scsi_defs.h>
-#include <scsi/rz.h>
-
-
-boolean_t
-rz_check(dev, p_sc, p_tgt)
- int dev;
- scsi_softc_t **p_sc;
- target_info_t **p_tgt;
-{
- if (rzcontroller(dev) >= NSCSI ||
- (*p_sc = scsi_softc[rzcontroller(dev)]) == 0)
- return FALSE;
-
- *p_tgt = (*p_sc)->target[rzslave(dev)];
-
- if (!*p_tgt ||
- !((*p_tgt)->flags&TGT_ALIVE))
- return FALSE;
- return TRUE;
-}
-
-/*
- * Open routine
- *
- * On tapes and other devices might have to wait a bit for
- * the unit to come alive. The following patchable variable
- * takes this into account
- */
-int rz_open_timeout = 60;/* seconds */
-
-int rz_open(dev, mode, ior)
- int dev;
- dev_mode_t mode;
- io_req_t ior;
-{
- scsi_softc_t *sc = 0;
- target_info_t *tgt;
- scsi_ret_t ret;
- register int i;
-
- if (!rz_check(dev, &sc, &tgt)) {
- /*
- * Probe it again: might have installed a new device
- */
- if (!sc || !scsi_probe(sc, &tgt, rzslave(dev), ior))
- return D_NO_SUCH_DEVICE;
- }
-
- /* tapes do not wait for rewind to complete on close */
- if (tgt->ior && !(tgt->flags & TGT_ONLINE))
- return D_WOULD_BLOCK;
-
- if (scsi_debug)
- printf("opening %s%d..", (*tgt->dev_ops->driver_name)(TRUE), dev&0xff);
-
- if (sc->watchdog) {
- (*sc->watchdog)(tgt->hw_state);
- sc->watchdog = 0;
- }
-
- /*
- * Bring the unit online, retrying if necessary.
- * If the target is spinning up we wait for it.
- */
- if ( ! (tgt->flags & TGT_ONLINE)) {
- io_req_t tmp_ior;
-
- io_req_alloc(tmp_ior,0);
- tmp_ior->io_next = 0;
- tmp_ior->io_count = 0;
-
- for (i = 0; i < rz_open_timeout; i++) {
-
- tmp_ior->io_op = IO_INTERNAL;
- tmp_ior->io_error = 0;
- ret = scsi_test_unit_ready(tgt, tmp_ior);
-
- if (ret == SCSI_RET_SUCCESS)
- break;
-
- if (ret == SCSI_RET_DEVICE_DOWN) {
- i = rz_open_timeout;
- break;
- }
-
- if (ret == SCSI_RET_NEED_SENSE) {
-
- tmp_ior->io_op = IO_INTERNAL;
- tmp_ior->io_count = 0;
- tmp_ior->io_residual = 0;
- tgt->ior = tmp_ior;
- scsi_request_sense(tgt, tmp_ior, 0);
- iowait(tmp_ior);
-
- }
-
- if (i == 5) printf("%s%d: %s\n",
- (*tgt->dev_ops->driver_name)(TRUE),
- tgt->target_id,
- "Waiting to come online..");
- timeout(wakeup, tgt, hz);
- await(tgt);
- }
-
- /* lock on removable media */
- if ((i != rz_open_timeout) && (tgt->flags & TGT_REMOVABLE_MEDIA)) {
- tmp_ior->io_op = IO_INTERNAL;
- /* too many dont support it. Sigh */
- tgt->flags |= TGT_OPTIONAL_CMD;
- (void) scsi_medium_removal( tgt, FALSE, tmp_ior);
- tgt->flags &= ~TGT_OPTIONAL_CMD;
- }
-
- io_req_free(tmp_ior);
- if (i == rz_open_timeout)
- return D_DEVICE_DOWN;
- }
- /*
- * Perform anything open-time special on the device
- */
- if (tgt->dev_ops->open != SCSI_OPEN_NULL) {
- ret = (*tgt->dev_ops->open)(tgt, ior);
- if (ret != SCSI_RET_SUCCESS) {
- if (scsi_debug) printf("%s%d: open failed x%x\n",
- (*tgt->dev_ops->driver_name)(TRUE), dev&0xff, ret);
- return ret;
- }
- }
- tgt->flags |= TGT_ONLINE;
- ior->io_device->bsize = tgt->block_size;
- return D_SUCCESS;
-}
-
-int rz_close(dev)
- int dev;
-{
- scsi_softc_t *sc;
- target_info_t *tgt;
- scsi_ret_t ret;
-
- if (!rz_check(dev, &sc, &tgt))
- return D_NO_SUCH_DEVICE;
-
- if (scsi_debug)
- printf("closing %s%d..", (*tgt->dev_ops->driver_name)(TRUE), dev&0xff);
-
- if (tgt->flags & TGT_REMOVABLE_MEDIA) {
- io_req_t ior;
-
- io_req_alloc(ior,0);
- ior->io_next = 0;
- ior->io_count = 0;
- ior->io_op = IO_INTERNAL;
- ior->io_error = 0;
- /* too many dont support it. Sigh */
- tgt->flags |= TGT_OPTIONAL_CMD;
- (void) scsi_medium_removal( tgt, TRUE, ior);
- tgt->flags &= ~TGT_OPTIONAL_CMD;
- io_req_free(ior);
- }
-
- /*
- * Perform anything close-time special on the device
- */
- if (tgt->dev_ops->close != SCSI_CLOSE_NULL) {
- ret = (*tgt->dev_ops->close)(tgt);
- if (ret != SCSI_RET_SUCCESS) {
- printf("%s%d: close failed x%x\n",
- (*tgt->dev_ops->driver_name)(TRUE), dev&0xff, ret);
- }
- }
- if (tgt->flags & TGT_REMOVABLE_MEDIA)
- tgt->flags &= ~TGT_ONLINE;
-
- return D_SUCCESS;
-}
-
-/* our own minphys */
-void rz_minphys(ior)
- io_req_t ior;
-{
-#ifdef MACH_KERNEL
-#else /*MACH_KERNEL*/
- if (ior->io_count > scsi_per_target_virtual)
- ior->io_count = scsi_per_target_virtual;
-#endif /*MACH_KERNEL*/
-}
-
-int rz_read(dev, ior)
- int dev;
- io_req_t ior;
-{
- target_info_t *tgt;
-
- tgt = scsi_softc[rzcontroller(dev)]->target[rzslave(dev)];
-
-#ifdef MACH_KERNEL
- return block_io(tgt->dev_ops->strategy, rz_minphys, ior);
-#else /*MACH_KERNEL*/
- return physio(tgt->dev_ops->strategy, getbp(dev), dev, IO_READ, rz_minphys, ior);
-#endif /*MACH_KERNEL*/
-}
-
-int rz_write(dev, ior)
- int dev;
- io_req_t ior;
-{
- target_info_t *tgt;
-
- tgt = scsi_softc[rzcontroller(dev)]->target[rzslave(dev)];
-
- if (tgt->flags & TGT_READONLY)
- return D_INVALID_OPERATION;
-
-#ifdef MACH_KERNEL
- return block_io(tgt->dev_ops->strategy, rz_minphys, ior);
-#else /*MACH_KERNEL*/
- return physio(tgt->dev_ops->strategy, getbp(dev), dev, IO_WRITE, rz_minphys, ior);
-#endif /*MACH_KERNEL*/
-}
-
-int rz_get_status(dev, flavor, status, status_count)
- int dev;
- dev_flavor_t flavor;
- dev_status_t status;
- natural_t *status_count;
-{
- target_info_t *tgt;
-
- tgt = scsi_softc[rzcontroller(dev)]->target[rzslave(dev)];
-
- if (scsi_debug)
- printf("rz_get_status: x%x x%x x%x x%x\n",
- dev, flavor, status, *status_count);
- return (*tgt->dev_ops->get_status)(dev, tgt, flavor, status, status_count);
-}
-
-int rz_set_status(dev, flavor, status, status_count)
- int dev;
- dev_flavor_t flavor;
- dev_status_t status;
- natural_t status_count;
-{
- target_info_t *tgt;
-
- tgt = scsi_softc[rzcontroller(dev)]->target[rzslave(dev)];
-
- if (scsi_debug)
- printf("rz_set_status: x%x x%x x%x x%x\n",
- dev, flavor, status, status_count);
- return (*tgt->dev_ops->set_status)(dev, tgt, flavor, status, status_count);
-}
-
-/*
- * Routine to return information to kernel.
- */
-int
-rz_devinfo(dev, flavor, info)
- int dev;
- int flavor;
- char *info;
-{
- register int result;
-
- result = D_SUCCESS;
-
- switch (flavor) {
- /* Caller stupidity, should use device->bsize instead */
- case D_INFO_BLOCK_SIZE:
- *((int *) info) = scsi_softc[rzcontroller(dev)]->
- target[rzslave(dev)]->block_size;
- break;
- default:
- result = D_INVALID_OPERATION;
- }
-
- return(result);
-}
-
-void
-rz_simpleq_strategy(ior, start)
- io_req_t ior;
- void (*start)();
-{
- target_info_t *tgt;
- register scsi_softc_t *sc;
- scsi_ret_t ret;
- register int i = ior->io_unit;
- io_req_t head, tail;
- spl_t s;
-
- sc = scsi_softc[rzcontroller(i)];
- tgt = sc->target[rzslave(i)];
-
- ior->io_next = 0;
- ior->io_prev = 0;
-
- s = splbio();
- simple_lock(&tgt->target_lock);
- if (head = tgt->ior) {
- /* Queue it up at the end of the list */
- if (tail = head->io_prev)
- tail->io_next = ior;
- else
- head->io_next = ior;
- head->io_prev = ior; /* tail pointer */
- simple_unlock(&tgt->target_lock);
- } else {
- /* Was empty, start operation */
- tgt->ior = ior;
- simple_unlock(&tgt->target_lock);
- (*start)( tgt, FALSE);
- }
- splx(s);
-}
-#ifdef MACH_KERNEL
-#else /*MACH_KERNEL*/
-
-rz_strategy(ior)
- io_req_t ior;
-{
- target_info_t *tgt;
- register int dev = ior->io_unit;
-
- tgt = scsi_softc[rzcontroller(dev)]->target[rzslave(dev)];
-
- return (*tgt->dev_ops->strategy)(ior);
-}
-
-
-#define IOCPARM_SIZE(c) (((c)>>16)&IOCPARM_MASK)
-#define IOC_WDSIZE(s) ((IOCPARM_SIZE(s))>>2)
-
-rz_ioctl(dev, cmd, data, flag)
-{
- io_return_t error;
- unsigned int count;
-
- count = IOC_WDSIZE(cmd);
- if (cmd & (IOC_VOID|IOC_IN)) {
- error = rz_set_status(dev, cmd, (dev_status_t)data, count);
- if (error)
- return (error);
- }
- if (cmd & IOC_OUT) {
- error = rz_get_status(dev, cmd, (dev_status_t *)data, &count);
- if (error)
- return (error);
- }
- return (0);
-}
-
-/* This is a very simple-minded config,
- * assumes we have << 8 disks per bus */
-#define NBUF (NSCSI*8)
-struct io_req rz_buffers[NBUF];
-
-static io_req_t
-getbp(dev)
-{
- io_req_t ior;
- int hash = minor(dev) >> 3;
-
- ior = &rz_buffers[hash];
- if (ior->io_op & IO_BUSY) {
- register io_req_t ior;
- for (ior = rz_buffers; ior < &rz_buffers[NBUF]; ior++)
- if ((ior->io_op & IO_BUSY) == 0)
- return ior;
-
- }
- return ior;
-}
-
-/*
- * This ugliness is only needed because of the
- * way the minor is encoded for tapes.
- */
-tz_open(dev, mode, ior)
- int dev;
- dev_mode_t mode;
- io_req_t ior;
-{
- io_return_t error;
-
- error = rz_open(TAPE_UNIT(dev), mode, ior);
- if(error)
- return error;
- if (TAPE_REWINDS(dev)) {
- scsi_softc_t *sc;
- target_info_t *tgt;
-
- rz_check(TAPE_UNIT(dev), &sc, &tgt);
- tgt->flags |= TGT_REWIND_ON_CLOSE;
- }
- return 0;
-}
-
-tz_close(dev) { return rz_close(TAPE_UNIT(dev));}
-tz_read(dev, ior) { return rz_read(TAPE_UNIT(dev), ior);}
-tz_write(dev, ior) { return rz_write(TAPE_UNIT(dev), ior);}
-tz_ioctl(dev, cmd, data, flag) { return rz_ioctl(TAPE_UNIT(dev), cmd, data, flag);}
-
-#endif /*MACH_KERNEL*/
-
-#endif (NSCSI>0)
diff --git a/scsi/rz.h b/scsi/rz.h
deleted file mode 100644
index 7fa7b88..0000000
--- a/scsi/rz.h
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * Mach Operating System
- * Copyright (c) 1991,1990 Carnegie Mellon University
- * All Rights Reserved.
- *
- * Permission to use, copy, modify and distribute this software and its
- * documentation is hereby granted, provided that both the copyright
- * notice and this permission notice appear in all copies of the
- * software, derivative works or modified versions, and any portions
- * thereof, and that both notices appear in supporting documentation.
- *
- * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
- * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
- * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
- *
- * Carnegie Mellon requests users of this software to return to
- *
- * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
- * School of Computer Science
- * Carnegie Mellon University
- * Pittsburgh PA 15213-3890
- *
- * any improvements or extensions that they make and grant Carnegie Mellon
- * the rights to redistribute these changes.
- */
-/*
- * File: rz.h
- * Author: Alessandro Forin, Carnegie Mellon University
- * Date: 9/90
- *
- * Mapping between U*x-like indexing and controller+slave
- * Each controller handles at most 8 slaves, few controllers.
- */
-
-#if 0
-#define rzcontroller(dev) (((dev)>>6)&0x3)
-#define rzslave(dev) (((dev)>>3)&0x7)
-#endif 0
-#define rzcontroller(dev) (((dev)>>13)&0x3)
-#define rzslave(dev) (((dev)>>10)&0x7)
-
-#if 0
-#define rzpartition(dev) ((PARTITION_TYPE(dev)==0xf)?MAXPARTITIONS:((dev)&0x7))
-#endif 0
-#define rzpartition(dev) ((dev)&0x3ff)
-
-/* To address the full 256 luns use upper bits 8..12 */
-/* NOTE: Under U*x this means the next major up.. what a mess */
-#define rzlun(dev) (((dev)&0x7) | (((dev)>>5)&0xf8))
-
-/* note: whatever this was used for is no longer cared about -- Kevin */
-#define PARTITION_TYPE(dev) (((dev)>>24)&0xf)
-#define PARTITION_ABSOLUTE (0xf<<24)
-
-#ifdef MACH_KERNEL
-#else /*MACH_KERNEL*/
-#define tape_unit(dev) ((((dev)&0xe0)>>3)|((dev)&0x3))
-#define TAPE_UNIT(dev) ((dev)&(~0xff))|(tape_unit((dev))<<3)
-#define TAPE_REWINDS(dev) (((dev)&0x1c)==0)||(((dev)&0x1c)==8)
-#endif /*MACH_KERNEL*/
diff --git a/scsi/rz_audio.c b/scsi/rz_audio.c
deleted file mode 100644
index 4d60fa1..0000000
--- a/scsi/rz_audio.c
+++ /dev/null
@@ -1,1901 +0,0 @@
-/*
- * Mach Operating System
- * Copyright (c) 1993 Carnegie Mellon University
- * All Rights Reserved.
- *
- * Permission to use, copy, modify and distribute this software and its
- * documentation is hereby granted, provided that both the copyright
- * notice and this permission notice appear in all copies of the
- * software, derivative works or modified versions, and any portions
- * thereof, and that both notices appear in supporting documentation.
- *
- * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
- * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
- * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
- *
- * Carnegie Mellon requests users of this software to return to
- *
- * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
- * School of Computer Science
- * Carnegie Mellon University
- * Pittsburgh PA 15213-3890
- *
- * any improvements or extensions that they make and grant Carnegie Mellon
- * the rights to redistribute these changes.
- */
-/*
- * File: rz_audio.c
- * Author: Alessandro Forin, Carnegie Mellon University
- * Date: 3/93
- *
- * Top layer of the SCSI driver: interface with the MI.
- * This file contains operations specific to audio CD-ROM devices.
- * Unlike many others, it sits on top of the rz.c module.
- */
-
-#include <mach/std_types.h>
-#include <kern/strings.h>
-#include <machine/machspl.h> /* spl definitions */
-#include <vm/vm_kern.h>
-#include <device/ds_routines.h>
-
-#include <scsi/compat_30.h>
-#include <scsi/scsi.h>
-#include <scsi/scsi2.h>
-#include <scsi/scsi_defs.h>
-#include <scsi/rz.h>
-
-#if (NSCSI > 0)
-
-#define private static
-
-/* some data is two BCD digits in one byte */
-#define bcd_to_decimal(b) (((b)&0xf) + 10 * (((b) >> 4) & 0xf))
-#define decimal_to_bcd(b) ((((b) / 10) << 4) | ((b) % 10))
-
-/*
- * Regular use of a CD-ROM is for data, and is handled
- * by the default set of operations. Ours is for funtime..
- */
-
-extern char *sccdrom_name();
-int cd_strategy();
-void cd_start();
-
-private scsi_devsw_t scsi_audio = {
- sccdrom_name, 0, 0, 0, cd_strategy, cd_start, 0, 0
-};
-
-private char unsupported[] = "Device does not support it.";
-
-/*
- * Unfortunately, none of the vendors appear to
- * abide by the SCSI-2 standard and many of them
- * violate or stretch even the SCSI-1 one.
- * Therefore, we keep a red-list here of the worse
- * offendors and how to deal with them.
- * The user is notified of the problem and invited
- * to solicit his vendor to upgrade the firmware.
- * [They had plenty of time to do so]
- */
-typedef struct red_list {
- char *vendor;
- char *product;
- char *rev;
- /*
- * The standard MANDATES [par 13.1.6] the play_audio command
- * at least as a way to discover if the device
- * supports audio operations at all. This is the only way
- * we need to use it.
- */
- scsi_ret_t (*can_play_audio)( target_info_t *, char *, io_req_t);
- /*
- * The standard defines the use of start_stop_unit to
- * cause the drive to eject the disk.
- */
- scsi_ret_t (*eject)( target_info_t *, char *, io_req_t );
- /*
- * The standard defines read_subchannel as a way to
- * get the current playing position.
- */
- scsi_ret_t (*current_position)( target_info_t *, char *, io_req_t );
- /*
- * The standard defines read_table_of_content to get
- * the listing of audio tracks available.
- */
- scsi_ret_t (*read_toc)( target_info_t *, char *, io_req_t );
- /*
- * The standard defines read_subchannel as the way to
- * report the current audio status (playing/stopped/...).
- */
- scsi_ret_t (*get_status)( target_info_t *, char *, io_req_t );
- /*
- * The standard defines two ways to issue a play command,
- * depending on the type of addressing used.
- */
- scsi_ret_t (*play_msf)( target_info_t *, char *, io_req_t );
- scsi_ret_t (*play_ti)( target_info_t *, char *, io_req_t );
- /*
- * The standard defines the pause_resume command to
- * suspend or resume playback of audio data.
- */
- scsi_ret_t (*pause_resume)( target_info_t *, char *, io_req_t );
- /*
- * The standard defines the audio page among the
- * mode selection options as a way to control
- * both volume and connectivity of the channels
- */
- scsi_ret_t (*volume_control)( target_info_t *, char *, io_req_t );
-} red_list_t;
-
-#define if_it_can_do(some_cmd) \
- if (tgt->dev_info.cdrom.violates_standards && \
- tgt->dev_info.cdrom.violates_standards->some_cmd) \
- rc = (*tgt->dev_info.cdrom.violates_standards->some_cmd) \
- (tgt,cmd,ior); \
- else
-
-/*
- * So now that you know what they should have implemented :-),
- * check at the end of the file what the naughty boys did instead.
- */
-/* private red_list_t audio_replacements[]; / * at end */
-
-/*
- * Forward decls
- */
-private void decode_status( char *buf, unsigned char audio_status );
-void zero_ior( io_req_t );
-
-/*
- * Open routine. Does some checking, sets up
- * the replacement pointer.
- */
-io_return_t
-cd_open(
- int dev,
- dev_mode_t mode,
- io_req_t req)
-{
- scsi_softc_t *sc = 0;
- target_info_t *tgt;
- int ret;
- scsi_ret_t rc;
- io_req_t ior = 0;
- vm_offset_t mem = 0;
- extern boolean_t rz_check();
-
- if (!rz_check(dev, &sc, &tgt)) {
- /*
- * Probe it again: might have installed a new device
- */
- if (!sc || !scsi_probe(sc, &tgt, rzslave(dev), ior))
- return D_NO_SUCH_DEVICE;
- bzero(&tgt->dev_info, sizeof(tgt->dev_info));
- }
-
- /*
- * Check this is indeded a CD-ROM
- */
- if (tgt->dev_ops != &scsi_devsw[SCSI_CDROM]) {
- rz_close(dev);
- return D_NO_SUCH_DEVICE;
- }
-
- /*
- * Switch to audio ops, unless some wrong
- */
- tgt->dev_ops = &scsi_audio;
-
- /*
- * Bring unit online
- */
- ret = rz_open(dev, mode, req);
- if (ret) goto bad;
-
- /* Pessimistic */
- ret = D_INVALID_OPERATION;
-
- /*
- * Check if this device is on the red list
- */
- {
- scsi2_inquiry_data_t *inq;
- private void check_red_list();
-
- scsi_inquiry(tgt, SCSI_INQ_STD_DATA);
- inq = (scsi2_inquiry_data_t*)tgt->cmd_ptr;
-
- check_red_list( tgt, inq );
-
- }
-
- /*
- * Allocate dynamic data
- */
- if (kmem_alloc(kernel_map, &mem, PAGE_SIZE) != KERN_SUCCESS)
- return D_NO_MEMORY;
- tgt->dev_info.cdrom.result = (void *)mem;
- tgt->dev_info.cdrom.result_available = FALSE;
-
- /*
- * See if this CDROM can play audio data
- */
- io_req_alloc(ior,0);
- zero_ior( ior );
-
- {
- char *cmd = 0;
- if_it_can_do(can_play_audio)
- rc = scsi_play_audio( tgt, 0, 0, FALSE, ior);
- }
-
- if (rc != SCSI_RET_SUCCESS) goto bad;
-
- io_req_free(ior);
- return D_SUCCESS;
-
-bad:
- if (ior) io_req_free(ior);
- if (mem) kmem_free(kernel_map, mem, PAGE_SIZE);
- tgt->dev_ops = &scsi_devsw[SCSI_CDROM];
- return ret;
-}
-
-/*
- * Close routine.
- */
-io_return_t
-cd_close(
- int dev)
-{
- scsi_softc_t *sc;
- target_info_t *tgt;
- vm_offset_t mem;
-
- if (!rz_check(dev, &sc, &tgt))
- return D_NO_SUCH_DEVICE;
- if (!tgt || (tgt->dev_ops != &scsi_audio))
- return D_NO_SUCH_DEVICE;
-
- /*
- * Cleanup state
- */
- mem = (vm_offset_t) tgt->dev_info.cdrom.result;
- tgt->dev_info.cdrom.result = (void *)0;
- tgt->dev_info.cdrom.result_available = FALSE;
-
- (void) kmem_free(kernel_map, mem, PAGE_SIZE);
-
- (void) rz_close(dev);
-
- tgt->dev_ops = &scsi_devsw[SCSI_CDROM];
- return D_SUCCESS;
-}
-
-/*
- * Write routine. It is passed an ASCII string
- * with the command to be executed.
- */
-io_return_t
-cd_write(
- int dev,
- io_req_t ior)
-{
- register kern_return_t rc;
- boolean_t wait = FALSE;
- io_return_t ret;
- int count;
- register char *data;
- vm_offset_t addr;
-
- data = ior->io_data;
- count = ior->io_count;
- if (count == 0)
- return D_SUCCESS;
-
- if (!(ior->io_op & IO_INBAND)) {
- /*
- * Copy out-of-line data into kernel address space.
- * Since data is copied as page list, it will be
- * accessible.
- */
- vm_map_copy_t copy = (vm_map_copy_t) data;
- kern_return_t kr;
-
- kr = vm_map_copyout(device_io_map, &addr, copy);
- if (kr != KERN_SUCCESS)
- return kr;
- data = (char *) addr;
- }
-
- if (scsi_debug) printf("Got command '%s'\n", data);
-
- ret = cd_command( dev, data, count, ior);
-
- if (!(ior->io_op & IO_INBAND))
- (void) vm_deallocate(device_io_map, addr, ior->io_count);
- return D_SUCCESS;
-}
-
-/*
- * Read routine. Returns an ASCII string with the results
- * of the last command executed.
- */
-io_return_t
-cd_read(
- int dev,
- io_req_t ior)
-{
- target_info_t *tgt;
- kern_return_t rc;
- natural_t count;
-
- /*
- * Allocate memory for read buffer.
- */
- count = (natural_t)ior->io_count;
- if (count > PAGE_SIZE)
- return D_INVALID_SIZE; /* sanity */
-
- rc = device_read_alloc(ior, count);
- if (rc != KERN_SUCCESS)
- return rc;
-
- if (scsi_debug) printf("Got read req for %d bytes\n", count);
-
- /*
- * See if last cmd left some to say
- */
- tgt = scsi_softc[rzcontroller(dev)]->target[rzslave(dev)];
- if (tgt->dev_info.cdrom.result_available) {
- int len;
-
- tgt->dev_info.cdrom.result_available = FALSE;
- len = strlen(tgt->dev_info.cdrom.result)+1;
-
- if (count > len)
- count = len;
- bcopy(tgt->dev_info.cdrom.result, ior->io_data, count);
-
- } else {
-# define noway "No results pending"
- count = (count > sizeof(noway)) ? sizeof(noway) : count;
- bcopy(noway, ior->io_data, count);
- }
-
- ior->io_residual = ior->io_count - count;
- return D_SUCCESS;
-}
-
-/*
- * This does all the work
- */
-io_return_t
-cd_command(
- int dev,
- char *cmd,
- int count,
- io_req_t req)
-{
- target_info_t *tgt;
- io_req_t ior;
- io_return_t ret = D_INVALID_OPERATION;
- scsi_ret_t rc;
- char *buf;
-
- tgt = scsi_softc[rzcontroller(dev)]->target[rzslave(dev)];
-
- buf = tgt->dev_info.cdrom.result;
- tgt->dev_info.cdrom.result_available = FALSE;
-
- io_req_alloc(ior,0);
- zero_ior( ior );
-
- switch (cmd[0]) {
-
- case 'E':
- /* "Eject" */
- /* too many dont support it. Sigh */
- tgt->flags |= TGT_OPTIONAL_CMD;
- (void) scsi_medium_removal( tgt, TRUE, ior);
- tgt->flags &= ~TGT_OPTIONAL_CMD;
-
- zero_ior( ior );
-
- if_it_can_do(eject)
- rc = scsi_start_unit(tgt, SCSI_CMD_SS_EJECT, ior);
- break;
-
- case 'G':
- switch (cmd[4]) {
-
- case 'P':
- /* "Get Position MSF|ABS" */
- if_it_can_do(current_position) {
- rc = scsi_read_subchannel(tgt,
- cmd[13] == 'M',
- SCSI_CMD_RS_FMT_CURPOS,
- 0,
- ior);
- if (rc == SCSI_RET_SUCCESS) {
- cdrom_chan_curpos_t *st;
- st = (cdrom_chan_curpos_t *)tgt->cmd_ptr;
- if (cmd[13] == 'M')
- sprintf(buf, "MSF Position %d %d %d %d %d %d",
- (integer_t)st->subQ.absolute_address.msf.minute,
- (integer_t)st->subQ.absolute_address.msf.second,
- (integer_t)st->subQ.absolute_address.msf.frame,
- (integer_t)st->subQ.relative_address.msf.minute,
- (integer_t)st->subQ.relative_address.msf.second,
- (integer_t)st->subQ.relative_address.msf.frame);
- else
- sprintf(buf, "ABS Position %d %d", (integer_t)
- (st->subQ.absolute_address.lba.lba1<<24)+
- (st->subQ.absolute_address.lba.lba2<<16)+
- (st->subQ.absolute_address.lba.lba3<< 8)+
- st->subQ.absolute_address.lba.lba4,
- (integer_t)
- (st->subQ.relative_address.lba.lba1<<24)+
- (st->subQ.relative_address.lba.lba2<<16)+
- (st->subQ.relative_address.lba.lba3<< 8)+
- st->subQ.relative_address.lba.lba4);
- tgt->dev_info.cdrom.result_available = TRUE;
- }
- }
- break;
-
- case 'T':
- /* "Get TH" */
- if_it_can_do(read_toc) {
- rc = scsi_read_toc(tgt, TRUE, 1, PAGE_SIZE, ior);
- if (rc == SCSI_RET_SUCCESS) {
- cdrom_toc_t *toc = (cdrom_toc_t *)tgt->cmd_ptr;
- sprintf(buf, "toc header: %d %d %d",
- (toc->len1 << 8) + toc->len2,
- toc->first_track,
- toc->last_track);
- tgt->dev_info.cdrom.result_available = TRUE;
- }
- }
- break;
-
- case 'S':
- /* "Get Status" */
- if_it_can_do(get_status) {
- rc = scsi_read_subchannel(tgt,
- TRUE,
- SCSI_CMD_RS_FMT_CURPOS,
- 0,
- ior);
- if (rc == SCSI_RET_SUCCESS) {
- cdrom_chan_curpos_t *st;
- st = (cdrom_chan_curpos_t *)tgt->cmd_ptr;
- decode_status(buf, st->audio_status);
- tgt->dev_info.cdrom.result_available = TRUE;
- }
- }
- break;
- }
- break;
-
- case 'P':
- switch (cmd[5]) {
- case 'A':
- /* "Play A startM startS startF endM endS endF" */
- if_it_can_do(play_msf) {
-
- int sm, ss, sf, em, es, ef;
-
- sscanf(&cmd[7], "%d %d %d %d %d %d",
- &sm, &ss, &sf, &em, &es, &ef);
-
- rc = scsi_play_audio_msf(tgt,
- sm, ss, sf,
- em, es, ef,
- ior);
- }
- break;
-
- case 'T':
- /* "Play TI startT startI endT endI" */
- if_it_can_do(play_ti) {
-
- int st, si, et, ei;
-
- sscanf(&cmd[8], "%d %d %d %d",
- &st, &si, &et, &ei);
-
- rc = scsi_play_audio_track_index(tgt,
- st, si, et, ei, ior);
- }
- break;
- }
- break;
-
- case 'R':
- /* "Resume" */
- if_it_can_do(pause_resume)
- rc = scsi_pause_resume(tgt, FALSE, ior);
- break;
-
- case 'S':
- switch (cmd[2]) {
-
- case 'a':
- /* "Start" */
- rc = scsi_start_unit(tgt, SCSI_CMD_SS_START, ior);
- break;
-
- case 'o':
- /* "Stop" */
- if_it_can_do(pause_resume)
- rc = scsi_pause_resume(tgt, TRUE, ior);
- break;
-
- case 't':
- /* "Set V chan0vol chan1vol chan2vol chan3vol" */
- if_it_can_do(volume_control) {
-
- int v0, v1, v2, v3;
- cdrom_audio_page_t au, *aup;
-
- rc = scsi_mode_sense(tgt,
- SCSI_CD_AUDIO_PAGE,
- sizeof(au),
- ior);
- if (rc == SCSI_RET_SUCCESS) {
-
- sscanf(&cmd[6], "%d %d %d %d",
- &v0, &v1, &v2, &v3);
-
- aup = (cdrom_audio_page_t *) tgt->cmd_ptr;
- au = *aup;
- /* au.h.bdesc ... */
- au.vol0 = v0;
- au.vol1 = v1;
- au.vol2 = v2;
- au.vol3 = v3;
- au.imm = 1;
- au.aprv = 0;
-
- zero_ior( ior );
-
- rc = scsi2_mode_select(tgt, FALSE,
- &au, sizeof(au), ior);
- }
- }
- break;
- }
- break;
-
- case 'T':
- /* "Toc MSF|ABS trackno" */
- if_it_can_do(read_toc) {
-
- int t, m;
-
- sscanf(&cmd[8], "%d", &t);
- rc = scsi_read_toc( tgt, cmd[4]=='M', t, PAGE_SIZE, ior);
-
- if (rc == SCSI_RET_SUCCESS) {
-
- cdrom_toc_t *toc = (cdrom_toc_t *)tgt->cmd_ptr;
-
- sprintf(buf, "TOC from track %d:\n", t);
- m = (toc->len1 << 8) + toc->len2;
- m -= 4; /* header */
- for (t = 0; m > 0; t++, m -= sizeof(struct cdrom_toc_desc)) {
- buf += strlen(buf);
- if (cmd[4] == 'M')
- sprintf(buf, "%d %d %d %d %d %d\n",
- toc->descs[t].control,
- toc->descs[t].adr,
- toc->descs[t].trackno,
- (integer_t)toc->descs[t].absolute_address.msf.minute,
- (integer_t)toc->descs[t].absolute_address.msf.second,
- (integer_t)toc->descs[t].absolute_address.msf.frame);
- else
- sprintf(buf, "%d %d %d %d\n",
- toc->descs[t].control,
- toc->descs[t].adr,
- toc->descs[t].trackno,
- (toc->descs[t].absolute_address.lba.lba1<<24)+
- (toc->descs[t].absolute_address.lba.lba2<<16)+
- (toc->descs[t].absolute_address.lba.lba3<<8)+
- toc->descs[t].absolute_address.lba.lba4);
- }
- tgt->dev_info.cdrom.result_available = TRUE;
- }
- }
- break;
- }
-
- if (rc == SCSI_RET_SUCCESS)
- ret = D_SUCCESS;
-
- /* We are stateless, but.. */
- if (rc == SCSI_RET_NEED_SENSE) {
- zero_ior( ior );
- tgt->ior = ior;
- scsi_request_sense(tgt, ior, 0);
- iowait(ior);
- if (scsi_check_sense_data(tgt, tgt->cmd_ptr))
- scsi_print_sense_data(tgt->cmd_ptr);
- }
-
- io_req_free(ior);
- return ret;
-}
-
-private char st_invalid [] = "Drive would not say";
-private char st_playing [] = "Playing";
-private char st_paused [] = "Suspended";
-private char st_complete[] = "Done playing";
-private char st_error [] = "Stopped in error";
-private char st_nothing [] = "Idle";
-
-private void
-decode_status(
- char *buf,
- unsigned char audio_status)
-{
- switch (audio_status) {
- case SCSI_CDST_INVALID:
- sprintf(buf, st_invalid); break;
- case SCSI_CDST_PLAYING:
- sprintf(buf, st_playing); break;
- case SCSI_CDST_PAUSED:
- sprintf(buf, st_paused); break;
- case SCSI_CDST_COMPLETED:
- sprintf(buf, st_complete); break;
- case SCSI_CDST_ERROR:
- sprintf(buf, st_error); break;
- case SCSI_CDST_NO_STATUS:
- sprintf(buf, st_nothing); break;
- }
-}
-
-/* some vendor specific use this instead */
-private void
-decode_status_1(
- char *buf,
- unsigned char audio_status)
-{
- switch (audio_status) {
- case 0: sprintf(buf, st_playing ); break;
- case 1:
- case 2: sprintf(buf, st_paused ); break;
- case 3: sprintf(buf, st_complete ); break;
- default:
- sprintf(buf, "Unknown status" ); break;
- }
-}
-
-
-private void
-curse_the_vendor(
- red_list_t *list,
- boolean_t not_really)
-{
- if (not_really) return;
-
- printf("%s\n%s\n%s\n%s\n",
- "The CDROM you use is not fully SCSI-2 compliant.",
- "We invite You to contact Your vendor and ask",
- "that they provide You with a firmware upgrade.",
- "Here is a list of some known deficiencies");
-
- printf("Vendor: %s Product: %s.. Revision: %s..\n",
- list->vendor, list->product, list->rev);
-
-#define check(x,y,z) \
- if (list->x) printf("Command code x%x %s not supported\n", y, z);
-
- check(can_play_audio, SCSI_CMD_PLAY_AUDIO, "PLAY_AUDIO");
- check(eject, SCSI_CMD_START_STOP_UNIT,
- "START_STOP_UNIT, flag EJECT(0x2) in byte 5");
- check(current_position, SCSI_CMD_READ_SUBCH, "READ_SUBCHANNEL");
- check(read_toc, SCSI_CMD_READ_TOC, "READ_TOC");
-/* check(get_status, ...); duplicate of current_position */
- check(play_msf, SCSI_CMD_PLAY_AUDIO_MSF, "PLAY_AUDIO_MSF");
- check(play_ti, SCSI_CMD_PLAY_AUDIO_TI, "PLAY_AUDIO_TRACK_INDEX");
- check(pause_resume, SCSI_CMD_PAUSE_RESUME, "PAUSE_RESUME");
- check(volume_control, SCSI_CMD_MODE_SELECT,
- "MODE_SELECT, AUDIO page(0xe)");
-
-#undef check
- printf("Will work around these problems...\n");
-}
-
-/*
- * Ancillaries
- */
-cd_strategy(ior)
- register io_req_t ior;
-{
- return rz_simpleq_strategy( ior, cd_start);
-}
-
-void cd_start( tgt, done)
- target_info_t *tgt;
- boolean_t done;
-{
- io_req_t ior;
-
- ior = tgt->ior;
- if (done && ior) {
- tgt->ior = 0;
- iodone(ior);
- return;
- }
- panic("cd start"); /* uhu? */
-}
-
-/*
- * When the hardware cannot
- */
-private scsi_ret_t
-op_not_supported(
- target_info_t *tgt,
- char *cmd,
- io_req_t ior)
-{
- /*
- * The command is not implemented, no way around it
- */
- sprintf(tgt->dev_info.cdrom.result, unsupported);
- tgt->dev_info.cdrom.result_available = TRUE;
- return SCSI_RET_SUCCESS;
-}
-
-/****************************************/
-/* Vendor Specific Operations */
-/****************************************/
-
- /* DEC RRD42 */
-
-#define SCSI_CMD_DEC_SET_ADDRESS_FORMAT 0xc0
-# define scsi_cmd_saf_fmt scsi_cmd_xfer_len_2
-
-#define SCSI_CMD_DEC_PLAYBACK_STATUS 0xc4
-typedef struct {
- unsigned char xxx;
- BITFIELD_2(unsigned char,
- is_msf: 1,
- xxx1: 7);
- unsigned char data_len1;
- unsigned char data_len0;
- unsigned char audio_status;
- BITFIELD_2(unsigned char,
- control : 4,
- xxx2 : 4);
- cdrom_addr_t address;
- BITFIELD_2(unsigned char,
- chan0_select : 4,
- xxx3 : 4);
- unsigned char chan0_volume;
- BITFIELD_2(unsigned char,
- chan1_select : 4,
- xxx4 : 4);
- unsigned char chan1_volume;
- BITFIELD_2(unsigned char,
- chan2_select : 4,
- xxx5 : 4);
- unsigned char chan2_volume;
- BITFIELD_2(unsigned char,
- chan3_select : 4,
- xxx6 : 4);
- unsigned char chan3_volume;
-} dec_playback_status_t;
-
-#define SCSI_CMD_DEC_PLAYBACK_CONTROL 0xc9
-typedef struct {
- unsigned char xxx0;
- BITFIELD_2(unsigned char,
- fmt : 1,
- xxx1 : 7);
- unsigned char xxx[8];
- BITFIELD_2(unsigned char,
- chan0_select : 4,
- xxx3 : 4);
- unsigned char chan0_volume;
- BITFIELD_2(unsigned char,
- chan1_select : 4,
- xxx4 : 4);
- unsigned char chan1_volume;
- BITFIELD_2(unsigned char,
- chan2_select : 4,
- xxx5 : 4);
- unsigned char chan2_volume;
- BITFIELD_2(unsigned char,
- chan3_select : 4,
- xxx6 : 4);
- unsigned char chan3_volume;
-} dec_playback_control_t;
-
-
-#if 0
-
-private scsi_ret_t
-rrd42_status(
- target_info_t *tgt,
- char *cmd,
- io_req_t ior)
-{
- scsi_ret_t rc;
- char *buf = tgt->dev_info.cdrom.result;
- scsi_command_group_2 c;
- dec_playback_status_t *st;
-
- /* We might have to specify addressing fmt */
- if (cmd[4] == 'P') {
- scsi_command_group_2 saf;
-
- bzero(&saf, sizeof(saf));
- saf.scsi_cmd_code = SCSI_CMD_DEC_SET_ADDRESS_FORMAT;
- saf.scsi_cmd_saf_fmt = (cmd[13] == 'A') ? 0 : 1;
-
- rc = cdrom_vendor_specific(tgt, &saf, 0, 0, 0, ior);
-
- if (rc != SCSI_RET_SUCCESS) return rc;
-
- zero_ior( ior );
- }
-
- bzero(&c, sizeof(c));
- c.scsi_cmd_code = SCSI_CMD_DEC_PLAYBACK_STATUS;
- c.scsi_cmd_xfer_len_2 = sizeof(*st);
- rc = cdrom_vendor_specific(tgt, &c, 0, 0, sizeof(*st), ior);
-
- if (rc != SCSI_RET_SUCCESS) return rc;
-
- st = (dec_playback_status_t *) tgt->cmd_ptr;
-
- if (cmd[4] == 'S')
- decode_status( buf, st->audio_status+0x11 );
- else {
- if (st->is_msf)
- sprintf(buf, "MSF Position %d %d %d",
- (integer_t)st->address.msf.minute,
- (integer_t)st->address.msf.second,
- (integer_t)st->address.msf.frame);
- else
- sprintf(buf, "ABS Position %d", (integer_t)
- (st->address.lba.lba1<<24)+
- (st->address.lba.lba2<<16)+
- (st->address.lba.lba3<< 8)+
- st->address.lba.lba4);
- }
- tgt->dev_info.cdrom.result_available = TRUE;
- return rc;
-}
-#endif
-
-private scsi_ret_t
-rrd42_set_volume(
- target_info_t *tgt,
- char *cmd,
- io_req_t ior)
-{
- scsi_command_group_2 c;
- dec_playback_control_t req;
- int v0, v1, v2, v3;
-
- sscanf(&cmd[6], "%d %d %d %d", &v0, &v1, &v2, &v3);
-
- bzero(&c, sizeof(c));
- c.scsi_cmd_code = SCSI_CMD_DEC_PLAYBACK_CONTROL;
- c.scsi_cmd_xfer_len_2 = sizeof(req);
- bzero(&req, sizeof(req));
- if (v0) {
- req.chan0_select = 1;
- req.chan0_volume = v0;
- }
- if (v1) {
- req.chan1_select = 2;
- req.chan1_volume = v1;
- }
- if (v2) {
- req.chan2_select = 4;
- req.chan2_volume = v2;
- }
- if (v3) {
- req.chan3_select = 8;
- req.chan3_volume = v3;
- }
- return cdrom_vendor_specific(tgt, &c, &req, sizeof(req), 0, ior);
-}
-
- /* NEC CD-ROM */
-
-#define SCSI_CMD_NEC_READ_TOC 0xde
-typedef struct {
- unsigned char xxx[9];
- unsigned char first_track;
- unsigned char xxx1[9];
- unsigned char last_track;
- unsigned char xxx2[9];
- unsigned char lead_out_addr[3];
- struct {
- BITFIELD_2(unsigned char,
- adr : 4,
- ctrl : 4);
- unsigned char xxx3[6];
- unsigned char address[3];
- } track_info[1]; /* VARSIZE */
-} nec_toc_data_t;
-
-#define SCSI_CMD_NEC_SEEK_TRK 0xd8
-#define SCSI_CMD_NEC_PLAY_AUDIO 0xd9
-#define SCSI_CMD_NEC_PAUSE 0xda
-#define SCSI_CMD_NEC_EJECT 0xdc
-
-#define SCSI_CMD_NEC_READ_SUBCH_Q 0xdd
-typedef struct {
- unsigned char audio_status; /* see decode_status_1 */
- BITFIELD_2(unsigned char,
- ctrl : 4,
- xxx1 : 4);
- unsigned char trackno;
- unsigned char indexno;
- unsigned char relative_address[3];
- unsigned char absolute_address[3];
-} nec_subch_data_t;
-
-/*
- * Reserved bits in byte1
- */
-#define NEC_LR_PLAY_MODE 0x01 /* RelAdr bit overload */
-#define NEC_LR_STEREO 0x02 /* mono/stereo */
-
-/*
- * Vendor specific bits in the control byte.
- * NEC uses them to specify the addressing mode
- */
-#define NEC_CTRL_A_ABS 0x00 /* XXX not sure about this */
-#define NEC_CTRL_A_MSF 0x40 /* min/sec/frame */
-#define NEC_CTRL_A_TI 0x80 /* track/index */
-#define NEC_CTRL_A_CURRENT 0xc0 /* same as last specified */
-
-private scsi_ret_t
-nec_eject(
- target_info_t *tgt,
- char *cmd,
- io_req_t ior)
-{
- scsi_command_group_2 c;
-
- bzero(&c, sizeof(c));
- c.scsi_cmd_code = SCSI_CMD_NEC_EJECT;
-
- return cdrom_vendor_specific(tgt, &c, 0, 0, 0, ior);
-}
-
-private scsi_ret_t
-nec_subchannel(
- target_info_t *tgt,
- char *cmd,
- io_req_t ior)
-{
- scsi_command_group_2 c;
- nec_subch_data_t *st;
- char *buf = tgt->dev_info.cdrom.result;
- scsi_ret_t rc;
-
- bzero(&c, sizeof(c));
- c.scsi_cmd_code = SCSI_CMD_NEC_READ_SUBCH_Q;
- c.scsi_cmd_lun_and_relbit = sizeof(*st); /* Sic! */
-
- rc = cdrom_vendor_specific(tgt, &c, 0, 0, sizeof(*st), ior);
- if (rc != SCSI_RET_SUCCESS) return rc;
-
- st = (nec_subch_data_t *) tgt->cmd_ptr;
-
- /* Status or Position ? */
-
- if (cmd[4] == 'S') {
- decode_status_1( buf, st->audio_status);
- } else {
-
- /* XXX can it do ABS addressing e.g. 'logical' ? */
-
- sprintf(buf, "MSF Position %d %d %d %d %d %d",
- (integer_t)bcd_to_decimal(st->absolute_address[0]), /* min */
- (integer_t)bcd_to_decimal(st->absolute_address[1]), /* sec */
- (integer_t)bcd_to_decimal(st->absolute_address[2]), /* frm */
- (integer_t)bcd_to_decimal(st->relative_address[0]), /* min */
- (integer_t)bcd_to_decimal(st->relative_address[1]), /* sec */
- (integer_t)bcd_to_decimal(st->relative_address[2])); /* frm */
- }
-
- tgt->dev_info.cdrom.result_available = TRUE;
- return SCSI_RET_SUCCESS;
-}
-
-private scsi_ret_t
-nec_read_toc(
- target_info_t *tgt,
- char *cmd,
- io_req_t ior)
-{
- scsi_command_group_2 c;
- nec_toc_data_t *t;
- char *buf = tgt->dev_info.cdrom.result;
- scsi_ret_t rc;
- int first, last, i;
-
- bzero(&c, sizeof(c));
- c.scsi_cmd_code = SCSI_CMD_NEC_READ_TOC;
- c.scsi_cmd_lun_and_relbit = NEC_LR_PLAY_MODE|NEC_LR_STEREO;
-
- rc = cdrom_vendor_specific(tgt, &c, 0, 0, 512/*XXX*/, ior);
- if (rc != SCSI_RET_SUCCESS) return rc;
-
- t = (nec_toc_data_t *) tgt->cmd_ptr;
-
- first = bcd_to_decimal(t->first_track);
- last = bcd_to_decimal(t->last_track);
-
- /*
- * "Get TH" wants summary, "TOC MSF|ABS from_track" wants all
- */
- if (cmd[0] == 'G') {
- sprintf(buf, "toc header: %d %d %d",
- sizeof(*t) + sizeof(t->track_info) * (last - first - 1),
- first, last);
- goto out;
- }
-
- /*
- * The whole shebang
- */
- sscanf(&cmd[8], "%d", &i);
- sprintf(buf, "TOC from track %d:\n", i);
-
- last -= first;
- i -= first;
- while ((i >= 0) && (i <= last)) {
- buf += strlen(buf);
- if (cmd[4] == 'M')
- sprintf(buf, "%d %d %d %d %d %d\n",
- t->track_info[i].ctrl,
- t->track_info[i].adr,
- first + i,
- bcd_to_decimal(t->track_info[i].address[0]),
- bcd_to_decimal(t->track_info[i].address[1]),
- bcd_to_decimal(t->track_info[i].address[2]));
- else
-/* THIS IS WRONG */
- sprintf(buf, "%d %d %d %d\n",
- t->track_info[i].ctrl,
- t->track_info[i].adr,
- first + i,
- bcd_to_decimal(t->track_info[i].address[0]) * 10000 +
- bcd_to_decimal(t->track_info[i].address[1]) * 100 +
- bcd_to_decimal(t->track_info[i].address[2]));
- i++;
- }
- /* To know how long the last track is */
- buf += strlen(buf);
- if (cmd[4] == 'M')
- sprintf(buf, "%d %d %d %d %d %d\n",
- 0, 1, 0xaa /* User expects this */,
- bcd_to_decimal(t->lead_out_addr[0]),
- bcd_to_decimal(t->lead_out_addr[1]),
- bcd_to_decimal(t->lead_out_addr[2]));
- else
-/* THIS IS WRONG */
- sprintf(buf, "%d %d %d %d\n",
- 0, 1, 0xaa /* User expects this */,
- bcd_to_decimal(t->lead_out_addr[0]) * 10000 +
- bcd_to_decimal(t->lead_out_addr[1]) * 100 +
- bcd_to_decimal(t->lead_out_addr[2]));
-out:
- tgt->dev_info.cdrom.result_available = TRUE;
- return SCSI_RET_SUCCESS;
-}
-
-
-private scsi_ret_t
-nec_play(
- target_info_t *tgt,
- char *cmd,
- io_req_t ior)
-{
- scsi_command_group_2 c;
- int sm, ss, sf, em, es, ef;
- int st, si, et, ei;
- scsi_ret_t rc;
-
- /*
- * Seek to desired position
- */
- bzero(&c, sizeof(c));
- c.scsi_cmd_code = SCSI_CMD_NEC_SEEK_TRK;
- c.scsi_cmd_lun_and_relbit = NEC_LR_PLAY_MODE;
-
- /*
- * Play_msf or Play_ti
- */
- if (cmd[5] == 'A') {
- /* "Play A startM startS startF endM endS endF" */
-
- sscanf(&cmd[7], "%d %d %d %d %d %d",
- &sm, &ss, &sf, &em, &es, &ef);
-
- c.scsi_cmd_lba1 = decimal_to_bcd(sm);
- c.scsi_cmd_lba2 = decimal_to_bcd(ss);
- c.scsi_cmd_lba3 = decimal_to_bcd(sf);
- c.scsi_cmd_ctrl_byte = NEC_CTRL_A_MSF;
-
- } else {
- /* "Play TI startT startI endT endI" */
-
- sscanf(&cmd[8], "%d %d %d %d", &st, &si, &et, &ei);
-
- c.scsi_cmd_lba1 = decimal_to_bcd(st);
- c.scsi_cmd_lba2 = decimal_to_bcd(si);
- c.scsi_cmd_lba3 = 0;
- c.scsi_cmd_ctrl_byte = NEC_CTRL_A_TI;
-
- }
-
- rc = cdrom_vendor_specific(tgt, &c, 0, 0, 0, ior);
- if (rc != SCSI_RET_SUCCESS) return rc;
-
- /*
- * Now ask it to play until..
- */
- zero_ior( ior );
-
- bzero(&c, sizeof(c));
- c.scsi_cmd_code = SCSI_CMD_NEC_PLAY_AUDIO;
- c.scsi_cmd_lun_and_relbit = NEC_LR_PLAY_MODE|NEC_LR_STEREO;
-
- if (cmd[5] == 'A') {
- c.scsi_cmd_lba1 = decimal_to_bcd(em);
- c.scsi_cmd_lba2 = decimal_to_bcd(es);
- c.scsi_cmd_lba3 = decimal_to_bcd(ef);
- c.scsi_cmd_ctrl_byte = NEC_CTRL_A_MSF;
- } else {
- c.scsi_cmd_lba1 = decimal_to_bcd(et);
- c.scsi_cmd_lba2 = decimal_to_bcd(ei);
- c.scsi_cmd_lba3 = 0;
- c.scsi_cmd_ctrl_byte = NEC_CTRL_A_TI;
- }
-
- return cdrom_vendor_specific(tgt, &c, 0, 0, 0, ior);
-}
-
-private scsi_ret_t
-nec_pause_resume(
- target_info_t *tgt,
- char *cmd,
- io_req_t ior)
-{
- scsi_command_group_2 c;
-
- bzero(&c, sizeof(c));
- /*
- * "Resume" or "Stop"
- */
- if (cmd[0] == 'R') {
- c.scsi_cmd_code = SCSI_CMD_NEC_PLAY_AUDIO;
- c.scsi_cmd_lun_and_relbit = NEC_LR_PLAY_MODE|NEC_LR_STEREO;
- c.scsi_cmd_ctrl_byte = NEC_CTRL_A_CURRENT;
- } else {
- c.scsi_cmd_code = SCSI_CMD_NEC_PAUSE;
- }
-
- return cdrom_vendor_specific(tgt, &c, 0, 0, 0, ior);
-}
-
- /* TOSHIBA CD-ROM DRIVE:XM 3232 */
-
-#define SCSI_CMD_TOSHIBA_SEEK_TRK 0xc0
-#define SCSI_CMD_TOSHIBA_PLAY_AUDIO 0xc1
-#define SCSI_CMD_TOSHIBA_PAUSE_AUDIO 0xc2
-#define SCSI_CMD_TOSHIBA_EJECT 0xc4
-
-#define SCSI_CMD_TOSHIBA_READ_SUBCH_Q 0xc6
-typedef nec_subch_data_t toshiba_subch_data_t;
-/* audio status -> decode_status_1 */
-
-#define SCSI_CMD_TOSHIBA_READ_TOC_ENTRY 0xc7
-typedef struct {
- unsigned char first_track;
- unsigned char last_track;
- unsigned char xxx[2];
-} toshiba_toc_header_t;
-typedef struct {
- unsigned char address[4];
-} toshiba_toc_data_t;
-
-
-private scsi_ret_t
-toshiba_eject(
- target_info_t *tgt,
- char *cmd,
- io_req_t ior)
-{
- scsi_command_group_2 c;
-
- bzero(&c, sizeof(c));
- c.scsi_cmd_code = SCSI_CMD_TOSHIBA_EJECT;
-
- return cdrom_vendor_specific(tgt, &c, 0, 0, 0, ior);
-}
-
-private scsi_ret_t
-toshiba_subchannel(
- target_info_t *tgt,
- char *cmd,
- io_req_t ior)
-{
- scsi_command_group_2 c;
- toshiba_subch_data_t *st;
- char *buf = tgt->dev_info.cdrom.result;
- scsi_ret_t rc;
-
- bzero(&c, sizeof(c));
- c.scsi_cmd_code = SCSI_CMD_TOSHIBA_READ_SUBCH_Q;
- c.scsi_cmd_lun_and_relbit = sizeof(*st); /* Sic! */
-
- rc = cdrom_vendor_specific(tgt, &c, 0, 0, sizeof(*st), ior);
- if (rc != SCSI_RET_SUCCESS) return rc;
-
- st = (toshiba_subch_data_t *) tgt->cmd_ptr;
-
- /* Status or Position ? */
-
- if (cmd[4] == 'S') {
- decode_status_1( buf, st->audio_status);
- } else {
-
- /* XXX can it do ABS addressing e.g. 'logical' ? */
-
- sprintf(buf, "MSF Position %d %d %d %d %d %d",
- (integer_t)bcd_to_decimal(st->absolute_address[0]), /* min */
- (integer_t)bcd_to_decimal(st->absolute_address[1]), /* sec */
- (integer_t)bcd_to_decimal(st->absolute_address[2]), /* frm */
- (integer_t)bcd_to_decimal(st->relative_address[0]), /* min */
- (integer_t)bcd_to_decimal(st->relative_address[1]), /* sec */
- (integer_t)bcd_to_decimal(st->relative_address[2])); /* frm */
- }
-
- tgt->dev_info.cdrom.result_available = TRUE;
- return SCSI_RET_SUCCESS;
-}
-
-private scsi_ret_t
-toshiba_read_toc(
- target_info_t *tgt,
- char *cmd,
- io_req_t ior)
-{
- scsi_command_group_2 c;
- toshiba_toc_data_t *t;
- toshiba_toc_header_t *th;
- char *buf = tgt->dev_info.cdrom.result;
- scsi_ret_t rc;
- int first, last, i;
-
- /* TOC header first */
- bzero(&c, sizeof(c));
- c.scsi_cmd_code = SCSI_CMD_TOSHIBA_READ_TOC_ENTRY;
- c.scsi_cmd_lun_and_relbit = 0;
- c.scsi_cmd_lba1 = 0;
-
- rc = cdrom_vendor_specific(tgt, &c, 0, 0, sizeof(*th), ior);
- if (rc != SCSI_RET_SUCCESS) return rc;
-
- th = (toshiba_toc_header_t *) tgt->cmd_ptr;
-
- first = bcd_to_decimal(th->first_track);
- last = bcd_to_decimal(th->last_track);
-
- /*
- * "Get TH" wants summary, "TOC MSF|ABS from_track" wants all
- */
- if (cmd[0] == 'G') {
- sprintf(buf, "toc header: %d %d %d",
- sizeof(*th) + sizeof(*t) * (last - first + 1),
- first, last);
- goto out;
- }
-
- /*
- * The whole shebang
- */
- sscanf(&cmd[8], "%d", &i);
- sprintf(buf, "TOC from track %d:\n", i);
-
- while (i <= last) {
- bzero(&c, sizeof(c));
-
- c.scsi_cmd_code = SCSI_CMD_TOSHIBA_READ_TOC_ENTRY;
- c.scsi_cmd_lun_and_relbit = 2;
- c.scsi_cmd_lba1 = decimal_to_bcd(i);
-
- zero_ior( ior );
- rc = cdrom_vendor_specific(tgt, &c, 0, 0, sizeof(*t), ior);
- if (rc != SCSI_RET_SUCCESS) break;
-
- t = (toshiba_toc_data_t *) tgt->cmd_ptr;
-
- buf += strlen(buf);
- if (cmd[4] == 'M')
- sprintf(buf, "0 0 %d %d %d %d\n",
- i,
- bcd_to_decimal(t->address[0]),
- bcd_to_decimal(t->address[1]),
- bcd_to_decimal(t->address[2]));
- else
-/* THIS IS WRONG */
- sprintf(buf, "0 0 %d %d\n",
- i,
- bcd_to_decimal(t->address[0]) * 10000 +
- bcd_to_decimal(t->address[1]) * 100 +
- bcd_to_decimal(t->address[2]));
- i++;
- }
-
- /* Must simulate the lead-out track */
- bzero(&c, sizeof(c));
-
- c.scsi_cmd_code = SCSI_CMD_TOSHIBA_READ_TOC_ENTRY;
- c.scsi_cmd_lun_and_relbit = 1;
- c.scsi_cmd_lba1 = 0;
-
- zero_ior( ior );
- rc = cdrom_vendor_specific(tgt, &c, 0, 0, sizeof(*t), ior);
- if (rc != SCSI_RET_SUCCESS) goto out;
-
- t = (toshiba_toc_data_t *) tgt->cmd_ptr;
-
- buf += strlen(buf);
- if (cmd[4] == 'M')
- sprintf(buf, "0 0 %d %d %d %d\n",
- i,
- bcd_to_decimal(t->address[0]),
- bcd_to_decimal(t->address[1]),
- bcd_to_decimal(t->address[2]));
- else
-/* THIS IS WRONG */
- sprintf(buf, "0 0 %d %d\n",
- i,
- bcd_to_decimal(t->address[0]) * 10000 +
- bcd_to_decimal(t->address[1]) * 100 +
- bcd_to_decimal(t->address[2]));
- i++;
-
-out:
- tgt->dev_info.cdrom.result_available = TRUE;
- return SCSI_RET_SUCCESS;
-}
-
-
-private scsi_ret_t
-toshiba_play(
- target_info_t *tgt,
- char *cmd,
- io_req_t ior)
-{
- scsi_command_group_2 c;
- int sm, ss, sf, em, es, ef;
- int st, si, et, ei;
- scsi_ret_t rc;
-
- /*
- * Seek to desired position
- */
- bzero(&c, sizeof(c));
- c.scsi_cmd_code = SCSI_CMD_TOSHIBA_SEEK_TRK;
-
- /*
- * Play_msf or Play_ti
- */
- if (cmd[5] == 'A') {
- /* "Play A startM startS startF endM endS endF" */
-
- sscanf(&cmd[7], "%d %d %d %d %d %d",
- &sm, &ss, &sf, &em, &es, &ef);
-
- c.scsi_cmd_lba1 = decimal_to_bcd(sm);
- c.scsi_cmd_lba2 = decimal_to_bcd(ss);
- c.scsi_cmd_lba3 = decimal_to_bcd(sf);
- c.scsi_cmd_ctrl_byte = NEC_CTRL_A_MSF;
-
- } else {
- /* "Play TI startT startI endT endI" */
-
- sscanf(&cmd[8], "%d %d %d %d", &st, &si, &et, &ei);
-
- c.scsi_cmd_lba1 = decimal_to_bcd(st);
- c.scsi_cmd_lba2 = decimal_to_bcd(si);
- c.scsi_cmd_lba3 = 0;
- c.scsi_cmd_ctrl_byte = NEC_CTRL_A_TI;
-
- }
-
- rc = cdrom_vendor_specific(tgt, &c, 0, 0, 0, ior);
- if (rc != SCSI_RET_SUCCESS) return rc;
-
- /*
- * Now ask it to play until..
- */
- zero_ior( ior );
-
- bzero(&c, sizeof(c));
- c.scsi_cmd_code = SCSI_CMD_TOSHIBA_PLAY_AUDIO;
- c.scsi_cmd_lun_and_relbit = NEC_LR_PLAY_MODE|NEC_LR_STEREO;
-
- if (cmd[5] == 'A') {
- c.scsi_cmd_lba1 = decimal_to_bcd(em);
- c.scsi_cmd_lba2 = decimal_to_bcd(es);
- c.scsi_cmd_lba3 = decimal_to_bcd(ef);
- c.scsi_cmd_ctrl_byte = NEC_CTRL_A_MSF;
- } else {
- c.scsi_cmd_lba1 = decimal_to_bcd(et);
- c.scsi_cmd_lba2 = decimal_to_bcd(ei);
- c.scsi_cmd_lba3 = 0;
- c.scsi_cmd_ctrl_byte = NEC_CTRL_A_TI;
- }
-
- return cdrom_vendor_specific(tgt, &c, 0, 0, 0, ior);
-}
-
-private scsi_ret_t
-toshiba_pause_resume(
- target_info_t *tgt,
- char *cmd,
- io_req_t ior)
-{
- scsi_command_group_2 c;
-
- bzero(&c, sizeof(c));
- /*
- * "Resume" or "Stop"
- */
- if (cmd[0] == 'R') {
- /* ???? would have to remember last cmd ???? */
-/* broken ! */
- c.scsi_cmd_code = SCSI_CMD_TOSHIBA_PLAY_AUDIO;
- c.scsi_cmd_lun_and_relbit = NEC_LR_PLAY_MODE|NEC_LR_STEREO;
- c.scsi_cmd_ctrl_byte = NEC_CTRL_A_CURRENT;
- } else {
- c.scsi_cmd_code = SCSI_CMD_TOSHIBA_PAUSE_AUDIO;
- }
-
- return cdrom_vendor_specific(tgt, &c, 0, 0, 0, ior);
-}
-
-
-#if 0
- /* I have info on these drives, but no drive to test */
-
- /* PIONEER DRM-600 */
-
-#define SCSI_CMD_PIONEER_EJECT 0xc0
-
-#define SCSI_CMD_PIONEER_READ_TOC 0xc1
-typedef struct {
- unsigned char first_track;
- unsigned char last_track;
- unsigned char xxx[2];
-} pioneer_toc_hdr_t;
-typedef struct {
- unsigned char ctrl;
- unsigned char address[3];
-} pioneer_toc_info_t;
-
-#define SCSI_CMD_PIONEER_READ_SUBCH 0xc2
-typedef struct {
- BITFIELD_2(unsigned char,
- ctrl : 4,
- xxx1 : 4);
- unsigned char trackno;
- unsigned char indexno;
- unsigned char relative_address[3];
- unsigned char absolute_address[3];
-} pioneer_subch_data_t;
-
-#define SCSI_CMD_PIONEER_SEEK_TRK 0xc8
-#define SCSI_CMD_PIONEER_PLAY_AUDIO 0xc9
-#define SCSI_CMD_PIONEER_PAUSE 0xca
-
-#define SCSI_CMD_PIONEER_AUDIO_STATUS 0xcc
-typedef struct {
- unsigned char audio_status;
- unsigned char xxx[5];
-} pioneer_status_t;
-
-/*
- * Reserved bits in byte1
- */
-#define PIONEER_LR_END_ADDR 0x10
-#define PIONEER_LR_PAUSE 0x10
-#define PIONEER_LR_RESUME 0x00
-
-/*
- * Vendor specific bits in the control byte.
- */
-#define PIONEER_CTRL_TH 0x00 /* TOC header */
-#define PIONEER_CTRL_TE 0x80 /* one TOC entry */
-#define PIONEER_CTRL_LO 0x40 /* lead-out track info */
-
-#define PIONEER_CTRL_A_MSF 0x40 /* min/sec/frame addr */
-
-private scsi_ret_t
-pioneer_eject(
- target_info_t *tgt,
- char *cmd,
- io_req_t ior)
-{
- scsi_command_group_2 c;
-
- bzero(&c, sizeof(c));
- c.scsi_cmd_code = SCSI_CMD_PIONEER_EJECT;
-
- return cdrom_vendor_specific(tgt, &c, 0, 0, 0, ior);
-}
-
-private scsi_ret_t
-pioneer_position(
- target_info_t *tgt,
- char *cmd,
- io_req_t ior)
-{
- scsi_command_group_2 c;
- scsi_ret_t rc;
- char *buf = tgt->dev_info.cdrom.result;
- pioneer_subch_data_t *st;
-
- bzero(&c, sizeof(c));
- c.scsi_cmd_code = SCSI_CMD_PIONEER_READ_SUBCH;
- c.scsi_cmd_xfer_len_2 = sizeof(pioneer_subch_data_t); /* 9 bytes */
-
- rc = cdrom_vendor_specific(tgt, &c, 0, 0, sizeof(pioneer_subch_data_t), ior);
- if (rc != SCSI_RET_SUCCESS) return rc;
-
- st = (pioneer_subch_data_t *) tgt->cmd_ptr;
-
- /* XXX can it do ABS addressing e.g. 'logical' ? */
-
- sprintf(buf, "MSF Position %d %d %d %d %d %d",
- (integer_t)bcd_to_decimal(st->absolute_address[0]), /* min */
- (integer_t)bcd_to_decimal(st->absolute_address[1]), /* sec */
- (integer_t)bcd_to_decimal(st->absolute_address[2]), /* frm */
- (integer_t)bcd_to_decimal(st->relative_address[0]), /* min */
- (integer_t)bcd_to_decimal(st->relative_address[1]), /* sec */
- (integer_t)bcd_to_decimal(st->relative_address[2])); /* frm */
-
- tgt->dev_info.cdrom.result_available = TRUE;
- return SCSI_RET_SUCCESS;
-}
-
-private scsi_ret_t
-pioneer_toc(
- target_info_t *tgt,
- char *cmd,
- io_req_t ior)
-{
- scsi_command_group_2 c;
- pioneer_toc_hdr_t *th;
- pioneer_toc_info_t *t;
- char *buf = tgt->dev_info.cdrom.result;
- scsi_ret_t rc;
- int first, last, i;
-
- /* Read header first */
- bzero(&c, sizeof(c));
- c.scsi_cmd_code = SCSI_CMD_PIONEER_READ_TOC;
- c.scsi_cmd_xfer_len_2 = sizeof(pioneer_toc_hdr_t);
- c.scsi_cmd_ctrl_byte = PIONEER_CTRL_TH;
-
- rc = cdrom_vendor_specific(tgt, &c, 0, 0, sizeof(pioneer_toc_hdr_t), ior);
- if (rc != SCSI_RET_SUCCESS) return rc;
-
- th = (pioneer_toc_hdr_t *)tgt->cmd_ptr;
- first = bcd_to_decimal(th->first_track);
- last = bcd_to_decimal(th->last_track);
-
- /*
- * "Get TH" wants summary, "TOC MSF|ABS from_track" wants all
- */
- if (cmd[0] == 'G') {
- sprintf(buf, "toc header: %d %d %d", 0, first, last);
- goto out;
- }
-
- /*
- * Must do it one track at a time
- */
- sscanf(&cmd[8], "%d", &i);
- sprintf(buf, "TOC from track %d:\n", i);
-
- for ( ; i <= last; i++) {
- zero_ior(ior);
- bzero(&c, sizeof(c));
- c.scsi_cmd_code = SCSI_CMD_PIONEER_READ_TOC;
- c.scsi_cmd_lba4 = decimal_to_bcd(i);
- c.scsi_cmd_xfer_len_2 = sizeof(pioneer_toc_info_t);
- c.scsi_cmd_ctrl_byte = PIONEER_CTRL_TE;
-
- rc = cdrom_vendor_specific(tgt, &c, 0, 0, sizeof(pioneer_toc_info_t), ior);
- if (rc != SCSI_RET_SUCCESS) break;
-
- t = (pioneer_toc_info_t *)tgt->cmd_ptr;
-
- buf += strlen(buf);
- if (cmd[4] == 'M')
- sprintf(buf, "%d %d %d %d %d %d\n",
- t->ctrl, 0, i,
- bcd_to_decimal(t->address[0]),
- bcd_to_decimal(t->address[1]),
- bcd_to_decimal(t->address[2]));
- else
-/* THIS IS WRONG */
- sprintf(buf, "%d %d %d %d\n",
- t->ctrl, 0, i,
- bcd_to_decimal(t->address[0]) * 10000 +
- bcd_to_decimal(t->address[1]) * 100 +
- bcd_to_decimal(t->address[2]));
- }
- /* To know how long the last track is */
- zero_ior(ior);
- bzero(&c, sizeof(c));
- c.scsi_cmd_code = SCSI_CMD_PIONEER_READ_TOC;
- c.scsi_cmd_xfer_len_2 = sizeof(pioneer_toc_info_t);
- c.scsi_cmd_ctrl_byte = PIONEER_CTRL_LO;
-
- rc = cdrom_vendor_specific(tgt, &c, 0, 0, sizeof(pioneer_toc_info_t), ior);
- if (rc != SCSI_RET_SUCCESS) return rc;
-
- buf += strlen(buf);
- t = (pioneer_toc_info_t *)tgt->cmd_ptr;
- if (cmd[4] == 'M')
- sprintf(buf, "%d %d %d %d %d %d\n",
- t->ctrl, 0, 0xaa /* User expects this */,
- bcd_to_decimal(t->address[0]),
- bcd_to_decimal(t->address[1]),
- bcd_to_decimal(t->address[2]));
- else
-/* THIS IS WRONG */
- sprintf(buf, "%d %d %d %d\n",
- t->ctrl, 0, 0xaa /* User expects this */,
- bcd_to_decimal(t->address[0]) * 10000 +
- bcd_to_decimal(t->address[1]) * 100 +
- bcd_to_decimal(t->address[2]));
-
-out:
- tgt->dev_info.cdrom.result_available = TRUE;
- return SCSI_RET_SUCCESS;
-}
-
-private scsi_ret_t
-pioneer_status(
- target_info_t *tgt,
- char *cmd,
- io_req_t ior)
-{
- scsi_command_group_2 c;
- pioneer_status_t *st;
- char *buf = tgt->dev_info.cdrom.result;
- scsi_ret_t rc;
-
- bzero(&c, sizeof(c));
- c.scsi_cmd_code = SCSI_CMD_PIONEER_AUDIO_STATUS;
- c.scsi_cmd_xfer_len_2 = sizeof(pioneer_status_t); /* 6 bytes */
-
- rc = cdrom_vendor_specific(tgt, &c, 0, 0, sizeof(pioneer_status_t), ior);
- if (rc != SCSI_RET_SUCCESS) return rc;
-
- st = (pioneer_status_t*) tgt->cmd_ptr;
- decode_status_1( buf, st->audio_status);
-
- tgt->dev_info.cdrom.result_available = TRUE;
- return SCSI_RET_SUCCESS;
-}
-
-private scsi_ret_t
-pioneer_play(
- target_info_t *tgt,
- char *cmd,
- io_req_t ior)
-{
- scsi_command_group_2 c;
- int sm, ss, sf, em, es, ef;
- int st, si, et, ei;
- scsi_ret_t rc;
-
- /*
- * Seek to desired position
- */
- bzero(&c, sizeof(c));
- c.scsi_cmd_code = SCSI_CMD_PIONEER_SEEK_TRK;
- /*
- * Play_msf or Play_ti
- */
- if (cmd[5] == 'A') {
- /* "Play A startM startS startF endM endS endF" */
-
- sscanf(&cmd[7], "%d %d %d %d %d %d",
- &sm, &ss, &sf, &em, &es, &ef);
-
- c.scsi_cmd_lba2 = decimal_to_bcd(sm);
- c.scsi_cmd_lba3 = decimal_to_bcd(ss);
- c.scsi_cmd_lba4 = decimal_to_bcd(sf);
- c.scsi_cmd_ctrl_byte = PIONEER_CTRL_A_MSF;
-
- } else {
- /* "Play TI startT startI endT endI" */
-
- sscanf(&cmd[8], "%d %d %d %d", &st, &si, &et, &ei);
-
- c.scsi_cmd_lba3 = decimal_to_bcd(st);
- c.scsi_cmd_lba4 = decimal_to_bcd(si);
- c.scsi_cmd_ctrl_byte = 0x80; /* Pure speculation!! */
-
- }
-
- rc = cdrom_vendor_specific(tgt, &c, 0, 0, 0, ior);
- if (rc != SCSI_RET_SUCCESS) return rc;
-
- /*
- * Now ask it to play until..
- */
- zero_ior( ior );
-
- bzero(&c, sizeof(c));
- c.scsi_cmd_code = SCSI_CMD_PIONEER_PLAY_AUDIO;
- c.scsi_cmd_lun_and_relbit = PIONEER_LR_END_ADDR;
-
- if (cmd[5] == 'A') {
- c.scsi_cmd_lba2 = decimal_to_bcd(em);
- c.scsi_cmd_lba3 = decimal_to_bcd(es);
- c.scsi_cmd_lba4 = decimal_to_bcd(ef);
- c.scsi_cmd_ctrl_byte = PIONEER_CTRL_A_MSF;
- } else {
- c.scsi_cmd_lba3 = decimal_to_bcd(et);
- c.scsi_cmd_lba4 = decimal_to_bcd(ei);
- c.scsi_cmd_ctrl_byte = 0x80; /* Pure speculation! */
- }
-
- return cdrom_vendor_specific(tgt, &c, 0, 0, 0, ior);
-}
-
-private scsi_ret_t
-pioneer_pause_resume(
- target_info_t *tgt,
- char *cmd,
- io_req_t ior)
-{
- scsi_command_group_2 c;
-
- bzero(&c, sizeof(c));
- c.scsi_cmd_code = SCSI_CMD_PIONEER_PAUSE;
- /*
- * "Resume" or "Stop"
- */
- if (cmd[0] == 'S')
- c.scsi_cmd_lun_and_relbit = PIONEER_LR_PAUSE;
- else
- c.scsi_cmd_lun_and_relbit = PIONEER_LR_RESUME;
-
- return cdrom_vendor_specific(tgt, &c, 0, 0, 0, ior);
-}
-
- /* DENON DRD-253 */
-
-#define SCSI_CMD_DENON_PLAY_AUDIO 0x22
-#define SCSI_CMD_DENON_EJECT 0xe6
-#define SCSI_CMD_DENON_PAUSE_AUDIO 0xe7
-#define SCSI_CMD_DENON_READ_TOC 0xe9
-#define SCSI_CMD_DENON_READ_SUBCH 0xeb
-
-
- /* HITACHI 1750 */
-
-#define SCSI_CMD_HITACHI_PLAY_AUDIO_MSF 0xe0
-#define SCSI_CMD_HITACHI_PAUSE_AUDIO 0xe1
-#define SCSI_CMD_HITACHI_EJECT 0xe4
-#define SCSI_CMD_HITACHI_READ_SUBCH 0xe5
-#define SCSI_CMD_HITACHI_READ_TOC 0xe8
-
-#endif
-
-/*
- * Tabulate all of the above
- */
-private red_list_t cdrom_exceptions[] = {
-
-#if 0
- For documentation purposes, here are some SCSI-2 compliant drives:
-
- Vendor Product Rev Comments
-
- "SONY " "CD-ROMCDU-541 " "2.6a" The NeXT drive
-#endif
-
- /* vendor, product, rev */
- /* can_play_audio */
- /* eject */
- /* current_position */
- /* read_toc */
- /* get_status */
- /* play_msf */
- /* play_ti */
- /* pause_resume */
- /* volume_control */
-
- /* We have seen a "RRD42(C)DEC " "4.5d" */
- { "DEC ", "RRD42", "",
- 0, 0, 0, 0, 0, 0, 0, 0, rrd42_set_volume },
-
- /* We have seen a "CD-ROM DRIVE:84 " "1.0 " */
- { "NEC ", "CD-ROM DRIVE:84", "",
- op_not_supported, nec_eject, nec_subchannel, nec_read_toc,
- nec_subchannel, nec_play, nec_play, nec_pause_resume,
- op_not_supported },
-
- /* We have seen a "CD-ROM DRIVE:XM " "3232" */
- { "TOSHIBA ", "CD-ROM DRIVE:XM", "32",
- op_not_supported, toshiba_eject, toshiba_subchannel, toshiba_read_toc,
- toshiba_subchannel, toshiba_play, toshiba_play, toshiba_pause_resume,
- op_not_supported },
-
- { "TOSHIBA ", "CD-ROM DRIVE:XM", "33",
- op_not_supported, toshiba_eject, toshiba_subchannel, toshiba_read_toc,
- toshiba_subchannel, toshiba_play, toshiba_play, toshiba_pause_resume,
- op_not_supported },
-
-#if 0
- { "PIONEER ", "???????DRM-6", "",
- op_not_supported, pioneer_eject, pioneer_position, pioneer_toc,
- pioneer_status, pioneer_play, pioneer_play, pioneer_pause_resume,
- op_not_supported },
-
- { "DENON ", "DRD 25X", "", ...},
- { "HITACHI ", "CDR 1750S", "", ...},
- { "HITACHI ", "CDR 1650S", "", ...},
- { "HITACHI ", "CDR 3650", "", ...},
-
-#endif
-
- /* Zero terminate this list */
- { 0, }
-};
-
-private void
-check_red_list(
- target_info_t *tgt,
- scsi2_inquiry_data_t *inq)
-
-{
- red_list_t *list;
-
- for (list = &cdrom_exceptions[0]; list->vendor; list++) {
-
- /*
- * Prefix-Match all strings
- */
- if ((strncmp(list->vendor, (const char *)inq->vendor_id,
- strlen(list->vendor)) == 0) &&
- (strncmp(list->product, (const char *)inq->product_id,
- strlen(list->product)) == 0) &&
- (strncmp(list->rev, (const char *)inq->product_rev,
- strlen(list->rev)) == 0)) {
- /*
- * One of them..
- */
- if (tgt->dev_info.cdrom.violates_standards != list) {
- tgt->dev_info.cdrom.violates_standards = list;
- curse_the_vendor( list, TRUE );
- }
- return;
- }
- }
-}
-#endif /* NSCSI > 0 */
diff --git a/scsi/rz_cpu.c b/scsi/rz_cpu.c
deleted file mode 100644
index 77c0683..0000000
--- a/scsi/rz_cpu.c
+++ /dev/null
@@ -1,450 +0,0 @@
-/*
- * Mach Operating System
- * Copyright (c) 1991,1990 Carnegie Mellon University
- * All Rights Reserved.
- *
- * Permission to use, copy, modify and distribute this software and its
- * documentation is hereby granted, provided that both the copyright
- * notice and this permission notice appear in all copies of the
- * software, derivative works or modified versions, and any portions
- * thereof, and that both notices appear in supporting documentation.
- *
- * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
- * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
- * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
- *
- * Carnegie Mellon requests users of this software to return to
- *
- * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
- * School of Computer Science
- * Carnegie Mellon University
- * Pittsburgh PA 15213-3890
- *
- * any improvements or extensions that they make and grant Carnegie Mellon
- * the rights to redistribute these changes.
- */
-/*
- * File: rz_cpu.c
- * Author: Alessandro Forin, Carnegie Mellon University
- * Date: 7/91
- *
- * Top layer of the SCSI driver: interface with the MI.
- * This file contains operations specific to CPU-like devices.
- *
- * We handle here the case of simple devices which do not use any
- * sophisticated host-to-host communication protocol, they look
- * very much like degenerative cases of TAPE devices.
- *
- * For documentation and debugging, we also provide code to act like one.
- */
-
-#include <mach/std_types.h>
-#include <scsi/compat_30.h>
-
-#include <scsi/scsi.h>
-#include <scsi/scsi_defs.h>
-#include <scsi/rz.h>
-
-#if (NSCSI > 0)
-
-void sccpu_act_as_target(); /* forwards */
-void sccpu_start();
-
-/*
- * This function decides which 'protocol' we well speak
- * to a cpu target. For now the decision is left to a
- * global var. XXXXXXX
- */
-extern scsi_devsw_t scsi_host;
-scsi_devsw_t *scsi_cpu_protocol = /* later &scsi_host*/
- &scsi_devsw[SCSI_CPU];
-
-void sccpu_new_initiator(self, initiator)
- target_info_t *self, *initiator;
-{
- initiator->dev_ops = scsi_cpu_protocol;
- if (initiator == self) {
- self->flags = TGT_DID_SYNCH|TGT_FULLY_PROBED|TGT_ONLINE|
- TGT_ALIVE|TGT_US;
- self->dev_info.cpu.req_pending = FALSE;
- } else {
- initiator->flags = TGT_ONLINE|TGT_ALIVE;
- initiator->dev_info.cpu.req_pending = TRUE;
- }
-}
-
-void sccpu_strategy(ior)
- register io_req_t ior;
-{
- void sccpu_start();
-
- rz_simpleq_strategy(ior, sccpu_start);
-}
-
-void sccpu_start(tgt, done)
- target_info_t *tgt;
- boolean_t done;
-{
- io_req_t head, ior;
- scsi_ret_t ret;
-
- /* this is to the doc & debug code mentioned in the beginning */
- if (!done && tgt->dev_info.cpu.req_pending) {
- panic("sccpu_act_as_target called");
-#if 0
- sccpu_act_as_target( tgt);
-#endif
- return;
- }
-
- ior = tgt->ior;
- if (ior == 0)
- return;
-
- if (done) {
-
- /* see if we must retry */
- if ((tgt->done == SCSI_RET_RETRY) &&
- ((ior->io_op & IO_INTERNAL) == 0)) {
- delay(1000000);/*XXX*/
- goto start;
- } else
- /* got a bus reset ? shouldn't matter */
- if ((tgt->done == (SCSI_RET_ABORTED|SCSI_RET_RETRY)) &&
- ((ior->io_op & IO_INTERNAL) == 0)) {
- goto start;
- } else
-
- /* check completion status */
-
- if (tgt->cur_cmd == SCSI_CMD_REQUEST_SENSE) {
- scsi_sense_data_t *sns;
-
- ior->io_op = ior->io_temporary;
- ior->io_error = D_IO_ERROR;
- ior->io_op |= IO_ERROR;
-
- sns = (scsi_sense_data_t *)tgt->cmd_ptr;
- if (scsi_debug)
- scsi_print_sense_data(sns);
-
- if (scsi_check_sense_data(tgt, sns)) {
- if (sns->u.xtended.ili) {
- if (ior->io_op & IO_READ) {
- int residue;
-
- residue = sns->u.xtended.info0 << 24 |
- sns->u.xtended.info1 << 16 |
- sns->u.xtended.info2 << 8 |
- sns->u.xtended.info3;
- if (scsi_debug)
- printf("Cpu Short Read (%d)\n", residue);
- /*
- * NOTE: residue == requested - actual
- * We only care if > 0
- */
- if (residue < 0) residue = 0;/* sanity */
- ior->io_residual += residue;
- ior->io_error = 0;
- ior->io_op &= ~IO_ERROR;
- /* goto ok */
- }
- }
- }
- }
-
- else if (tgt->done != SCSI_RET_SUCCESS) {
-
- if (tgt->done == SCSI_RET_NEED_SENSE) {
-
- ior->io_temporary = ior->io_op;
- ior->io_op = IO_INTERNAL;
- if (scsi_debug)
- printf("[NeedSns x%x x%x]", ior->io_residual, ior->io_count);
- scsi_request_sense(tgt, ior, 0);
- return;
-
- } else if (tgt->done == SCSI_RET_RETRY) {
- /* only retry here READs and WRITEs */
- if ((ior->io_op & IO_INTERNAL) == 0) {
- ior->io_residual = 0;
- goto start;
- } else{
- ior->io_error = D_WOULD_BLOCK;
- ior->io_op |= IO_ERROR;
- }
- } else {
- ior->io_error = D_IO_ERROR;
- ior->io_op |= IO_ERROR;
- }
- }
-
- if (scsi_debug)
- printf("[Resid x%x]", ior->io_residual);
-
- /* dequeue next one */
- head = ior;
-
- simple_lock(&tgt->target_lock);
- ior = head->io_next;
- tgt->ior = ior;
- if (ior)
- ior->io_prev = head->io_prev;
- simple_unlock(&tgt->target_lock);
-
- iodone(head);
-
- if (ior == 0)
- return;
- }
- ior->io_residual = 0;
-start:
- if (ior->io_op & IO_READ) {
- ret = scsi_receive( tgt, ior );
- } else if ((ior->io_op & IO_INTERNAL) == 0) {
- ret = scsi_send( tgt, ior );
- }
-}
-
-
-#if 0
-/* XX turned off this code because it's impossible
- to reference 'end' and other such magic symbols
- from boot modules. */
-/*
- * This is a simple code to make us act as a dumb
- * processor type. Use for debugging only.
- */
-static struct io_req sccpu_ior;
-vm_offset_t sccpu_buffer; /* set this with debugger */
-
-void sccpu_act_as_target(self)
- target_info_t *self;
-{
- static char inq_data[] = "\3\0\1\0\040\0\0\0Mach3.0 Processor Link v0.1";
- static char sns_data[] = "\160\0\0\0\0\0\0\0\0";
-
- self->dev_info.cpu.req_pending = FALSE;
- sccpu_ior.io_next = 0;
-#define MAXSIZE 1024*64
- sccpu_ior.io_count = (MAXSIZE < self->dev_info.cpu.req_len) ?
- MAXSIZE : self->dev_info.cpu.req_len;
-
- switch (self->dev_info.cpu.req_cmd) {
- case SCSI_CMD_INQUIRY:
- sccpu_ior.io_data = inq_data; break;
- case SCSI_CMD_REQUEST_SENSE:
- sccpu_ior.io_data = sns_data; break;
- default:
- if (sccpu_buffer == 0) {
- /* ( read my lips :-) */
- /* extern char end[]; */
- sccpu_buffer = trunc_page(kalloc(MAXSIZE));
- }
- sccpu_ior.io_data = (char*)sccpu_buffer; break;
- }
-
- if (self->dev_info.cpu.req_cmd == SCSI_CMD_SEND) {
- self->cur_cmd = SCSI_CMD_READ;
- sccpu_ior.io_op = IO_READ;
- } else {
- self->cur_cmd = SCSI_CMD_WRITE;
- sccpu_ior.io_op = IO_WRITE;
- }
- self->ior = &sccpu_ior;
-}
-#endif
-
-/*#define PERF*/
-#ifdef PERF
-int test_read_size = 512;
-int test_read_nreads = 1000;
-int test_read_bdev = 0;
-int test_read_or_write = 1;
-
-#include <sys/time.h>
-#include <machine/machspl.h> /* spl */
-
-test_read(max)
-{
- int i, ssk, usecs;
- struct timeval start, stop;
- spl_t s;
-
- if (max != 0)
- test_read_nreads = max;
-
- s = spl0();
- start = time;
- if (test_read_or_write) read_test(); else write_test();
- stop = time;
- splx(s);
-
- usecs = stop.tv_usec - start.tv_usec;
- if (usecs < 0) {
- stop.tv_sec -= 1;
- usecs += 1000000;
- }
- printf("Size %d count %d time %3d sec %d us\n",
- test_read_size, test_read_nreads,
- stop.tv_sec - start.tv_sec, usecs);
-}
-
-read_test()
-{
- struct io_req io, io1;
- register int i;
-
- bzero(&io, sizeof(io));
- io.io_unit = test_read_bdev;
- io.io_op = IO_READ;
- io.io_count = test_read_size;
- io.io_data = (char*)sccpu_buffer;
- io1 = io;
-
- sccpu_strategy(&io);
- for (i = 1; i < test_read_nreads; i += 2) {
- io1.io_op = IO_READ;
- sccpu_strategy(&io1);
- iowait(&io);
- io.io_op = IO_READ;
- sccpu_strategy(&io);
- iowait(&io1);
- }
- iowait(&io);
-}
-
-write_test()
-{
- struct io_req io, io1;
- register int i;
-
- bzero(&io, sizeof(io));
- io.io_unit = test_read_bdev;
- io.io_op = IO_WRITE;
- io.io_count = test_read_size;
- io.io_data = (char*)sccpu_buffer;
- io1 = io;
-
- sccpu_strategy(&io);
- for (i = 1; i < test_read_nreads; i += 2) {
- io1.io_op = IO_WRITE;
- sccpu_strategy(&io1);
- iowait(&io);
- io.io_op = IO_WRITE;
- sccpu_strategy(&io);
- iowait(&io1);
- }
- iowait(&io);
-}
-
-tur_test()
-{
- struct io_req io;
- register int i;
- char *a;
- struct timeval start, stop;
- spl_t s;
- target_info_t *tgt;
-
- bzero(&io, sizeof(io));
- io.io_unit = test_read_bdev;
- io.io_data = (char*)&io;/*unused but kernel space*/
-
- rz_check(io.io_unit, &a, &tgt);
- s = spl0();
- start = time;
- for (i = 0; i < test_read_nreads; i++) {
- io.io_op = IO_INTERNAL;
- scsi_test_unit_ready(tgt,&io);
- }
- stop = time;
- splx(s);
- i = stop.tv_usec - start.tv_usec;
- if (i < 0) {
- stop.tv_sec -= 1;
- i += 1000000;
- }
- printf("%d test-unit-ready took %3d sec %d us\n",
- test_read_nreads,
- stop.tv_sec - start.tv_sec, i);
-}
-
-/*#define MEM_PERF*/
-#ifdef MEM_PERF
-int mem_read_size = 1024; /* ints! */
-int mem_read_nreads = 1000;
-volatile int *mem_read_address = (volatile int*)0xb0080000;
-volatile int *mem_write_address = (volatile int*)0xb0081000;
-
-mem_test(max, which)
-{
- int i, ssk, usecs;
- struct timeval start, stop;
- int (*fun)(), mwrite_test(), mread_test(), mcopy_test();
- spl_t s;
-
- if (max == 0)
- max = mem_read_nreads;
-
- switch (which) {
- case 1: fun = mwrite_test; break;
- case 2: fun = mcopy_test; break;
- default:fun = mread_test; break;
- }
-
- s = spl0();
- start = time;
- for (i = 0; i < max; i++)
- (*fun)(mem_read_size);
- stop = time;
- splx(s);
-
- usecs = stop.tv_usec - start.tv_usec;
- if (usecs < 0) {
- stop.tv_sec -= 1;
- usecs += 1000000;
- }
- printf("Size %d count %d time %3d sec %d us\n",
- mem_read_size*4, max,
- stop.tv_sec - start.tv_sec, usecs);
-}
-
-mread_test(max)
- register int max;
-{
- register int i;
- register volatile int *addr = mem_read_address;
-
- for (i = 0; i < max; i++) {
- register int j = *addr++;
- }
-}
-mwrite_test(max)
- register int max;
-{
- register int i;
- register volatile int *addr = mem_read_address;
-
- for (i = 0; i < max; i++) {
- *addr++ = i;
- }
-}
-
-mcopy_test(max)
- register int max;
-{
- register volatile int *from = mem_read_address;
- register volatile int *to = mem_write_address;
- register volatile int *endaddr;
-
- endaddr = to + max;
- while (to < endaddr)
- *to++ = *from++;
-
-}
-#endif /*MEM_PERF*/
-
-#endif /*PERF*/
-
-#endif /* NSCSI > 0 */
diff --git a/scsi/rz_disk.c b/scsi/rz_disk.c
deleted file mode 100644
index 87a992b..0000000
--- a/scsi/rz_disk.c
+++ /dev/null
@@ -1,1222 +0,0 @@
-/*
- * Mach Operating System
- * Copyright (c) 1991,1990 Carnegie Mellon University
- * All Rights Reserved.
- *
- * Permission to use, copy, modify and distribute this software and its
- * documentation is hereby granted, provided that both the copyright
- * notice and this permission notice appear in all copies of the
- * software, derivative works or modified versions, and any portions
- * thereof, and that both notices appear in supporting documentation.
- *
- * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
- * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
- * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
- *
- * Carnegie Mellon requests users of this software to return to
- *
- * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
- * School of Computer Science
- * Carnegie Mellon University
- * Pittsburgh PA 15213-3890
- *
- * any improvements or extensions that they make and grant Carnegie Mellon
- * the rights to redistribute these changes.
- */
-/*
- * File: rz_disk.c
- * Author: Alessandro Forin, Carnegie Mellon University
- * Date: 10/90
- *
- * Top layer of the SCSI driver: interface with the MI.
- * This file contains operations specific to disk-like devices.
- *
- * Modified by Kevin T. Van Maren to use a common partition code
- * with the ide driver, and support 'slices'.
- */
-
-
-#include <scsi/scsi.h>
-#if (NSCSI > 0)
-
-#include <device/buf.h>
-#include <device/disk_status.h>
-#include <device/device_types.h>
-#include <device/param.h>
-#include <device/errno.h>
-
-#include <kern/time_out.h>
-#include <machine/machspl.h> /* spl definitions */
-#include <mach/std_types.h>
-#include <platforms.h>
-
-#include <scsi/compat_30.h>
-#include <scsi/scsi.h>
-#include <scsi/scsi_defs.h>
-#include <scsi/rz.h>
-#include <scsi/rz_labels.h>
-
-#ifdef MACH_KERNEL
-#else /*MACH_KERNEL*/
-#include <sys/kernel.h> /* for hz */
-#endif /*MACH_KERNEL*/
-
-#include <sys/types.h>
-#include <sys/ioctl.h>
-#include "vm_param.h"
-#include <vm/vm_kern.h>
-#include <vm/pmap.h>
-
-extern void scdisk_read(), scdisk_write(),
- scsi_long_read(), scsi_long_write();
-
-void scdisk_start(); /* forwards */
-void scdisk_start_rw();
-unsigned dkcksum();
-
-#if 0
-struct diskpart scsi_array[8*64];
-#endif 0
-
-
-/* THIS IS THE BOTTOM LAYER FOR THE SCSI PARTITION CODE */
-typedef struct scsi_driver_info {
- target_info_t *tgt;
- io_req_t ior;
- void (*readfun)();
- int sectorsize;
-} scsi_driver_info;
-
-int scsi_read_fun(scsi_driver_info *param, int sectornum, void *buff)
-{
- char *psave;
- int result = TRUE; /* SUCCESS */
- psave=param->ior->io_data; /* is this necessary ? */
-
- param->ior->io_data=buff;
- param->ior->io_count = param->sectorsize;
- param->ior->io_op = IO_READ;
- param->ior->io_error = 0;
- param->tgt->ior = param->ior;
-
- (*param->readfun)( param->tgt, sectornum, param->ior);
- iowait(param->ior);
-
- param->ior->io_data=psave; /* restore the io_data pointer ?? */
- return(result);
-}
-
-
-
-/*
- * Specialized side of the open routine for disks
- */
-scsi_ret_t scdisk_open(tgt, req)
- target_info_t *tgt;
- io_req_t req;
-{
- register int i, dev_bsize;
- scsi_ret_t ret = /* SCSI_RET_SUCCESS; */ -1;
- unsigned int disk_size, secs_per_cyl, sector_size;
- scsi_rcap_data_t *cap;
- struct disklabel *label;
- io_req_t ior;
- void (*readfun)() = scdisk_read;
- char *data = (char *)0;
-
- int numpart;
-
- scsi_driver_info scsi_info;
- char drive_name[10]; /* used for disklabel strings */
-
- if (tgt->flags & TGT_ONLINE)
- return SCSI_RET_SUCCESS;
-
- /*
- * Dummy ior for proper sync purposes
- */
- io_req_alloc(ior,0);
- ior->io_next = 0;
- ior->io_count = 0;
-
- /*
- * Set the LBN to DEV_BSIZE with a MODE SELECT.
- * If this fails we try a couple other tricks.
- */
- dev_bsize = 0;
- for (i = 0; i < 5; i++) {
- ior->io_op = IO_INTERNAL;
- ior->io_error = 0;
- ret = scdisk_mode_select(tgt, DEV_BSIZE, ior, 0, 0, 0);
- if (ret == SCSI_RET_SUCCESS) {
- dev_bsize = DEV_BSIZE;
- break;
- }
- if (ret == SCSI_RET_RETRY) {
- timeout(wakeup, tgt, 2*hz);
- await(tgt);
- }
- if (ret == SCSI_RET_DEVICE_DOWN)
- goto done;
- }
-#if 0
- if (ret != SCSI_RET_SUCCESS) {
- scsi_error( tgt, SCSI_ERR_MSEL, ret, 0);
- ret = D_INVALID_SIZE;
- goto done;
- }
-#endif
- /*
- * Do a READ CAPACITY to get max size. Check LBN too.
- */
- for (i = 0; i < 5; i++) {
- ior->io_op = IO_INTERNAL;
- ior->io_error = 0;
- ret = scsi_read_capacity(tgt, 0, ior);
- if (ret == SCSI_RET_SUCCESS)
- break;
- }
- if (ret == SCSI_RET_SUCCESS) {
- int val;
-
- cap = (scsi_rcap_data_t*) tgt->cmd_ptr;
- disk_size = (cap->lba1<<24) |
- (cap->lba2<<16) |
- (cap->lba3<< 8) |
- cap->lba4;
- if (scsi_debug)
- printf("rz%d holds %d blocks\n", tgt->unit_no, disk_size);
- val = (cap->blen1<<24) |
- (cap->blen2<<16) |
- (cap->blen3<<8 ) |
- cap->blen4;
- if (dev_bsize == 0)
- dev_bsize = val;
- else
- if (val != dev_bsize) panic("read capacity bad");
-
- if (disk_size > SCSI_CMD_READ_MAX_LBA)
- tgt->flags |= TGT_BIG;
-
- } else {
- printf("Unknown disk capacity??\n");
- disk_size = -1;
- }
- /*
- * Mandatory long-form commands ?
- */
- if (BGET(scsi_use_long_form,(unsigned char)tgt->masterno,tgt->target_id))
- tgt->flags |= TGT_BIG;
- if (tgt->flags & TGT_BIG)
- readfun = scsi_long_read;
-
- /*
- * Some CDROMS truly dislike 512 as LBN.
- * Use a MODE_SENSE to cover for this case.
- */
- if (dev_bsize == 0) {
- scsi_mode_sense_data_t *m;
-
- ior->io_op = IO_INTERNAL;
- ior->io_error = 0;
- ret = scsi_mode_sense(tgt, 0/*pagecode*/, 32/*?*/, ior);
- if (ret == SCSI_RET_SUCCESS) {
- m = (scsi_mode_sense_data_t *) tgt->cmd_ptr;
- dev_bsize =
- m->bdesc[0].blen_msb << 16 |
- m->bdesc[0].blen << 8 |
- m->bdesc[0].blen_lsb;
- }
- }
-
- /*
- * Find out about the phys disk geometry -- scsi specific
- */
-
- ior->io_op = IO_INTERNAL;
- ior->io_error = 0;
- ret = scsi_read_capacity( tgt, 1, ior);
- if (ret == SCSI_RET_SUCCESS) {
- cap = (scsi_rcap_data_t*) tgt->cmd_ptr;
- secs_per_cyl = (cap->lba1<<24) | (cap->lba2<<16) |
- (cap->lba3<< 8) | cap->lba4;
- secs_per_cyl += 1;
- sector_size = (cap->blen1<<24) | (cap->blen2<<16) |
- (cap->blen3<<8 ) | cap->blen4;
- } else {
- sector_size = dev_bsize ? dev_bsize : DEV_BSIZE;
- secs_per_cyl = disk_size;
- }
- if (dev_bsize == 0)
- dev_bsize = sector_size;
-
- if (scsi_debug)
- printf("rz%d: %d sect/cyl %d bytes/sec\n", tgt->unit_no,
- secs_per_cyl, sector_size);
-
- /*
- * At this point, one way or other, we are committed to
- * a given disk capacity and sector size.
- */
- tgt->block_size = dev_bsize;
-
- /*
- * Get partition table off pack
- */
-
-#ifdef MACH_KERNEL
- ior->io_data = (char *)kalloc(sector_size);
-#endif /*MACH_KERNEL*/
-
- scsi_info.tgt=tgt;
- scsi_info.ior=ior;
- scsi_info.readfun=readfun;
- scsi_info.sectorsize=sector_size;
-
- /* label has NOT been allocated space yet! set to the tgt disklabel */
- label=&scsi_info.tgt->dev_info.disk.l;
-
- sprintf(drive_name, "sd%d:", tgt->unit_no);
-
- if (scsi_debug)
- printf("Using bogus geometry: 32 sectors/track, 64 heads\n");
-
- fudge_bsd_label(label, DTYPE_SCSI, disk_size /* /(32*64)*/ ,
- 64, 32, sector_size, 8);
-
- numpart=get_only_partition(&scsi_info, (*scsi_read_fun),
- tgt->dev_info.disk.scsi_array, MAX_SCSI_PARTS, disk_size, drive_name);
-
- printf("%s %d partitions found\n",drive_name,numpart);
-
- ret=SCSI_RET_SUCCESS; /* if 0, return SCSI_RET_SUCCESS */
-
-
-done:
- io_req_free(ior);
-
- return(ret);
-}
-
-
-/*
- * Disk strategy routine
- */
-int scdisk_strategy(ior)
- register io_req_t ior;
-{
- target_info_t *tgt;
- register scsi_softc_t *sc;
- register int i = ior->io_unit, part;
- register unsigned rec, max;
- spl_t s;
- struct diskpart *label;
-
- sc = scsi_softc[rzcontroller(i)];
- tgt = sc->target[rzslave(i)];
- part = rzpartition(i);
-
- /*
- * Validate request
- */
-
- /* readonly ? */
- if ((tgt->flags & TGT_READONLY) &&
- (ior->io_op & (IO_READ|IO_INTERNAL) == 0)) {
- ior->io_error = D_READ_ONLY;
- ior->io_op |= IO_ERROR;
- ior->io_residual = ior->io_count;
- iodone(ior);
- return ior->io_error;
- }
-
- rec = ior->io_recnum;
-
- label=lookup_part(tgt->dev_info.disk.scsi_array, part);
- if (!label) {
- if (scsi_debug)
- printf("sc strategy -- bad partition\n");
- ior->io_error = D_INVALID_SIZE;
- ior->io_op |= IO_ERROR;
- ior->io_residual = ior->io_count;
- iodone(ior);
- return ior->io_error;
- }
- else max=label->size;
- if (max == -1) /* what about 0? */
- max = tgt->dev_info.disk.l.d_secperunit -
-
- label->start;
-
- i = (ior->io_count + tgt->block_size - 1) / tgt->block_size;
- if (((rec + i) > max) || (ior->io_count < 0) ||
-#if later
- ((rec <= LABELSECTOR) && ((tgt->flags & TGT_WRITE_LABEL) == 0))
-#else
- FALSE
-#endif
- ) {
- ior->io_error = D_INVALID_SIZE;
- ior->io_op |= IO_ERROR;
- ior->io_residual = ior->io_count;
- iodone(ior);
- return ior->io_error;
- }
- /*
- * Find location on disk: secno and cyl (for disksort)
- */
- rec += label->start;
- ior->io_residual = rec / tgt->dev_info.disk.l.d_secpercyl;
-
- /*
- * Enqueue operation
- */
- s = splbio();
- simple_lock(&tgt->target_lock);
- if (tgt->ior) {
- disksort(tgt->ior, ior);
- simple_unlock(&tgt->target_lock);
- splx(s);
- } else {
- ior->io_next = 0;
- tgt->ior = ior;
- simple_unlock(&tgt->target_lock);
- splx(s);
-
- scdisk_start(tgt,FALSE);
- }
-
- return D_SUCCESS;
-}
-
-/*#define CHECKSUM*/
-#ifdef CHECKSUM
-int max_checksum_size = 0x2000;
-#endif CHECKSUM
-
-/*
- * Start/completion routine for disks
- */
-void scdisk_start(tgt, done)
- target_info_t *tgt;
- boolean_t done;
-{
- register io_req_t ior = tgt->ior;
- register unsigned part;
-#ifdef CHECKSUM
- register unsigned secno;
-#endif
- struct diskpart *label;
-
- if (ior == 0)
- return;
-
- if (tgt->flags & TGT_BBR_ACTIVE)
- {
- scdisk_bbr_start(tgt, done);
- return;
- }
-
- if (done) {
- register unsigned int xferred;
- unsigned int max_dma_data;
-
- max_dma_data = scsi_softc[(unsigned char)tgt->masterno]->max_dma_data;
- /* see if we must retry */
- if ((tgt->done == SCSI_RET_RETRY) &&
- ((ior->io_op & IO_INTERNAL) == 0)) {
- delay(1000000);/*XXX*/
- goto start;
- } else
- /* got a bus reset ? pifff.. */
- if ((tgt->done == (SCSI_RET_ABORTED|SCSI_RET_RETRY)) &&
- ((ior->io_op & IO_INTERNAL) == 0)) {
- if (xferred = ior->io_residual) {
- ior->io_data -= xferred;
- ior->io_count += xferred;
- ior->io_recnum -= xferred / tgt->block_size;
- ior->io_residual = 0;
- }
- goto start;
- } else
- /*
- * Quickly check for errors: if anything goes wrong
- * we do a request sense, see if that is what we did.
- */
- if (tgt->cur_cmd == SCSI_CMD_REQUEST_SENSE) {
- scsi_sense_data_t *sns;
- unsigned int blockno;
- char *outcome;
-
- ior->io_op = ior->io_temporary;
-
- sns = (scsi_sense_data_t *)tgt->cmd_ptr;
- if (sns->addr_valid)
- blockno = sns->u.xtended.info0 << 24 |
- sns->u.xtended.info1 << 16 |
- sns->u.xtended.info2 << 8 |
- sns->u.xtended.info3;
- else {
- part = rzpartition(ior->io_unit);
- label = lookup_part(tgt->dev_info.disk.scsi_array, part);
- blockno = label->start;
- blockno += ior->io_recnum;
- if (!label) blockno=-1;
- }
-
- if (scsi_check_sense_data(tgt, sns)) {
- ior->io_error = 0;
- if ((tgt->done == SCSI_RET_RETRY) &&
- ((ior->io_op & IO_INTERNAL) == 0)) {
- delay(1000000);/*XXX*/
- goto start;
- }
- outcome = "Recovered";
- } else {
- outcome = "Unrecoverable";
- ior->io_error = D_IO_ERROR;
- ior->io_op |= IO_ERROR;
- }
- if ((tgt->flags & TGT_OPTIONAL_CMD) == 0) {
- printf("%s Error, rz%d: %s%s%d\n", outcome,
- tgt->target_id + (tgt->masterno * 8),
- (ior->io_op & IO_READ) ? "Read" :
- ((ior->io_op & IO_INTERNAL) ? "(command)" : "Write"),
- " disk error, phys block no. ", blockno);
-
- scsi_print_sense_data(sns);
-
- /*
- * On fatal read/write errors try replacing the bad block
- * The bbr routine will return TRUE iff it took control
- * over the target for all subsequent operations. In this
- * event, the queue of requests is effectively frozen.
- */
- if (ior->io_error &&
- ((sns->error_class == SCSI_SNS_XTENDED_SENSE_DATA) &&
- ((sns->u.xtended.sense_key == SCSI_SNS_HW_ERR) ||
- (sns->u.xtended.sense_key == SCSI_SNS_MEDIUM_ERR))) &&
- scdisk_bad_block_repl(tgt, blockno))
- return;
- }
- }
-
- /*
- * See if we had errors
- */
- else if (tgt->done != SCSI_RET_SUCCESS) {
-
- if (tgt->done == SCSI_RET_NEED_SENSE) {
-
- ior->io_temporary = ior->io_op;
- ior->io_op = IO_INTERNAL;
- scsi_request_sense(tgt, ior, 0);
- return;
-
- } else if (tgt->done == SCSI_RET_DEVICE_DOWN) {
- ior->io_error = D_DEVICE_DOWN;
- ior->io_op |= IO_ERROR;
- } else {
- printf("%s%x\n", "?rz_disk Disk error, ret=x", tgt->done);
- ior->io_error = D_IO_ERROR;
- ior->io_op |= IO_ERROR;
- }
- }
- /*
- * No errors.
- * See if we requested more than the max
- * (We use io_residual in a flip-side way here)
- */
- else if (ior->io_count > (xferred = max_dma_data)) {
- ior->io_residual += xferred;
- ior->io_count -= xferred;
- ior->io_data += xferred;
- ior->io_recnum += xferred / tgt->block_size;
- goto start;
- }
- else if (xferred = ior->io_residual) {
- ior->io_data -= xferred;
- ior->io_count += xferred;
- ior->io_recnum -= xferred / tgt->block_size;
- ior->io_residual = 0;
- } /* that's it */
-
-#ifdef CHECKSUM
- if ((ior->io_op & IO_READ) && (ior->io_count < max_checksum_size)) {
- part = rzpartition(ior->io_unit);
- label=lookup_part(tgt->dev_info.disk.scsi_array, part);
- if (!label) printf("NOT FOUND!\n");
- secno = ior->io_recnum + label->start;
- scdisk_bcheck(secno, ior->io_data, ior->io_count);
- }
-#endif CHECKSUM
-
- /* dequeue next one */
- {
- io_req_t next;
-
- simple_lock(&tgt->target_lock);
- next = ior->io_next;
- tgt->ior = next;
- simple_unlock(&tgt->target_lock);
-
- iodone(ior);
- if (next == 0)
- return;
-
- ior = next;
- }
-
-#ifdef CHECKSUM
- if (((ior->io_op & IO_READ) == 0) && (ior->io_count < max_checksum_size)) {
- part = rzpartition(ior->io_unit);
- label=lookup_part(tgt->dev_info.disk.scsi_array, part);
- secno = ior->io_recnum + label->start;
- scdisk_checksum(secno, ior->io_data, ior->io_count);
- }
-#endif CHECKSUM
- }
- ior->io_residual = 0;
-start:
- scdisk_start_rw( tgt, ior);
-}
-
-void scdisk_start_rw( tgt, ior)
- target_info_t *tgt;
- register io_req_t ior;
-{
- unsigned int part, secno;
- register boolean_t long_form;
- struct diskpart *label;
-
- part = rzpartition(ior->io_unit);
- label=lookup_part(tgt->dev_info.disk.scsi_array, part);
- if (!label)
- printf("NOT FOUND!\n");
- secno = ior->io_recnum + label->start;
-
- /* Use long form if either big block addresses or
- the size is more than we can fit in one byte */
- long_form = (tgt->flags & TGT_BIG) ||
- (ior->io_count > (256 * tgt->block_size));
- if (ior->io_op & IO_READ)
- (long_form ? scsi_long_read : scdisk_read)(tgt, secno, ior);
- else if ((ior->io_op & IO_INTERNAL) == 0)
- (long_form ? scsi_long_write : scdisk_write)(tgt, secno, ior);
-}
-
-#include <sys/ioctl.h>
-#ifdef ULTRIX_COMPAT
-#include <mips/PMAX/rzdisk.h>
-#endif /*ULTRIX_COMPAT*/
-
-io_return_t
-scdisk_get_status(dev, tgt, flavor, status, status_count)
- int dev;
- target_info_t *tgt;
- dev_flavor_t flavor;
- dev_status_t status;
- natural_t *status_count;
-{
- struct disklabel *lp;
- struct diskpart *label;
-
- lp = &tgt->dev_info.disk.l;
-
- switch (flavor) {
-#ifdef MACH_KERNEL
- case DEV_GET_SIZE:
-
- label=lookup_part(tgt->dev_info.disk.scsi_array, rzpartition(dev));
- status[DEV_GET_SIZE_DEVICE_SIZE] = label->size * lp->d_secsize;
- status[DEV_GET_SIZE_RECORD_SIZE] = tgt->block_size;
- *status_count = DEV_GET_SIZE_COUNT;
- break;
-#endif
-
- case DIOCGDINFO:
- *(struct disklabel *)status = *lp;
-#ifdef MACH_KERNEL
- *status_count = sizeof(struct disklabel)/sizeof(int);
-#endif MACH_KERNEL
- break;
-
- case DIOCGDINFO - (0x10<<16):
- *(struct disklabel *)status = *lp;
-#ifdef MACH_KERNEL
- *status_count = sizeof(struct disklabel)/sizeof(int) - 4;
-#endif MACH_KERNEL
- break;
-
-#ifdef MACH_KERNEL
-#else /*MACH_KERNEL*/
-#if ULTRIX_COMPAT
- case SCSI_MODE_SENSE: /*_IOWR(p, 9, struct mode_sel_sns_params) */
- break;
- case DIOCGETPT: /*_IOR(p, 1, struct pt) */
- case SCSI_GET_SENSE: /*_IOR(p, 10, struct extended_sense) */
- return ul_disk_ioctl(tgt, flavor, status, status_count);
-#endif /*ULTRIX_COMPAT*/
-#endif /*!MACH_KERNEL*/
-
-#if 0
- case DIOCRFORMAT:
- break;
-#endif
- default:
-#ifdef i386
- return(scsi_i386_get_status(dev, tgt, flavor, status, status_count));
-#else i386
- return(D_INVALID_OPERATION);
-#endif i386
- }
- return D_SUCCESS;
-}
-
-io_return_t
-scdisk_set_status(dev, tgt, flavor, status, status_count)
- int dev;
- target_info_t *tgt;
- dev_flavor_t flavor;
- dev_status_t status;
- natural_t status_count;
-{
- io_return_t error = D_SUCCESS;
- struct disklabel *lp;
-
- lp = &tgt->dev_info.disk.l;
-
-
- switch (flavor) {
- case DIOCSRETRIES:
-#ifdef MACH_KERNEL
- if (status_count != sizeof(int))
- return D_INVALID_SIZE;
-#endif /* MACH_KERNEL */
- scsi_bbr_retries = *(int *)status;
- break;
-
- case DIOCWLABEL:
- case DIOCWLABEL - (0x10<<16):
- if (*(int*)status)
- tgt->flags |= TGT_WRITE_LABEL;
- else
- tgt->flags &= ~TGT_WRITE_LABEL;
- break;
- case DIOCSDINFO:
- case DIOCSDINFO - (0x10<<16):
- case DIOCWDINFO:
- case DIOCWDINFO - (0x10<<16):
-#ifdef MACH_KERNEL
- if (status_count != sizeof(struct disklabel) / sizeof(int))
- return D_INVALID_SIZE;
-#endif /* MACH_KERNEL */
- error = setdisklabel(lp, (struct disklabel*) status);
- if (error || (flavor == DIOCSDINFO) || (flavor == DIOCSDINFO - (0x10<<16)))
- return error;
- error = scdisk_writelabel(tgt);
- break;
-
-#ifdef MACH_KERNEL
-#else /*MACH_KERNEL*/
-#if ULTRIX_COMPAT
- case SCSI_FORMAT_UNIT: /*_IOW(p, 4, struct format_params) */
- case SCSI_REASSIGN_BLOCK: /*_IOW(p, 5, struct reassign_params) */
- case SCSI_READ_DEFECT_DATA: /*_IOW(p, 6, struct read_defect_params) */
- case SCSI_VERIFY_DATA: /*_IOW(p, 7, struct verify_params) */
- case SCSI_MODE_SELECT: /*_IOW(p, 8, struct mode_sel_sns_params) */
- case SCSI_MODE_SENSE: /*_IOW(p, 9, struct mode_sel_sns_params) */
- case SCSI_GET_INQUIRY_DATA: /*_IOW(p, 11, struct inquiry_info) */
- return ul_disk_ioctl(tgt, flavor, status, status_count);
-#endif /*ULTRIX_COMPAT*/
-#endif /*!MACH_KERNEL*/
-
-#if notyet
- case DIOCWFORMAT:
- case DIOCSBAD: /* ?? how ? */
-#endif
- default:
-#ifdef i386
- error = scsi_i386_set_status(dev, tgt, flavor, status, status_count);
-#else i386
- error = D_INVALID_OPERATION;
-#endif i386
- }
- return error;
-}
-
-static int grab_it(tgt, ior)
- target_info_t *tgt;
- io_req_t ior;
-{
- spl_t s;
-
- s = splbio();
- simple_lock(&tgt->target_lock);
- if (!tgt->ior)
- tgt->ior = ior;
- simple_unlock(&tgt->target_lock);
- splx(s);
-
- if (tgt->ior != ior)
- return D_ALREADY_OPEN;
- return D_SUCCESS;
-}
-
-/* Write back a label to the disk */
-io_return_t scdisk_writelabel(tgt)
- target_info_t *tgt;
-{
-
-printf("scdisk_writelabel: NO LONGER IMPLEMENTED\n");
-#if 0
-/* Taken out at Bryan's suggestion until 'fixed' for slices */
-
- io_req_t ior;
- char *data = (char *)0;
- struct disklabel *label;
- io_return_t error;
- int dev_bsize = tgt->block_size;
-
- io_req_alloc(ior,0);
-#ifdef MACH_KERNEL
- data = (char *)kalloc(dev_bsize);
-#else /*MACH_KERNEL*/
- data = (char *)ior->io_data;
-#endif /*MACH_KERNEL*/
- ior->io_next = 0;
- ior->io_prev = 0;
- ior->io_data = data;
- ior->io_count = dev_bsize;
- ior->io_op = IO_READ;
- ior->io_error = 0;
-
- if (grab_it(tgt, ior) != D_SUCCESS) {
- error = D_ALREADY_OPEN;
- goto ret;
- }
-
- scdisk_read( tgt, tgt->dev_info.disk.labelsector, ior);
- iowait(ior);
- if (error = ior->io_error)
- goto ret;
-
- label = (struct disklabel *) &data[tgt->dev_info.disk.labeloffset];
- *label = tgt->dev_info.disk.l;
-
- ior->io_next = 0;
- ior->io_prev = 0;
- ior->io_data = data;
- ior->io_count = dev_bsize;
- ior->io_op = IO_WRITE;
-
- while (grab_it(tgt, ior) != D_SUCCESS) ; /* ahem */
-
- scdisk_write( tgt, tgt->dev_info.disk.labelsector, ior);
- iowait(ior);
-
- error = ior->io_error;
-ret:
-#ifdef MACH_KERNEL
- if (data) kfree((int)data, dev_bsize);
-#endif /*MACH_KERNEL*/
- io_req_free(ior);
- return error;
-
-#endif 0 scdisk_writelabel
-return -1; /* FAILURE ? */
-}
-
-#ifdef MACH_KERNEL
-#else /*MACH_KERNEL*/
-#if ULTRIX_COMPAT
-
-io_return_t ul_disk_ioctl(tgt, flavor, status, status_count)
- target_info_t *tgt;
- dev_flavor_t flavor;
- dev_status_t status;
- natural_t status_count;
-{
- io_return_t ret;
- scsi_ret_t err = SCSI_RET_ABORTED;/*xxx*/
- io_req_t ior;
-
- if (!suser())
- return EACCES;
-
- ior = geteblk(sizeof(struct defect_descriptors));
- ior->io_next = 0;
- ior->io_count = 0;
- ior->io_op = IO_INTERNAL;
- ior->io_error = 0;
- ior->io_recnum = 0;
- ior->io_residual = 0;
-
- switch (flavor) {
-
- case DIOCGETPT: { /*_IOR(p, 1, struct pt) */
- scsi_dec_label_t *p;
- struct disklabel *lp;
- int i;
-
- lp = &tgt->dev_info.disk.l;
- p = (scsi_dec_label_t *)status;
-
- p->magic = DEC_PARTITION_MAGIC;
- p->in_use = 1;
- for (i = 0; i < 8; i++) {
- label=lookup_part(tgt->dev_info.disk.scsi_array, part);
- p->partitions[i].n_sectors = label->size;
- p->partitions[i].offset = label->start;
- }
- err = SCSI_RET_SUCCESS;
- }
- break;
-
- case SCSI_GET_SENSE: { /*_IOR(p, 10, struct extended_sense) */
- scsi_sense_data_t *s;
-
- s = (scsi_sense_data_t*)tgt->cmd_ptr;
- bcopy(s, status, sizeof(*s) + s->u.xtended.add_len - 1);
- err = SCSI_RET_SUCCESS;
- /* only once */
- bzero(tgt->cmd_ptr, sizeof(scsi_sense_data_t));
- }
- break;
-
- case SCSI_GET_INQUIRY_DATA: { /*_IOR(p, 11, struct inquiry_info) */
- struct mode_sel_sns_params *ms;
-
- ms = (struct mode_sel_sns_params*)status;
- err = scsi_inquiry( tgt, SCSI_INQ_STD_DATA);
- if (copyout(tgt->cmd_ptr, ms->msp_addr, sizeof(struct inquiry_info))){
- ret = EFAULT;
- goto out;
- }
- }
- break;
-
- case SCSI_FORMAT_UNIT: { /*_IOW(p, 4, struct format_params) */
- struct format_params *fp;
- struct defect_descriptors *df;
- unsigned char mode;
- unsigned int old_timeout;
-
- fp = (struct format_params *)status;
- df = (struct defect_descriptors*)ior->io_data;
- if (fp->fp_length != 0) {
- if (copyin(fp->fp_addr, df, sizeof(*df))) {
- ret = EFAULT;
- goto out;
- }
- ior->io_count = sizeof(*df);
- } else
- ior->io_count = 0;
- mode = fp->fp_format & SCSI_CMD_FMT_LIST_TYPE;
- switch (fp->fp_defects) {
- case VENDOR_DEFECTS:
- mode |= SCSI_CMD_FMT_FMTDATA|SCSI_CMD_FMT_CMPLIST;
- break;
- case KNOWN_DEFECTS:
- mode |= SCSI_CMD_FMT_FMTDATA;
- break;
- case NO_DEFECTS:
- default:
- break;
- }
- old_timeout = scsi_watchdog_period;
- scsi_watchdog_period = 60*60; /* 1 hour should be enough, I hope */
- err = scsi_format_unit( tgt, mode, fp->fp_pattern,
- fp->fp_interleave, ior);
- scsi_watchdog_period = old_timeout;
- /* Make sure we re-read all info afresh */
- tgt->flags = TGT_ALIVE |
- (tgt->flags & (TGT_REMOVABLE_MEDIA|TGT_FULLY_PROBED));
- }
- break;
-
- case SCSI_REASSIGN_BLOCK: { /*_IOW(p, 5, struct reassign_params) */
- struct reassign_params *r;
- int ndef;
-
- r = (struct reassign_params*) status;
- ndef = r->rp_header.defect_len0 | (r->rp_header.defect_len1 >> 8);
- ndef >>= 2;
- tgt->ior = ior;
- (void) scsi_reassign_blocks( tgt, &r->rp_lbn3, ndef, ior);
- iowait(ior);
- err = tgt->done;
- }
- break;
-
- case SCSI_READ_DEFECT_DATA: { /*_IOW(p, 6, struct read_defect_params) */
- struct read_defect_params *dp;
-
- dp = (struct read_defect_params *)status;
- ior->io_count = ior->io_alloc_size;
- if (dp->rdp_alclen > ior->io_count)
- dp->rdp_alclen = ior->io_count;
- else
- ior->io_count = dp->rdp_alclen;
- ior->io_op |= IO_READ;
- tgt->ior = ior;
- err = scsi_read_defect(tgt, dp->rdp_format|0x18, ior);
- if (copyout(ior->io_data, dp->rdp_addr, dp->rdp_alclen)) {
- ret = EFAULT;
- goto out;
- }
- }
- break;
-
- case SCSI_VERIFY_DATA: { /*_IOW(p, 7, struct verify_params) */
- struct verify_params *v;
- unsigned int old_timeout;
-
- old_timeout = scsi_watchdog_period;
- scsi_watchdog_period = 5*60; /* 5 mins enough, I hope */
- v = (struct verify_params *)status;
- ior->io_count = 0;
- err = scdisk_verify( tgt, v->vp_lbn, v->vp_length, ior);
- scsi_watchdog_period = old_timeout;
- }
- break;
-
- case SCSI_MODE_SELECT: { /*_IOW(p, 8, struct mode_sel_sns_params) */
- struct mode_sel_sns_params *ms;
-
- ms = (struct mode_sel_sns_params*)status;
- if(copyin(ms->msp_addr, ior->io_data, ms->msp_length)) {
- ret = EFAULT;
- goto out;
- }
- err = scdisk_mode_select( tgt, DEV_BSIZE, ior, ior->io_data,
- ms->msp_length, ms->msp_setps);
- }
- break;
-
- case SCSI_MODE_SENSE: { /*_IOWR(p, 9, struct mode_sel_sns_params) */
- struct mode_sel_sns_params *ms;
- unsigned char pagecode;
-
- ms = (struct mode_sel_sns_params*)status;
- pagecode = (ms->msp_pgcode & 0x3f) | (ms->msp_pgctrl << 6);
- err = scsi_mode_sense( tgt, pagecode, ms->msp_length, ior);
- if (copyout(tgt->cmd_ptr, ms->msp_addr, ms->msp_length)){
- ret = EFAULT;
- goto out;
- }
- }
- break;
- }
-
- ret = (err == SCSI_RET_SUCCESS) ? D_SUCCESS : D_IO_ERROR;
- if (ior->io_op & IO_ERROR)
- ret = D_IO_ERROR;
-out:
- brelse(ior);
- return ret;
-}
-#endif /*ULTRIX_COMPAT*/
-#endif /*!MACH_KERNEL*/
-
-#ifdef CHECKSUM
-
-#define SUMSIZE 0x10000
-#define SUMHASH(b) (((b)>>1) & (SUMSIZE - 1))
-struct {
- long blockno;
- long sum;
-} scdisk_checksums[SUMSIZE];
-
-void scdisk_checksum(bno, addr, size)
- long bno;
- register unsigned int *addr;
-{
- register int i = size/sizeof(int);
- register unsigned int sum = -1;
-
- while (i-- > 0)
- sum ^= *addr++;
- scdisk_checksums[SUMHASH(bno)].blockno = bno;
- scdisk_checksums[SUMHASH(bno)].sum = sum;
-}
-
-void scdisk_bcheck(bno, addr, size)
- long bno;
- register unsigned int *addr;
-{
- register int i = size/sizeof(int);
- register unsigned int sum = -1;
- unsigned int *start = addr;
-
- if (scdisk_checksums[SUMHASH(bno)].blockno != bno) {
-if (scsi_debug) printf("No checksum for block x%x\n", bno);
- return;
- }
-
- while (i-- > 0)
- sum ^= *addr++;
-
- if (scdisk_checksums[SUMHASH(bno)].sum != sum) {
- printf("Bad checksum (x%x != x%x), bno x%x size x%x at x%x\n",
- sum,
- scdisk_checksums[bno & (SUMSIZE - 1)].sum,
- bno, size, start);
- gimmeabreak();
- scdisk_checksums[SUMHASH(bno)].sum = sum;
- }
-}
-
-
-#endif CHECKSUM
-
-/*#define PERF */
-#ifdef PERF
-int test_read_size = 512;
-int test_read_skew = 12;
-int test_read_skew_min = 0;
-int test_read_nreads = 1000;
-int test_read_bdev = 0;
-
-#include <sys/time.h>
-
-void test_read(max)
-{
- int i, ssk, usecs;
- struct timeval start, stop;
-
- if (max == 0)
- max = test_read_skew + 1;
- ssk = test_read_skew;
- for (i = test_read_skew_min; i < max; i++){
- test_read_skew = i;
-
- start = time;
- read_test();
- stop = time;
-
- usecs = stop.tv_usec - start.tv_usec;
- if (usecs < 0) {
- stop.tv_sec -= 1;
- usecs += 1000000;
- }
- printf("Skew %3d size %d count %d time %3d sec %d us\n",
- i, test_read_size, test_read_nreads,
- stop.tv_sec - start.tv_sec, usecs);
- }
- test_read_skew = ssk;
-}
-
-void read_test()
-{
- static int buffer[(8192*2)/sizeof(int)];
- struct io_req io;
- register int i, rec;
-
- bzero(&io, sizeof(io));
- io.io_unit = test_read_bdev;
- io.io_op = IO_READ;
- io.io_count = test_read_size;
- io.io_data = (char*) buffer;
-
- for (rec = 0, i = 0; i < test_read_nreads; i++) {
- io.io_op = IO_READ;
- io.io_recnum = rec;
- scdisk_strategy(&io);
- rec += test_read_skew;
- iowait(&io);
- }
-}
-
-void tur_test()
-{
- struct io_req io;
- register int i;
- char *a, *b;
- struct timeval start, stop;
-
- bzero(&io, sizeof(io));
- io.io_unit = test_read_bdev;
- io.io_data = (char*)&io;/*unused but kernel space*/
-
- start = time;
- for (i = 0; i < test_read_nreads; i++) {
- io.io_op = IO_INTERNAL;
- rz_check(io.io_unit, &a, &b);
- scsi_test_unit_ready(b,&io);
- }
- stop = time;
- i = stop.tv_usec - start.tv_usec;
- if (i < 0) {
- stop.tv_sec -= 1;
- i += 1000000;
- }
- printf("%d test-unit-ready took %3d sec %d us\n",
- test_read_nreads,
- stop.tv_sec - start.tv_sec, i);
-}
-
-#endif PERF
-
-/*#define WDEBUG*/
-#ifdef WDEBUG
-
-int buggo_write_size = 8192;
-int buggo_dev = 2; /* rz0b */ /* changed by KTVM from 1 (still b) */
-int buggo_out_buffer[8192/2];
-int buggo_in_buffer[8192/2];
-int buggotest(n, pattern, verbose)
-{
- struct io_req io;
- register int i, rec;
-
- if (n <= 0)
- n = 1;
-
- if(pattern)
- for (i = 0; i < buggo_write_size/4; i++)
- buggo_out_buffer[i] = i + pattern;
-
- for (i = 0; i < n; i++) {
- register int j;
-
- buggo_out_buffer[0] = i + pattern;
- buggo_out_buffer[(buggo_write_size/4)-1] = i + pattern;
- bzero(&io, sizeof(io));
- io.io_unit = buggo_dev;
- io.io_data = (char*)buggo_out_buffer;
- io.io_op = IO_WRITE;
- io.io_count = buggo_write_size;
- io.io_recnum = i % 1024;
- scdisk_strategy(&io);
-
- bzero(buggo_in_buffer, sizeof(buggo_in_buffer));
- iowait(&io);
-
- if (verbose)
- printf("Done write with %x", io.io_error);
-
- bzero(&io, sizeof(io));
- io.io_unit = buggo_dev;
- io.io_data = (char*)buggo_in_buffer;
- io.io_op = IO_READ;
- io.io_count = buggo_write_size;
- io.io_recnum = i % 1024;
- scdisk_strategy(&io);
- iowait(&io);
-
- if (verbose)
- printf("Done read with %x", io.io_error);
-
- for (j = 0; j < buggo_write_size/4; j++)
- if (buggo_out_buffer[j] != buggo_in_buffer[j]){
- printf("Difference at %d-th word: %x %x\n",
- buggo_out_buffer[j], buggo_in_buffer[j]);
- return i;
- }
- }
- printf("Test ok\n");
- return n;
-}
-#endif WDEBUG
-#endif /* NSCSI > 0 */
diff --git a/scsi/rz_disk_bbr.c b/scsi/rz_disk_bbr.c
deleted file mode 100644
index 9d87675..0000000
--- a/scsi/rz_disk_bbr.c
+++ /dev/null
@@ -1,259 +0,0 @@
-/*
- * Mach Operating System
- * Copyright (c) 1991,1990 Carnegie Mellon University
- * All Rights Reserved.
- *
- * Permission to use, copy, modify and distribute this software and its
- * documentation is hereby granted, provided that both the copyright
- * notice and this permission notice appear in all copies of the
- * software, derivative works or modified versions, and any portions
- * thereof, and that both notices appear in supporting documentation.
- *
- * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
- * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
- * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
- *
- * Carnegie Mellon requests users of this software to return to
- *
- * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
- * School of Computer Science
- * Carnegie Mellon University
- * Pittsburgh PA 15213-3890
- *
- * any improvements or extensions that they make and grant Carnegie Mellon
- * the rights to redistribute these changes.
- */
-/*
- * File: rz_disk_bbr.c
- * Author: Alessandro Forin, Carnegie Mellon University
- * Date: 4/91
- *
- * Top layer of the SCSI driver: interface with the MI.
- * This file contains bad-block management functions
- * (retry, replace) for disk-like devices.
- */
-
-#include <mach/std_types.h>
-#include <scsi/compat_30.h>
-
-#include <scsi/scsi.h>
-#include <scsi/scsi_defs.h>
-#include <scsi/rz.h>
-
-#if (NSCSI > 0)
-
-int scsi_bbr_retries = 10;
-
-#define BBR_ACTION_COMPLETE 1
-#define BBR_ACTION_RETRY_READ 2
-#define BBR_ACTION_REASSIGN 3
-#define BBR_ACTION_COPY 4
-#define BBR_ACTION_VERIFY 5
-
-static void make_msf(); /* forward */
-
-/*
- * Bad block replacement routine, invoked on
- * unrecovereable disk read/write errors.
- */
-boolean_t
-scdisk_bad_block_repl(tgt, blockno)
- target_info_t *tgt;
- unsigned int blockno;
-{
- register io_req_t ior = tgt->ior;
-
- if (scsi_no_automatic_bbr || (ior->io_op & IO_INTERNAL))
- return FALSE;
-
- /* signal we took over */
- tgt->flags |= TGT_BBR_ACTIVE;
-
- printf("%s", "Attempting bad block replacement..");
-
- tgt->dev_info.disk.b.badblockno = blockno;
- tgt->dev_info.disk.b.retry_count = 0;
-
- tgt->dev_info.disk.b.save_rec = ior->io_recnum;
- tgt->dev_info.disk.b.save_addr = ior->io_data;
- tgt->dev_info.disk.b.save_count = ior->io_count;
- tgt->dev_info.disk.b.save_resid = ior->io_residual;
-
- /*
- * On a write all we need is to rewire the offending block.
- * Note that the sense data identified precisely which 512 sector
- * is bad. At the end we'll retry the entire write, so if there
- * is more than one bad sector involved they will be handled one
- * at a time.
- */
- if ((ior->io_op & IO_READ) == 0) {
- char msf[sizeof(int)];
- ior->io_temporary = BBR_ACTION_COMPLETE;
- printf("%s", "just reassign..");
- make_msf(msf,blockno);
- scsi_reassign_blocks( tgt, msf, 1, ior);
- } else
- /*
- * This is more complicated. We asked for N bytes, and somewhere
- * in there there is a chunk of bad data. First off, we should retry
- * at least a couple of times to retrieve that data [yes the drive
- * should have done its best already so what]. If that fails we
- * should recover as much good data as possible (before the bad one).
- */
- {
- ior->io_temporary = BBR_ACTION_RETRY_READ;
- printf("%s", "retry read..");
- ior->io_residual = 0;
- scdisk_start_rw(tgt, ior);
- }
-
- return TRUE;
-}
-
-static
-void make_msf(buf,val)
- unsigned char *buf;
- unsigned int val;
-{
- *buf++ = val >> 24;
- *buf++ = val >> 16;
- *buf++ = val >> 8;
- *buf++ = val >> 0;
-}
-
-/*
- * This effectively replaces the strategy routine during bbr.
- */
-void scdisk_bbr_start( tgt, done)
- target_info_t *tgt;
- boolean_t done;
-{
- register io_req_t ior = tgt->ior;
- char *msg;
-
- switch (ior->io_temporary) {
-
- case BBR_ACTION_COMPLETE:
-
- /* all done, either way */
-fin:
- tgt->flags &= ~TGT_BBR_ACTIVE;
- ior->io_recnum = tgt->dev_info.disk.b.save_rec;
- ior->io_data = tgt->dev_info.disk.b.save_addr;
- ior->io_count = tgt->dev_info.disk.b.save_count;
- ior->io_residual = tgt->dev_info.disk.b.save_resid;
-
- if (tgt->done == SCSI_RET_SUCCESS) {
- /* restart normal life */
- register unsigned int xferred;
- if (xferred = ior->io_residual) {
- ior->io_data -= xferred;
- ior->io_count += xferred;
- ior->io_recnum -= xferred / tgt->block_size;
- ior->io_residual = 0;
- }
- /* from the beginning */
- ior->io_error = 0;
- msg = "done, restarting.";
- } else {
- /* we could not fix it. Tell user and give up */
- tgt->ior = ior->io_next;
- iodone(ior);
- msg = "done, but could not recover.";
- }
-
- printf("%s\n", msg);
- scdisk_start( tgt, FALSE);
- return;
-
- case BBR_ACTION_RETRY_READ:
-
- /* see if retry worked, if not do it again */
- if (tgt->done == SCSI_RET_SUCCESS) {
- char msf[sizeof(int)];
-
- /* whew, retry worked. Now rewire that bad block
- * and don't forget to copy the good data over */
-
- tgt->dev_info.disk.b.retry_count = 0;
- printf("%s", "ok now, reassign..");
- ior->io_temporary = BBR_ACTION_COPY;
- make_msf(msf, tgt->dev_info.disk.b.badblockno);
- scsi_reassign_blocks( tgt, msf, 1, ior);
- return;
- }
- if (tgt->dev_info.disk.b.retry_count++ < scsi_bbr_retries) {
- scdisk_start_rw( tgt, ior);
- return;
- }
- /* retrying was hopeless. Leave the bad block there for maintainance */
- /* because we do not know what to write on it */
- printf("%s%d%s", "failed after ", scsi_bbr_retries, " retries..");
- goto fin;
-
-
- case BBR_ACTION_COPY:
-
- /* retrying succeded and we rewired the bad block. */
- if (tgt->done == SCSI_RET_SUCCESS) {
- unsigned int tmp;
- struct diskpart *label;
-
- printf("%s", "ok, rewrite..");
-
- /* writeback only the bad sector */
-
- /* map blockno back to partition offset */
-/* !!! partition code changes: */
- tmp = rzpartition(ior->io_unit);
-/* label=lookup_part(array, tmp +1); */
- tmp = tgt->dev_info.disk.b.badblockno -
-/* label->start; */
-/* #if 0 */
- tgt->dev_info.disk.l.d_partitions[tmp].p_offset;
-/* #endif 0 */
- ior->io_data += (tmp - ior->io_recnum) * tgt->block_size;
- ior->io_recnum = tmp;
- ior->io_count = tgt->block_size;
- ior->io_op &= ~IO_READ;
-
- ior->io_temporary = BBR_ACTION_VERIFY;
- scdisk_start_rw( tgt, ior);
- } else {
-
- /* either unsupported command, or repl table full */
- printf("%s", "reassign failed (really needs reformatting), ");
- ior->io_error = 0;
- goto fin;
- }
- break;
-
- case BBR_ACTION_VERIFY:
-
- if (tgt->done == SCSI_RET_SUCCESS) {
- ior->io_op |= IO_READ;
- goto fin;
- }
-
- if (tgt->dev_info.disk.b.retry_count++ > scsi_bbr_retries) {
- printf("%s%d%s", "failed after ",
- scsi_bbr_retries, " retries..");
- ior->io_op |= IO_READ;
- goto fin;
- }
-
- /* retry, we are *this* close to success.. */
- scdisk_start_rw( tgt, ior);
-
- break;
-
- case BBR_ACTION_REASSIGN:
-
- /* if we wanted to issue the reassign multiple times */
- /* XXX unimplemented XXX */
-
- default: /* snafu */
- panic("scdisk_bbr_start");
- }
-}
-#endif /* NSCSI > 0 */
diff --git a/scsi/rz_host.c b/scsi/rz_host.c
deleted file mode 100644
index 94ccd81..0000000
--- a/scsi/rz_host.c
+++ /dev/null
@@ -1,108 +0,0 @@
-/*
- * Mach Operating System
- * Copyright (c) 1991,1990 Carnegie Mellon University
- * All Rights Reserved.
- *
- * Permission to use, copy, modify and distribute this software and its
- * documentation is hereby granted, provided that both the copyright
- * notice and this permission notice appear in all copies of the
- * software, derivative works or modified versions, and any portions
- * thereof, and that both notices appear in supporting documentation.
- *
- * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
- * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
- * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
- *
- * Carnegie Mellon requests users of this software to return to
- *
- * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
- * School of Computer Science
- * Carnegie Mellon University
- * Pittsburgh PA 15213-3890
- *
- * any improvements or extensions that they make and grant Carnegie Mellon
- * the rights to redistribute these changes.
- */
-/*
- * File: rz_host.c
- * Author: Alessandro Forin, Carnegie Mellon University
- * Date: 7/91
- *
- * Top layer of the SCSI driver: interface with the MI.
- * This file contains operations specific to CPU-like devices.
- *
- * We handle here the case of other hosts that are capable of
- * sophisticated host-to-host communication protocols, we make
- * them look like... you'll see.
- *
- * There are two sides of the coin here: when we take the initiative
- * and when the other host does it. Code for handling both cases is
- * provided in this one file.
- */
-
-#include <mach/std_types.h>
-#include <machine/machspl.h> /* spl definitions */
-#include <scsi/compat_30.h>
-
-#include <scsi/scsi.h>
-#include <scsi/scsi_defs.h>
-#include <scsi/rz.h>
-
-#if (NSCSI > 0)
-/* Since we have invented a new "device" this cannot go into the
- the 'official' scsi_devsw table. Too bad. */
-
-extern char *schost_name();
-extern scsi_ret_t
- schost_open(), schost_close();
-extern int schost_strategy();
-extern void schost_start();
-
-scsi_devsw_t scsi_host = {
- schost_name, 0, schost_open, schost_close, schost_strategy,
- schost_start, 0, 0
-};
-
-char *schost_name(internal)
- boolean_t internal;
-{
- return internal ? "sh" : "host";
-}
-
-scsi_ret_t
-schost_open(tgt)
- target_info_t *tgt;
-{
- return SCSI_RET_SUCCESS; /* XXX if this is it, drop it */
-}
-
-scsi_ret_t
-schost_close(tgt)
- target_info_t *tgt;
-{
- return SCSI_RET_SUCCESS; /* XXX if this is it, drop it */
-}
-
-schost_strategy(ior)
- register io_req_t ior;
-{
- return rz_simpleq_strategy( ior, schost_start);
-}
-
-void
-schost_start( tgt, done)
- target_info_t *tgt;
- boolean_t done;
-{
- io_req_t head, ior;
- scsi_ret_t ret;
-
- if (done || (!tgt->dev_info.cpu.req_pending)) {
- sccpu_start( tgt, done);
- return;
- }
-
- ior = tgt->ior;
-}
-
-#endif /* NSCSI > 0 */
diff --git a/scsi/rz_labels.h b/scsi/rz_labels.h
deleted file mode 100644
index 6ffaa11..0000000
--- a/scsi/rz_labels.h
+++ /dev/null
@@ -1,243 +0,0 @@
-/*
- * Mach Operating System
- * Copyright (c) 1991,1990,1989 Carnegie Mellon University
- * All Rights Reserved.
- *
- * Permission to use, copy, modify and distribute this software and its
- * documentation is hereby granted, provided that both the copyright
- * notice and this permission notice appear in all copies of the
- * software, derivative works or modified versions, and any portions
- * thereof, and that both notices appear in supporting documentation.
- *
- * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
- * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
- * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
- *
- * Carnegie Mellon requests users of this software to return to
- *
- * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
- * School of Computer Science
- * Carnegie Mellon University
- * Pittsburgh PA 15213-3890
- *
- * any improvements or extensions that they make and grant Carnegie Mellon
- * the rights to redistribute these changes.
- */
-/*
- * File: rz_labels.h
- * Author: Alessandro Forin, Carnegie Mellon University
- * Date: 10/90
- *
- * Definitions of various vendor's disk label formats.
- */
-
-/* modified by Kevin T. Van Maren for the unified partition code */
-
-#ifndef _RZ_LABELS_H_
-#define _RZ_LABELS_H_
-
-/*
- * This function looks for, and converts to BSD format
- * a vendor's label. It is only called if we did not
- * find a standard BSD label on the disk pack.
- */
-extern boolean_t rz_vendor_label();
-
-/*
- * Definition of the DEC disk label,
- * which is located (you guessed it)
- * at the end of the 4.3 superblock.
- */
-
-struct dec_partition_info {
- unsigned int n_sectors; /* how big the partition is */
- unsigned int offset; /* sector no. of start of part. */
-};
-
-typedef struct {
- int magic;
-# define DEC_LABEL_MAGIC 0x032957
- int in_use;
- struct dec_partition_info partitions[8];
-} dec_label_t;
-
-/*
- * Physical location on disk.
- * This is independent of the filesystem we use,
- * although of course we'll be in trouble if we
- * screwup the 4.3 SBLOCK..
- */
-
-#define DEC_LABEL_BYTE_OFFSET ((2*8192)-sizeof(dec_label_t))
-
-
-/*
- * Definitions for the primary boot information
- * This is common, cuz the prom knows it.
- */
-
-typedef struct {
- int pad[2];
- unsigned int magic;
-# define DEC_BOOT0_MAGIC 0x2757a
- int mode;
- unsigned int phys_base;
- unsigned int virt_base;
- unsigned int n_sectors;
- unsigned int start_sector;
-} dec_boot0_t;
-
-typedef struct {
- dec_boot0_t vax_boot;
- /* BSD label still fits in pad */
- char pad[0x1e0-sizeof(dec_boot0_t)];
- unsigned long block_count;
- unsigned long starting_lbn;
- unsigned long flags;
- unsigned long checksum; /* add cmpl-2 all but here */
-} alpha_boot0_t;
-
-/*
- * Definition of the Omron disk label,
- * which is located at sector 0. It
- * _is_ sector 0, actually.
- */
-struct omron_partition_info {
- unsigned long offset;
- unsigned long n_sectors;
-};
-
-typedef struct {
- char packname[128]; /* in ascii */
-
- char pad[512-(128+8*8+11*2+4)];
-
- unsigned short badchk; /* checksum of bad track */
- unsigned long maxblk; /* # of total logical blocks */
- unsigned short dtype; /* disk drive type */
- unsigned short ndisk; /* # of disk drives */
- unsigned short ncyl; /* # of data cylinders */
- unsigned short acyl; /* # of alternate cylinders */
- unsigned short nhead; /* # of heads in this partition */
- unsigned short nsect; /* # of 512 byte sectors per track */
- unsigned short bhead; /* identifies proper label locations */
- unsigned short ppart; /* physical partition # */
- struct omron_partition_info
- partitions[8];
-
- unsigned short magic; /* identifies this label format */
-# define OMRON_LABEL_MAGIC 0xdabe
-
- unsigned short cksum; /* xor checksum of sector */
-
-} omron_label_t;
-
-/*
- * Physical location on disk.
- */
-
-#define OMRON_LABEL_BYTE_OFFSET 0
-
-
-/*
- * Definition of the i386AT disk label, which lives inside sector 0.
- * This is the info the BIOS knows about, which we use for bootstrapping.
- * It is common across all disks known to BIOS.
- */
-
-struct bios_partition_info {
-
- unsigned char bootid; /* bootable or not */
-# define BIOS_BOOTABLE 128
-
- unsigned char beghead;/* beginning head, sector, cylinder */
- unsigned char begsect;/* begcyl is a 10-bit number. High 2 bits */
- unsigned char begcyl; /* are in begsect. */
-
- unsigned char systid; /* filesystem type */
-# define UNIXOS 99 /* GNU HURD? */
-# define BSDOS 165 /* 386BSD */
-# define LINUXSWAP 130
-# define LINUXOS 131
-# define DOS_EXTENDED 05 /* container for logical partitions */
-
-# define HPFS 07 /* OS/2 Native */
-# define OS_2_BOOT 10 /* OS/2 Boot Manager */
-# define DOS_12 01 /* 12 bit FAT */
-# define DOS_16_OLD 04 /* < 32MB */
-# define DOS_16 06 /* >= 32MB (#4 not used anymore) */
-
- /* these numbers can't be trusted because */
- /* of newer, larger drives */
- unsigned char endhead;/* ending head, sector, cylinder */
- unsigned char endsect;/* endcyl is a 10-bit number. High 2 bits */
- unsigned char endcyl; /* are in endsect. */
-
- unsigned long offset;
- unsigned long n_sectors;
-};
-
-typedef struct {
-/* struct bios_partition_info bogus compiler alignes wrong
- partitions[4];
-*/
- char partitions[4*sizeof(struct bios_partition_info)];
- unsigned short magic;
-# define BIOS_LABEL_MAGIC 0xaa55
-} bios_label_t;
-
-/*
- * Physical location on disk.
- */
-
-#define BIOS_LABEL_BYTE_OFFSET 446
-
-/*
- * Definitions for the primary boot information
- * This _is_ block 0
- */
-
-#define BIOS_BOOT0_SIZE BIOS_LABEL_BYTE_OFFSET
-
-typedef struct {
- char boot0[BIOS_BOOT0_SIZE]; /* boot code */
-/* bios_label_t label; bogus compiler alignes wrong */
- char label[sizeof(bios_label_t)];
-} bios_boot0_t;
-
-/* Moved from i386at/nhdreg.h */
-#define PDLOCATION 29 /* VTOC sector */
-
-
-/* these are the partition types that can contain sub-partitions */
-/* enum types... */
-#define DISKPART_NONE 0 /* smallest piece flag !?! */
-#define DISKPART_DOS 1
-#define DISKPART_BSD 2
-#define DISKPART_VTOC 3
-#define DISKPART_OMRON 4
-#define DISKPART_DEC 5 /* VAX disks? */
-#define DISKPART_UNKNOWN 99
-
-
-
-/* for NEW partition code */
-/* this is the basic partition structure. an array of these is
- filled, with element 0 being the whole drive, element 1-n being
- the n top-level partitions, followed by 0+ groups of 1+ sub-partitions. */
-typedef struct diskpart {
- short type; /* DISKPART_xxx (see above) */
- short fsys; /* file system (if known) */
- int nsubs; /* number of sub-slices */
- struct diskpart *subs; /* pointer to the sub-partitions */
- int start; /* relative to the start of the DRIVE */
- int size; /* # sectors in this piece */
-} diskpart;
-
-int get_only_partition(void *driver_info, int (*bottom_read_fun)(),
- struct diskpart *array, int array_size,
- int disk_size, char *drive_name);
-
-struct diskpart *lookup_part(struct diskpart *array, int dev_number);
-#endif _RZ_LABELS_H_
-
diff --git a/scsi/rz_tape.c b/scsi/rz_tape.c
deleted file mode 100644
index 1d27722..0000000
--- a/scsi/rz_tape.c
+++ /dev/null
@@ -1,560 +0,0 @@
-/*
- * Mach Operating System
- * Copyright (c) 1991,1990 Carnegie Mellon University
- * All Rights Reserved.
- *
- * Permission to use, copy, modify and distribute this software and its
- * documentation is hereby granted, provided that both the copyright
- * notice and this permission notice appear in all copies of the
- * software, derivative works or modified versions, and any portions
- * thereof, and that both notices appear in supporting documentation.
- *
- * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
- * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
- * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
- *
- * Carnegie Mellon requests users of this software to return to
- *
- * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
- * School of Computer Science
- * Carnegie Mellon University
- * Pittsburgh PA 15213-3890
- *
- * any improvements or extensions that they make and grant Carnegie Mellon
- * the rights to redistribute these changes.
- */
-/*
- * File: rz_tape.c
- * Author: Alessandro Forin, Carnegie Mellon University
- * Date: 10/90
- *
- * Top layer of the SCSI driver: interface with the MI.
- * This file contains operations specific to TAPE-like devices.
- */
-
-#include <mach/std_types.h>
-#include <scsi/compat_30.h>
-
-#include <sys/ioctl.h>
-#ifdef MACH_KERNEL
-#include <device/tape_status.h>
-#else /*MACH_KERNEL*/
-#include <mips/PMAX/tape_status.h>
-#endif /*MACH_KERNEL*/
-
-#include <scsi/scsi.h>
-#include <scsi/scsi_defs.h>
-#include <scsi/rz.h>
-
-#if (NSCSI > 0)
-
-
-void sctape_start(); /* forward */
-
-int scsi_tape_timeout = 5*60; /* secs, tk50 is slow when positioning far apart */
-
-int sctape_open(tgt, req)
- target_info_t *tgt;
- io_req_t req;
-{
- io_return_t ret;
- io_req_t ior;
- int i;
- scsi_mode_sense_data_t *mod;
-
-#ifdef MACH_KERNEL
- req->io_device->flag |= D_EXCL_OPEN;
-#endif /*MACH_KERNEL*/
-
- /* Preferably allow tapes to disconnect */
- if (BGET(scsi_might_disconnect,(unsigned char)tgt->masterno,tgt->target_id))
- BSET(scsi_should_disconnect,(unsigned char)tgt->masterno,tgt->target_id);
-
- /*
- * Dummy ior for proper sync purposes
- */
- io_req_alloc(ior,0);
- ior->io_count = 0;
-
- /*
- * Do a mode sense first, some drives might be picky
- * about changing params [even if the standard might
- * say otherwise, sigh.]
- */
- do {
- ior->io_op = IO_INTERNAL;
- ior->io_next = 0;
- ior->io_error = 0;
- ret = scsi_mode_sense(tgt, 0, 32, ior);
- } while (ret == SCSI_RET_RETRY);
-
- mod = (scsi_mode_sense_data_t *)tgt->cmd_ptr;
- if (scsi_debug) {
- int p[5];
- bcopy((char*)mod, (char*)p, sizeof(p));
- printf("[modsns(%x): x%x x%x x%x x%x x%x]", ret,
- p[0], p[1], p[2], p[3], p[4]);
- }
- if (ret == SCSI_RET_DEVICE_DOWN)
- goto out;
- if (ret == SCSI_RET_SUCCESS) {
- tgt->dev_info.tape.read_only = mod->wp;
- tgt->dev_info.tape.speed = mod->speed;
- tgt->dev_info.tape.density = mod->bdesc[0].density_code;
- } /* else they all default sensibly, using zeroes */
-
- /* Some tapes have limits on record-length */
-again:
- ior->io_op = IO_INTERNAL;
- ior->io_next = 0;
- ior->io_error = 0;
- ret = scsi_read_block_limits( tgt, ior);
- if (ret == SCSI_RET_RETRY) goto again;
- if (!ior->io_error && (ret == SCSI_RET_SUCCESS)) {
- scsi_blimits_data_t *lim;
- int maxl;
-
- lim = (scsi_blimits_data_t *) tgt->cmd_ptr;
-
- tgt->block_size = (lim->minlen_msb << 8) |
- lim->minlen_lsb;
-
- maxl = (lim->maxlen_msb << 16) |
- (lim->maxlen_sb << 8) |
- lim->maxlen_lsb;
- if (maxl == 0)
- maxl = (unsigned)-1;
- tgt->dev_info.tape.maxreclen = maxl;
- tgt->dev_info.tape.fixed_size = (maxl == tgt->block_size);
- } else {
- /* let the user worry about it */
- /* default: tgt->block_size = 1; */
- tgt->dev_info.tape.maxreclen = (unsigned)-1;
- tgt->dev_info.tape.fixed_size = FALSE;
- }
-
- /* Try hard to do a mode select */
- for (i = 0; i < 5; i++) {
- ior->io_op = IO_INTERNAL;
- ior->io_error = 0;
- ret = sctape_mode_select(tgt, 0, 0, FALSE, ior);
- if (ret == SCSI_RET_SUCCESS)
- break;
- }
- if (scsi_watchdog_period < scsi_tape_timeout)
- scsi_watchdog_period += scsi_tape_timeout;
-
-#if 0 /* this might imply rewind, which we do not want, although yes, .. */
- /* we want the tape loaded */
- ior->io_op = IO_INTERNAL;
- ior->io_next = 0;
- ior->io_error = 0;
- ret = scsi_start_unit(tgt, SCSI_CMD_SS_START, ior);
-#endif
- req->io_device->bsize = tgt->block_size;
-out:
- io_req_free(ior);
- return ret;
-}
-
-
-io_return_t sctape_close(tgt)
- target_info_t *tgt;
-{
- io_return_t ret = SCSI_RET_SUCCESS;
- io_req_t ior;
-
- /*
- * Dummy ior for proper sync purposes
- */
- io_req_alloc(ior,0);
- ior->io_op = IO_INTERNAL;
- ior->io_next = 0;
- ior->io_count = 0;
-
- if (tgt->ior) printf("TAPE: Close with pending requests ?? \n");
-
- /* write a filemark if we xtnded/truncated the tape */
- if (tgt->flags & TGT_WRITTEN_TO) {
- tgt->ior = ior;
- ior->io_error = 0;
- ret = scsi_write_filemarks(tgt, 2, ior);
- if (ret != SCSI_RET_SUCCESS)
- printf("%s%d: wfmark failed x%x\n",
- (*tgt->dev_ops->driver_name)(TRUE), tgt->target_id, ret);
- /*
- * Don't bother repositioning if we'll rewind it
- */
- if (tgt->flags & TGT_REWIND_ON_CLOSE)
- goto rew;
-retry:
- tgt->ior = ior;
- ior->io_op = IO_INTERNAL;
- ior->io_error = 0;
- ior->io_next = 0;
- ret = scsi_space(tgt, SCSI_CMD_SP_FIL, -1, ior);
- if (ret != SCSI_RET_SUCCESS) {
- if (ret == SCSI_RET_RETRY) {
- timeout(wakeup, tgt, hz);
- await(tgt);
- goto retry;
- }
- printf("%s%d: bspfile failed x%x\n",
- (*tgt->dev_ops->driver_name)(TRUE), tgt->target_id, ret);
- }
- }
-rew:
- if (tgt->flags & TGT_REWIND_ON_CLOSE) {
- /* Rewind tape */
- ior->io_error = 0;
- ior->io_op = IO_INTERNAL;
- ior->io_error = 0;
- tgt->ior = ior;
- (void) scsi_rewind(tgt, ior, FALSE);
- iowait(ior);
- if (tgt->done == SCSI_RET_RETRY) {
- timeout(wakeup, tgt, 5*hz);
- await(tgt);
- goto rew;
- }
- }
- io_req_free(ior);
-
- tgt->flags &= ~(TGT_ONLINE|TGT_WRITTEN_TO|TGT_REWIND_ON_CLOSE);
- return ret;
-}
-
-int sctape_strategy(ior)
- register io_req_t ior;
-{
- target_info_t *tgt;
- register int i = ior->io_unit;
-
- tgt = scsi_softc[rzcontroller(i)]->target[rzslave(i)];
-
- if (((ior->io_op & IO_READ) == 0) &&
- tgt->dev_info.tape.read_only) {
- ior->io_error = D_INVALID_OPERATION;
- ior->io_op |= IO_ERROR;
- ior->io_residual = ior->io_count;
- iodone(ior);
- return ior->io_error;
- }
-
- return rz_simpleq_strategy( ior, sctape_start);
-}
-
-static void
-do_residue(ior, sns, bsize)
- io_req_t ior;
- scsi_sense_data_t *sns;
- int bsize;
-{
- int residue;
-
- /* Not an error situation */
- ior->io_error = 0;
- ior->io_op &= ~IO_ERROR;
-
- if (!sns->addr_valid) {
- ior->io_residual = ior->io_count;
- return;
- }
-
- residue = sns->u.xtended.info0 << 24 |
- sns->u.xtended.info1 << 16 |
- sns->u.xtended.info2 << 8 |
- sns->u.xtended.info3;
- /* fixed ? */
- residue *= bsize;
- /*
- * NOTE: residue == requested - actual
- * We only care if > 0
- */
- if (residue < 0) residue = 0;/* sanity */
- ior->io_residual += residue;
-}
-
-void sctape_start( tgt, done)
- target_info_t *tgt;
- boolean_t done;
-{
- io_req_t head, ior = tgt->ior;
-
- if (ior == 0)
- return;
-
- if (done) {
-
- /* see if we must retry */
- if ((tgt->done == SCSI_RET_RETRY) &&
- ((ior->io_op & IO_INTERNAL) == 0)) {
- delay(1000000);/*XXX*/
- goto start;
- } else
- /* got a bus reset ? ouch, that hurts */
- if (tgt->done == (SCSI_RET_ABORTED|SCSI_RET_RETRY)) {
- /*
- * we really cannot retry because the tape position
- * is lost.
- */
- printf("Lost tape position\n");
- ior->io_error = D_IO_ERROR;
- ior->io_op |= IO_ERROR;
- } else
-
- /* check completion status */
-
- if (tgt->cur_cmd == SCSI_CMD_REQUEST_SENSE) {
- scsi_sense_data_t *sns;
-
- ior->io_op = ior->io_temporary;
- ior->io_error = D_IO_ERROR;
- ior->io_op |= IO_ERROR;
-
- sns = (scsi_sense_data_t *)tgt->cmd_ptr;
-
- if (scsi_debug)
- scsi_print_sense_data(sns);
-
- if (scsi_check_sense_data(tgt, sns)) {
- if (sns->u.xtended.ili) {
- if (ior->io_op & IO_READ) {
- do_residue(ior, sns, tgt->block_size);
- if (scsi_debug)
- printf("Tape Short Read (%d)\n",
- ior->io_residual);
- }
- } else if (sns->u.xtended.eom) {
- do_residue(ior, sns, tgt->block_size);
- if (scsi_debug)
- printf("End of Physical Tape!\n");
- } else if (sns->u.xtended.fm) {
- do_residue(ior, sns, tgt->block_size);
- if (scsi_debug)
- printf("File Mark\n");
- }
- }
- }
-
- else if (tgt->done != SCSI_RET_SUCCESS) {
-
- if (tgt->done == SCSI_RET_NEED_SENSE) {
-
- ior->io_temporary = ior->io_op;
- ior->io_op = IO_INTERNAL;
- if (scsi_debug)
- printf("[NeedSns x%x x%x]", ior->io_residual, ior->io_count);
- scsi_request_sense(tgt, ior, 0);
- return;
-
- } else if (tgt->done == SCSI_RET_RETRY) {
- /* only retry here READs and WRITEs */
- if ((ior->io_op & IO_INTERNAL) == 0) {
- ior->io_residual = 0;
- goto start;
- } else{
- ior->io_error = D_WOULD_BLOCK;
- ior->io_op |= IO_ERROR;
- }
- } else {
- ior->io_error = D_IO_ERROR;
- ior->io_op |= IO_ERROR;
- }
- }
-
- if (scsi_debug)
- printf("[Resid x%x]", ior->io_residual);
-
- /* dequeue next one */
- head = ior;
-
- simple_lock(&tgt->target_lock);
- ior = head->io_next;
- tgt->ior = ior;
- if (ior)
- ior->io_prev = head->io_prev;
- simple_unlock(&tgt->target_lock);
-
- iodone(head);
-
- if (ior == 0)
- return;
- }
- ior->io_residual = 0;
-start:
- if (ior->io_op & IO_READ) {
- tgt->flags &= ~TGT_WRITTEN_TO;
- sctape_read( tgt, ior );
- } else if ((ior->io_op & IO_INTERNAL) == 0) {
- tgt->flags |= TGT_WRITTEN_TO;
- sctape_write( tgt, ior );
- }
-}
-
-io_return_t
-sctape_get_status( dev, tgt, flavor, status, status_count)
- int dev;
- target_info_t *tgt;
- dev_flavor_t flavor;
- dev_status_t status;
- natural_t *status_count;
-{
- switch (flavor) {
- case DEV_GET_SIZE:
-
- status[DEV_GET_SIZE_DEVICE_SIZE] = 0;
- status[DEV_GET_SIZE_RECORD_SIZE] = tgt->block_size;
- *status_count = DEV_GET_SIZE_COUNT;
- break;
- case TAPE_STATUS: {
- struct tape_status *ts = (struct tape_status *) status;
-
- ts->mt_type = MT_ISSCSI;
- ts->speed = tgt->dev_info.tape.speed;
- ts->density = tgt->dev_info.tape.density;
- ts->flags = (tgt->flags & TGT_REWIND_ON_CLOSE) ?
- TAPE_FLG_REWIND : 0;
- if (tgt->dev_info.tape.read_only)
- ts->flags |= TAPE_FLG_WP;
-#ifdef MACH_KERNEL
- *status_count = TAPE_STATUS_COUNT;
-#endif
-
- break;
- }
- /* U*x compat */
- case MTIOCGET: {
- struct mtget *g = (struct mtget *) status;
-
- bzero(g, sizeof(struct mtget));
- g->mt_type = 0x7; /* Ultrix compat */
-#ifdef MACH_KERNEL
- *status_count = sizeof(struct mtget)/sizeof(int);
-#endif
- break;
- }
- default:
- return D_INVALID_OPERATION;
- }
- return D_SUCCESS;
-}
-
-io_return_t
-sctape_set_status( dev, tgt, flavor, status, status_count)
- int dev;
- target_info_t *tgt;
- dev_flavor_t flavor;
- dev_status_t status;
- natural_t status_count;
-{
- scsi_ret_t ret;
-
- switch (flavor) {
- case TAPE_STATUS: {
- struct tape_status *ts = (struct tape_status *) status;
- if (ts->flags & TAPE_FLG_REWIND)
- tgt->flags |= TGT_REWIND_ON_CLOSE;
- else
- tgt->flags &= ~TGT_REWIND_ON_CLOSE;
-
- if (ts->speed || ts->density) {
- unsigned int ospeed, odensity;
- io_req_t ior;
-
- io_req_alloc(ior,0);
- ior->io_op = IO_INTERNAL;
- ior->io_error = 0;
- ior->io_next = 0;
- ior->io_count = 0;
-
- ospeed = tgt->dev_info.tape.speed;
- odensity = tgt->dev_info.tape.density;
- tgt->dev_info.tape.speed = ts->speed;
- tgt->dev_info.tape.density = ts->density;
-
- ret = sctape_mode_select(tgt, 0, 0, (ospeed == ts->speed), ior);
- if (ret != SCSI_RET_SUCCESS) {
- tgt->dev_info.tape.speed = ospeed;
- tgt->dev_info.tape.density = odensity;
- }
-
- io_req_free(ior);
- }
-
- break;
- }
- /* U*x compat */
- case MTIOCTOP: {
- struct tape_params *mt = (struct tape_params *) status;
- io_req_t ior;
-
- if (scsi_debug)
- printf("[sctape_sstatus: %x %x %x]\n",
- flavor, mt->mt_operation, mt->mt_repeat_count);
-
- io_req_alloc(ior,0);
-retry:
- ior->io_count = 0;
- ior->io_op = IO_INTERNAL;
- ior->io_error = 0;
- ior->io_next = 0;
- tgt->ior = ior;
-
- /* compat: in U*x it is a short */
- switch ((short)(mt->mt_operation)) {
- case MTWEOF: /* write an end-of-file record */
- ret = scsi_write_filemarks(tgt, mt->mt_repeat_count, ior);
- break;
- case MTFSF: /* forward space file */
- ret = scsi_space(tgt, SCSI_CMD_SP_FIL, mt->mt_repeat_count, ior);
- break;
- case MTBSF: /* backward space file */
- ret = scsi_space(tgt, SCSI_CMD_SP_FIL, -mt->mt_repeat_count,ior);
- break;
- case MTFSR: /* forward space record */
- ret = scsi_space(tgt, SCSI_CMD_SP_BLOCKS, mt->mt_repeat_count, ior);
- break;
- case MTBSR: /* backward space record */
- ret = scsi_space(tgt, SCSI_CMD_SP_BLOCKS, -mt->mt_repeat_count, ior);
- break;
- case MTREW: /* rewind */
- case MTOFFL: /* rewind and put the drive offline */
- ret = scsi_rewind(tgt, ior, TRUE);
- iowait(ior);
- if ((short)(mt->mt_operation) == MTREW) break;
- ior->io_op = 0;
- ior->io_next = 0;
- ior->io_error = 0;
- (void) scsi_start_unit(tgt, 0, ior);
- break;
- case MTNOP: /* no operation, sets status only */
- case MTCACHE: /* enable controller cache */
- case MTNOCACHE: /* disable controller cache */
- ret = SCSI_RET_SUCCESS;
- break;
- default:
- tgt->ior = 0;
- io_req_free(ior);
- return D_INVALID_OPERATION;
- }
-
- if (ret == SCSI_RET_RETRY) {
- timeout(wakeup, ior, 5*hz);
- await(ior);
- goto retry;
- }
-
- io_req_free(ior);
- if (ret != SCSI_RET_SUCCESS)
- return D_IO_ERROR;
- break;
- }
- case MTIOCIEOT:
- case MTIOCEEOT:
- default:
- return D_INVALID_OPERATION;
- }
- return D_SUCCESS;
-}
-#endif /* NSCSI > 0 */
diff --git a/scsi/scsi.c b/scsi/scsi.c
deleted file mode 100644
index d4aecf6..0000000
--- a/scsi/scsi.c
+++ /dev/null
@@ -1,642 +0,0 @@
-/*
- * Mach Operating System
- * Copyright (c) 1993-1989 Carnegie Mellon University
- * All Rights Reserved.
- *
- * Permission to use, copy, modify and distribute this software and its
- * documentation is hereby granted, provided that both the copyright
- * notice and this permission notice appear in all copies of the
- * software, derivative works or modified versions, and any portions
- * thereof, and that both notices appear in supporting documentation.
- *
- * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
- * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
- * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
- *
- * Carnegie Mellon requests users of this software to return to
- *
- * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
- * School of Computer Science
- * Carnegie Mellon University
- * Pittsburgh PA 15213-3890
- *
- * any improvements or extensions that they make and grant Carnegie Mellon
- * the rights to redistribute these changes.
- */
-/*
- * File: scsi.c
- * Author: Alessandro Forin, Carnegie Mellon University
- * Date: 9/90
- *
- * Middle layer of the SCSI driver: chip independent functions
- * This file contains Controller and Device-independent functions
- */
-
-#include <scsi.h>
-
-#if NSCSI > 0
-#include <platforms.h>
-
-#include <machine/machspl.h> /* spl definitions */
-
-#include <mach/std_types.h>
-#include <sys/types.h>
-#include <scsi/compat_30.h>
-
-#include <chips/busses.h>
-#include <scsi/scsi.h>
-#include <scsi/scsi2.h>
-#include <scsi/scsi_defs.h>
-#include <machine/machspl.h>
-
-
-
-#ifdef VAXSTATION
-/* We run some of this code on the interrupt stack */
-#undef spl0
-#define spl0() spl1()
-#endif /*VAXSTATION*/
-
-/*
- * Overall driver state
- */
-
-target_info_t scsi_target_data[NSCSI*8]; /* per target state */
-scsi_softc_t scsi_softc_data[NSCSI]; /* per HBA state */
-scsi_softc_t *scsi_softc[NSCSI]; /* quick access&checking */
-
-/*
- * If a specific target should NOT be asked to go synchronous
- * then its bit in this bitmap should be set. Each SCSI controller
- * (Host Bus Adapter) can hold at most 8 targets --> use one
- * byte per controller. A bit set to one means NO synchronous.
- * Patch with adb if necessary.
- */
-unsigned char scsi_no_synchronous_xfer[NSCSI];
-
-/*
- * For certain targets it is wise to use the long form of the
- * read/write commands even if their capacity would not necessitate
- * it. Same as above for usage.
- */
-unsigned char scsi_use_long_form[NSCSI];
-
-
-/*
- * Control over disconnect-reconnect mode.
- */
-unsigned char scsi_might_disconnect[NSCSI] = /* do it if deemed appropriate */
- { 0xff, 0xff, 0xff, 0xff, 0xff};/* Fix by hand viz NSCSI */
-unsigned char scsi_should_disconnect[NSCSI] = /* just do it */
- { 0,};
-unsigned char scsi_initiator_id[NSCSI] = /* our id on the bus(ses) */
- { 7, 7, 7, 7, 7};
-
-/*
- * Miscellaneus config
- */
-boolean_t scsi_exabyte_filemarks = FALSE; /* use short filemarks */
-int scsi_watchdog_period = 10; /* but exabyte needs >=30 for bspace */
-int scsi_delay_after_reset = 1000000;/* microseconds */
-boolean_t scsi_no_automatic_bbr = FALSE; /* revector bad blocks automatically */
-
-#ifdef MACH_KERNEL
-#else
-/* This covers Exabyte's max record size */
-unsigned int scsi_per_target_virtual = 256*1024;
-#endif MACH_KERNEL
-
-
-/*
- * Device-specific operations are switched off this table
- */
-
-extern char
- *scdisk_name(), *sctape_name(), *scprt_name(),
- *sccpu_name(), *scworm_name(), *sccdrom_name(),
- *scscn_name(), *scmem_name(), *scjb_name(), *sccomm_name();
-extern void
- sctape_optimize();
-extern scsi_ret_t
- scdisk_open(), sctape_open(), sctape_close(),
- sccomm_open(), sccomm_close();
-extern int
- scdisk_strategy(), sctape_strategy(), sccpu_strategy(),
- sccomm_strategy();
-extern void
- scdisk_start(), sctape_start(), sccpu_start(), sccomm_start();
-
-extern io_return_t
- scdisk_set_status(), scdisk_get_status(),
- sctape_set_status(), sctape_get_status(),
- sccomm_set_status(), sccomm_get_status();
-
-scsi_devsw_t scsi_devsw[] = {
-
-/* SCSI_DISK */ { scdisk_name, SCSI_OPTIMIZE_NULL,
- scdisk_open, SCSI_CLOSE_NULL,
- scdisk_strategy, scdisk_start,
- scdisk_get_status, scdisk_set_status },
-
-/* SCSI_TAPE */ { sctape_name, sctape_optimize,
- sctape_open, sctape_close,
- sctape_strategy, sctape_start,
- sctape_get_status, sctape_set_status },
-
-/* SCSI_PRINTER */ { scprt_name, SCSI_OPTIMIZE_NULL, /*XXX*/},
-
-/* SCSI_CPU */ { sccpu_name, SCSI_OPTIMIZE_NULL,
- SCSI_OPEN_NULL, SCSI_CLOSE_NULL,
- sccpu_strategy, sccpu_start,},
-
-/* SCSI_WORM */ { scworm_name, SCSI_OPTIMIZE_NULL,
- scdisk_open, SCSI_CLOSE_NULL,
- scdisk_strategy, scdisk_start,
- scdisk_get_status, scdisk_set_status },
-
-/* SCSI_CDROM */ { sccdrom_name, SCSI_OPTIMIZE_NULL,
- scdisk_open, SCSI_CLOSE_NULL,
- scdisk_strategy, scdisk_start,
- scdisk_get_status, scdisk_set_status },
-/* scsi2 */
-/* SCSI_SCANNER */ { scscn_name, SCSI_OPTIMIZE_NULL, /*XXX*/ },
-
-/* SCSI_MEMORY */ { scmem_name, SCSI_OPTIMIZE_NULL,
- scdisk_open, SCSI_CLOSE_NULL,
- scdisk_strategy, scdisk_start,
- scdisk_get_status, scdisk_set_status },
-
-/* SCSI_J_BOX */ { scjb_name, SCSI_OPTIMIZE_NULL, /*XXX*/ },
-
-/* SCSI_COMM */ { sccomm_name, SCSI_OPTIMIZE_NULL,
-#if (NCENDATA>0)
- sccomm_open, sccomm_close,
- sccomm_strategy, sccomm_start,
- sccomm_get_status, sccomm_set_status
-#endif
- },
- 0
-};
-
-/*
- * Allocation routines for state structures
- */
-scsi_softc_t *
-scsi_master_alloc(unit, hw)
- unsigned unit;
- char *hw;
-{
- scsi_softc_t *sc;
-
- if (unit < NSCSI) {
- sc = &scsi_softc_data[unit];
- scsi_softc[unit] = sc;
- sc->masterno = unit;
- sc->hw_state = hw;
- return sc;
- }
- return 0;
-}
-
-target_info_t *
-scsi_slave_alloc(unit, slave, hw)
- unsigned unit, slave;
- char *hw;
-{
- target_info_t *tgt;
-
- tgt = &scsi_target_data[(unit<<3) + slave];
- tgt->hw_state = hw;
- tgt->dev_ops = 0; /* later */
- tgt->target_id = slave;
- tgt->masterno = unit;
- tgt->block_size = 1; /* default */
- tgt->flags = TGT_ALIVE;
- tgt->sync_period = 0;
- tgt->sync_offset = 0;
- simple_lock_init(&tgt->target_lock);
-
- scsi_softc[unit]->target[slave] = tgt;
- return tgt;
-}
-
-void
-zero_ior(
- io_req_t ior )
-{
- ior->io_next = ior->io_prev = 0;
- ior->io_count = 0;
- ior->io_op = IO_INTERNAL;
- ior->io_error = 0;
-}
-
-/*
- * Slave routine:
- * See if the slave description (controller, unit, ..)
- * matches one of the slaves found during probe
- *
- * Implementation:
- * Send out an INQUIRY command to see what sort of device
- * the slave is.
- * Notes:
- * At this time the driver is fully functional and works
- * off interrupts.
- * TODO:
- * The SCSI2 spec says what exactly must happen: see F.2.3
- */
-int scsi_slave( ui, reg)
- struct bus_device *ui;
- unsigned reg;
-{
- scsi_softc_t *sc = scsi_softc[(unsigned char)ui->ctlr];
- target_info_t *tgt = sc->target[(unsigned char)ui->slave];
- scsi2_inquiry_data_t *inq;
- int scsi_std;
- int ptype, s;
-
- if (!tgt || !(tgt->flags & TGT_ALIVE))
- return 0;
-
- /* Might have scanned already */
- if (tgt->dev_ops)
- goto out;
-
-#ifdef SCSI2
- This is what should happen:
- - for all LUNs
- INQUIRY
- scsi_verify_state (see)
- scsi_initialize (see)
-#endif SCSI2
-
- tgt->unit_no = ui->slave; /* incorrect, but needed early */
-
- s = spl0(); /* we need interrupts */
-
- if (BGET(scsi_no_synchronous_xfer,(unsigned char)sc->masterno,tgt->target_id))
- tgt->flags |= TGT_DID_SYNCH;
-
- /*
- * Ok, it is time to see what type of device this is,
- * send an INQUIRY cmd and wait till done.
- * Possibly do the synch negotiation here.
- */
- scsi_inquiry(tgt, SCSI_INQ_STD_DATA);
-
- inq = (scsi2_inquiry_data_t*)tgt->cmd_ptr;
- ptype = inq->periph_type;
-
- switch (ptype) {
- case SCSI_CDROM :
- tgt->flags |= TGT_READONLY;
- /* fall through */
- case SCSI_DISK :
- case SCSI_TAPE :
- case SCSI_PRINTER :
- case SCSI_CPU :
- case SCSI_WORM :
- case SCSI_SCANNER :
- case SCSI_MEMORY :
- case SCSI_J_BOX :
- case SCSI_COMM :
-/* case SCSI_PREPRESS1 : reserved, really
- case SCSI_PREPRESS2 : */
- tgt->dev_ops = &scsi_devsw[ptype];
- break;
- default:
- printf("scsi%d: %s %d (x%x). ", ui->ctlr,
- "Unsupported device type at SCSI id", ui->slave,
- inq->periph_type);
- scsi_print_inquiry((scsi2_inquiry_data_t*)inq,
- SCSI_INQ_STD_DATA, 0);
- tgt->flags = 0;
- splx(s);
- return 0;
- }
-
- if (inq->rmb)
- tgt->flags |= TGT_REMOVABLE_MEDIA;
-
- /*
- * Tell the user we know this target, then see if we
- * can be a bit smart about it.
- */
- scsi_print_inquiry((scsi2_inquiry_data_t*)inq,
- SCSI_INQ_STD_DATA, tgt->tgt_name);
- if (scsi_debug)
- scsi_print_inquiry((scsi2_inquiry_data_t*)inq,
- SCSI_INQ_STD_DATA, 0);
-
- /*
- * The above says if it currently behaves as a scsi2,
- * however scsi1 might just be the default setting.
- * The spec say that even if in scsi1 mode the target
- * should answer to the full scsi2 inquiry spec.
- */
- scsi_std = (inq->ansi == 2 || inq->response_fmt == 2) ? 2 : 1;
-#if nosey
- if (scsi_std == 2) {
- unsigned char supp_pages[256], i;
- scsi2_impl_opdef_page_t *impl;
-
- scsi_inquiry(tgt, SCSI_INQ_SUPP_PAGES);
- impl = (scsi2_impl_opdef_page_t *)inq;
- npages = impl->page_len - 2;
- bcopy(impl->supp_opdef, supp_pages, npages);
-
- for (i = 0; i < npages; i++) {
- scsi_inquiry(tgt, supp_pages[i]);
- scsi_print_inquiry(inq, supp_pages[i], 0);
- }
- }
-
- if (scsi_std == 2) {
- scsi2_impl_opdef_page_t *impl;
- int i;
-
- scsi_inquiry(tgt, SCSI_INQ_IMPL_OPDEF);
- impl = (scsi2_impl_opdef_page_t *)inq;
- for (i = 0; i < impl->page_len - 2; i++)
- if (impl->supp_opdef[i] == SCSI2_OPDEF) {
- scsi_change_definition(tgt, SCSI2_OPDEF);
- /* if success .. */
- tgt->flags |= TGT_SCSI_2_MODE;
- break;
- }
- }
-#endif nosey
-
- splx(s);
-out:
- return (strcmp(ui->name, (*tgt->dev_ops->driver_name)(TRUE)) == 0);
-}
-
-#ifdef SCSI2
-scsi_verify_state(...)
-{
-verify_state: send test_unit_ready up to 3 times, each time it fails
-(with check condition) send a requeste_sense. It is ok to get UNIT ATTENTION
-the first time only, NOT READY the second, only GOOD the last time.
-If you get BUSY or RESERVATION CONFLICT retry.
-}
-
-scsi_initialize(...)
-{
-
-initialize: send start_unit with immed=0 (->disconnect), if fails
-with check condition send requeste_sense and if "illegal request"
-proceed anyways. Retry on BUSY.
-Do a verify_state, then
-disks:
- - mode_sense (current) if ANSI2 or needed by vendor (!!!!)
- and if check-condition&illegal-request goto capacity
- - mode_sense (changeable)
- - if needed do a mode_select (yes, 512)
- - read_capacity
-tapes:
-
-}
-#endif SCSI2
-
-/*
- * Attach routine:
- * Fill in all the relevant per-slave data and make
- * the slave operational.
- *
- * Implementation:
- * Get target's status, start the unit and then
- * switch off to device-specific functions to gather
- * as much info as possible about the slave.
- */
-void scsi_attach(ui)
- register struct bus_device *ui;
-{
- scsi_softc_t *sc = scsi_softc[ui->mi->unit];
- target_info_t *tgt = sc->target[(unsigned char)ui->slave];
- int i;
- spl_t s;
-
- printf(" (%s %s) ", (*tgt->dev_ops->driver_name)(FALSE),tgt->tgt_name);
-
- if (tgt->flags & TGT_US) {
- printf(" [this cpu]");
- return;
- }
-
- s = spl0();
-
- /* sense return from inquiry */
- scsi_request_sense(tgt, 0, 0);
-
- /*
- * Do this twice, certain targets need it
- */
- if (tgt->dev_ops != &scsi_devsw[SCSI_CPU]) {
- (void) scsi_start_unit(tgt, SCSI_CMD_SS_START, 0);
- i = 0;
- while (scsi_start_unit(tgt, SCSI_CMD_SS_START, 0) == SCSI_RET_RETRY) {
- if (i++ == 5)
- printf(".. not yet online ..");
- delay(1000000);
- if (i == 60) {
- printf(" seems hopeless.");
- break;
- }
- }
- }
-
- /*
- * See if it is up and about
- */
- scsi_test_unit_ready(tgt, 0);
-
- if (tgt->dev_ops->optimize != SCSI_OPTIMIZE_NULL)
- (*tgt->dev_ops->optimize)(tgt);
-
- tgt->flags |= TGT_FULLY_PROBED;
-
- splx(s);
-}
-
-/*
- * Probe routine:
- * See if a device answers. Used AFTER autoconf.
- *
- * Implementation:
- * First ask the HBA to see if anyone is there at all, then
- * call the scsi_slave and scsi_attach routines with a fake ui.
- */
-boolean_t
-scsi_probe( sc, tgt_ptr, target_id, ior)
- scsi_softc_t *sc;
- target_info_t **tgt_ptr;
- int target_id;
- io_req_t ior;
-{
- struct bus_device ui;
- target_info_t *tgt;
-
- if (!sc->probe || target_id > 7 || target_id == sc->initiator_id)
- return FALSE; /* sanity */
-
- if (sc->target[target_id] == 0)
- scsi_slave_alloc( sc->masterno, target_id, sc->hw_state);
- tgt = sc->target[target_id];
- tgt->flags = 0;/* we donno yet */
- tgt->dev_ops = 0;
-
- /* mildly enquire */
- if (!(sc->probe)(tgt, ior))
- goto fail;
-
- /* There is something there, see what it is */
- bzero(&ui, sizeof(ui));
- ui.ctlr = sc->masterno;
- ui.unit =
- ui.slave = target_id;
- ui.name = "";
-
- /* this fails on the name for sure */
- (void) scsi_slave( &ui, 0 /* brrrr */);
- if ((tgt->flags & TGT_ALIVE) == 0)
- goto fail;
-
- {
- struct bus_ctlr mi;
-
- mi.unit = sc->masterno;
- ui.mi = &mi;
- printf("%s at slave %d ",
- (*tgt->dev_ops->driver_name)(TRUE), target_id);
- scsi_attach(&ui);
- }
-
- *tgt_ptr = tgt;
- return TRUE;
-fail:
- tgt->flags = 0;
- return FALSE;
-}
-
-
-/*
- * Watchdog routine:
- * Issue a SCSI bus reset if a target holds up the
- * bus for too long.
- *
- * Implementation:
- * Each HBA that wants to use this should have a
- * watchdog_t structure at the head of its hardware
- * descriptor. This variable is set by this periodic
- * routine and reset on bus activity. If it is not reset on
- * time (say some ten seconds or so) we reset the
- * SCSI bus.
- * NOTE:
- * An HBA must be ready to accept bus reset interrupts
- * properly in order to use this.
- */
-void scsi_watchdog(hw)
- watchdog_t *hw;
-{
- spl_t s = splbio();
-
- switch (hw->watchdog_state) {
- case SCSI_WD_EXPIRED:
-
- /* double check first */
- if (hw->nactive == 0) {
- hw->watchdog_state = SCSI_WD_INACTIVE;
- break;
- }
- if (scsi_debug)
- printf("SCSI Watchdog expired\n");
- hw->watchdog_state = SCSI_WD_INACTIVE;
- (*hw->reset)(hw);
- break;
-
- case SCSI_WD_ACTIVE:
-
- hw->watchdog_state = SCSI_WD_EXPIRED;
- break;
-
- case SCSI_WD_INACTIVE:
-
- break;
- }
-
- /* do this here, fends against powered down devices */
- if (scsi_watchdog_period != 0)
- timeout((int(*)())scsi_watchdog, (char*)hw, scsi_watchdog_period * hz);
-
- splx(s);
-}
-
-
-/*
- * BusReset Notification:
- * Called when the HBA sees a BusReset interrupt
- *
- * Implementation:
- * Go through the list of targets, redo the synch
- * negotiation, and restart whatever operation was
- * in progress for that target.
- */
-void scsi_bus_was_reset(sc)
- scsi_softc_t *sc;
-{
- register target_info_t *tgt;
- int i;
- /*
- * Redo the synch negotiation
- */
- for (i = 0; i < 8; i++) {
- io_req_t ior;
- spl_t s;
-
- if (i == sc->initiator_id)
- continue;
- tgt = sc->target[i];
- if (!tgt || !(tgt->flags & TGT_ALIVE))
- continue;
-
- tgt->flags &= ~(TGT_DID_SYNCH|TGT_DISCONNECTED);
-#if 0
- /* the standard does *not* imply this gets reset too */
- tgt->sync_period = 0;
- tgt->sync_offset = 0;
-#endif
-
- /*
- * retry the synch negotiation
- */
- ior = tgt->ior;
- tgt->ior = 0;
- printf(".. tgt %d ", tgt->target_id);
- if (BGET(scsi_no_synchronous_xfer,(unsigned char)sc->masterno,tgt->target_id))
- tgt->flags |= TGT_DID_SYNCH;
- else {
- s = spl0();
- scsi_test_unit_ready(tgt, 0);
- splx(s);
- }
- tgt->ior = ior;
- }
-
- /*
- * Notify each target of the accident
- */
- for (i = 0; i < 8; i++) {
- if (i == sc->initiator_id)
- continue;
- tgt = sc->target[i];
- if (!tgt)
- continue;
- tgt->done = SCSI_RET_ABORTED|SCSI_RET_RETRY;
- if (tgt->ior)
- (*tgt->dev_ops->restart)( tgt, TRUE);
- }
-
- printf("%s", " reset complete\n");
-}
-
-#endif NSCSI > 0
diff --git a/scsi/scsi.h b/scsi/scsi.h
deleted file mode 100644
index 9aa0bee..0000000
--- a/scsi/scsi.h
+++ /dev/null
@@ -1,599 +0,0 @@
-/*
- * Mach Operating System
- * Copyright (c) 1991,1990 Carnegie Mellon University
- * All Rights Reserved.
- *
- * Permission to use, copy, modify and distribute this software and its
- * documentation is hereby granted, provided that both the copyright
- * notice and this permission notice appear in all copies of the
- * software, derivative works or modified versions, and any portions
- * thereof, and that both notices appear in supporting documentation.
- *
- * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
- * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
- * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
- *
- * Carnegie Mellon requests users of this software to return to
- *
- * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
- * School of Computer Science
- * Carnegie Mellon University
- * Pittsburgh PA 15213-3890
- *
- * any improvements or extensions that they make and grant Carnegie Mellon
- * the rights to redistribute these changes.
- */
-/*
- * File: scsi.h
- * Author: Alessandro Forin, Carnegie Mellon University
- * Date: 9/90
- *
- * Definitions of the SCSI-1 Standard
- */
-
-#ifndef _SCSI_SCSI_H_
-#define _SCSI_SCSI_H_
-
-#include <nscsi.h>
-#include <scsi/scsi_endian.h>
-
-/*
- * Bus phases
- */
-
-#define SCSI_IO 0x01 /* Input/Output */
-#define SCSI_CD 0x02 /* Command/Data */
-#define SCSI_MSG 0x04 /* Message */
-
-#define SCSI_PHASE_MASK 0x07
-#define SCSI_PHASE(x) ((x)&SCSI_PHASE_MASK)
-
-#define SCSI_PHASE_DATAO 0x00 /* 0 */
-#define SCSI_PHASE_DATAI SCSI_IO /* 1 */
-#define SCSI_PHASE_CMD SCSI_CD /* 2 */
-#define SCSI_PHASE_STATUS (SCSI_CD|SCSI_IO) /* 3 */
- /* 4..5 ANSI reserved */
-#define SCSI_PHASE_MSG_OUT (SCSI_MSG|SCSI_CD) /* 6 */
-#define SCSI_PHASE_MSG_IN (SCSI_MSG|SCSI_CD|SCSI_IO) /* 7 */
-
-/*
- * Single byte messages
- *
- * originator: I-nitiator T-arget
- * T-support: M-andatory O-ptional
- */
-
-#define SCSI_COMMAND_COMPLETE 0x00 /* M T */
-#define SCSI_EXTENDED_MESSAGE 0x01 /* IT */
-#define SCSI_SAVE_DATA_POINTER 0x02 /* O T */
-#define SCSI_RESTORE_POINTERS 0x03 /* O T */
-#define SCSI_DISCONNECT 0x04 /* O T */
-#define SCSI_I_DETECTED_ERROR 0x05 /* M I */
-#define SCSI_ABORT 0x06 /* M I */
-#define SCSI_MESSAGE_REJECT 0x07 /* M IT */
-#define SCSI_NOP 0x08 /* M I */
-#define SCSI_MSG_PARITY_ERROR 0x09 /* M I */
-#define SCSI_LNKD_CMD_COMPLETE 0x0a /* O T */
-#define SCSI_LNKD_CMD_COMPLETE_F 0x0b /* O T */
-#define SCSI_BUS_DEVICE_RESET 0x0c /* M I */
- /* 0x0d..0x11 scsi2 */
- /* 0x12..0x1f reserved */
-#define SCSI_IDENTIFY 0x80 /* IT */
-# define SCSI_IFY_ENABLE_DISCONNECT 0x40 /* I */
-# define SCSI_IFY_LUNTAR 0x20 /* IT */
-# define SCSI_IFY_LUN_MASK 0x07 /* IT */
-
-
-/* Message codes 0x30..0x7f are reserved */
-
-/*
- * Extended messages, codes and formats
- */
-
-#define SCSI_MODIFY_DATA_PTR 0x00 /* T */
-typedef struct {
- unsigned char xtn_msg_tag; /* const 0x01 */
- unsigned char xtn_msg_len; /* const 0x05 */
- unsigned char xtn_msg_code; /* const 0x00 */
- unsigned char xtn_msg_arg_1000; /* MSB, signed 2cmpl */
- unsigned char xtn_msg_arg_0200;
- unsigned char xtn_msg_arg_0030;
- unsigned char xtn_msg_arg_0004; /* LSB */
-} scsi_mod_ptr_t;
-
-#define SCSI_SYNC_XFER_REQUEST 0x01 /* IT */
-typedef struct {
- unsigned char xtn_msg_tag; /* const 0x01 */
- unsigned char xtn_msg_len; /* const 0x03 */
- unsigned char xtn_msg_code; /* const 0x01 */
- unsigned char xtn_msg_xfer_period; /* times 4nsecs */
- unsigned char xtn_msg_xfer_offset; /* pending ack window */
-#define SCSI_SYNCH_XFER_OFFANY 0xff /* T unlimited */
-} scsi_synch_xfer_req_t;
-
-#define SCSI_XTN_IDENTIFY 0x02 /* IT -2 */
-typedef struct {
- unsigned char xtn_msg_tag; /* const 0x01 */
- unsigned char xtn_msg_len; /* const 0x02 */
- unsigned char xtn_msg_code; /* const 0x02 */
- unsigned char xtn_msg_sublun;
-} scsi_xtn_identify_t;
-
- /* 0x03..0x7f reserved */
-
-#define SCSI_XTN_VENDOR_UQE 0x80 /* vendor unique bit */
-typedef struct {
- unsigned char xtn_msg_tag; /* const 0x01 */
- unsigned char xtn_msg_len; /* args' len+1 (0-->256)*/
- unsigned char xtn_msg_code; /* const 0x80..0xff */
- unsigned char xtn_msg_args[1]; /* 0..255 bytes */
-} scsi_xtn_vedor_unique_t;
-
-
-/*
- * Commands, generic structures
- */
-
-/* SIX byte commands */
-typedef struct {
- unsigned char scsi_cmd_code; /* group(7..5) and command(4..1) */
-#define SCSI_CODE_GROUP 0xe0
-#define SCSI_CODE_CMD 0x1f
- unsigned char scsi_cmd_lun_and_lba1; /* lun(7..5) and block# msb[20..16] */
-#define SCSI_LUN_MASK 0xe0
-#define SCSI_LBA_MASK 0x1f
-#define SCSI_LUN_SHIFT 5
- unsigned char scsi_cmd_lba2; /* block#[15.. 8] */
- unsigned char scsi_cmd_lba3; /* block#[ 7.. 0] */
- unsigned char scsi_cmd_xfer_len; /* if required */
- unsigned char scsi_cmd_ctrl_byte; /* contains: */
-#define SCSI_CTRL_VUQ 0xc0 /* vendor unique bits */
-#define SCSI_CTRL_RESVD 0x3c /* reserved, mbz */
-#define SCSI_CTRL_FLAG 0x02 /* send a complete_with_flag at end */
-#define SCSI_CTRL_LINK 0x01 /* link this command with next */
-} scsi_command_group_0;
-
-/* TEN byte commands */
-typedef struct {
- unsigned char scsi_cmd_code; /* group(7..5) and command(4..1) */
- unsigned char scsi_cmd_lun_and_relbit;/* lun(7..5) and RelAdr(0) */
-#define SCSI_RELADR 0x01
- unsigned char scsi_cmd_lba1; /* block#[31..24] */
- unsigned char scsi_cmd_lba2; /* block#[23..16] */
- unsigned char scsi_cmd_lba3; /* block#[15.. 8] */
- unsigned char scsi_cmd_lba4; /* block#[ 7.. 0] */
- unsigned char scsi_cmd_xxx; /* reserved, mbz */
- unsigned char scsi_cmd_xfer_len_1; /* if required */
- unsigned char scsi_cmd_xfer_len_2; /* if required */
- unsigned char scsi_cmd_ctrl_byte; /* see above */
-} scsi_command_group_1,
- scsi_command_group_2;
-
-/* TWELVE byte commands */
-typedef struct {
- unsigned char scsi_cmd_code; /* group(7..5) and command(4..1) */
- unsigned char scsi_cmd_lun_and_relbit;/* lun(7..5) and RelAdr(0) */
- unsigned char scsi_cmd_lba1; /* block#[31..24] */
- unsigned char scsi_cmd_lba2; /* block#[23..16] */
- unsigned char scsi_cmd_lba3; /* block#[15.. 8] */
- unsigned char scsi_cmd_lba4; /* block#[ 7.. 0] */
- unsigned char scsi_cmd_xfer_len_1; /* if required */
- unsigned char scsi_cmd_xfer_len_2; /* if required */
- unsigned char scsi_cmd_xfer_len_3; /* if required */
- unsigned char scsi_cmd_xfer_len_4; /* if required */
- unsigned char scsi_cmd_xxx1; /* reserved, mbz */
- unsigned char scsi_cmd_ctrl_byte; /* see above */
-} scsi_command_group_5;
-
-
-/*
- * Commands, codes and aliases
- */
-
- /* GROUP 0 */
-#define SCSI_CMD_TEST_UNIT_READY 0x00 /* O all 2M all */
-#define scsi_cmd_test_unit_ready_t scsi_command_group_0
-
-#define SCSI_CMD_REZERO_UNIT 0x01 /* O disk worm rom */
-#define SCSI_CMD_REWIND 0x01 /* M tape */
-#define scsi_cmd_rewind_t scsi_command_group_0
-#define scsi_cmd_rezero_t scsi_command_group_0
-# define SCSI_CMD_REW_IMMED 0x01
-
- /* 0x02 vendor unique */
-
-#define SCSI_CMD_REQUEST_SENSE 0x03 /* M all */
-#define scsi_cmd_request_sense_t scsi_command_group_0
-# define scsi_cmd_allocation_length scsi_cmd_xfer_len
-
-#define SCSI_CMD_FORMAT_UNIT 0x04 /* M disk O prin */
-#define scsi_cmd_format_t scsi_command_group_0
-# define SCSI_CMD_FMT_FMTDATA 0x10
-# define SCSI_CMD_FMT_CMPLIST 0x08
-# define SCSI_CMD_FMT_LIST_TYPE 0x07
-# define scsi_cmd_intleave1 scsi_cmd_lba3
-# define scsi_cmd_intleave2 scsi_cmd_xfer_len
-
-#define SCSI_CMD_READ_BLOCK_LIMITS 0x05 /* E tape */
-#define scsi_cmd_block_limits_t scsi_command_group_0
-
- /* 0x06 vendor unique */
-
-#define SCSI_CMD_REASSIGN_BLOCKS 0x07 /* O disk worm */
-#define scsi_cmd_reassign_blocks_t scsi_command_group_0
-
-#define SCSI_CMD_READ 0x08 /* M disk tape O worm rom */
-#define SCSI_CMD_RECEIVE 0x08 /* O proc */
-#define SCSI_CMD_GET_MESSAGE 0x08 /* M comm */
-#define scsi_cmd_read_t scsi_command_group_0
-# define SCSI_CMD_TP_FIXED 0x01 /* tape */
-# define scsi_cmd_tp_len1 scsi_cmd_lba2
-# define scsi_cmd_tp_len2 scsi_cmd_lba3
-# define scsi_cmd_tp_len3 scsi_cmd_xfer_len
- /* largest addressable blockno */
-#define SCSI_CMD_READ_MAX_LBA ((1 << 21) - 1)
-
- /* 0x09 vendor unique */
-
-#define SCSI_CMD_WRITE 0x0a /* M disk tape O worm */
-#define SCSI_CMD_PRINT 0x0a /* M prin */
-#define SCSI_CMD_SEND 0x0a /* M proc */
-#define SCSI_CMD_SEND_MESSAGE 0x0a /* M comm */
-#define scsi_cmd_write_t scsi_command_group_0
-
-#define SCSI_CMD_SEEK 0x0b /* O disk worm rom */
-#define SCSI_CMD_TRACK_SELECT 0x0b /* O tape */
-#define SCSI_CMD_SLEW_AND_PRINT 0x0b /* O prin */
-#define scsi_cmd_seek_t scsi_command_group_0
-# define SCSI_CMD_SLW_CHANNEL 0x01
-# define scsi_cmd_tp_trackno scsi_cmd_xfer_len
-# define scsi_cmd_slew_value scsi_cmd_lba2
-
- /* 0x0c..0x0e vendor unique */
-
-#define SCSI_CMD_READ_REVERSE 0x0f /* O tape */
-#define scsi_cmd_rev_read_t scsi_command_group_0
-
-#define SCSI_CMD_WRITE_FILEMARKS 0x10 /* M tape */
-#define SCSI_CMD_FLUSH_BUFFER 0x10 /* M prin */
-#define scsi_cmd_write_fil_t scsi_command_group_0
-
-#define SCSI_CMD_SPACE 0x11 /* O tape */
-#define scsi_cmd_space_t scsi_command_group_0
-# define SCSI_CMD_SP_BLOCKS 0x00
-# define SCSI_CMD_SP_FIL 0x01
-# define SCSI_CMD_SP_SEQ_FIL 0x02
-# define SCSI_CMD_SP_EOT 0x03
-
-#define SCSI_CMD_INQUIRY 0x12 /* E all (2M all) */
-#define scsi_cmd_inquiry_t scsi_command_group_0
-# define SCSI_CMD_INQ_EVPD 0x01 /* 2 */
-# define scsi_cmd_page_code scsi_cmd_lba2 /* 2 */
-
-#define SCSI_CMD_VERIFY_0 0x13 /* O tape */
-#define scsi_cmd_verify_t scsi_command_group_0
-# define SCSI_CMD_VFY_BYTCMP 0x02
-
-#define SCSI_CMD_RECOVER_BUFFERED_DATA 0x14 /* O tape prin */
-#define scsi_cmd_recover_buffer_t scsi_command_group_0
-
-#define SCSI_CMD_MODE_SELECT 0x15 /* O disk tape prin worm rom */
-# define SCSI_CMD_MSL_PF 0x10
-# define SCSI_CMD_MSL_SP 0x01
-#define scsi_cmd_mode_select_t scsi_command_group_0
-
-#define SCSI_CMD_RESERVE 0x16 /* O disk tape prin worm rom */
-#define scsi_cmd_reserve_t scsi_command_group_0
-# define SCSI_CMD_RES_3RDPTY 0x10
-# define SCSI_CMD_RES_3RDPTY_DEV 0x0e
-# define SCSI_CMD_RES_EXTENT 0x01
-# define scsi_cmd_reserve_id scsi_cmd_lba2
-# define scsi_cmd_extent_llen1 scsi_cmd_lba3
-# define scsi_cmd_extent_llen2 scsi_cmd_xfer_len
-
-#define SCSI_CMD_RELEASE 0x17 /* O disk tape prin worm rom */
-#define scsi_cmd_release_t scsi_command_group_0
-
-#define SCSI_CMD_COPY 0x18 /* O all */
-#define scsi_cmd_copy_t scsi_command_group_0
-# define SCSI_CMD_CPY_PAD 0x01 /* 2 */
-# define scsi_cmd_paraml_len0 scsi_cmd_lba2
-# define scsi_cmd_paraml_len1 scsi_cmd_lba3
-# define scsi_cmd_paraml_len2 scsi_cmd_xfer_len
-
-#define SCSI_CMD_ERASE 0x19 /* O tape */
-#define scsi_cmd_erase_t scsi_command_group_0
-# define SCSI_CMD_ER_LONG 0x01
-
-#define SCSI_CMD_MODE_SENSE 0x1a /* O disk tape prin worm rom */
-#define scsi_cmd_mode_sense_t scsi_command_group_0
-# define scsi_cmd_ms_pagecode scsi_cmd_lba2
-
-#define SCSI_CMD_START_STOP_UNIT 0x1b /* O disk prin worm rom */
-#define SCSI_CMD_LOAD_UNLOAD 0x1b /* O tape */
-#define scsi_cmd_start_t scsi_command_group_0
-# define SCSI_CMD_SS_IMMED 0x01
-# define scsi_cmd_ss_flags scsi_cmd_xfer_len
-# define SCSI_CMD_SS_START 0x01
-# define SCSI_CMD_SS_RETEN 0x02
-# define SCSI_CMD_SS_RETAIN 0x01
-# define SCSI_CMD_SS_EJECT 0x02
-
-#define SCSI_CMD_RECEIVE_DIAG_RESULTS 0x1c /* O all */
-#define scsi_cmd_receive_diag_t scsi_command_group_0
-# define scsi_cmd_allocation_length1 scsi_cmd_lba3
-# define scsi_cmd_allocation_length2 scsi_cmd_xfer_len
-
-#define SCSI_CMD_SEND_DIAGNOSTICS 0x1d /* O all */
-#define scsi_cmd_send_diag_t scsi_command_group_0
-# define SCSI_CMD_DIAG_SELFTEST 0x04
-# define SCSI_CMD_DIAG_DEVOFFL 0x02
-# define SCSI_CMD_DIAG_UNITOFFL 0x01
-
-#define SCSI_CMD_PREVENT_ALLOW_REMOVAL 0x1e /* O disk tape worm rom */
-#define scsi_cmd_medium_removal_t scsi_command_group_0
-# define scsi_cmd_pa_prevent scsi_cmd_xfer_len /* 0x1 */
-
- /* 0x1f reserved */
-
- /* GROUP 1 */
- /* 0x20..0x24 vendor unique */
-
-#define SCSI_CMD_READ_CAPACITY 0x25 /* E disk worm rom */
-#define scsi_cmd_read_capacity_t scsi_command_group_1
-# define scsi_cmd_rcap_flags scsi_cmd_xfer_len_2
-# define SCSI_CMD_RCAP_PMI 0x01
-
- /* 0x26..0x27 vendor unique */
-
-#define SCSI_CMD_LONG_READ 0x28 /* E disk M worm rom */
-#define scsi_cmd_long_read_t scsi_command_group_1
-
- /* 0x29 vendor unique */
-
-#define SCSI_CMD_LONG_WRITE 0x2a /* E disk M worm */
-#define scsi_cmd_long_write_t scsi_command_group_1
-
-#define SCSI_CMD_LONG_SEEK 0x2b /* O disk worm rom */
-#define scsi_cmd_long_seek_t scsi_command_group_1
-
- /* 0x2c..0x2d vendor unique */
-
-#define SCSI_CMD_WRITE_AND_VERIFY 0x2e /* O disk worm */
-#define scsi_cmd_write_vfy_t scsi_command_group_1
-# define SCSI_CMD_VFY_BYTCHK 0x02
-
-#define SCSI_CMD_VERIFY_1 0x2f /* O disk worm rom */
-#define scsi_cmd_verify_long_t scsi_command_group_1
-# define SCSI_CMD_VFY_BLKVFY 0x04
-
-#define SCSI_CMD_SEARCH_HIGH 0x30 /* O disk worm rom */
-#define scsi_cmd_search_t scsi_command_group_1
-# define SCSI_CMD_SRCH_INVERT 0x10
-# define SCSI_CMD_SRCH_SPNDAT 0x02
-
-#define SCSI_CMD_SEARCH_EQUAL 0x31 /* O disk worm rom */
-#define SCSI_CMD_SEARCH_LOW 0x32 /* O disk worm rom */
-
-#define SCSI_CMD_SET_LIMITS 0x33 /* O disk worm rom */
-#define scsi_cmd_set_limits_t scsi_command_group_1
-# define SCSI_CMD_SL_RDINH 0x02
-# define SCSI_CMD_SL_WRINH 0x01
-
- /* 0x34..0x38 reserved */
-
-#define SCSI_CMD_COMPARE 0x39 /* O all */
-#define scsi_cmd_compare_t scsi_command_group_1
-# define scsi_cmd_1_paraml1 scsi_cmd_lba2
-# define scsi_cmd_1_paraml2 scsi_cmd_lba3
-# define scsi_cmd_1_paraml3 scsi_cmd_lba4
-
-#define SCSI_CMD_COPY_AND_VERIFY 0x3a /* O all */
-#define scsi_cmd_copy_vfy_t scsi_command_group_1
-# define SCSI_CMD_CPY_BYTCHK 0x02
-
- /* 0x3b..0x3f reserved */
-
- /* GROUP 2 */
- /* 0x40..0x5f reserved */
-
- /* GROUP 3 */
- /* 0x60..0x7f reserved */
-
- /* GROUP 4 */
- /* 0x80..0x9f reserved */
-
- /* GROUP 5 */
- /* 0xa0..0xaf vendor unique */
- /* 0xb0..0xbf reserved */
-
- /* GROUP 6 */
- /* 0xc0..0xdf vendor unique */
-
- /* GROUP 7 */
- /* 0xe0..0xff vendor unique */
-
-
-/*
- * Command-specific results and definitions
- */
-
-/* inquiry data */
-typedef struct {
- unsigned char periph_type;
-#define SCSI_DISK 0x00
-#define SCSI_TAPE 0x01
-#define SCSI_PRINTER 0x02
-#define SCSI_CPU 0x03
-#define SCSI_WORM 0x04
-#define SCSI_CDROM 0x05
-
- BITFIELD_2( unsigned char,
- device_type : 7,
- rmb : 1);
- BITFIELD_3( unsigned char,
- ansi : 3,
- ecma : 3,
- iso : 2);
- unsigned char reserved;
- unsigned char length;
- unsigned char param[1];
-} scsi_inquiry_data_t;
-
-#define SCSI_INQ_STD_DATA -1
-
-/* request sense data */
-#define SCSI_SNS_NOSENSE 0x0
-#define SCSI_SNS_RECOVERED 0x1
-#define SCSI_SNS_NOTREADY 0x2
-#define SCSI_SNS_MEDIUM_ERR 0x3
-#define SCSI_SNS_HW_ERR 0x4
-#define SCSI_SNS_ILLEGAL_REQ 0x5
-#define SCSI_SNS_UNIT_ATN 0x6
-#define SCSI_SNS_PROTECT 0x7
-#define SCSI_SNS_BLANK_CHK 0x8
-#define SCSI_SNS_VUQE 0x9
-#define SCSI_SNS_COPY_ABRT 0xa
-#define SCSI_SNS_ABORTED 0xb
-#define SCSI_SNS_EQUAL 0xc
-#define SCSI_SNS_VOLUME_OVFL 0xd
-#define SCSI_SNS_MISCOMPARE 0xe
-#define SCSI_SNS_RESERVED 0xf
-
-typedef struct {
- BITFIELD_3( unsigned char,
- error_code : 4,
- error_class : 3,
- addr_valid : 1);
-# define SCSI_SNS_XTENDED_SENSE_DATA 0x7 /* e.g. error_class=7 */
- union {
- struct {
- BITFIELD_2(unsigned char,
- lba_msb : 5,
- vuqe : 3);
- unsigned char lba;
- unsigned char lba_lsb;
- } non_xtnded;
- struct {
- unsigned char segment_number;
- BITFIELD_5(unsigned char,
- sense_key : 4,
- res : 1,
- ili : 1,
- eom : 1,
- fm : 1);
- unsigned char info0;
- unsigned char info1;
- unsigned char info2;
- unsigned char info3;
- unsigned char add_len;
- unsigned char add_bytes[1];/* VARSIZE */
- } xtended;
- } u;
-} scsi_sense_data_t;
-
-
-/* mode select params */
-typedef struct {
- unsigned char reserved1;
- unsigned char medium_type;
- BITFIELD_3(unsigned char,
- speed:4, /* special for tapes, reserved in SCSI-1 */
- buffer_mode:3,
- reserved2:1);
- unsigned char desc_len;
- struct scsi_mode_parm_blockdesc {
- unsigned char density_code;
- unsigned char nblocks1;
- unsigned char nblocks2;
- unsigned char nblocks3;
- unsigned char reserved;
- unsigned char reclen1;
- unsigned char reclen2;
- unsigned char reclen3;
- } descs[1]; /* VARSIZE, really */
-} scsi_mode_select_param_t;
-
-/* mode sense data (TAPE) */
-typedef struct {
- unsigned char data_len;
- unsigned char medium_type;
- BITFIELD_3(unsigned char,
- speed : 4,
- buffered_mode : 3,
- wp : 1);
- unsigned char bdesc_len;
- struct {
- unsigned char density_code;
- unsigned char no_blks_msb;
- unsigned char no_blks;
- unsigned char no_blks_lsb;
- unsigned char reserved;
- unsigned char blen_msb;
- unsigned char blen;
- unsigned char blen_lsb;
- } bdesc[1]; /* VARSIZE */
- /* vuqe data might follow */
-} scsi_mode_sense_data_t;
-
-/* read capacity data */
-typedef struct {
- unsigned char lba1;
- unsigned char lba2;
- unsigned char lba3;
- unsigned char lba4;
- unsigned char blen1;
- unsigned char blen2;
- unsigned char blen3;
- unsigned char blen4;
-} scsi_rcap_data_t;
-
-/* defect list(s) */
-typedef struct {
- unsigned char res1;
- unsigned char res2;
- unsigned char list_len_msb;
- unsigned char list_len_lsb;
- struct {
- unsigned char blockno_msb;
- unsigned char blockno_sb1;
- unsigned char blockno_sb2;
- unsigned char blockno_lsb;
- } defects[1]; /* VARSIZE */
-} scsi_Ldefect_data_t;
-
-/* block limits (tape) */
-typedef struct {
- unsigned char res1;
- unsigned char maxlen_msb;
- unsigned char maxlen_sb;
- unsigned char maxlen_lsb;
- unsigned char minlen_msb;
- unsigned char minlen_lsb;
-} scsi_blimits_data_t;
-
-/*
- * Status byte (a-la scsi1)
- */
-
-typedef union {
- struct {
- BITFIELD_4( unsigned char,
- scsi_status_vendor_uqe1:1,
- scsi_status_code:4,
- scsi_status_vendor_uqe:2,
- scsi_status_reserved:1);
-# define SCSI_ST_GOOD 0x00 /* scsi_status_code values */
-# define SCSI_ST_CHECK_CONDITION 0x01
-# define SCSI_ST_CONDITION_MET 0x02
-# define SCSI_ST_BUSY 0x04
-# define SCSI_ST_INT_GOOD 0x08
-# define SCSI_ST_INT_MET 0x0a
-# define SCSI_ST_RES_CONFLICT 0x0c
- /* anything else is reserved */
- } st;
- unsigned char bits;
-} scsi_status_byte_t;
-
-
-#endif _SCSI_SCSI_H_
diff --git a/scsi/scsi2.h b/scsi/scsi2.h
deleted file mode 100644
index 93a5a76..0000000
--- a/scsi/scsi2.h
+++ /dev/null
@@ -1,447 +0,0 @@
-/*
- * Mach Operating System
- * Copyright (c) 1991,1990 Carnegie Mellon University
- * All Rights Reserved.
- *
- * Permission to use, copy, modify and distribute this software and its
- * documentation is hereby granted, provided that both the copyright
- * notice and this permission notice appear in all copies of the
- * software, derivative works or modified versions, and any portions
- * thereof, and that both notices appear in supporting documentation.
- *
- * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
- * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
- * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
- *
- * Carnegie Mellon requests users of this software to return to
- *
- * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
- * School of Computer Science
- * Carnegie Mellon University
- * Pittsburgh PA 15213-3890
- *
- * any improvements or extensions that they make and grant Carnegie Mellon
- * the rights to redistribute these changes.
- */
-/*
- * File: scsi2.h
- * Author: Alessandro Forin, Carnegie Mellon University
- * Date: 9/90
- *
- * Additions and changes of the SCSI-II standard viz SCSI-I
- */
-
-#ifndef _SCSI_SCSI2_H_
-#define _SCSI_SCSI2_H_
-
-#include <scsi/scsi_endian.h>
-
-/*
- * Single byte messages
- *
- * originator: I-nitiator T-arget
- * T-support: M-andatory O-ptional
- */
-
-#define SCSI_ABORT_TAG 0x0d /* O I 2 */
-#define SCSI_CLEAR_QUEUE 0x0e /* O I 2 */
-#define SCSI_INITIATE_RECOVERY 0x0f /* O IT2 */
-#define SCSI_RELEASE_RECOVERY 0x10 /* O I 2 */
-#define SCSI_TERMINATE_IO_PROCESS 0x11 /* O I 2 */
-
-/*
- * Two byte messages
- */
-#define SCSI_SIMPLE_QUEUE_TAG 0x20 /* O IT2 */
-#define SCSI_HEADOF_QUEUE_TAG 0x21 /* O I 2 */
-#define SCSI_ORDERED_QUEUE_TAG 0x22 /* O I 2 */
-#define SCSI_IGNORE_WIDE_RESIDUE 0x23 /* O T2 */
- /* 0x24..0x2f reserved */
-
-/*
- * Extended messages, codes and formats
- */
-
-#define SCSI_WIDE_XFER_REQUEST 0x03 /* IT 2 */
-typedef struct {
- unsigned char xtn_msg_tag; /* const 0x01 */
- unsigned char xtn_msg_len; /* const 0x02 */
- unsigned char xtn_msg_code; /* const 0x03 */
- unsigned char xtn_msg_xfer_width;
-} scsi_wide_xfer_t;
-
-/*
- * NOTE: some command-specific mods and extensions
- * are actually defined in the scsi.h file for
- * readability reasons
- */
-
- /* GROUP 1 */
-
-#define SCSI_CMD_READ_DEFECT_DATA 0x37 /* O2 disk opti */
-typedef scsi_command_group_1 scsi_cmd_read_defect_t;
-# define SCSI_CMD_RDD_LIST_TYPE 0x07
-# define SCSI_CMD_RDD_GLIST 0x08
-# define SCSI_CMD_RDD_PLIST 0x10
-
-#define SCSI_CMD_WRITE_BUFFER 0x3b /* O2 all */
-typedef scsi_command_group_1 scsi_cmd_write_buffer_t;
-# define SCSI_CMD_BUF_MODE 0x07
-# define scsi_cmd_buf_id scs_cmd_lba1
-# define scsi_cmd_buf_offset1 scs_cmd_lba2
-# define scsi_cmd_buf_offset2 scs_cmd_lba3
-# define scsi_cmd_buf_offset3 scs_cmd_lba4
-# define scsi_cmd_buf_alloc1 scs_cmd_xxx
-# define scsi_cmd_buf_alloc2 scs_cmd_xfer_len_1
-# define scsi_cmd_buf_alloc3 scs_cmd_xfer_len_2
-
-#define SCSI_CMD_READ_BUFFER 0x3c /* O2 all */
-#define scsi_cmd_read_buffer_t scsi_command_group_1
-
- /* GROUP 2 */
-
-#define SCSI_CMD_CHANGE_DEFINITION 0x40 /* O2 all */
-#define scsi_cmd_change_def_t scsi_command_group_2
-# define scsi_cmd_chg_save scsi_cmd_lba1
-# define scsi_cmd_chg_definition scsi_cmd_lba2
-# define SCSI_CMD_CHG_CURRENT 0x00
-# define SCSI_CMD_CHG_SCSI_1 0x01
-# define SCSI_CMD_CHG_CCS 0x02
-# define SCSI_CMD_CHG_SCSI_2 0x03
-
- /* 0x41 reserved */
-
-#define SCSI_CMD_READ_SUBCH 0x42 /* O2 rom */
-#define scsi_cmd_read_subch_t scsi_command_group_2
-# define SCSI_CMD_CD_MSF 0x02
-# define SCSI_CMD_RS_SUBQ 0x40
-# define scsi_cmd_rs_format scsi_cmd_lba2
-# define SCSI_CMD_RS_FMT_SUBQ 0x00
-# define SCSI_CMD_RS_FMT_CURPOS 0x01
-# define SCSI_CMD_RS_FMT_CATALOG 0x02
-# define SCSI_CMD_RS_FMT_ISRC 0x03
-# define scsi_cmd_rs_trackno scsi_cmd_xxx
-
-
-#define SCSI_CMD_READ_TOC 0x43 /* O2 rom */
-#define scsi_cmd_read_toc_t scsi_command_group_2
-# define scsi_cmd_rtoc_startT scsi_cmd_xxx
-
-#define SCSI_CMD_READ_HEADER 0x44 /* O2 rom */
-#define scsi_cmd_read_header_t scsi_command_group_2
-
-#define SCSI_CMD_PLAY_AUDIO 0x45 /* O2 rom */
-#define scsi_cmd_play_audio_t scsi_command_group_2
-
-#define SCSI_CMD_PLAY_AUDIO_MSF 0x47 /* O2 rom */
-#define scsi_cmd_play_audio_msf_t scsi_command_group_2
-# define scsi_cmd_pamsf_startM scsi_cmd_lba2
-# define scsi_cmd_pamsf_startS scsi_cmd_lba3
-# define scsi_cmd_pamsf_startF scsi_cmd_lba4
-# define scsi_cmd_pamsf_endM scsi_cmd_xxx
-# define scsi_cmd_pamsf_endS scsi_cmd_xfer_len_1
-# define scsi_cmd_pamsf_endF scsi_cmd_xfer_len_2
-
-#define SCSI_CMD_PLAY_AUDIO_TI 0x48 /* O2 rom */
-#define scsi_cmd_play_audio_ti_t scsi_command_group_2
-# define scsi_cmd_pati_startT scsi_cmd_lba3
-# define scsi_cmd_pati_startI scsi_cmd_lba4
-# define scsi_cmd_pati_endT scsi_cmd_xfer_len_1
-# define scsi_cmd_pati_endI scsi_cmd_xfer_len_2
-
-#define SCSI_CMD_PLAY_AUDIO_TR 0x49 /* O2 rom */
-#define scsi_cmd_play_audio_tr_t scsi_command_group_2
-# define scsi_cmd_patr_startT scsi_cmd_xxx
-
-
-#define SCSI_CMD_PAUSE_RESUME 0x4b /* O2 rom */
-#define scsi_cmd_pausres_t scsi_command_group_2
-# define SCSI_CMD_PAUSRES_RESUME 0x01
-# define scsi_cmd_pausres_res scsi_cmd_xfer_len_2
-
-#define SCSI_CMD_LOG_SELECT 0x4c /* O2 all */
-#define scsi_cmd_logsel_t scsi_command_group_2
-# define SCSI_CMD_LOG_SP 0x01
-# define SCSI_CMD_LOG_PCR 0x02
-# define scsi_cmd_log_page_control scsi_cmd_lba1
-
-#define SCSI_CMD_LOG_SENSE 0x4d /* O2 all */
-#define scsi_cmd_logsense_t scsi_command_group_2
-# define SCSI_CMD_LOG_PPC 0x02
-# define scsi_cmd_log_page_code scsi_cmd_lba1
-# define scsi_cmd_log_param_ptr1 scsi_cmd_lba4
-# define scsi_cmd_log_param_ptr2 scsi_cmd_xxx
-
-
- /* 0x4e..0x54 reserved */
-
-#define SCSI_CMD_MODE_SELECT_2 0x55 /* Z2 */
-#define scsi_cmd_mode_select_long_t scsi_command_group_2
-# define SCSI_CMD_MSL2_PF 0x10
-# define SCSI_CMD_MSL2_SP 0x01
-
- /* 0x56..0x59 reserved */
-
-#define SCSI_CMD_MODE_SENSE_2 0x5a /* Z2 */
-#define scsi_cmd_mode_sense_long_t scsi_command_group_2
-# define SCSI_CMD_MSS2_DBD 0x08
-
- /* 0x5b..0x5f reserved */
-
- /* GROUP 5 */
-
-#define SCSI_CMD_PLAY_AUDIO_LONG 0xa5 /* O2 rom */
-#define scsi_cmd_play_audio_l_t scsi_command_group_5
-
-#define SCSI_CMD_PLAY_AUDIO_TR_LONG 0xa9 /* O2 rom */
-#define scsi_cmd_play_audio_tr_l_t scsi_command_group_5
-# define scsi_cmd_patrl_startT scsi_cmd_xxx1
-
-
-/*
- * Command specific defines
- */
-typedef struct {
- BITFIELD_2(unsigned char,
- periph_type : 5,
- periph_qual : 3);
-#define SCSI_SCANNER 0x06 /* periph_type values */
-#define SCSI_MEMORY 0x07
-#define SCSI_J_BOX 0x08
-#define SCSI_COMM 0x09
-#define SCSI_PREPRESS1 0x0a
-#define SCSI_PREPRESS2 0x0b
-
-#define SCSI_PERIPH_CONNECTED 0x00 /* periph_qual values */
-#define SCSI_PERIPH_DISCONN 0x20
-#define SCSI_PERIPH_NOTHERE 0x30
-
- BITFIELD_2(unsigned char,
- device_type : 7,
- rmb : 1);
-
- BITFIELD_3( unsigned char,
- ansi : 3,
- ecma : 3,
- iso : 2);
-
- BITFIELD_4( unsigned char,
- response_fmt : 4,
- res1 : 2,
- trmIOP : 1,
- aenc : 1);
- unsigned char length;
- unsigned char res2;
- unsigned char res3;
-
- BITFIELD_8(unsigned char,
- SftRe : 1,
- CmdQue : 1,
- res4 : 1,
- Linked : 1,
- Sync : 1,
- Wbus16 : 1,
- Wbus32 : 1,
- RelAdr : 1);
-
- unsigned char vendor_id[8];
- unsigned char product_id[16];
- unsigned char product_rev[4];
- unsigned char vendor_uqe[20];
- unsigned char reserved[40];
- unsigned char vendor_uqe1[1]; /* varsize */
-} scsi2_inquiry_data_t;
-#define SCSI_INQ_SUPP_PAGES 0x00
-#define SCSI_INQ_A_INFO 0x01 /* 0x01..0x1f, really */
-#define SCSI_INQ_SERIALNO 0x80
-#define SCSI_INQ_IMPL_OPDEF 0x81
-#define SCSI_INQ_A_IMPL_OPDEF 0x82
-
-/* mode_select */
-typedef struct {
- unsigned char data_len;
- unsigned char medium_type;
- unsigned char device_specific;
- unsigned char desc_len;
- /* block descriptors are optional, same struct as scsi1 */
- /* page info then follows, see individual pages */
-} scsi2_mode_param_t;
-
-/*
- * CDROM thingies
- */
-typedef union {
- struct {
- unsigned char xxx;
- unsigned char minute;
- unsigned char second;
- unsigned char frame;
- } msf;
- struct {
- unsigned char lba1;
- unsigned char lba2;
- unsigned char lba3;
- unsigned char lba4;
- } lba;
-} cdrom_addr_t;
-
-typedef struct {
- unsigned char len1; /* MSB */
- unsigned char len2; /* LSB */
- unsigned char first_track;
- unsigned char last_track;
- struct cdrom_toc_desc {
-
- unsigned char xxx;
-
- BITFIELD_2(unsigned char,
- control : 4,
- adr : 4);
-
- unsigned char trackno;
- unsigned char xxx1;
- cdrom_addr_t absolute_address;
- } descs[1]; /* varsize */
-} cdrom_toc_t;
-
-typedef struct {
- unsigned char xxx;
-
- unsigned char audio_status;
-#define SCSI_CDST_INVALID 0x00
-#define SCSI_CDST_PLAYING 0x11
-#define SCSI_CDST_PAUSED 0x12
-#define SCSI_CDST_COMPLETED 0x13
-#define SCSI_CDST_ERROR 0x14
-#define SCSI_CDST_NO_STATUS 0x15
-
- unsigned char len1;
- unsigned char len2;
- struct cdrom_chanQ {
- unsigned char format;
- BITFIELD_2(unsigned char,
- control : 4,
- adr : 4);
- unsigned char trackno;
- unsigned char indexno;
- cdrom_addr_t absolute_address;
- cdrom_addr_t relative_address;
- BITFIELD_2(unsigned char,
- xxx : 7,
- mcv : 1);
- unsigned char catalog[15];
- BITFIELD_2(unsigned char,
- xxx1 : 7,
- tcv : 1);
- unsigned char isrc[15];
- } subQ;
-} cdrom_chan_data_t;
-
-/* subsets */
-typedef struct {
- unsigned char xxx;
- unsigned char audio_status;
- unsigned char len1;
- unsigned char len2;
- struct {
- unsigned char format;
- BITFIELD_2(unsigned char,
- control : 4,
- adr : 4);
- unsigned char trackno;
- unsigned char indexno;
- cdrom_addr_t absolute_address;
- cdrom_addr_t relative_address;
- } subQ;
-} cdrom_chan_curpos_t;
-
-typedef struct {
- unsigned char xxx;
- unsigned char audio_status;
- unsigned char len1;
- unsigned char len2;
- struct {
- unsigned char format;
- unsigned char xxx1[3];
- BITFIELD_2(unsigned char,
- xxx : 7,
- mcv : 1);
- unsigned char catalog[15];
- } subQ;
-} cdrom_chan_catalog_t;
-
-typedef struct {
- unsigned char xxx;
- unsigned char audio_status;
- unsigned char len1;
- unsigned char len2;
- struct {
- unsigned char format;
- BITFIELD_2(unsigned char,
- control : 4,
- adr : 4);
- unsigned char trackno;
- unsigned char xxx0;
- BITFIELD_2(unsigned char,
- xxx1 : 7,
- tcv : 1);
- unsigned char isrc[15];
- } subQ;
-} cdrom_chan_isrc_t;
-
-/* Audio page */
-typedef struct {
- scsi_mode_sense_data_t h; /* includes bdescs */
- unsigned char page_code;
-#define SCSI_CD_AUDIO_PAGE 0x0e
- unsigned char page_len;
- BITFIELD_4(unsigned char,
- xxx1 : 1,
- sotc : 1,
- imm : 1,
- xxx2 : 5);
- unsigned char xxx3[2];
- BITFIELD_3(unsigned char,
- fmt : 4,
- xxx4 : 3,
- aprv : 1);
- unsigned char bps1;
- unsigned char bps2;
- BITFIELD_2(unsigned char,
- sel0 : 4,
- xxx5 : 4);
- unsigned char vol0;
- BITFIELD_2(unsigned char,
- sel1 : 4,
- xxx6 : 4);
- unsigned char vol1;
- BITFIELD_2(unsigned char,
- sel2 : 4,
- xxx7 : 4);
- unsigned char vol2;
- BITFIELD_2(unsigned char,
- sel3 : 4,
- xxx8 : 4);
- unsigned char vol3;
-} cdrom_audio_page_t;
-
-/*
- * Status byte (a-la scsi2)
- */
-
-typedef union {
- struct {
- BITFIELD_3( unsigned char,
- scsi_status_reserved1:1,
- scsi_status_code:5,
- scsi_status_reserved2:2);
- /* more scsi_status_code values */
- /* 00..0c as in SCSI-I */
-# define SCSI_ST2_CMD_TERMINATED 0x11 /* 2 */
-# define SCSI_ST2_QUEUE_FULL 0x14 /* 2 */
- /* anything else is reserved */
- } st;
- unsigned char bits;
-} scsi2_status_byte_t;
-
-#endif _SCSI_SCSI2_H_
diff --git a/scsi/scsi_alldevs.c b/scsi/scsi_alldevs.c
deleted file mode 100644
index 2c4f37e..0000000
--- a/scsi/scsi_alldevs.c
+++ /dev/null
@@ -1,858 +0,0 @@
-/*
- * Mach Operating System
- * Copyright (c) 1991,1990 Carnegie Mellon University
- * All Rights Reserved.
- *
- * Permission to use, copy, modify and distribute this software and its
- * documentation is hereby granted, provided that both the copyright
- * notice and this permission notice appear in all copies of the
- * software, derivative works or modified versions, and any portions
- * thereof, and that both notices appear in supporting documentation.
- *
- * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
- * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
- * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
- *
- * Carnegie Mellon requests users of this software to return to
- *
- * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
- * School of Computer Science
- * Carnegie Mellon University
- * Pittsburgh PA 15213-3890
- *
- * any improvements or extensions that they make and grant Carnegie Mellon
- * the rights to redistribute these changes.
- */
-/*
- * File: scsi_alldevs.c
- * Author: Alessandro Forin, Carnegie Mellon University
- * Date: 10/90
- *
- * Middle layer of the SCSI driver: SCSI protocol implementation
- * This file contains code for SCSI commands defined for all device types.
- */
-
-#include <mach/std_types.h>
-#include <sys/types.h>
-#include <scsi/compat_30.h>
-
-#include <scsi/scsi.h>
-#include <scsi/scsi2.h>
-#include <scsi/scsi_defs.h>
-
-#if (NSCSI > 0)
-
-void scsi_print_add_sense_keys(); /* forward */
-
-/*
- * Utilities
- */
-void scsi_go_and_wait(tgt, insize, outsize, ior)
- target_info_t *tgt;
- int insize, outsize;
- io_req_t ior;
-{
- register scsi_softc_t *sc = scsi_softc[(unsigned char)tgt->masterno];
-
- tgt->ior = ior;
-
- (*sc->go)(tgt, insize, outsize, ior==0);
-
- if (ior)
- iowait(ior);
- else
- while (tgt->done == SCSI_RET_IN_PROGRESS);
-}
-
-void scsi_go(tgt, insize, outsize, cmd_only)
- target_info_t *tgt;
- int insize, outsize, cmd_only;
-{
- register scsi_softc_t *sc = scsi_softc[(unsigned char)tgt->masterno];
-
- (*sc->go)(tgt, insize, outsize, cmd_only);
-}
-
-int sizeof_scsi_command(
- unsigned char cmd)
-{
- switch ((cmd & SCSI_CODE_GROUP) >> 5) {
- case 0: return sizeof(scsi_command_group_0);
- case 1: return sizeof(scsi_command_group_1);
- case 2: return sizeof(scsi_command_group_2);
- /* 3,4 reserved */
- case 5: return sizeof(scsi_command_group_5);
- /* 6,7 vendor specific (!!) */
- case 6: return sizeof(scsi_command_group_2);
- }
-}
-
-/*
- * INQUIRY (Almost mandatory)
- */
-int scsi_inquiry( tgt, pagecode)
- register target_info_t *tgt;
- int pagecode;
-{
- scsi_cmd_inquiry_t *cmd;
- boolean_t no_ify = TRUE;
-
-retry:
- cmd = (scsi_cmd_inquiry_t*) (tgt->cmd_ptr);
- cmd->scsi_cmd_code = SCSI_CMD_INQUIRY;
- cmd->scsi_cmd_lun_and_lba1 = 0;
- cmd->scsi_cmd_lba3 = 0;
- cmd->scsi_cmd_xfer_len = 0xff; /* max len always */
- cmd->scsi_cmd_ctrl_byte = 0; /* not linked */
-/*#ifdef SCSI2*/
- if (pagecode != SCSI_INQ_STD_DATA) {
- cmd->scsi_cmd_lun_and_lba1 |= SCSI_CMD_INQ_EVPD;
- cmd->scsi_cmd_page_code = pagecode;
- } else
-/*#endif SCSI2*/
- cmd->scsi_cmd_page_code = 0;
-
- tgt->cur_cmd = SCSI_CMD_INQUIRY;
-
- /*
- * Note: this is sent when we do not know much about the
- * target, so we might not put an identify message upfront
- */
- scsi_go(tgt, sizeof(*cmd), 0xff, no_ify);
-
- /*
- * This spin loop is because we are called at autoconf
- * time where we cannot thread_block(). Sigh.
- */
- while (tgt->done == SCSI_RET_IN_PROGRESS) ;
- if (tgt->done == SCSI_RET_RETRY) /* sync negotiation ? */
- goto retry;
- if ((tgt->done != SCSI_RET_SUCCESS) && no_ify) {
- no_ify = FALSE;
- goto retry;
- }
- return tgt->done;
-}
-
-void scsi_print_inquiry( inq, pagecode, result)
- scsi2_inquiry_data_t *inq;
- int pagecode;
- char *result;
-{
- static char *periph_names[10] = {
- "disk", "tape", "printer", "processor", "WORM-disk",
- "CD-ROM", "scanner", "memory", "jukebox", "communication"
- };
- static char *periph_state[4] = {
- "online", "offline", "?", "absent"
- };
-
- char dev[SCSI_TARGET_NAME_LEN], *devname;
- register int i, j = 0;
-
- if (pagecode != SCSI_INQ_STD_DATA)
- return;
-
- devname = result ? result : dev;
-
- if (!result) {
- printf("\n\t%s%s %s (%s %x)",
- (inq->rmb) ? "" : "non-", "removable SCSI",
- (inq->periph_type > 10) ?
- "?device?" : periph_names[inq->periph_type],
- periph_state[inq->periph_qual & 0x3],
- inq->device_type);
- printf("\n\t%s%s%s",
- inq->iso ? "ISO-compliant, " : "",
- inq->ecma ? "ECMA-compliant, " : "",
- inq->ansi ? "ANSI-compliant, " : "");
- if (inq->ansi)
- printf("%s%d, ", "SCSI-", inq->ansi);
- if (inq->response_fmt == 2)
- printf("%s%s%s%s%s%s%s%s%s%s%s", "Supports: ",
- inq->aenc ? "AENC, " : "",
- inq->trmIOP ? "TrmIOP, " : "",
- inq->RelAdr ? "RelAdr, " : "",
- inq->Wbus32 ? "32 bit xfers, " : "",
- inq->Wbus16 ? "16 bis xfers, " : "",
- inq->Sync ? "Sync xfers, " : "",
- inq->Linked ? "Linked cmds, " : "",
- inq->CmdQue ? "Tagged cmd queues, " : "",
- inq->SftRe ? "Soft" : "Hard", " RESET, ");
- }
-
- for (i = 0; i < 8; i++)
- if (inq->vendor_id[i] != ' ')
- devname[j++] = inq->vendor_id[i];
- devname[j++] = ' ';
- for (i = 0; i < 16; i++)
- if (inq->product_id[i] != ' ')
- devname[j++] = inq->product_id[i];
- devname[j++] = ' ';
- for (i = 0; i < 4; i++)
- if (inq->product_rev[i] != ' ')
- devname[j++] = inq->product_rev[i];
-#if unsafe
- devname[j++] = ' ';
- for (i = 0; i < 8; i++)
- if (inq->vendor_uqe[i] != ' ')
- devname[j++] = inq->vendor_uqe[i];
-#endif
- devname[j] = 0;
-
- if (!result)
- printf("(%s, %s%s)\n", devname, "SCSI ",
- (inq->periph_type > 10) ?
- "?device?" : periph_names[inq->periph_type]);
-}
-
-/*
- * REQUESTE SENSE (Mandatory, All)
- */
-
-int scsi_request_sense(tgt, ior, data)
- register target_info_t *tgt;
- io_req_t ior;
- char **data;
-{
- scsi_cmd_request_sense_t *cmd;
-
- cmd = (scsi_cmd_request_sense_t *) (tgt->cmd_ptr);
- cmd->scsi_cmd_code = SCSI_CMD_REQUEST_SENSE;
- cmd->scsi_cmd_lun_and_lba1 = 0;
- cmd->scsi_cmd_lba2 = 0;
- cmd->scsi_cmd_lba3 = 0;
- cmd->scsi_cmd_allocation_length = 0xff; /* max len always */
- cmd->scsi_cmd_ctrl_byte = 0; /* not linked */
-
- tgt->cur_cmd = SCSI_CMD_REQUEST_SENSE;
-
- if (ior==0)
- scsi_go_and_wait (tgt, sizeof(*cmd), 0xff, ior);
- else {
- scsi_go(tgt, sizeof(*cmd), 0xff, FALSE);
- return tgt->done;
- }
-
- if (data)
- *data = tgt->cmd_ptr;
-
- (void) scsi_check_sense_data(tgt, tgt->cmd_ptr);
-
- return tgt->done;
-}
-
-boolean_t
-scsi_check_sense_data(tgt, sns)
- register target_info_t *tgt;
- scsi_sense_data_t *sns;
-{
- unsigned char code;
-
- if (sns->error_class != SCSI_SNS_XTENDED_SENSE_DATA) {
- printf("Bad sense data, vuqe class x%x code x%x\n",
- sns->error_class, sns->error_code);
- return FALSE; /* and good luck */
- } else {
- code = sns->u.xtended.sense_key;
-
- switch (code) {
- case SCSI_SNS_NOSENSE:
- case SCSI_SNS_EQUAL:
- return TRUE;
- break;
- case SCSI_SNS_RECOVERED:
- scsi_error(tgt, SCSI_ERR_BAD | SCSI_ERR_SENSE,
- code, sns->u.xtended.add_bytes);
- return TRUE;
- break;
- case SCSI_SNS_UNIT_ATN:
- scsi_error(tgt, SCSI_ERR_SENSE,
- code, sns->u.xtended.add_bytes);
- return TRUE;
- break;
- case SCSI_SNS_NOTREADY:
- tgt->done = SCSI_RET_RETRY;
- return TRUE;
- case SCSI_SNS_ILLEGAL_REQ:
- if (tgt->flags & TGT_OPTIONAL_CMD)
- return TRUE;
- /* fall through */
- default:
-/* e.g.
- case SCSI_SNS_MEDIUM_ERR:
- case SCSI_SNS_HW_ERR:
- case SCSI_SNS_PROTECT:
- case SCSI_SNS_BLANK_CHK:
- case SCSI_SNS_VUQE:
- case SCSI_SNS_COPY_ABRT:
- case SCSI_SNS_ABORTED:
- case SCSI_SNS_VOLUME_OVFL:
- case SCSI_SNS_MISCOMPARE:
- case SCSI_SNS_RESERVED:
-*/
- scsi_error(tgt, SCSI_ERR_GRAVE|SCSI_ERR_SENSE,
- code, sns->u.xtended.add_bytes);
- return FALSE;
- break;
- }
- }
-}
-
-/*
- * START STOP UNIT (Optional, disk prin work rom tape[load/unload])
- */
-int scsi_start_unit( tgt, ss, ior)
- register target_info_t *tgt;
- int ss;
- io_req_t ior;
-{
- scsi_cmd_start_t *cmd;
-
- cmd = (scsi_cmd_start_t*) (tgt->cmd_ptr);
- cmd->scsi_cmd_code = SCSI_CMD_START_STOP_UNIT;
- cmd->scsi_cmd_lun_and_lba1 = SCSI_CMD_SS_IMMED;/* 0 won't work ? */
- cmd->scsi_cmd_lba2 = 0;
- cmd->scsi_cmd_lba3 = 0;
- cmd->scsi_cmd_ss_flags = ss;
- cmd->scsi_cmd_ctrl_byte = 0; /* not linked */
-
- tgt->cur_cmd = SCSI_CMD_START_STOP_UNIT;
-
- scsi_go_and_wait(tgt, sizeof(*cmd), 0, ior);
- return tgt->done;
-}
-
-/*
- * TEST UNIT READY (Optional, All)
- * Note: this is where we do the synch negotiation at autoconf
- */
-int scsi_test_unit_ready( tgt, ior)
- register target_info_t *tgt;
- io_req_t ior;
-{
- scsi_cmd_test_unit_ready_t *cmd;
-
- cmd = (scsi_cmd_test_unit_ready_t*) (tgt->cmd_ptr);
-
- cmd->scsi_cmd_code = SCSI_CMD_TEST_UNIT_READY;
- cmd->scsi_cmd_lun_and_lba1 = 0;
- cmd->scsi_cmd_lba2 = 0;
- cmd->scsi_cmd_lba3 = 0;
- cmd->scsi_cmd_ss_flags = 0;
- cmd->scsi_cmd_ctrl_byte = 0; /* not linked */
-
- tgt->cur_cmd = SCSI_CMD_TEST_UNIT_READY;
-
- scsi_go_and_wait(tgt, sizeof(*cmd), 0, ior);
-
- return tgt->done;
-}
-
-/*
- * RECEIVE DIAGNOSTIC RESULTS (Optional, All)
- */
-int scsi_receive_diag( tgt, result, result_len, ior)
- register target_info_t *tgt;
- char *result;
- int result_len;
- io_req_t ior;
-{
- scsi_cmd_receive_diag_t *cmd;
-
- cmd = (scsi_cmd_receive_diag_t*) (tgt->cmd_ptr);
- cmd->scsi_cmd_code = SCSI_CMD_RECEIVE_DIAG_RESULTS;
- cmd->scsi_cmd_lun_and_lba1 = 0;
- cmd->scsi_cmd_lba2 = 0;
- cmd->scsi_cmd_lba3 = result_len >> 8 & 0xff;
- cmd->scsi_cmd_xfer_len = result_len & 0xff;
- cmd->scsi_cmd_ctrl_byte = 0; /* not linked */
-
- tgt->cur_cmd = SCSI_CMD_RECEIVE_DIAG_RESULTS;
-
- scsi_go_and_wait(tgt, sizeof(*cmd), result_len, ior);
-
- bcopy(tgt->cmd_ptr, (char*)result, result_len);
-
- return tgt->done;
-}
-
-
-int scsi_mode_sense( tgt, pagecode, len, ior)
- register target_info_t *tgt;
- int pagecode;
- int len;
- io_req_t ior;
-{
- scsi_cmd_mode_sense_t *cmd;
-
- cmd = (scsi_cmd_mode_sense_t*) (tgt->cmd_ptr);
- cmd->scsi_cmd_code = SCSI_CMD_MODE_SENSE;
- cmd->scsi_cmd_lun_and_lba1 = 0;
- cmd->scsi_cmd_ms_pagecode = pagecode;
- cmd->scsi_cmd_lba3 = 0;
- cmd->scsi_cmd_xfer_len = len;
- cmd->scsi_cmd_ctrl_byte = 0; /* not linked */
-
- tgt->cur_cmd = SCSI_CMD_MODE_SENSE;
-
- scsi_go_and_wait(tgt, sizeof(*cmd), len, ior);
-
- return tgt->done;
-}
-
-#if 0 /* unused */
-
-/*
- * COPY (Optional, All)
- */
-void scsi_copy( tgt, params, params_len, ior)
- register target_info_t *tgt;
- char *params;
- io_req_t ior;
-{
- scsi_cmd_copy_t *cmd;
-
- cmd = (scsi_cmd_copy_t*) (tgt->cmd_ptr;
- cmd->scsi_cmd_code = SCSI_CMD_COPY;
- cmd->scsi_cmd_lun_and_lba1 = 0;
- cmd->scsi_cmd_lba2 = params_len>>16 & 0xff;
- cmd->scsi_cmd_lba3 = params_len >> 8 & 0xff;
- cmd->scsi_cmd_xfer_len = params_len & 0xff;
- cmd->scsi_cmd_ctrl_byte = 0; /* not linked */
-
- bcopy(params, cmd + 1, params_len);
-
- tgt->cur_cmd = SCSI_CMD_COPY;
-
- scsi_go_and_wait(tgt, sizeof(*cmd) + params_len, 0, ior);
-}
-
-/*
- * SEND DIAGNOSTIC (Optional, All)
- */
-void scsi_send_diag( tgt, flags, params, params_len, ior)
- register target_info_t *tgt;
- char *params;
- io_req_t ior;
-{
- scsi_cmd_send_diag_t *cmd;
-
- cmd = (scsi_cmd_send_diag_t*) (tgt->cmd_ptr);
- cmd->scsi_cmd_code = SCSI_CMD_SEND_DIAGNOSTICS;
- cmd->scsi_cmd_lun_and_lba1 = flags & 0x7;
- cmd->scsi_cmd_lba2 = 0;
- cmd->scsi_cmd_lba3 = params_len >> 8 & 0xff;
- cmd->scsi_cmd_xfer_len = params_len & 0xff;
- cmd->scsi_cmd_ctrl_byte = 0; /* not linked */
-
- bcopy(params, cmd + 1, params_len);
-
- tgt->cur_cmd = SCSI_CMD_SEND_DIAGNOSTICS;
-
- scsi_go_and_wait(tgt, sizeof(*cmd), 0, ior);
-}
-
-/*
- * COMPARE (Optional, All)
- */
-void scsi_compare( tgt, params, params_len, ior)
- register target_info_t *tgt;
- char *params;
- io_req_t ior;
-{
- scsi_cmd_compare_t *cmd;
-
- cmd = (scsi_cmd_compare_t*) (tgt->cmd_ptr);
- cmd->scsi_cmd_code = SCSI_CMD_COMPARE;
- cmd->scsi_cmd_lun_and_relbit = 0;
- cmd->scsi_cmd_lba1 = 0;
- cmd->scsi_cmd_1_paraml1 = params_len >> 16 & 0xff;
- cmd->scsi_cmd_1_paraml2 = params_len >> 8 & 0xff;
- cmd->scsi_cmd_1_paraml3 = params_len & 0xff;
- cmd->scsi_cmd_xxx = 0;
- cmd->scsi_cmd_xfer_len_1 = 0;
- cmd->scsi_cmd_xfer_len_2 = 0;
- cmd->scsi_cmd_ctrl_byte = 0; /* not linked */
-
- bcopy(params, cmd + 1, params_len);
-
- tgt->cur_cmd = SCSI_CMD_COMPARE;
-
- scsi_go_and_wait(tgt, sizeof(*cmd), 0, ior);
-}
-
-/*
- * COPY AND VERIFY (Optional, All)
- */
-void scsi_copy_and_verify( tgt, params, params_len, bytchk, ior)
- register target_info_t *tgt;
- char *params;
- io_req_t ior;
-{
- scsi_cmd_compare_t *cmd;
-
- cmd = (scsi_cmd_compare_t*) (tgt->cmd_ptr);
- cmd->scsi_cmd_code = SCSI_CMD_COMPARE;
- cmd->scsi_cmd_lun_and_relbit = bytchk ? SCSI_CMD_CPY_BYTCHK : 0;
- cmd->scsi_cmd_lba1 = 0;
- cmd->scsi_cmd_1_paraml1 = params_len >> 16 & 0xff;
- cmd->scsi_cmd_1_paraml2 = params_len >> 8 & 0xff;
- cmd->scsi_cmd_1_paraml3 = params_len & 0xff;
- cmd->scsi_cmd_xxx = 0;
- cmd->scsi_cmd_xfer_len_1 = 0;
- cmd->scsi_cmd_xfer_len_2 = 0;
- cmd->scsi_cmd_ctrl_byte = 0; /* not linked */
-
- bcopy(params, cmd + 1, params_len);
-
- tgt->cur_cmd = SCSI_CMD_COMPARE;
-
- scsi_go_and_wait(tgt, sizeof(*cmd), 0, ior);
-}
-
-#endif
-
-#ifdef SCSI2
-scsi_change_definition
-scsi_log_select
-scsi_log_sense
-scsi_long_mode_select
-scsi_read_buffer
-scsi_write_buffer
-#endif SCSI2
-
-/*
- * Warn user of some device error
- */
-int scsi_debug = 0;
-
-static char *sns_msg[SCSI_SNS_RESERVED+1] = {
- "No Sense Data",/* shouldn't happen */
- "Recovered",
- "Unit not ready",
- "Medium",
- "Hardware failure",
- "Illegal request",
- "Unit Attention Condition",
- "Protection",
- "Blank Check",
- "Vendor Unique",
- "Copy Operation Aborted",
- "Aborted Command",
- "Equal Comparison",
- "Volume Overflow",
- "Miscompare",
- "Reserved"
-};
-
-void
-scsi_error( tgt, code, info, addtl)
- target_info_t *tgt;
- unsigned code;
- unsigned info;
- char *addtl;
-{
- char unit;
- char *msg, *cmd;
- scsi2_status_byte_t status;
- if (scsi_debug)
- code |= SCSI_ERR_GRAVE;
-
- if (tgt)
- unit = tgt->unit_no + '0';
- else
- unit = '?';
-
-
- switch (SCSI_ERR_CLASS(code)) {
- case SCSI_ERR_STATUS:
- cmd = "Bad status return";
- status.bits = info;
- switch (status.st.scsi_status_code) {
- case SCSI_ST_GOOD:
- case SCSI_ST_CONDITION_MET:
- case SCSI_ST_INT_GOOD:
- case SCSI_ST_INT_MET:
- return; /* all is fine */
- case SCSI_ST_CHECK_CONDITION:
- msg = "Check condition"; break;
- case SCSI_ST_RES_CONFLICT:
- msg = "Reservation conflict"; break;
- case SCSI_ST_BUSY:
- msg = "Target busy"; break;
- case SCSI_ST2_QUEUE_FULL:
- msg = "Queue full"; break;
- case SCSI_ST2_CMD_TERMINATED:
- msg = "Command terminated"; break;
- default:
- msg = "Strange"; break;
- }
- break;
- case SCSI_ERR_SENSE:
- cmd = "Sensed a";
- msg = sns_msg[info & 0xf];
- break;
- case SCSI_ERR_MSEL:
- cmd = "Mode select broken"; msg = ""; break;
- default:
- cmd = "Generic"; msg = "";
- }
- if (SCSI_ERR_GRAVITY(code)) {
- printf("\n%s%c: %s %s %sx%x", "target ", unit, cmd, msg,
- "error, code ", info);
- if (addtl) {
- unsigned int add[3];
- bcopy(addtl, (char*)add, 3*sizeof(int));
- printf("%s x%x x%x x%x", ", additional info ",
- add[0], add[1], add[2]);
- }
- printf("\n");
- }
-}
-
-void scsi_print_sense_data(sns)
- scsi_sense_data_t *sns;
-{
- printf("Sense data: %s%s, segment %d",
- sns_msg[sns->u.xtended.sense_key], " error",
- sns->u.xtended.segment_number);
- if (sns->u.xtended.ili) printf(", IncorrectLengthIndicator");
- if (sns->u.xtended.eom) printf(", EndOfMedium");
- if (sns->u.xtended.fm) printf(", FileMark");
-
- if (sns->addr_valid) {
- unsigned int info;
- info = (sns->u.xtended.info0 << 24) |
- (sns->u.xtended.info1 << 16) |
- (sns->u.xtended.info2 << 8) |
- sns->u.xtended.info3;
- printf(", Info x%x", info);
- }
-
- if (sns->u.xtended.add_len > 6)
- scsi_print_add_sense_keys(sns->u.xtended.add_bytes[4],
- sns->u.xtended.add_bytes[5]);
-}
-
-/*
- * Table of the official SCSI-2 error messages
- * Last update:
- * X3T9.2/86-109, Revision 10c, March 9, 1990
- */
-static struct addtl_sns_keys_msg {
- unsigned char byte12;
- unsigned char byte13;
- char *means;
-} addtl_sns_msgs[] = {
- { 0x00, 0x00, "No additional sense information" },
- { 0x00, 0x01, "Filemark detected" },
- { 0x00, 0x02, "End-of-partition/medium detected" },
- { 0x00, 0x03, "Setmark detected" },
- { 0x00, 0x04, "Beginning of partition/medium detected" },
- { 0x00, 0x05, "End-of-data detected" },
- { 0x00, 0x06, "I/O process terminated" },
- { 0x00, 0x11, "Audio play operation in progress" },
- { 0x00, 0x12, "Audio play operation paused" },
- { 0x00, 0x13, "Audio play operation successfully completed" },
- { 0x00, 0x14, "Audio play operation stopped due to error" },
- { 0x00, 0x15, "No current audio status to return" },
- { 0x01, 0x00, "No index/sector signal" },
- { 0x02, 0x00, "No seek complete" },
- { 0x03, 0x00, "Peripheral device write fault" },
- { 0x03, 0x01, "No write current" },
- { 0x03, 0x02, "Excessive write errors" },
- { 0x04, 0x00, "Logical unit not ready, cause not reportable" },
- { 0x04, 0x01, "Logical unit is in process of becoming ready" },
- { 0x04, 0x02, "Logical unit not ready, initializing command required" },
- { 0x04, 0x03, "Logical unit not ready, manual intervention required" },
- { 0x04, 0x04, "Logical unit not ready, format in progress" },
- { 0x05, 0x00, "Logical unit does not respond to selection" },
- { 0x06, 0x00, "No reference position found" },
- { 0x07, 0x00, "Multiple peripheral devices selected" },
- { 0x08, 0x00, "Logical unit communication failure" },
- { 0x08, 0x01, "Logical unit communication time-out" },
- { 0x08, 0x02, "Logical unit communication parity error" },
- { 0x09, 0x00, "Track following error" },
- { 0x09, 0x01, "Tracking servo failure" },
- { 0x09, 0x02, "Focus servo failure" },
- { 0x09, 0x03, "Spindle servo failure" },
- { 0x0a, 0x00, "Error log overflow" },
- { 0x0c, 0x00, "Write error" },
- { 0x0c, 0x01, "Write error recovered with auto-reallocation" },
- { 0x0c, 0x02, "Write error - auto-reallocation failed" },
- { 0x10, 0x00, "Id CRC or ECC error" },
- { 0x10, 0x04, "Recovered data with LEC" },
- { 0x11, 0x00, "Unrecovered read error" },
- { 0x11, 0x01, "Read retries exhausted" },
- { 0x11, 0x02, "Error too long to correct" },
- { 0x11, 0x03, "Multiple read errors" },
- { 0x11, 0x04, "Unrecovered read error - auto-reallocate failed" },
- { 0x11, 0x05, "L-EC uncorrectable error" },
- { 0x11, 0x06, "CIRC unrecovered error" },
- { 0x11, 0x07, "Data resynchronization error" },
- { 0x11, 0x08, "Incomplete block read" },
- { 0x11, 0x09, "No gap found" },
- { 0x11, 0x0a, "Miscorrected error" },
- { 0x11, 0x0b, "Unrecovered read error - recommend reassignment" },
- { 0x11, 0x0c, "Unrecovered read error - recommend rewrite the data" },
- { 0x12, 0x00, "Address mark not found for id field" },
- { 0x13, 0x00, "Address mark not found for data field" },
- { 0x14, 0x00, "Recorded entity not found" },
- { 0x14, 0x01, "Record not found" },
- { 0x14, 0x02, "Filemark or setmark not found" },
- { 0x14, 0x03, "End-of-data not found" },
- { 0x14, 0x04, "Block sequence error" },
- { 0x15, 0x00, "Random positioning error" },
- { 0x15, 0x01, "Mechanical positioning error" },
- { 0x15, 0x02, "Positioning error detected by read of medium" },
- { 0x16, 0x00, "Data synchronization mark error" },
- { 0x17, 0x00, "Recovered data with no error correction applied" },
- { 0x17, 0x01, "Recovered data with retries" },
- { 0x17, 0x02, "Recovered data with positive head offset" },
- { 0x17, 0x03, "Recovered data with negative head offset" },
- { 0x17, 0x04, "Recovered data with retries and/or CIRC applied" },
- { 0x17, 0x05, "Recovered data using previous sector id" },
- { 0x17, 0x06, "Recovered data without ECC - data auto-reallocated" },
- { 0x17, 0x07, "Recovered data without ECC - recommend reassignment" },
- { 0x18, 0x00, "Recovered data with error correction applied" },
- { 0x18, 0x01, "Recovered data with error correction and retries applied" },
- { 0x18, 0x02, "Recovered data - data auto-reallocated" },
- { 0x18, 0x03, "Recovered data with CIRC" },
- { 0x18, 0x05, "Recovered data - recommended reassignment" },
- { 0x19, 0x00, "Defect list error" },
- { 0x19, 0x01, "Defect list not available" },
- { 0x19, 0x02, "Defect list error in primary list" },
- { 0x19, 0x03, "Defect list error in grown list" },
- { 0x1a, 0x00, "Parameter list length error" },
- { 0x1b, 0x00, "Synchronous data transfer error" },
- { 0x1c, 0x00, "Defect list not found" },
- { 0x1c, 0x01, "Primary defect list not found" },
- { 0x1c, 0x02, "Grown defect list not found" },
- { 0x1d, 0x00, "Miscompare during verify operation" },
- { 0x1e, 0x00, "Recovered id with ECC correction" },
- { 0x20, 0x00, "Invalid command operation code" },
- { 0x21, 0x00, "Logical block address out of range" },
- { 0x21, 0x01, "Invalid element address" },
- { 0x22, 0x00, "Illegal function" },
- { 0x24, 0x00, "Invalid field in CDB" },
- { 0x24, 0x02, "Log parameters changed" },
- { 0x25, 0x00, "Logical unit not supported" },
- { 0x26, 0x00, "Invalid field in parameter list" },
- { 0x26, 0x01, "Parameter not supported" },
- { 0x26, 0x02, "Parameter value invalid" },
- { 0x26, 0x03, "Threshold parameters not supported" },
- { 0x27, 0x00, "Write protected" },
- { 0x28, 0x00, "Not ready to ready transition (medium may have changed)" },
- { 0x28, 0x01, "Import or export element accessed" },
- { 0x29, 0x00, "Power on, reset, or bus device reset occurred" },
- { 0x2a, 0x00, "Parameters changed" },
- { 0x2a, 0x01, "Mode parameters changed" },
- { 0x2b, 0x00, "Copy cannot execute since host cannot disconnect" },
- { 0x2c, 0x00, "Command sequence error" },
- { 0x2c, 0x01, "Too many windows specified" },
- { 0x2c, 0x02, "Invalid combination of windows specified" },
- { 0x2d, 0x00, "Overwrite error on update in place" },
- { 0x2f, 0x00, "Commands cleared by another initiator" },
- { 0x30, 0x00, "Incompatible medium installed" },
- { 0x30, 0x01, "Cannot read medium - unknown format" },
- { 0x30, 0x02, "Cannot read medium - incompatible format" },
- { 0x30, 0x03, "Cleaning cartridge installed" },
- { 0x31, 0x00, "Medium format corrupted" },
- { 0x31, 0x01, "Format command failed" },
- { 0x32, 0x00, "No defect spare location available" },
- { 0x32, 0x01, "Defect list update failure" },
- { 0x33, 0x00, "Tape length error" },
- { 0x36, 0x00, "Ribbon, ink, or toner failure" },
- { 0x37, 0x00, "Rounded parameter" },
- { 0x39, 0x00, "Saving parameters not supported" },
- { 0x3a, 0x00, "Medium not present" },
- { 0x3b, 0x00, "Sequential positioning error" },
- { 0x3b, 0x01, "Tape position error at beginning of medium" },
- { 0x3b, 0x02, "Tape position error at end of medium" },
- { 0x3b, 0x03, "Tape or electronic vertical forms unit not ready" },
- { 0x3b, 0x04, "Slew failure" },
- { 0x3b, 0x05, "Paper jam" },
- { 0x3b, 0x06, "Failed to sense top-of-form" },
- { 0x3b, 0x07, "Failed to sense bottom-of-form" },
- { 0x3b, 0x08, "Reposition error" },
- { 0x3b, 0x09, "Read past end of medium" },
- { 0x3b, 0x0a, "Read past beginning of medium" },
- { 0x3b, 0x0b, "Position past end of medium" },
- { 0x3b, 0x0c, "Position past beginning of medium" },
- { 0x3b, 0x0d, "Medium destination element full" },
- { 0x3b, 0x0e, "Medium source element empty" },
- { 0x3d, 0x00, "Invalid bits in identify message" },
- { 0x3e, 0x00, "Logical unit has not self-configured yet" },
- { 0x3f, 0x00, "Target operating conditions have changed" },
- { 0x3f, 0x01, "Microcode has been changed" },
- { 0x3f, 0x02, "Changed operating definition" },
- { 0x3f, 0x03, "Inquiry data has changed" },
- { 0x40, 0x00, "RAM failure" },
- { 0x40, 0xff, "Diagnostic failure on component <NN>" },
- { 0x41, 0x00, "Data path failure" },
- { 0x42, 0x00, "Power on or self-test failure" },
- { 0x43, 0x00, "Message error" },
- { 0x44, 0x00, "Internal target failure" },
- { 0x45, 0x00, "Select or reselect failure" },
- { 0x46, 0x00, "Unsuccessful soft reset" },
- { 0x47, 0x00, "SCSI parity error" },
- { 0x48, 0x00, "Initiator detected message received" },
- { 0x49, 0x00, "Invalid message error" },
- { 0x4a, 0x00, "Command phase error" },
- { 0x4b, 0x00, "Data phase error" },
- { 0x4c, 0x00, "Logical unit failed self-configuration" },
- { 0x4e, 0x00, "Overlapped commands attempted" },
- { 0x50, 0x00, "Write append error" },
- { 0x50, 0x01, "Write append position error" },
- { 0x50, 0x02, "Position error related to timing" },
- { 0x51, 0x00, "Erase failure" },
- { 0x52, 0x00, "Cartridge fault" },
- { 0x53, 0x00, "Media load or eject failed" },
- { 0x53, 0x01, "Unload tape failure" },
- { 0x53, 0x02, "Medium removal prevented" },
- { 0x54, 0x00, "SCSI to host system interface failure" },
- { 0x55, 0x00, "System resource failure" },
- { 0x57, 0x00, "Unable to recover table-of-contents" },
- { 0x58, 0x00, "Generation does not exist" },
- { 0x59, 0x00, "Updated block read" },
- { 0x5a, 0x00, "Operator request or state change input (unspecified)" },
- { 0x5a, 0x01, "Operator medium removal request" },
- { 0x5a, 0x02, "Operator selected write protect" },
- { 0x5a, 0x03, "Operator selected write permit" },
- { 0x5b, 0x00, "Log exception" },
- { 0x5b, 0x01, "Threshold condition met" },
- { 0x5b, 0x02, "Log counter at maximum" },
- { 0x5b, 0x03, "Log list codes exhausted" },
- { 0x5c, 0x00, "RPL status change" },
- { 0x5c, 0x01, "Spindles synchronized" },
- { 0x5c, 0x02, "Spindles not synchronized" },
- { 0x60, 0x00, "Lamp failure" },
- { 0x61, 0x00, "Video acquisition error" },
- { 0x61, 0x01, "Unable to acquire video" },
- { 0x61, 0x02, "Out of focus" },
- { 0x62, 0x00, "Scan head positioning error" },
- { 0x63, 0x00, "End of user area encountered on this track" },
- { 0x64, 0x00, "Illegal mode for this track" },
- { 0, 0, 0}
-};
-
-void scsi_print_add_sense_keys(key, qualif)
- register unsigned key, qualif;
-{
- register struct addtl_sns_keys_msg *msg;
-
- for (msg = addtl_sns_msgs; msg->means; msg++) {
- if (msg->byte12 != key) continue;
- if ((msg->byte12 == 0x40) && qualif) {
- printf(", %s, NN=x%x", msg->means, qualif);
- return;
- }
- if (msg->byte13 == qualif) {
- printf(" %s", msg->means);
- return;
- }
- };
- printf(", Unknown additional sense keys: 0x%x 0x%x\n", key, qualif);
-}
-#endif /* NSCSI > 0 */
diff --git a/scsi/scsi_comm.c b/scsi/scsi_comm.c
deleted file mode 100644
index 1f0095a..0000000
--- a/scsi/scsi_comm.c
+++ /dev/null
@@ -1,115 +0,0 @@
-/*
- * Mach Operating System
- * Copyright (c) 1991,1990 Carnegie Mellon University
- * All Rights Reserved.
- *
- * Permission to use, copy, modify and distribute this software and its
- * documentation is hereby granted, provided that both the copyright
- * notice and this permission notice appear in all copies of the
- * software, derivative works or modified versions, and any portions
- * thereof, and that both notices appear in supporting documentation.
- *
- * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
- * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
- * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
- *
- * Carnegie Mellon requests users of this software to return to
- *
- * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
- * School of Computer Science
- * Carnegie Mellon University
- * Pittsburgh PA 15213-3890
- *
- * any improvements or extensions that they make and grant Carnegie Mellon
- * the rights to redistribute these changes.
- */
-/*
- * File: scsi_comm.c
- * Author: Alessandro Forin, Carnegie Mellon University
- * Date: 10/90
- *
- * Middle layer of the SCSI driver: SCSI protocol implementation
- *
- * This file contains code for SCSI commands for COMMUNICATION devices.
- */
-
-#include <mach/std_types.h>
-#include <scsi/compat_30.h>
-
-#include <scsi/scsi.h>
-#include <scsi/scsi_defs.h>
-
-#if (NSCSI > 0)
-
-char *sccomm_name(
- boolean_t internal)
-{
- return internal ? "cz" : "comm";
-}
-
-void scsi_get_message(
- register target_info_t *tgt,
- io_req_t ior)
-{
- scsi_cmd_read_t *cmd;
- register unsigned len, max;
-
- max = scsi_softc[(unsigned char)tgt->masterno]->max_dma_data;
-
- len = ior->io_count;
- if (len > max) {
- ior->io_residual = len - max;
- len = max;
- }
-
- cmd = (scsi_cmd_read_t*) (tgt->cmd_ptr);
- cmd->scsi_cmd_code = SCSI_CMD_GET_MESSAGE;
- cmd->scsi_cmd_lun_and_lba1 = tgt->lun << SCSI_LUN_SHIFT;
- cmd->scsi_cmd_lba2 = len >> 16;
- cmd->scsi_cmd_lba3 = len >> 8;
- cmd->scsi_cmd_xfer_len = len;
- cmd->scsi_cmd_ctrl_byte = 0; /* not linked */
-
- tgt->cur_cmd = SCSI_CMD_GET_MESSAGE;
-
- scsi_go(tgt, sizeof(*cmd), len, FALSE);
-}
-
-void scsi_send_message(
- register target_info_t *tgt,
- io_req_t ior)
-{
- scsi_cmd_write_t *cmd;
- register unsigned len, max;
-
- len = ior->io_count;
- max = scsi_softc[(unsigned char)tgt->masterno]->max_dma_data;
-
- if (len > max) {
- ior->io_residual = len - max;
- len = max;
- }
-
- cmd = (scsi_cmd_write_t*) (tgt->cmd_ptr);
- cmd->scsi_cmd_code = SCSI_CMD_SEND_MESSAGE;
- cmd->scsi_cmd_lun_and_lba1 = tgt->lun << SCSI_LUN_SHIFT;
- cmd->scsi_cmd_lba2 = len >> 16;
- cmd->scsi_cmd_lba3 = len >> 8;
- cmd->scsi_cmd_xfer_len = len;
- cmd->scsi_cmd_ctrl_byte = 0; /* not linked */
-
- tgt->cur_cmd = SCSI_CMD_SEND_MESSAGE;
-
- scsi_go(tgt, sizeof(*cmd), 0, FALSE);
-}
-
-
-#if 0
-/* For now, these are not needed */
-scsi_get_message_long
-scsi_get_message_vlong
-scsi_send_message_long
-scsi_send_message_vlong
-#endif
-
-#endif /* NSCSI > 0 */
diff --git a/scsi/scsi_cpu.c b/scsi/scsi_cpu.c
deleted file mode 100644
index 979847c..0000000
--- a/scsi/scsi_cpu.c
+++ /dev/null
@@ -1,109 +0,0 @@
-/*
- * Mach Operating System
- * Copyright (c) 1991,1990 Carnegie Mellon University
- * All Rights Reserved.
- *
- * Permission to use, copy, modify and distribute this software and its
- * documentation is hereby granted, provided that both the copyright
- * notice and this permission notice appear in all copies of the
- * software, derivative works or modified versions, and any portions
- * thereof, and that both notices appear in supporting documentation.
- *
- * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
- * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
- * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
- *
- * Carnegie Mellon requests users of this software to return to
- *
- * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
- * School of Computer Science
- * Carnegie Mellon University
- * Pittsburgh PA 15213-3890
- *
- * any improvements or extensions that they make and grant Carnegie Mellon
- * the rights to redistribute these changes.
- */
-/*
- * File: scsi_cpu.c
- * Author: Alessandro Forin, Carnegie Mellon University
- * Date: 10/90
- *
- * Middle layer of the SCSI driver: SCSI protocol implementation
- *
- * This file contains code for SCSI commands for PROCESSOR devices.
- */
-
-#include <mach/std_types.h>
-#include <scsi/compat_30.h>
-
-#include <scsi/scsi.h>
-#include <scsi/scsi2.h>
-#include <scsi/scsi_defs.h>
-
-#if (NSCSI > 0)
-
-char *sccpu_name(internal)
- boolean_t internal;
-{
- return internal ? "sc" : "cpu";
-}
-
-void scsi_send( tgt, ior)
- register target_info_t *tgt;
- io_req_t ior;
-{
- scsi_cmd_write_t *cmd;
- unsigned len; /* in bytes */
- unsigned int max_dma_data;
-
- max_dma_data = scsi_softc[(unsigned char)tgt->masterno]->max_dma_data;
-
- len = ior->io_count;
- if (len > max_dma_data)
- len = max_dma_data;
- if (len < tgt->block_size)
- len = tgt->block_size;
-
- cmd = (scsi_cmd_write_t*) (tgt->cmd_ptr);
- cmd->scsi_cmd_code = SCSI_CMD_SEND;
- cmd->scsi_cmd_lun_and_lba1 = 0;
- cmd->scsi_cmd_lba2 = len >> 16;
- cmd->scsi_cmd_lba3 = len >> 8;
- cmd->scsi_cmd_xfer_len = len;
- cmd->scsi_cmd_ctrl_byte = 0; /* not linked */
-
- tgt->cur_cmd = SCSI_CMD_SEND;
-
- scsi_go(tgt, sizeof(*cmd), 0, FALSE);
-}
-
-void scsi_receive( tgt, ior)
- register target_info_t *tgt;
- io_req_t ior;
-{
- scsi_cmd_read_t *cmd;
- register unsigned len;
- unsigned int max_dma_data;
-
- max_dma_data = scsi_softc[(unsigned char)tgt->masterno]->max_dma_data;
-
- len = ior->io_count;
- if (len > max_dma_data)
- len = max_dma_data;
- if (len < tgt->block_size)
- len = tgt->block_size;
-
- cmd = (scsi_cmd_read_t*) (tgt->cmd_ptr);
- cmd->scsi_cmd_code = SCSI_CMD_RECEIVE;
- cmd->scsi_cmd_lun_and_lba1 = 0;
- cmd->scsi_cmd_lba2 = len >> 16;
- cmd->scsi_cmd_lba3 = len >> 8;
- cmd->scsi_cmd_xfer_len = len;
- cmd->scsi_cmd_ctrl_byte = 0; /* not linked */
-
- tgt->cur_cmd = SCSI_CMD_RECEIVE;
-
- scsi_go(tgt, sizeof(*cmd), len, FALSE);
-}
-
-#endif /* NSCSI > 0 */
diff --git a/scsi/scsi_defs.h b/scsi/scsi_defs.h
deleted file mode 100644
index c98bc85..0000000
--- a/scsi/scsi_defs.h
+++ /dev/null
@@ -1,284 +0,0 @@
-/*
- * Mach Operating System
- * Copyright (c) 1993-1989 Carnegie Mellon University
- * All Rights Reserved.
- *
- * Permission to use, copy, modify and distribute this software and its
- * documentation is hereby granted, provided that both the copyright
- * notice and this permission notice appear in all copies of the
- * software, derivative works or modified versions, and any portions
- * thereof, and that both notices appear in supporting documentation.
- *
- * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
- * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
- * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
- *
- * Carnegie Mellon requests users of this software to return to
- *
- * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
- * School of Computer Science
- * Carnegie Mellon University
- * Pittsburgh PA 15213-3890
- *
- * any improvements or extensions that they make and grant Carnegie Mellon
- * the rights to redistribute these changes.
- */
-/*
- * File: scsi_defs.h
- * Author: Alessandro Forin, Carnegie Mellon University
- * Date: 9/90
- *
- * Controller-independent definitions for the SCSI driver
- */
-
-#ifndef _SCSI_SCSI_DEFS_H_
-#define _SCSI_SCSI_DEFS_H_
-
-#include <kern/queue.h>
-#include <kern/lock.h>
-
-#include <rz_labels.h>
-
-#define await(event) sleep(event,0)
-extern void wakeup();
-
-typedef vm_offset_t opaque_t; /* should be elsewhere */
-
-/*
- * Internal error codes, and return values
- * XXX use the mach/error.h scheme XXX
- */
-typedef unsigned int scsi_ret_t;
-
-#define SCSI_ERR_GRAVITY(x) ((unsigned)(x)&0xf0000000U)
-#define SCSI_ERR_GRAVE 0x80000000U
-#define SCSI_ERR_BAD 0x40000000
-
-#define SCSI_ERR_CLASS(x) ((unsigned)(x)&0x0fffffffU)
-#define SCSI_ERR_STATUS 0x00000001
-#define SCSI_ERR_SENSE 0x00000002
-#define SCSI_ERR_MSEL 0x00000004
-
-extern void scsi_error(/* target_info_t *, unsigned, unsigned */);
-
-#define SCSI_RET_IN_PROGRESS 0x00
-#define SCSI_RET_SUCCESS 0x01
-#define SCSI_RET_RETRY 0x02
-#define SCSI_RET_NEED_SENSE 0x04
-#define SCSI_RET_ABORTED 0x08
-#define SCSI_RET_DEVICE_DOWN 0x10
-
-/*
- * Device-specific information kept by driver
- */
-#define MAX_SCSI_PARTS 32 /* maximum partitions on a disk;can be larger */
-typedef struct {
- struct disklabel l; /* NOT accurate. partitions stored below */
- struct {
- unsigned int badblockno;
- unsigned int save_rec;
- char *save_addr;
- int save_count;
- int save_resid;
- int retry_count;
- } b;
-#if 0 /* no longer used by partition code */
- int labelsector;
- int labeloffset;
-#endif 0
- struct diskpart scsi_array[MAX_SCSI_PARTS]; /* new partition info */
-} scsi_disk_info_t;
-
-typedef struct {
- boolean_t read_only;
- unsigned int speed;
- unsigned int density;
- unsigned int maxreclen;
- boolean_t fixed_size;
-} scsi_tape_info_t;
-
-typedef struct {
- char req_pending;
- char req_id;
- char req_lun;
- char req_cmd;
- unsigned int req_len;
- /* more later */
-} scsi_processor_info_t;
-
-typedef struct {
- void *result;
- boolean_t result_available;
- int result_size;
- struct red_list *violates_standards;
-} scsi_cdrom_info_t;
-
-typedef struct {
-# define SCSI_MAX_COMM_TTYS 16
- struct tty *tty[SCSI_MAX_COMM_TTYS];
- io_req_t ior;
-} scsi_comm_info_t;
-
-/*
- * Device descriptor
- */
-
-#define SCSI_TARGET_NAME_LEN 8+16+4+8 /* our way to keep it */
-
-typedef struct target_info {
- queue_chain_t links; /* to queue for bus */
- io_req_t ior; /* what we are doing */
-
- unsigned int flags;
-#define TGT_DID_SYNCH 0x00000001 /* finished the synch neg */
-#define TGT_TRY_SYNCH 0x00000002 /* do the synch negotiation */
-#define TGT_FULLY_PROBED 0x00000004 /* can sleep to wait */
-#define TGT_ONLINE 0x00000008 /* did the once-only stuff */
-#define TGT_ALIVE 0x00000010
-#define TGT_BBR_ACTIVE 0x00000020 /* bad block replc in progress */
-#define TGT_DISCONNECTED 0x00000040 /* waiting for reconnect */
-#define TGT_WRITTEN_TO 0x00000080 /* tapes: needs a filemark on close */
-#define TGT_REWIND_ON_CLOSE 0x00000100 /* tapes: rewind */
-#define TGT_BIG 0x00000200 /* disks: > 1Gb, use long R/W */
-#define TGT_REMOVABLE_MEDIA 0x00000400 /* e.g. floppy, cd-rom,.. */
-#define TGT_READONLY 0x00000800 /* cd-rom, scanner, .. */
-#define TGT_OPTIONAL_CMD 0x00001000 /* optional cmd, ignore errors */
-#define TGT_WRITE_LABEL 0x00002000 /* disks: enable overwriting of label */
-#define TGT_US 0x00004000 /* our desc, when target role */
-
-#define TGT_HW_SPECIFIC_BITS 0xffff0000U /* see specific HBA */
- char *hw_state; /* opaque */
- char *dma_ptr;
- char *cmd_ptr;
- struct scsi_devsw_struct *dev_ops; /* circularity */
- struct target_info *next_lun; /* if multi-LUN */
- char target_id;
- char unit_no;
- unsigned char sync_period;
- unsigned char sync_offset;
- decl_simple_lock_data(,target_lock)
-#ifdef MACH_KERNEL
-#else /*MACH_KERNEL*/
- struct fdma fdma;
-#endif /*MACH_KERNEL*/
- /*
- * State info kept while waiting to seize bus, either for first
- * selection or while in disconnected state
- */
- struct {
- struct script *script;
- int (*handler)();
- unsigned int out_count;
- unsigned int in_count;
- unsigned int copy_count; /* optional */
- unsigned int dma_offset;
- unsigned char identify;
- unsigned char cmd_count;
- unsigned char hba_dep[2];
- } transient_state;
- unsigned int block_size;
- volatile char done;
- unsigned char cur_cmd;
- unsigned char lun;
- char masterno;
- char tgt_name[SCSI_TARGET_NAME_LEN];
- union {
- scsi_disk_info_t disk;
- scsi_tape_info_t tape;
- scsi_cdrom_info_t cdrom;
- scsi_processor_info_t cpu;
- scsi_comm_info_t comm;
- } dev_info;
-} target_info_t;
-
-
-/*
- * Device-specific operations
- */
-typedef struct scsi_devsw_struct {
- char *(*driver_name)(boolean_t); /* my driver's name */
- void (*optimize)(target_info_t *); /* tune up internal params */
- scsi_ret_t (*open)(target_info_t *,io_req_t);/* open time ops */
- scsi_ret_t (*close)(target_info_t *); /* close time ops */
- int (*strategy)(io_req_t); /* sort/start routine */
- void (*restart)(target_info_t *,
- boolean_t); /* completion routine */
- io_return_t (*get_status)(int,
- target_info_t *,
- dev_flavor_t,
- dev_status_t,
- natural_t *); /* specialization */
- io_return_t (*set_status)(int,
- target_info_t *,
- dev_flavor_t,
- dev_status_t,
- natural_t); /* specialization */
-} scsi_devsw_t;
-
-#define SCSI_OPTIMIZE_NULL ((void (*)(target_info_t *)) 0)
-#define SCSI_OPEN_NULL ((scsi_ret_t (*)(target_info_t *,io_req_t)) 0)
-#define SCSI_CLOSE_NULL ((scsi_ret_t (*)(target_info_t *)) 0)
-
-extern scsi_devsw_t scsi_devsw[];
-
-/*
- * HBA descriptor
- */
-
-typedef struct {
- /* initiator (us) state */
- unsigned char initiator_id;
- unsigned char masterno;
- unsigned int max_dma_data;
- char *hw_state; /* opaque */
- int (*go)();
- void (*watchdog)();
- boolean_t (*probe)();
- /* per-target state */
- target_info_t *target[8];
-} scsi_softc_t;
-
-extern scsi_softc_t *scsi_softc[];
-extern scsi_softc_t *scsi_master_alloc(/* int unit */);
-extern target_info_t *scsi_slave_alloc(/* int unit, int slave, char *hw */);
-
-#define BGET(d,mid,id) (d[mid] & (1 << id)) /* bitmap ops */
-#define BSET(d,mid,id) d[mid] |= (1 << id)
-#define BCLR(d,mid,id) d[mid] &= ~(1 << id)
-
-extern unsigned char scsi_no_synchronous_xfer[]; /* one bitmap per ctlr */
-extern unsigned char scsi_use_long_form[]; /* one bitmap per ctlr */
-extern unsigned char scsi_might_disconnect[]; /* one bitmap per ctlr */
-extern unsigned char scsi_should_disconnect[]; /* one bitmap per ctlr */
-extern unsigned char scsi_initiator_id[]; /* one id per ctlr */
-
-extern boolean_t scsi_exabyte_filemarks;
-extern boolean_t scsi_no_automatic_bbr;
-extern int scsi_bbr_retries;
-extern int scsi_watchdog_period;
-extern int scsi_delay_after_reset;
-extern unsigned int scsi_per_target_virtual; /* 2.5 only */
-
-extern int scsi_debug;
-
-/*
- * HBA-independent Watchdog
- */
-typedef struct {
-
- unsigned short reset_count;
- char nactive;
-
- char watchdog_state;
-
-#define SCSI_WD_INACTIVE 0
-#define SCSI_WD_ACTIVE 1
-#define SCSI_WD_EXPIRED 2
-
- int (*reset)();
-
-} watchdog_t;
-
-extern void scsi_watchdog( watchdog_t* );
-
-#endif _SCSI_SCSI_DEFS_H_
diff --git a/scsi/scsi_disk.c b/scsi/scsi_disk.c
deleted file mode 100644
index 99bbe76..0000000
--- a/scsi/scsi_disk.c
+++ /dev/null
@@ -1,624 +0,0 @@
-/*
- * Mach Operating System
- * Copyright (c) 1991,1990 Carnegie Mellon University
- * All Rights Reserved.
- *
- * Permission to use, copy, modify and distribute this software and its
- * documentation is hereby granted, provided that both the copyright
- * notice and this permission notice appear in all copies of the
- * software, derivative works or modified versions, and any portions
- * thereof, and that both notices appear in supporting documentation.
- *
- * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
- * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
- * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
- *
- * Carnegie Mellon requests users of this software to return to
- *
- * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
- * School of Computer Science
- * Carnegie Mellon University
- * Pittsburgh PA 15213-3890
- *
- * any improvements or extensions that they make and grant Carnegie Mellon
- * the rights to redistribute these changes.
- */
-/*
- * File: scsi_disk.c
- * Author: Alessandro Forin, Carnegie Mellon University
- * Date: 10/90
- *
- * Middle layer of the SCSI driver: SCSI protocol implementation
- *
- * This file contains code for SCSI commands for DISK devices.
- */
-
-#include <string.h>
-
-#include <mach/std_types.h>
-#include <scsi/compat_30.h>
-
-#include <scsi/scsi.h>
-#include <scsi/scsi2.h>
-#include <scsi/scsi_defs.h>
-
-#if (NSCSI > 0)
-
-
-char *scdisk_name(internal)
- boolean_t internal;
-{
- return internal ? "rz" : "disk";
-}
-
-/*
- * SCSI commands partially specific to disks
- */
-void scdisk_read( tgt, secno, ior)
- register target_info_t *tgt;
- register unsigned int secno;
- io_req_t ior;
-{
- scsi_cmd_read_t *cmd;
- register unsigned len;
- unsigned int max_dma_data;
-
- max_dma_data = scsi_softc[(unsigned char)tgt->masterno]->max_dma_data;
-
- len = ior->io_count;
- if (len > max_dma_data)
- len = max_dma_data;
- if (len < tgt->block_size)
- len = tgt->block_size;
-
- cmd = (scsi_cmd_read_t*) (tgt->cmd_ptr);
- cmd->scsi_cmd_code = SCSI_CMD_READ;
- cmd->scsi_cmd_lun_and_lba1 = (secno>>16)&SCSI_LBA_MASK;
- cmd->scsi_cmd_lba2 = (secno>> 8)&0xff;
- cmd->scsi_cmd_lba3 = (secno )&0xff;
- cmd->scsi_cmd_xfer_len = len / tgt->block_size;
- cmd->scsi_cmd_ctrl_byte = 0; /* not linked */
-
- tgt->cur_cmd = SCSI_CMD_READ;
-
- scsi_go(tgt, sizeof(*cmd), len, FALSE);
-}
-
-void scdisk_write( tgt, secno, ior)
- register target_info_t *tgt;
- register unsigned int secno;
- io_req_t ior;
-{
- scsi_cmd_write_t *cmd;
- unsigned len; /* in bytes */
- unsigned int max_dma_data;
-
- max_dma_data = scsi_softc[(unsigned char)tgt->masterno]->max_dma_data;
-
- len = ior->io_count;
- if (len > max_dma_data)
- len = max_dma_data;
- if (len < tgt->block_size)
- len = tgt->block_size;
-
- cmd = (scsi_cmd_write_t*) (tgt->cmd_ptr);
- cmd->scsi_cmd_code = SCSI_CMD_WRITE;
- cmd->scsi_cmd_lun_and_lba1 = (secno>>16)&SCSI_LBA_MASK;
- cmd->scsi_cmd_lba2 = (secno>> 8)&0xff;
- cmd->scsi_cmd_lba3 = (secno )&0xff;
- cmd->scsi_cmd_xfer_len = len / tgt->block_size;
- cmd->scsi_cmd_ctrl_byte = 0; /* not linked */
-
- tgt->cur_cmd = SCSI_CMD_WRITE;
-
- scsi_go(tgt, sizeof(*cmd), 0, FALSE);
-}
-
-
-int scdisk_mode_select(tgt, lbn, ior, mdata, mlen, save)
- register target_info_t *tgt;
- register int lbn;
- io_req_t ior;
- char *mdata;
- int mlen, save;
-{
- scsi_cmd_mode_select_t *cmd;
- scsi_mode_select_param_t *parm;
-
- bzero(tgt->cmd_ptr, sizeof(*cmd) + sizeof(*parm));
- cmd = (scsi_cmd_mode_select_t*) (tgt->cmd_ptr);
- cmd->scsi_cmd_code = SCSI_CMD_MODE_SELECT;
- cmd->scsi_cmd_lun_and_lba1 = SCSI_CMD_MSL_PF; /* XXX only if... */
- cmd->scsi_cmd_xfer_len = sizeof(scsi_mode_select_param_t);/* no vuq */
-
- parm = (scsi_mode_select_param_t*) (cmd + 1);
- if (mdata) {
- cmd->scsi_cmd_xfer_len = mlen;
- bcopy(mdata, (char*)parm, mlen);
- if (save)
- cmd->scsi_cmd_lun_and_lba1 |= SCSI_CMD_MSL_SP;
- } else {
- /* parm->medium_type = if (floppy)disk.. */
- parm->desc_len = 8;
- /* this really is the LBN */
- parm->descs[0].density_code = 0;/* XXX default XXX */
- parm->descs[0].reclen1 = (lbn>>16)&0xff;
- parm->descs[0].reclen2 = (lbn>> 8)&0xff;
- parm->descs[0].reclen3 = (lbn )&0xff;
- mlen = sizeof(*parm);
- }
-
- tgt->cur_cmd = SCSI_CMD_MODE_SELECT;
-
- scsi_go_and_wait(tgt, sizeof(*cmd) + mlen, 0, ior);
-
- return tgt->done;
-}
-
-/*
- * SCSI commands fully specific to disks
- */
-int scsi_read_capacity( tgt, lbn, ior)
- register target_info_t *tgt;
- int lbn;
- io_req_t ior;
-{
- scsi_cmd_read_capacity_t *cmd;
-
- bzero(tgt->cmd_ptr, sizeof(*cmd));
- cmd = (scsi_cmd_read_capacity_t*) (tgt->cmd_ptr);
- cmd->scsi_cmd_code = SCSI_CMD_READ_CAPACITY;
- /* all zeroes, unless... */
- if (lbn) {
- cmd->scsi_cmd_rcap_flags = SCSI_CMD_RCAP_PMI;
- cmd->scsi_cmd_lba1 = (lbn>>24);
- cmd->scsi_cmd_lba2 = (lbn>>16)&0xff;
- cmd->scsi_cmd_lba3 = (lbn>> 8)&0xff;
- cmd->scsi_cmd_lba4 = (lbn )&0xff;
- }
-
- tgt->cur_cmd = SCSI_CMD_READ_CAPACITY;
-
- scsi_go_and_wait(tgt, sizeof(*cmd), sizeof(scsi_rcap_data_t),ior);
-
- return tgt->done;
-}
-
-void scsi_reassign_blocks( tgt, defect_list, n_defects, ior)
- register target_info_t *tgt;
- unsigned int *defect_list; /* In ascending order ! */
- int n_defects;
- io_req_t ior;
-{
- scsi_cmd_reassign_blocks_t *cmd;
- scsi_Ldefect_data_t *parm;
-
- cmd = (scsi_cmd_reassign_blocks_t*) (tgt->cmd_ptr);
- cmd->scsi_cmd_code = SCSI_CMD_REASSIGN_BLOCKS;
- cmd->scsi_cmd_lun_and_lba1 = 0;
- cmd->scsi_cmd_lba2 = 0;
- cmd->scsi_cmd_lba3 = 0;
- cmd->scsi_cmd_xfer_len = 0;
- cmd->scsi_cmd_ctrl_byte = 0; /* not linked */
-
- parm = (scsi_Ldefect_data_t *) (cmd + 1);
- parm->res1 = parm->res2 = 0;
- n_defects *= 4; /* in 4-byte-ints */
- parm->list_len_msb = n_defects >> 8;
- parm->list_len_lsb = n_defects;
- bcopy((char*)defect_list, (char*)parm->defects, n_defects);
-
- tgt->cur_cmd = SCSI_CMD_REASSIGN_BLOCKS;
-
- scsi_go(tgt, sizeof(*cmd) + sizeof(*parm) + (n_defects - 4), 0, FALSE);
-}
-
-void scsi_medium_removal( tgt, allow, ior)
- register target_info_t *tgt;
- boolean_t allow;
- io_req_t ior;
-{
- scsi_cmd_medium_removal_t *cmd;
-
- cmd = (scsi_cmd_medium_removal_t*) (tgt->cmd_ptr);
- cmd->scsi_cmd_code = SCSI_CMD_PREVENT_ALLOW_REMOVAL;
- cmd->scsi_cmd_lun_and_lba1 = 0;
- cmd->scsi_cmd_lba2 = 0;
- cmd->scsi_cmd_lba3 = 0;
- cmd->scsi_cmd_pa_prevent = allow ? 0 : 1;
- cmd->scsi_cmd_ctrl_byte = 0; /* not linked */
-
-
- tgt->cur_cmd = SCSI_CMD_PREVENT_ALLOW_REMOVAL;
-
- scsi_go_and_wait(tgt, sizeof(*cmd), 0, ior);
-}
-
-int scsi_format_unit( tgt, mode, vuqe, intlv, ior)
- register target_info_t *tgt;
- int mode, vuqe;
- register unsigned int intlv;
- io_req_t ior;
-{
- scsi_cmd_format_t *cmd;
- char *parms;
-
- cmd = (scsi_cmd_format_t*) (tgt->cmd_ptr);
- cmd->scsi_cmd_code = SCSI_CMD_FORMAT_UNIT;
- cmd->scsi_cmd_lun_and_lba1 =
- mode & (SCSI_CMD_FMT_FMTDATA|SCSI_CMD_FMT_CMPLIST|SCSI_CMD_FMT_LIST_TYPE);
- cmd->scsi_cmd_lba2 = vuqe;
- cmd->scsi_cmd_lba3 = intlv >> 8;
- cmd->scsi_cmd_xfer_len = intlv;
- cmd->scsi_cmd_ctrl_byte = 0; /* not linked */
-
- parms = (char*) cmd + 1;
- if (ior->io_count)
- bcopy(ior->io_data, parms, ior->io_count);
- else
- bzero(parms, 0xff - sizeof(*cmd));
-
- tgt->cur_cmd = SCSI_CMD_FORMAT_UNIT;
-
- scsi_go_and_wait(tgt, sizeof(*cmd) + ior->io_count, 0, ior);
- return tgt->done;
-}
-
-
-/* Group 1 Commands */
-
-void scsi_long_read( tgt, secno, ior)
- register target_info_t *tgt;
- register unsigned int secno;
- io_req_t ior;
-{
- scsi_cmd_long_read_t *cmd;
- register unsigned len, n_blks;
- unsigned int max_dma_data;
-
- max_dma_data = scsi_softc[(unsigned char)tgt->masterno]->max_dma_data;
-
- len = ior->io_count;
- if (len > max_dma_data)
- len = max_dma_data;
- if (len < tgt->block_size)
- len = tgt->block_size;
- n_blks = len /tgt->block_size;
-
- cmd = (scsi_cmd_long_read_t*) (tgt->cmd_ptr);
- cmd->scsi_cmd_code = SCSI_CMD_LONG_READ;
- cmd->scsi_cmd_lun_and_relbit = 0;
- cmd->scsi_cmd_lba1 = secno >> 24;
- cmd->scsi_cmd_lba2 = secno >> 16;
- cmd->scsi_cmd_lba3 = secno >> 8;
- cmd->scsi_cmd_lba4 = secno;
- cmd->scsi_cmd_xxx = 0;
- cmd->scsi_cmd_xfer_len_1 = n_blks >> 8;
- cmd->scsi_cmd_xfer_len_2 = n_blks;
- cmd->scsi_cmd_ctrl_byte = 0; /* not linked */
-
- tgt->cur_cmd = SCSI_CMD_LONG_READ;
-
- scsi_go(tgt, sizeof(*cmd), len, FALSE);
-}
-
-void scsi_long_write( tgt, secno, ior)
- register target_info_t *tgt;
- register unsigned int secno;
- io_req_t ior;
-{
- scsi_cmd_long_write_t *cmd;
- unsigned len; /* in bytes */
- unsigned int max_dma_data, n_blks;
-
- max_dma_data = scsi_softc[(unsigned char)tgt->masterno]->max_dma_data;
-
- len = ior->io_count;
- if (len > max_dma_data)
- len = max_dma_data;
- if (len < tgt->block_size)
- len = tgt->block_size;
- n_blks = len /tgt->block_size;
-
- cmd = (scsi_cmd_long_write_t*) (tgt->cmd_ptr);
- cmd->scsi_cmd_code = SCSI_CMD_LONG_WRITE;
- cmd->scsi_cmd_lun_and_relbit = 0;
- cmd->scsi_cmd_lba1 = secno >> 24;
- cmd->scsi_cmd_lba2 = secno >> 16;
- cmd->scsi_cmd_lba3 = secno >> 8;
- cmd->scsi_cmd_lba4 = secno;
- cmd->scsi_cmd_xxx = 0;
- cmd->scsi_cmd_xfer_len_1 = n_blks >> 8;
- cmd->scsi_cmd_xfer_len_2 = n_blks;
- cmd->scsi_cmd_ctrl_byte = 0; /* not linked */
-
- tgt->cur_cmd = SCSI_CMD_LONG_WRITE;
-
- scsi_go(tgt, sizeof(*cmd), 0, FALSE);
-}
-
-int scdisk_verify( tgt, secno, nsectrs, ior)
- register target_info_t *tgt;
- int secno, nsectrs;
- io_req_t ior;
-{
- scsi_cmd_verify_long_t *cmd;
- int len;
-
- len = ior->io_count;
-
- cmd = (scsi_cmd_verify_long_t*) (tgt->cmd_ptr);
- cmd->scsi_cmd_code = SCSI_CMD_VERIFY_1;
- cmd->scsi_cmd_lun_and_relbit = len ? SCSI_CMD_VFY_BYTCHK : 0;
- cmd->scsi_cmd_lba1 = secno >> 24;
- cmd->scsi_cmd_lba2 = secno >> 16;
- cmd->scsi_cmd_lba3 = secno >> 8;
- cmd->scsi_cmd_lba4 = secno;
- cmd->scsi_cmd_xxx = 0;
- cmd->scsi_cmd_xfer_len_1 = (nsectrs) >> 8;
- cmd->scsi_cmd_xfer_len_2 = nsectrs;
- cmd->scsi_cmd_ctrl_byte = 0; /* not linked */
-
- tgt->cur_cmd = SCSI_CMD_VERIFY_1;
-
- scsi_go_and_wait(tgt, sizeof(*cmd) + len, 0, ior);
- return tgt->done;
-}
-
-
-int scsi_read_defect( tgt, mode, ior)
- register target_info_t *tgt;
- register unsigned int mode;
- io_req_t ior;
-{
- scsi_cmd_long_read_t *cmd;
- register unsigned len;
-
- len = ior->io_count;
- if (len > 0xffff)
- len = 0xffff;
-
- cmd = (scsi_cmd_read_defect_t*) (tgt->cmd_ptr);
- cmd->scsi_cmd_code = SCSI_CMD_READ_DEFECT_DATA;
- cmd->scsi_cmd_lun_and_relbit = 0;
- cmd->scsi_cmd_lba1 = mode & 0x1f;
- cmd->scsi_cmd_lba2 = 0;
- cmd->scsi_cmd_lba3 = 0;
- cmd->scsi_cmd_lba4 = 0;
- cmd->scsi_cmd_xxx = 0;
- cmd->scsi_cmd_xfer_len_1 = (len) >> 8;
- cmd->scsi_cmd_xfer_len_2 = (len);
- cmd->scsi_cmd_ctrl_byte = 0; /* not linked */
-
- /* ++ HACK Alert */
-/* tgt->cur_cmd = SCSI_CMD_READ_DEFECT_DATA;*/
- tgt->cur_cmd = SCSI_CMD_LONG_READ;
- /* -- HACK Alert */
-
- scsi_go(tgt, sizeof(*cmd), len, FALSE);
- iowait(ior);
- return tgt->done;
-}
-
-
-#if 0 /* unused commands */
-scsi_rezero_unit( tgt, ior)
- register target_info_t *tgt;
- io_req_t ior;
-{
- scsi_cmd_rezero_t *cmd;
-
- cmd = (scsi_cmd_rezero_t*) (tgt->cmd_ptr);
- cmd->scsi_cmd_code = SCSI_CMD_REZERO_UNIT;
- cmd->scsi_cmd_lun_and_lba1 = 0;
- cmd->scsi_cmd_lba2 = 0;
- cmd->scsi_cmd_lba3 = 0;
- cmd->scsi_cmd_xfer_len = 0;
- cmd->scsi_cmd_ctrl_byte = 0; /* not linked */
-
-
- tgt->cur_cmd = SCSI_CMD_REZERO_UNIT;
-
- scsi_go_and_wait(tgt, sizeof(*cmd), 0, ior);
-
-}
-
-scsi_seek( tgt, where, ior)
- register target_info_t *tgt;
- register unsigned int where;
- io_req_t ior;
-{
- scsi_cmd_seek_t *cmd;
-
- cmd = (scsi_cmd_seek_t*) (tgt->cmd_ptr);
- cmd->scsi_cmd_code = SCSI_CMD_SEEK;
- cmd->scsi_cmd_lun_and_lba1 = (where >> 16) & 0x1f;
- cmd->scsi_cmd_lba2 = where >> 8;
- cmd->scsi_cmd_lba3 = where;
- cmd->scsi_cmd_xfer_len = 0;
- cmd->scsi_cmd_ctrl_byte = 0; /* not linked */
-
-
- tgt->cur_cmd = SCSI_CMD_SEEK;
-
- scsi_go_and_wait(tgt, sizeof(*cmd), 0, ior);
-
-}
-
-scsi_reserve( tgt, len, id, mode, ior)
- register target_info_t *tgt;
- register unsigned int len;
- unsigned char id;
- io_req_t ior;
-{
- scsi_cmd_reserve_t *cmd;
-
- cmd = (scsi_cmd_reserve_t*) (tgt->cmd_ptr);
- cmd->scsi_cmd_code = SCSI_CMD_RESERVE;
- cmd->scsi_cmd_lun_and_lba1 = mode & 0x1f;
- cmd->scsi_cmd_reserve_id = id;
- cmd->scsi_cmd_extent_llen1 = len >> 8;
- cmd->scsi_cmd_extent_llen2 = len;
- cmd->scsi_cmd_ctrl_byte = 0; /* not linked */
-
-
- tgt->cur_cmd = SCSI_CMD_RESERVE;
-
- scsi_go_and_wait(tgt, sizeof(*cmd), 0, ior);
-
-}
-
-scsi_release( tgt, id, mode, ior)
- register target_info_t *tgt;
- unsigned char id, mode;
- io_req_t ior;
-{
- scsi_cmd_release_t *cmd;
-
- cmd = (scsi_cmd_release_t*) (tgt->cmd_ptr);
- cmd->scsi_cmd_code = SCSI_CMD_RELEASE;
- cmd->scsi_cmd_lun_and_lba1 = mode & 0x1f;
- cmd->scsi_cmd_reserve_id = id;
- cmd->scsi_cmd_lba3 = 0;
- cmd->scsi_cmd_xfer_len = 0;
- cmd->scsi_cmd_ctrl_byte = 0; /* not linked */
-
-
- tgt->cur_cmd = SCSI_CMD_RELEASE;
-
- scsi_go_and_wait(tgt, sizeof(*cmd), 0, ior);
-
-}
-
-
-/* Group 1 Commands */
-
-scsi_long_seek( tgt, secno, ior)
- register target_info_t *tgt;
- io_req_t ior;
-{
- scsi_cmd_long_seek_t *cmd;
-
- cmd = (scsi_cmd_long_seek_t*) (tgt->cmd_ptr);
- cmd->scsi_cmd_code = SCSI_CMD_LONG_SEEK;
- cmd->scsi_cmd_lun_and_relbit = 0;
- cmd->scsi_cmd_lba1 = secno >> 24;
- cmd->scsi_cmd_lba2 = secno >> 16;
- cmd->scsi_cmd_lba3 = secno >> 8;
- cmd->scsi_cmd_lba4 = secno;
- cmd->scsi_cmd_xxx = 0;
- cmd->scsi_cmd_xfer_len_1 = 0;
- cmd->scsi_cmd_xfer_len_2 = 0;
- cmd->scsi_cmd_ctrl_byte = 0; /* not linked */
-
- tgt->cur_cmd = SCSI_CMD_LONG_SEEK;
-
- scsi_go(tgt, sizeof(*cmd), 0, FALSE);
-}
-
-scsi_write_verify( tgt, secno, ior)
- register target_info_t *tgt;
- io_req_t ior;
-{
- scsi_cmd_write_vfy_t *cmd;
- unsigned len; /* in bytes */
- unsigned int max_dma_data, n_blks;
-
- max_dma_data = scsi_softc[(unsigned char)tgt->masterno]->max_dma_data;
-
- len = ior->io_count;
- if (len > max_dma_data)
- len = max_dma_data;
- if (len < tgt->block_size)
- len = tgt->block_size;
- n_blks = len / tgt->block_size;
-
- cmd = (scsi_cmd_write_vfy_t*) (tgt->cmd_ptr);
- cmd->scsi_cmd_code = SCSI_CMD_WRITE_AND_VERIFY;
- cmd->scsi_cmd_lun_and_relbit = SCSI_CMD_VFY_BYTCHK;
- cmd->scsi_cmd_lba1 = secno >> 24;
- cmd->scsi_cmd_lba2 = secno >> 16;
- cmd->scsi_cmd_lba3 = secno >> 8;
- cmd->scsi_cmd_lba4 = secno;
- cmd->scsi_cmd_xxx = 0;
- cmd->scsi_cmd_xfer_len_1 = n_blks >> 8;
- cmd->scsi_cmd_xfer_len_2 = n_blks;
- cmd->scsi_cmd_ctrl_byte = 0; /* not linked */
-
- tgt->cur_cmd = SCSI_CMD_WRITE_AND_VERIFY;
-
- scsi_go(tgt, sizeof(*cmd), 0, FALSE);
-}
-
-scsi_search_data( tgt, secno, how, flags, ior)
- register target_info_t *tgt;
- io_req_t ior;
-{
- scsi_cmd_search_t *cmd;
- unsigned len; /* in bytes */
- unsigned int max_dma_data, n_blks;
-
- max_dma_data = scsi_softc[(unsigned char)tgt->masterno]->max_dma_data;
-
- if (how != SCSI_CMD_SEARCH_HIGH &&
- how != SCSI_CMD_SEARCH_EQUAL &&
- how != SCSI_CMD_SEARCH_LOW)
- panic("scsi_search_data");
-
- len = ior->io_count;
- if (len > max_dma_data)
- len = max_dma_data;
- n_blks = len / tgt->block_size;
-
- cmd = (scsi_cmd_search_t*) (tgt->cmd_ptr);
- cmd->scsi_cmd_code = how;
- cmd->scsi_cmd_lun_and_relbit = flags & 0x1e;
- cmd->scsi_cmd_lba1 = secno >> 24;
- cmd->scsi_cmd_lba2 = secno >> 16;
- cmd->scsi_cmd_lba3 = secno >> 8;
- cmd->scsi_cmd_lba4 = secno;
- cmd->scsi_cmd_xxx = 0;
- cmd->scsi_cmd_xfer_len_1 = n_blks >> 8;
- cmd->scsi_cmd_xfer_len_2 = n_blks;
- cmd->scsi_cmd_ctrl_byte = 0; /* not linked */
-
- tgt->cur_cmd = how;
-
- scsi_go(tgt, sizeof(*cmd), 0, FALSE);
-}
-
-
-scsi_set_limits( tgt, secno, nblocks, inhibit, ior)
- register target_info_t *tgt;
- io_req_t ior;
-{
- scsi_cmd_set_limits_t *cmd;
-
- cmd = (scsi_cmd_set_limits_t*) (tgt->cmd_ptr);
- cmd->scsi_cmd_code = SCSI_CMD_SET_LIMITS;
- cmd->scsi_cmd_lun_and_relbit = inhibit & 0x3;
- cmd->scsi_cmd_lba1 = secno >> 24;
- cmd->scsi_cmd_lba2 = secno >> 16;
- cmd->scsi_cmd_lba3 = secno >> 8;
- cmd->scsi_cmd_lba4 = secno;
- cmd->scsi_cmd_xxx = 0;
- cmd->scsi_cmd_xfer_len_1 = nblocks >> 8;
- cmd->scsi_cmd_xfer_len_2 = nblocks;
- cmd->scsi_cmd_ctrl_byte = 0; /* not linked */
-
- tgt->cur_cmd = SCSI_CMD_SET_LIMITS;
-
- scsi_go(tgt, sizeof(*cmd), 0, FALSE);
-}
-
-
-#endif
-
-#ifdef SCSI2
-scsi_lock_cache
-scsi_prefetch
-scsi_read_defect_data
-scsi_sync_cache
-scsi_write_same
-#endif SCSI2
-#endif /* NSCSI > 0 */
diff --git a/scsi/scsi_endian.h b/scsi/scsi_endian.h
deleted file mode 100644
index d298a78..0000000
--- a/scsi/scsi_endian.h
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * Mach Operating System
- * Copyright (c) 1991,1990 Carnegie Mellon University
- * All Rights Reserved.
- *
- * Permission to use, copy, modify and distribute this software and its
- * documentation is hereby granted, provided that both the copyright
- * notice and this permission notice appear in all copies of the
- * software, derivative works or modified versions, and any portions
- * thereof, and that both notices appear in supporting documentation.
- *
- * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
- * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
- * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
- *
- * Carnegie Mellon requests users of this software to return to
- *
- * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
- * School of Computer Science
- * Carnegie Mellon University
- * Pittsburgh PA 15213-3890
- *
- * any improvements or extensions that they make and grant Carnegie Mellon
- * the rights to redistribute these changes.
- */
-/*
- * File: scsi_endian.h
- * Author: Alessandro Forin, Carnegie Mellon University
- * Date: 6/91
- *
- * Byte/Bit order issues are solved here.
- */
-
-
-#ifndef _SCSI_ENDIAN_H_
-#define _SCSI_ENDIAN_H_ 1
-
-/*
- * Macros to take care of bitfield placement within a byte.
- * It might be possible to extend these to something that
- * takes care of multibyte structures, using perhaps the
- * type ("t") parameter. Someday.
- */
-#if BYTE_MSF
-
-#define BITFIELD_2(t,a,b) t b,a
-#define BITFIELD_3(t,a,b,c) t c,b,a
-#define BITFIELD_4(t,a,b,c,d) t d,c,b,a
-#define BITFIELD_5(t,a,b,c,d,e) t e,d,c,b,a
-#define BITFIELD_6(t,a,b,c,d,e,f) t f,e,d,c,b,a
-#define BITFIELD_7(t,a,b,c,d,e,f,g) t g,f,e,d,c,b,a
-#define BITFIELD_8(t,a,b,c,d,e,f,g,h) t h,g,f,e,d,c,b,a
-
-#else /*BYTE_MSF*/
-
-#define BITFIELD_2(t,a,b) t a,b
-#define BITFIELD_3(t,a,b,c) t a,b,c
-#define BITFIELD_4(t,a,b,c,d) t a,b,c,d
-#define BITFIELD_5(t,a,b,c,d,e) t a,b,c,d,e
-#define BITFIELD_6(t,a,b,c,d,e,f) t a,b,c,d,e
-#define BITFIELD_7(t,a,b,c,d,e,f,g) t a,b,c,d,e,f,g
-#define BITFIELD_8(t,a,b,c,d,e,f,g,h) t a,b,c,d,e,f,g,h
-
-#endif /*BYTE_MSF*/
-
-#endif /*_SCSI_ENDIAN_H_*/
diff --git a/scsi/scsi_jukebox.c b/scsi/scsi_jukebox.c
deleted file mode 100644
index b62d0bf..0000000
--- a/scsi/scsi_jukebox.c
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * Mach Operating System
- * Copyright (c) 1991,1990 Carnegie Mellon University
- * All Rights Reserved.
- *
- * Permission to use, copy, modify and distribute this software and its
- * documentation is hereby granted, provided that both the copyright
- * notice and this permission notice appear in all copies of the
- * software, derivative works or modified versions, and any portions
- * thereof, and that both notices appear in supporting documentation.
- *
- * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
- * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
- * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
- *
- * Carnegie Mellon requests users of this software to return to
- *
- * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
- * School of Computer Science
- * Carnegie Mellon University
- * Pittsburgh PA 15213-3890
- *
- * any improvements or extensions that they make and grant Carnegie Mellon
- * the rights to redistribute these changes.
- */
-/*
- * File: scsi_jukebox.c
- * Author: Alessandro Forin, Carnegie Mellon University
- * Date: 10/90
- *
- * Middle layer of the SCSI driver: SCSI protocol implementation
- *
- * This file contains code for SCSI commands for MEDIA CHANGER devices.
- */
-
-#include <scsi.h>
-#if (NSCSI > 0)
-
-#include <mach/std_types.h>
-
-char *scjb_name(internal)
- boolean_t internal;
-{
- return internal ? "jz" : "jukebox";
-}
-
-#if 0
-scsi_exchange_medium
-scsi_init_element_status
-scsi_move_medium
-scsi_position_to_element
-scsi_read_element_status
-scsi_request_volume_address
-scsi_send_volume_tag
-#endif
-#endif /* NSCSI > 0 */
-
diff --git a/scsi/scsi_optical.c b/scsi/scsi_optical.c
deleted file mode 100644
index 6188174..0000000
--- a/scsi/scsi_optical.c
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * Mach Operating System
- * Copyright (c) 1991,1990 Carnegie Mellon University
- * All Rights Reserved.
- *
- * Permission to use, copy, modify and distribute this software and its
- * documentation is hereby granted, provided that both the copyright
- * notice and this permission notice appear in all copies of the
- * software, derivative works or modified versions, and any portions
- * thereof, and that both notices appear in supporting documentation.
- *
- * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
- * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
- * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
- *
- * Carnegie Mellon requests users of this software to return to
- *
- * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
- * School of Computer Science
- * Carnegie Mellon University
- * Pittsburgh PA 15213-3890
- *
- * any improvements or extensions that they make and grant Carnegie Mellon
- * the rights to redistribute these changes.
- */
-/*
- * File: scsi_optical.c
- * Author: Alessandro Forin, Carnegie Mellon University
- * Date: 10/90
- *
- * Middle layer of the SCSI driver: SCSI protocol implementation
- *
- * This file contains code for SCSI commands for OPTICAL MEMORY devices.
- */
-
-#include <scsi.h>
-#if (NSCSI > 0)
-
-#include <mach/std_types.h>
-
-char *scmem_name(internal)
- boolean_t internal;
-{
- return internal ? "rz" : "optical disk";
-}
-
-#if 0
-scsi_erase_long
-scsi_medium_scan
-scsi_read_defect_data
-scsi_read_generation
-scsi_read_updated_block
-scsi_update_block
-scsi_write_verify_long
-#endif
-#endif /* NSCSI > 0 */
-
diff --git a/scsi/scsi_printer.c b/scsi/scsi_printer.c
deleted file mode 100644
index 0ffb09a..0000000
--- a/scsi/scsi_printer.c
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * Mach Operating System
- * Copyright (c) 1991,1990 Carnegie Mellon University
- * All Rights Reserved.
- *
- * Permission to use, copy, modify and distribute this software and its
- * documentation is hereby granted, provided that both the copyright
- * notice and this permission notice appear in all copies of the
- * software, derivative works or modified versions, and any portions
- * thereof, and that both notices appear in supporting documentation.
- *
- * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
- * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
- * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
- *
- * Carnegie Mellon requests users of this software to return to
- *
- * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
- * School of Computer Science
- * Carnegie Mellon University
- * Pittsburgh PA 15213-3890
- *
- * any improvements or extensions that they make and grant Carnegie Mellon
- * the rights to redistribute these changes.
- */
-/*
- * File: scsi_printer.c
- * Author: Alessandro Forin, Carnegie Mellon University
- * Date: 10/90
- *
- * Middle layer of the SCSI driver: SCSI protocol implementation
- *
- * This file contains code for SCSI commands for PRINTER devices.
- */
-
-#include <scsi.h>
-#if (NSCSI > 0)
-
-#include <mach/std_types.h>
-
-
-char *scprt_name(internal)
- boolean_t internal;
-{
- return internal ? "lz" : "printer";
-}
-
-void scprt_optimize()
-{}
-
-#if 0
-scsi_print
-scsi_slew_and_print
-scsi_flush_buffer
-scsi_stop_print
-#endif
-#endif /* NSCSI > 0 */
diff --git a/scsi/scsi_rom.c b/scsi/scsi_rom.c
deleted file mode 100644
index 1a8dec9..0000000
--- a/scsi/scsi_rom.c
+++ /dev/null
@@ -1,401 +0,0 @@
-/*
- * Mach Operating System
- * Copyright (c) 1991,1990 Carnegie Mellon University
- * All Rights Reserved.
- *
- * Permission to use, copy, modify and distribute this software and its
- * documentation is hereby granted, provided that both the copyright
- * notice and this permission notice appear in all copies of the
- * software, derivative works or modified versions, and any portions
- * thereof, and that both notices appear in supporting documentation.
- *
- * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
- * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
- * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
- *
- * Carnegie Mellon requests users of this software to return to
- *
- * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
- * School of Computer Science
- * Carnegie Mellon University
- * Pittsburgh PA 15213-3890
- *
- * any improvements or extensions that they make and grant Carnegie Mellon
- * the rights to redistribute these changes.
- */
-/*
- * File: scsi_rom.c
- * Author: Alessandro Forin, Carnegie Mellon University
- * Date: 10/90
- *
- * Middle layer of the SCSI driver: SCSI protocol implementation
- *
- * This file contains code for SCSI commands for CD-ROM devices.
- */
-
-#include <mach/std_types.h>
-#include <scsi/compat_30.h>
-
-#include <scsi/scsi.h>
-#include <scsi/scsi2.h>
-#include <scsi/scsi_defs.h>
-
-#if (NSCSI > 0)
-
-char *sccdrom_name(
- boolean_t internal)
-{
- return internal ? "rz" : "CD-ROM";
-}
-
-int scsi_pause_resume(
- target_info_t *tgt,
- boolean_t stop_it,
- io_req_t ior)
-{
- scsi_cmd_pausres_t *cmd;
-
- cmd = (scsi_cmd_pausres_t*) (tgt->cmd_ptr);
- cmd->scsi_cmd_code = SCSI_CMD_PAUSE_RESUME;
- cmd->scsi_cmd_lun_and_relbit = 0;
- cmd->scsi_cmd_lba1 = 0;
- cmd->scsi_cmd_lba2 = 0;
- cmd->scsi_cmd_lba3 = 0;
- cmd->scsi_cmd_lba4 = 0;
- cmd->scsi_cmd_xxx = 0;
- cmd->scsi_cmd_xfer_len_1 = 0;
- cmd->scsi_cmd_pausres_res = stop_it ? 0 : SCSI_CMD_PAUSRES_RESUME;
- cmd->scsi_cmd_ctrl_byte = 0; /* not linked */
-
- tgt->cur_cmd = SCSI_CMD_PAUSE_RESUME;
-
- scsi_go_and_wait(tgt, sizeof(*cmd), 0, ior);
-
- return tgt->done;
-}
-
-scsi_play_audio(
- target_info_t *tgt,
- unsigned int start,
- unsigned int len,
- boolean_t relative_address,
- io_req_t ior)
-{
- scsi_cmd_play_audio_t *cmd;
-
- cmd = (scsi_cmd_play_audio_t*) (tgt->cmd_ptr);
- cmd->scsi_cmd_code = SCSI_CMD_PLAY_AUDIO;
- cmd->scsi_cmd_lun_and_relbit = relative_address ? SCSI_RELADR : 0;
- cmd->scsi_cmd_lba1 = start >> 24;
- cmd->scsi_cmd_lba2 = start >> 16;
- cmd->scsi_cmd_lba3 = start >> 8;
- cmd->scsi_cmd_lba4 = start >> 0;
- cmd->scsi_cmd_xxx = 0;
- cmd->scsi_cmd_xfer_len_1 = len >> 8;
- cmd->scsi_cmd_xfer_len_2 = len >> 0;
- cmd->scsi_cmd_ctrl_byte = 0; /* not linked */
-
- tgt->cur_cmd = SCSI_CMD_PLAY_AUDIO;
-
- scsi_go_and_wait(tgt, sizeof(*cmd), 0, ior);
-
- return tgt->done;
-}
-
-scsi_play_audio_long(
- target_info_t *tgt,
- unsigned int start,
- unsigned int len,
- boolean_t relative_address,
- io_req_t ior)
-{
- scsi_cmd_play_audio_l_t *cmd;
-
- cmd = (scsi_cmd_play_audio_l_t*) (tgt->cmd_ptr);
- cmd->scsi_cmd_code = SCSI_CMD_PLAY_AUDIO_LONG;
- cmd->scsi_cmd_lun_and_relbit = relative_address ? SCSI_RELADR : 0;
- cmd->scsi_cmd_lba1 = start >> 24;
- cmd->scsi_cmd_lba2 = start >> 16;
- cmd->scsi_cmd_lba3 = start >> 8;
- cmd->scsi_cmd_lba4 = start >> 0;
- cmd->scsi_cmd_xfer_len_1 = len >> 24;
- cmd->scsi_cmd_xfer_len_2 = len >> 16;
- cmd->scsi_cmd_xfer_len_3 = len >> 8;
- cmd->scsi_cmd_xfer_len_4 = len >> 0;
- cmd->scsi_cmd_xxx1 = 0;
- cmd->scsi_cmd_ctrl_byte = 0; /* not linked */
-
- tgt->cur_cmd = SCSI_CMD_PLAY_AUDIO_LONG;
-
- scsi_go_and_wait(tgt, sizeof(*cmd), 0, ior);
-
- return tgt->done;
-}
-
-scsi_play_audio_msf(
- target_info_t *tgt,
- int sm,
- int ss,
- int sf,
- int em,
- int es,
- int ef,
- io_req_t ior)
-{
- scsi_cmd_play_audio_msf_t *cmd;
-
- cmd = (scsi_cmd_play_audio_msf_t*) (tgt->cmd_ptr);
- cmd->scsi_cmd_code = SCSI_CMD_PLAY_AUDIO_MSF;
- cmd->scsi_cmd_lun_and_relbit = 0;
- cmd->scsi_cmd_lba1 = 0;
- cmd->scsi_cmd_pamsf_startM = sm;
- cmd->scsi_cmd_pamsf_startS = ss;
- cmd->scsi_cmd_pamsf_startF = sf;
- cmd->scsi_cmd_pamsf_endM = em;
- cmd->scsi_cmd_pamsf_endS = es;
- cmd->scsi_cmd_pamsf_endF = ef;
- cmd->scsi_cmd_ctrl_byte = 0; /* not linked */
-
- tgt->cur_cmd = SCSI_CMD_PLAY_AUDIO_MSF;
-
- scsi_go_and_wait(tgt, sizeof(*cmd), 0, ior);
-
- return tgt->done;
-}
-
-scsi_play_audio_track_index(
- target_info_t *tgt,
- int st,
- int si,
- int et,
- int ei,
- io_req_t ior)
-{
- scsi_cmd_play_audio_ti_t *cmd;
-
- cmd = (scsi_cmd_play_audio_ti_t*) (tgt->cmd_ptr);
- cmd->scsi_cmd_code = SCSI_CMD_PLAY_AUDIO_TI;
- cmd->scsi_cmd_lun_and_relbit = 0;
- cmd->scsi_cmd_lba1 = 0;
- cmd->scsi_cmd_lba2 = 0;
- cmd->scsi_cmd_pati_startT = st;
- cmd->scsi_cmd_pati_startI = si;
- cmd->scsi_cmd_xxx = 0;
- cmd->scsi_cmd_pati_endT = et;
- cmd->scsi_cmd_pati_endI = ei;
- cmd->scsi_cmd_ctrl_byte = 0; /* not linked */
-
- tgt->cur_cmd = SCSI_CMD_PLAY_AUDIO_TI;
-
- scsi_go_and_wait(tgt, sizeof(*cmd), 0, ior);
-
- return tgt->done;
-}
-
-scsi_play_audio_track_relative(
- target_info_t *tgt,
- unsigned int lba,
- int st,
- unsigned int len,
- io_req_t ior)
-{
- scsi_cmd_play_audio_tr_t *cmd;
-
- cmd = (scsi_cmd_play_audio_tr_t*) (tgt->cmd_ptr);
- cmd->scsi_cmd_code = SCSI_CMD_PLAY_AUDIO_TR;
- cmd->scsi_cmd_lun_and_relbit = 0;
- cmd->scsi_cmd_lba1 = lba >> 24;
- cmd->scsi_cmd_lba2 = lba >> 16;
- cmd->scsi_cmd_lba3 = lba >> 8;
- cmd->scsi_cmd_lba4 = lba >> 0;
- cmd->scsi_cmd_patr_startT = st;
- cmd->scsi_cmd_xfer_len_1 = len >> 8;
- cmd->scsi_cmd_xfer_len_2 = len >> 0;
- cmd->scsi_cmd_ctrl_byte = 0; /* not linked */
-
- tgt->cur_cmd = SCSI_CMD_PLAY_AUDIO_TR;
-
- scsi_go_and_wait(tgt, sizeof(*cmd), 0, ior);
-
- return tgt->done;
-}
-
-scsi_play_audio_track_relative_long(
- target_info_t *tgt,
- unsigned int lba,
- int st,
- unsigned int len,
- io_req_t ior)
-{
- scsi_cmd_play_audio_tr_l_t *cmd;
-
- cmd = (scsi_cmd_play_audio_tr_l_t*) (tgt->cmd_ptr);
- cmd->scsi_cmd_code = SCSI_CMD_PLAY_AUDIO_TR_LONG;
- cmd->scsi_cmd_lun_and_relbit = 0;
- cmd->scsi_cmd_lba1 = lba >> 24;
- cmd->scsi_cmd_lba2 = lba >> 16;
- cmd->scsi_cmd_lba3 = lba >> 8;
- cmd->scsi_cmd_lba4 = lba >> 0;
- cmd->scsi_cmd_xfer_len_1 = len >> 24;
- cmd->scsi_cmd_xfer_len_2 = len >> 16;
- cmd->scsi_cmd_xfer_len_3 = len >> 8;
- cmd->scsi_cmd_xfer_len_4 = len >> 0;
- cmd->scsi_cmd_patrl_startT = st;
- cmd->scsi_cmd_ctrl_byte = 0; /* not linked */
-
- tgt->cur_cmd = SCSI_CMD_PLAY_AUDIO_TR_LONG;
-
- scsi_go_and_wait(tgt, sizeof(*cmd), 0, ior);
-
- return tgt->done;
-}
-
-scsi_read_header(
- target_info_t *tgt,
- boolean_t msf_format,
- unsigned int lba,
- unsigned int allocsize,
- io_req_t ior)
-{
- scsi_cmd_read_header_t *cmd;
-
- cmd = (scsi_cmd_read_header_t*) (tgt->cmd_ptr);
- cmd->scsi_cmd_code = SCSI_CMD_READ_HEADER;
- cmd->scsi_cmd_lun_and_relbit = msf_format ? SCSI_CMD_CD_MSF : 0;
- cmd->scsi_cmd_lba1 = lba >> 24;
- cmd->scsi_cmd_lba2 = lba >> 16;
- cmd->scsi_cmd_lba3 = lba >> 8;
- cmd->scsi_cmd_lba4 = lba >> 0;
- cmd->scsi_cmd_xxx = 0;
- cmd->scsi_cmd_xfer_len_1 = allocsize >> 8;
- cmd->scsi_cmd_xfer_len_2 = allocsize >> 0;
- cmd->scsi_cmd_ctrl_byte = 0; /* not linked */
-
- tgt->cur_cmd = SCSI_CMD_READ_HEADER;
-
- scsi_go_and_wait(tgt, sizeof(*cmd), allocsize, ior);
-
- return tgt->done;
-}
-
-scsi_read_subchannel(
- target_info_t *tgt,
- boolean_t msf_format,
- unsigned int data_format,
- unsigned int trackno,
- io_req_t ior)
-{
- scsi_cmd_read_subch_t *cmd;
- int allocsize;
-
- switch (data_format) {
- case SCSI_CMD_RS_FMT_SUBQ:
- allocsize = sizeof(cdrom_chan_data_t);
- trackno = 0; break;
- case SCSI_CMD_RS_FMT_CURPOS:
- allocsize = sizeof(cdrom_chan_curpos_t);
- trackno = 0; break;
- case SCSI_CMD_RS_FMT_CATALOG:
- allocsize = sizeof(cdrom_chan_catalog_t);
- trackno = 0; break;
- case SCSI_CMD_RS_FMT_ISRC:
- allocsize = sizeof(cdrom_chan_isrc_t); break;
- }
-
- cmd = (scsi_cmd_read_subch_t*) (tgt->cmd_ptr);
- cmd->scsi_cmd_code = SCSI_CMD_READ_SUBCH;
- cmd->scsi_cmd_lun_and_relbit = msf_format ? SCSI_CMD_CD_MSF : 0;
- cmd->scsi_cmd_lba1 = SCSI_CMD_RS_SUBQ;
- cmd->scsi_cmd_rs_format = data_format;
- cmd->scsi_cmd_lba3 = 0;
- cmd->scsi_cmd_lba4 = 0;
- cmd->scsi_cmd_rs_trackno = trackno;
- cmd->scsi_cmd_xfer_len_1 = allocsize >> 8;
- cmd->scsi_cmd_xfer_len_2 = allocsize >> 0;
- cmd->scsi_cmd_ctrl_byte = 0; /* not linked */
-
- tgt->cur_cmd = SCSI_CMD_READ_SUBCH;
-
- scsi_go_and_wait(tgt, sizeof(*cmd), allocsize, ior);
-
- return tgt->done;
-}
-
-scsi_read_toc(
- target_info_t *tgt,
- boolean_t msf_format,
- int trackno,
- int allocsize,
- io_req_t ior)
-{
- scsi_cmd_read_toc_t *cmd;
-
- cmd = (scsi_cmd_read_toc_t*) (tgt->cmd_ptr);
- cmd->scsi_cmd_code = SCSI_CMD_READ_TOC;
- cmd->scsi_cmd_lun_and_relbit = msf_format ? SCSI_CMD_CD_MSF : 0;
- cmd->scsi_cmd_lba1 = 0;
- cmd->scsi_cmd_lba2 = 0;
- cmd->scsi_cmd_lba3 = 0;
- cmd->scsi_cmd_lba4 = 0;
- cmd->scsi_cmd_rtoc_startT = trackno;
- cmd->scsi_cmd_xfer_len_1 = allocsize >> 8;
- cmd->scsi_cmd_xfer_len_2 = allocsize >> 0;
- cmd->scsi_cmd_ctrl_byte = 0; /* not linked */
-
- tgt->cur_cmd = SCSI_CMD_READ_TOC;
-
- scsi_go_and_wait(tgt, sizeof(*cmd), allocsize, ior);
-
- return tgt->done;
-}
-
-/* move elsewhere ifworks */
-scsi2_mode_select(
- target_info_t *tgt,
- boolean_t save,
- unsigned char *page,
- int pagesize,
- io_req_t ior)
-{
- scsi_cmd_mode_select_t *cmd;
- scsi2_mode_param_t *parm;
-
- bzero(tgt->cmd_ptr, sizeof(*cmd) + sizeof(*parm));
- cmd = (scsi_cmd_mode_select_t*) (tgt->cmd_ptr);
- cmd->scsi_cmd_code = SCSI_CMD_MODE_SELECT;
- cmd->scsi_cmd_lun_and_lba1 = SCSI_CMD_MSL_PF | (save ? SCSI_CMD_MSL_SP : 0);
- cmd->scsi_cmd_xfer_len = pagesize;
-
- parm = (scsi2_mode_param_t*) (cmd + 1);
-
- bcopy(page, parm, pagesize);
-
- tgt->cur_cmd = SCSI_CMD_MODE_SELECT;
-
- scsi_go_and_wait(tgt, sizeof(*cmd) + pagesize, 0, ior);
-
- return tgt->done;
-}
-
-/*
- * obnoxious
- */
-cdrom_vendor_specific(
- target_info_t *tgt,
- scsi_command_group_2 *cmd,
- unsigned char *params,
- int paramlen,
- int retlen,
- io_req_t ior)
-{
- bcopy(cmd, tgt->cmd_ptr, sizeof(*cmd));
- if (paramlen)
- bcopy(params, tgt->cmd_ptr + sizeof(*cmd), paramlen);
-
- tgt->cur_cmd = cmd->scsi_cmd_code;
-
- scsi_go_and_wait(tgt, sizeof(*cmd) + paramlen, retlen, ior);
-
- return tgt->done;
-}
-#endif /* NSCSI > 0 */
diff --git a/scsi/scsi_scanner.c b/scsi/scsi_scanner.c
deleted file mode 100644
index b6ba358..0000000
--- a/scsi/scsi_scanner.c
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * Mach Operating System
- * Copyright (c) 1991,1990 Carnegie Mellon University
- * All Rights Reserved.
- *
- * Permission to use, copy, modify and distribute this software and its
- * documentation is hereby granted, provided that both the copyright
- * notice and this permission notice appear in all copies of the
- * software, derivative works or modified versions, and any portions
- * thereof, and that both notices appear in supporting documentation.
- *
- * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
- * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
- * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
- *
- * Carnegie Mellon requests users of this software to return to
- *
- * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
- * School of Computer Science
- * Carnegie Mellon University
- * Pittsburgh PA 15213-3890
- *
- * any improvements or extensions that they make and grant Carnegie Mellon
- * the rights to redistribute these changes.
- */
-/*
- * File: scsi_scanner.c
- * Author: Alessandro Forin, Carnegie Mellon University
- * Date: 10/90
- *
- * Middle layer of the SCSI driver: SCSI protocol implementation
- *
- * This file contains code for SCSI commands for SCANNER devices.
- */
-
-#include <scsi.h>
-#if (NSCSI > 0)
-
-#include <mach/std_types.h>
-
-char *scscn_name(internal)
- boolean_t internal;
-{
- return internal ? "oz" : "scanner";
-}
-
-#if 0
-scsi_get_buffer_status
-scsi_get_window
-scsi_object_position
-scsi_scan
-scsi_set_window
-#endif
-#endif /* NSCSI > 0 */
diff --git a/scsi/scsi_tape.c b/scsi/scsi_tape.c
deleted file mode 100644
index c73f432..0000000
--- a/scsi/scsi_tape.c
+++ /dev/null
@@ -1,415 +0,0 @@
-/*
- * Mach Operating System
- * Copyright (c) 1991,1990 Carnegie Mellon University
- * All Rights Reserved.
- *
- * Permission to use, copy, modify and distribute this software and its
- * documentation is hereby granted, provided that both the copyright
- * notice and this permission notice appear in all copies of the
- * software, derivative works or modified versions, and any portions
- * thereof, and that both notices appear in supporting documentation.
- *
- * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
- * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
- * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
- *
- * Carnegie Mellon requests users of this software to return to
- *
- * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
- * School of Computer Science
- * Carnegie Mellon University
- * Pittsburgh PA 15213-3890
- *
- * any improvements or extensions that they make and grant Carnegie Mellon
- * the rights to redistribute these changes.
- */
-/*
- * File: scsi_tape.c
- * Author: Alessandro Forin, Carnegie Mellon University
- * Date: 10/90
- *
- * Middle layer of the SCSI driver: SCSI protocol implementation
- *
- * This file contains code for SCSI commands for SEQUENTIAL ACCESS devices.
- */
-
-#include <mach/std_types.h>
-#include <scsi/compat_30.h>
-
-#include <scsi/scsi.h>
-#include <scsi/scsi_defs.h>
-
-#if (NSCSI > 0)
-
-
-char *sctape_name(internal)
- boolean_t internal;
-{
- return internal ? "tz" : "tape";
-}
-
-void sctape_optimize(tgt)
- target_info_t *tgt;
-{
- register int i;
- char result[6];
-
- /* Some (DEC) tapes want to send you the self-test results */
- for (i = 0; i < 10; i++) {
- if (scsi_receive_diag( tgt, result, sizeof(result), 0)
- == SCSI_RET_SUCCESS)
- break;
- }
- if (scsi_debug)
- printf("[tape_rcvdiag: after %d, x%x x%x x%x x%x x%x x%x]\n", i+1,
- result[0], result[1], result[2], result[3], result[4], result[5]);
-}
-
-/*
- * SCSI commands specific to sequential access devices
- */
-int sctape_mode_select( tgt, vuque_data, vuque_data_len, newspeed, ior)
- register target_info_t *tgt;
- unsigned char *vuque_data;
- int vuque_data_len;
- int newspeed;
- io_req_t ior;
-{
- scsi_cmd_mode_select_t *cmd;
- scsi_mode_select_param_t *parm;
-
- bzero(tgt->cmd_ptr, sizeof(*cmd) + 2 * sizeof(*parm));
- cmd = (scsi_cmd_mode_select_t*) (tgt->cmd_ptr);
- cmd->scsi_cmd_code = SCSI_CMD_MODE_SELECT;
- cmd->scsi_cmd_lun_and_lba1 = 0;
- cmd->scsi_cmd_xfer_len = sizeof(scsi_mode_select_param_t) + vuque_data_len;
-
- parm = (scsi_mode_select_param_t*) (cmd + 1);
- if (newspeed) {
- parm->speed = tgt->dev_info.tape.speed;
- } else {
- /* Standard sez 0 -> no change */
- parm->speed = 0;
- }
- /* parm->medium_type = 0; reserved */
- parm->descs[0].density_code = tgt->dev_info.tape.density;
- parm->buffer_mode = 1;
- parm->desc_len = 8;
- if (tgt->dev_info.tape.fixed_size) {
- register int reclen = tgt->block_size;
- parm->descs[0].reclen1 = reclen >> 16;
- parm->descs[0].reclen2 = reclen >> 8;
- parm->descs[0].reclen3 = reclen;
- }
-
- if (vuque_data_len)
- bcopy(vuque_data, (char*)(parm+1), vuque_data_len);
-
- tgt->cur_cmd = SCSI_CMD_MODE_SELECT;
-
- scsi_go_and_wait(tgt, sizeof(*cmd) + sizeof(*parm) + vuque_data_len, 0, ior);
-
- return tgt->done;
-}
-
-void sctape_read( tgt, ior)
- register target_info_t *tgt;
- io_req_t ior;
-{
- scsi_cmd_read_t *cmd;
- register unsigned len, max;
-# define nbytes max
- boolean_t fixed = FALSE;
-
- max = scsi_softc[(unsigned char)tgt->masterno]->max_dma_data;
-
- len = ior->io_count;
- if (tgt->dev_info.tape.fixed_size) {
- unsigned int bs = tgt->block_size;
- fixed = TRUE;
- nbytes = len;
- ior->io_residual += len % bs;
- len = len / bs;
- } else {
- if (max > tgt->dev_info.tape.maxreclen)
- max = tgt->dev_info.tape.maxreclen;
- if (len > max) {
- ior->io_residual = len - max;
- len = max;
- }
- if (len < tgt->block_size)
- len = tgt->block_size;
- nbytes = len;
- }
-
- cmd = (scsi_cmd_read_t*) (tgt->cmd_ptr);
- cmd->scsi_cmd_code = SCSI_CMD_READ;
- cmd->scsi_cmd_lun_and_lba1 = fixed ? SCSI_CMD_TP_FIXED : 0;
- cmd->scsi_cmd_lba2 = len >> 16;
- cmd->scsi_cmd_lba3 = len >> 8;
- cmd->scsi_cmd_xfer_len = len;
- cmd->scsi_cmd_ctrl_byte = 0; /* not linked */
-
- tgt->cur_cmd = SCSI_CMD_READ;
-
- scsi_go(tgt, sizeof(*cmd), nbytes, FALSE);
-#undef nbytes
-}
-
-void sctape_write( tgt, ior)
- register target_info_t *tgt;
- io_req_t ior;
-{
- scsi_cmd_write_t *cmd;
- register unsigned len, max;
- boolean_t fixed = FALSE;
-
- len = ior->io_count;
- max = scsi_softc[(unsigned char)tgt->masterno]->max_dma_data;
-
- if (tgt->dev_info.tape.fixed_size) {
- unsigned int bs = tgt->block_size;
- fixed = TRUE;
- ior->io_residual += len % bs;
- len = len / bs;
- } else {
- if (max > tgt->dev_info.tape.maxreclen)
- max = tgt->dev_info.tape.maxreclen;
- if (len > max) {
- ior->io_residual = len - max;
- len = max;
- }
- if (len < tgt->block_size)
- len = tgt->block_size;
- }
-
- cmd = (scsi_cmd_write_t*) (tgt->cmd_ptr);
- cmd->scsi_cmd_code = SCSI_CMD_WRITE;
- cmd->scsi_cmd_lun_and_lba1 = fixed ? SCSI_CMD_TP_FIXED : 0;
- cmd->scsi_cmd_lba2 = len >> 16;
- cmd->scsi_cmd_lba3 = len >> 8;
- cmd->scsi_cmd_xfer_len = len;
- cmd->scsi_cmd_ctrl_byte = 0; /* not linked */
-
- tgt->cur_cmd = SCSI_CMD_WRITE;
-
- scsi_go(tgt, sizeof(*cmd), 0, FALSE);
-}
-
-int scsi_rewind( tgt, ior, wait)
- register target_info_t *tgt;
- io_req_t ior;
- boolean_t wait;
-{
- scsi_cmd_rewind_t *cmd;
-
-
- cmd = (scsi_cmd_rewind_t*) (tgt->cmd_ptr);
- cmd->scsi_cmd_code = SCSI_CMD_REWIND;
- cmd->scsi_cmd_lun_and_lba1 = wait ? 0 : SCSI_CMD_REW_IMMED;
- cmd->scsi_cmd_lba2 = 0;
- cmd->scsi_cmd_lba3 = 0;
- cmd->scsi_cmd_xfer_len = 0;
- cmd->scsi_cmd_ctrl_byte = 0; /* not linked */
-
- tgt->cur_cmd = SCSI_CMD_REWIND;
-
- scsi_go( tgt, sizeof(*cmd), 0, FALSE);
- return SCSI_RET_SUCCESS;
-}
-
-int scsi_write_filemarks( tgt, count, ior)
- register target_info_t *tgt;
- register unsigned int count;
- io_req_t ior;
-{
- scsi_cmd_write_fil_t *cmd;
-
- cmd = (scsi_cmd_write_fil_t*) (tgt->cmd_ptr);
- cmd->scsi_cmd_code = SCSI_CMD_WRITE_FILEMARKS;
- cmd->scsi_cmd_lun_and_lba1 = 0;
- cmd->scsi_cmd_lba2 = count >> 16;
- cmd->scsi_cmd_lba3 = count >> 8;
- cmd->scsi_cmd_xfer_len = count;
- cmd->scsi_cmd_ctrl_byte = 0; /* not linked */
-
-
- tgt->cur_cmd = SCSI_CMD_WRITE_FILEMARKS;
-
- scsi_go_and_wait(tgt, sizeof(*cmd), 0, ior);
-
- return tgt->done;
-}
-
-int scsi_space( tgt, mode, count, ior)
- register target_info_t *tgt;
- int mode;
- register int count;
- io_req_t ior;
-{
- scsi_cmd_space_t *cmd;
-
- cmd = (scsi_cmd_space_t*) (tgt->cmd_ptr);
- cmd->scsi_cmd_code = SCSI_CMD_SPACE;
- cmd->scsi_cmd_lun_and_lba1 = mode & 0x3;
- cmd->scsi_cmd_lba2 = count >> 16;
- cmd->scsi_cmd_lba3 = count >> 8;
- cmd->scsi_cmd_xfer_len = count;
- cmd->scsi_cmd_ctrl_byte = 0; /* not linked */
-
-
- tgt->cur_cmd = SCSI_CMD_SPACE;
-
- scsi_go_and_wait(tgt, sizeof(*cmd), 0, ior);
-
- return tgt->done;
-}
-
-
-int scsi_read_block_limits( tgt, ior)
- register target_info_t *tgt;
- io_req_t ior;
-{
- scsi_cmd_block_limits_t *cmd;
-
- cmd = (scsi_cmd_block_limits_t*) (tgt->cmd_ptr);
- cmd->scsi_cmd_code = SCSI_CMD_READ_BLOCK_LIMITS;
- cmd->scsi_cmd_lun_and_lba1 = 0;
- cmd->scsi_cmd_lba2 = 0;
- cmd->scsi_cmd_lba3 = 0;
- cmd->scsi_cmd_xfer_len = 0;
- cmd->scsi_cmd_ctrl_byte = 0; /* not linked */
-
-
- tgt->cur_cmd = SCSI_CMD_READ_BLOCK_LIMITS;
-
- scsi_go_and_wait(tgt, sizeof(*cmd), sizeof(scsi_blimits_data_t), ior);
- return tgt->done;
-}
-
-#if 0 /* unused */
-
-void scsi_track_select( tgt, trackno, ior)
- register target_info_t *tgt;
- register unsigned char trackno;
- io_req_t ior;
-{
- scsi_cmd_seek_t *cmd;
-
- cmd = (scsi_cmd_seek_t*) (tgt->cmd_ptr);
- cmd->scsi_cmd_code = SCSI_CMD_TRACK_SELECT;
- cmd->scsi_cmd_lun_and_lba1 = 0;
- cmd->scsi_cmd_lba2 = 0;
- cmd->scsi_cmd_lba3 = 0;
- cmd->scsi_cmd_tp_trackno = trackno;
- cmd->scsi_cmd_ctrl_byte = 0; /* not linked */
-
-
- tgt->cur_cmd = SCSI_CMD_TRACK_SELECT;
-
- scsi_go_and_wait(tgt, sizeof(*cmd), 0, ior);
-}
-
-void scsi_read_reverse( tgt, ior)
- register target_info_t *tgt;
- io_req_t ior;
-{
- scsi_cmd_rev_read_t *cmd;
- register unsigned len;
- unsigned int max_dma_data;
-
- max_dma_data = scsi_softc[(unsigned char)tgt->masterno]->max_dma_data;
-
- len = ior->io_count;
- if (len > max_dma_data)
- len = max_dma_data;
-
- cmd = (scsi_cmd_rev_read_t*) (tgt->cmd_ptr);
- cmd->scsi_cmd_code = SCSI_CMD_READ_REVERSE;
- cmd->scsi_cmd_lun_and_lba1 = 0;
- cmd->scsi_cmd_lba2 = len >> 16;
- cmd->scsi_cmd_lba3 = len >> 8;
- cmd->scsi_cmd_xfer_len = len;
- cmd->scsi_cmd_ctrl_byte = 0; /* not linked */
-
- tgt->cur_cmd = SCSI_CMD_READ_REVERSE;
-
- scsi_go(tgt, sizeof(*cmd), len, FALSE);
-}
-
-void sctape_verify( tgt, len, ior)
- register target_info_t *tgt;
- register unsigned int len;
- io_req_t ior;
-{
- scsi_cmd_verify_t *cmd;
-
- cmd = (scsi_cmd_verify_t*) (tgt->cmd_ptr);
- cmd->scsi_cmd_code = SCSI_CMD_VERIFY_0;
- cmd->scsi_cmd_lun_and_lba1 = 0;/* XXX */
- cmd->scsi_cmd_lba2 = len >> 16;
- cmd->scsi_cmd_lba3 = len >> 8;
- cmd->scsi_cmd_xfer_len = len;
- cmd->scsi_cmd_ctrl_byte = 0; /* not linked */
-
-
- tgt->cur_cmd = SCSI_CMD_VERIFY_0;
-
- scsi_go_and_wait(tgt, sizeof(*cmd), 0, ior);
-}
-
-
-void scsi_recover_buffered_data( tgt, ior)
- register target_info_t *tgt;
- io_req_t ior;
-{
- scsi_cmd_recover_buffer_t *cmd;
- register unsigned len;
- unsigned int max_dma_data;
-
- max_dma_data = scsi_softc[(unsigned char)tgt->masterno]->max_dma_data;
-
- len = ior->io_count;
- if (len > max_dma_data)
- len = max_dma_data;
-
- cmd = (scsi_cmd_recover_buffer_t*) (tgt->cmd_ptr);
- cmd->scsi_cmd_code = SCSI_CMD_RECOVER_BUFFERED_DATA;
- cmd->scsi_cmd_lun_and_lba1 = 0;
- cmd->scsi_cmd_lba2 = len >> 16;
- cmd->scsi_cmd_lba3 = len >> 8;
- cmd->scsi_cmd_xfer_len = len;
- cmd->scsi_cmd_ctrl_byte = 0; /* not linked */
-
- tgt->cur_cmd = SCSI_CMD_RECOVER_BUFFERED_DATA;
-
- scsi_go(tgt, sizeof(*cmd), len, FALSE);
-}
-
-void scsi_erase( tgt, mode, ior)
- register target_info_t *tgt;
- io_req_t ior;
-{
- scsi_cmd_erase_t *cmd;
-
- cmd = (scsi_cmd_erase_t*) (tgt->cmd_ptr);
- cmd->scsi_cmd_code = SCSI_CMD_ERASE;
- cmd->scsi_cmd_lun_and_lba1 = mode & SCSI_CMD_ER_LONG;
- cmd->scsi_cmd_lba2 = 0;
- cmd->scsi_cmd_lba3 = 0;
- cmd->scsi_cmd_xfer_len = 0;
- cmd->scsi_cmd_ctrl_byte = 0; /* not linked */
-
-
- tgt->cur_cmd = SCSI_CMD_ERASE;
-
- scsi_go_and_wait(tgt, sizeof(*cmd), 0, ior);
-}
-
-#endif
-
-#ifdef SCSI2
-scsi_locate
-scsi_read_position
-#endif SCSI2
-#endif /* NSCSI > 0 */
diff --git a/scsi/scsi_worm.c b/scsi/scsi_worm.c
deleted file mode 100644
index 7490ea2..0000000
--- a/scsi/scsi_worm.c
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * Mach Operating System
- * Copyright (c) 1991,1990 Carnegie Mellon University
- * All Rights Reserved.
- *
- * Permission to use, copy, modify and distribute this software and its
- * documentation is hereby granted, provided that both the copyright
- * notice and this permission notice appear in all copies of the
- * software, derivative works or modified versions, and any portions
- * thereof, and that both notices appear in supporting documentation.
- *
- * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
- * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
- * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
- *
- * Carnegie Mellon requests users of this software to return to
- *
- * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
- * School of Computer Science
- * Carnegie Mellon University
- * Pittsburgh PA 15213-3890
- *
- * any improvements or extensions that they make and grant Carnegie Mellon
- * the rights to redistribute these changes.
- */
-/*
- * File: scsi_worm.c
- * Author: Alessandro Forin, Carnegie Mellon University
- * Date: 10/90
- *
- * Middle layer of the SCSI driver: SCSI protocol implementation
- *
- * This file contains code for SCSI commands for WORM devices,
- * e.g. disks that employ write once / read multiple media.
- */
-
-#include <mach/std_types.h>
-
-
-
-char *scworm_name(internal)
- boolean_t internal;
-{
- return internal ? "rz" : "WORM-disk";
-}
-
-#ifdef SCSI2
-see optical mem:
- - no format
- - no "update"
-#endif SCSI2