Switch to MI SCSI and drop old pmax MD SCSI support completely.
This commit is contained in:
parent
47bb32d470
commit
cddf6cf55b
|
@ -1,11 +1,11 @@
|
|||
#
|
||||
# $NetBSD: GENERIC,v 1.88 2001/07/08 16:32:23 abs Exp $
|
||||
# $NetBSD: GENERIC,v 1.89 2001/08/26 11:47:20 simonb Exp $
|
||||
#
|
||||
# Distribution kernel (any model) kernel config file
|
||||
#
|
||||
include "arch/pmax/conf/std.pmax"
|
||||
|
||||
#ident "GENERIC-$Revision: 1.88 $"
|
||||
#ident "GENERIC-$Revision: 1.89 $"
|
||||
|
||||
maxusers 64
|
||||
|
||||
|
@ -100,6 +100,7 @@ options IPFILTER_LOG # ipmon(8) log support
|
|||
#options TCP_DEBUG # Record last TCP_NDEBUG packets with SO_DEBUG
|
||||
|
||||
# NetBSD backwards compatibility
|
||||
#options EXEC_ELF_CATCHALL # Older .note-less ELF binaries
|
||||
#options COMPAT_10 # NetBSD 1.0, (needed for X on 386?)
|
||||
#options COMPAT_11 # NetBSD 1.1,
|
||||
options COMPAT_12 # Netbsd 1.2 reboot()
|
||||
|
@ -115,6 +116,7 @@ options FONT_LUCIDA16x29 # Font for px devices
|
|||
|
||||
# pmax specific
|
||||
options COMPAT_ULTRIX # Ultrix compatibility
|
||||
#options EXEC_AOUT # Old NetBSD/pmax a.out compatibility
|
||||
options EXEC_ECOFF # Ultrix RISC binaries are ECOFF format
|
||||
options "HZ=256" # RTC rate required
|
||||
|
||||
|
@ -143,7 +145,6 @@ audio* at bba?
|
|||
dtop* at ioasic? offset ? # MAXINE kbd and mouse
|
||||
#fdc at ioasic? offset ? # MAXINE floppy disk (not supported)
|
||||
asc* at ioasic? offset ? # NCR53C94 SCSI with IOASIC
|
||||
#xasc* at ioasic? offset ? # [ MI SCSI version ]
|
||||
|
||||
# 3MAX has TURBOchannel but no IOASIC
|
||||
ibus0 at tc? slot ? offset ? # 3MAX system slot
|
||||
|
@ -161,38 +162,30 @@ px0 at tc? slot ? offset ? # PMAG-C,D,E,F PX family
|
|||
#sfbp* at tc? slot ? offset ? # PMAGD HX+ Smart Framebuffer
|
||||
xcfb* at tc? slot ? offset ? # PMAG-DV Color Framebuffer at MAXINE
|
||||
asc* at tc? slot ? offset ? # PMAZ-A single channel SCSI
|
||||
#xasc* at tc? slot ? offset ? # [ MI SCSI version ]
|
||||
le* at tc? slot ? offset ? # PMAD-A LANCE
|
||||
fta* at tc? slot ? offset ? # PMAF-F FDDI
|
||||
#tcds* at tc? slot ? offset ? # PMAZB/PMAZC dual channel SCSI
|
||||
#asc* at tcds? chip ?
|
||||
tcds* at tc? slot ? offset ? # PMAZB/PMAZC dual channel SCSI
|
||||
asc* at tcds? chip ?
|
||||
|
||||
# PMAX and MIPSMATE
|
||||
ibus0 at mainbus0
|
||||
pm* at ibus0 addr ? # 3100 onboard fb
|
||||
le* at ibus0 addr ? # 3100, 5100 onboard LANCE
|
||||
sii* at ibus0 addr ? # DC7061 onboard SCSI
|
||||
#xsii* at ibus0 addr ? # [ MI SCSI version ]
|
||||
|
||||
#########################################################################
|
||||
# SCSI configuration #
|
||||
#########################################################################
|
||||
|
||||
# old 4.4BSD/pmax DECstation SCSI driver
|
||||
oldscsibus* at sii?
|
||||
oldscsibus* at asc?
|
||||
include "arch/pmax/conf/scsi.pmax"
|
||||
scsibus* at sii?
|
||||
scsibus* at asc?
|
||||
|
||||
# MI SCSI configuration
|
||||
#scsibus* at xsii?
|
||||
#scsibus* at xasc?
|
||||
#
|
||||
#sd* at scsibus? target ? lun ? # SCSI disks
|
||||
#st* at scsibus? target ? lun ? # SCSI tapes
|
||||
#cd* at scsibus? target ? lun ? # SCSI CD-ROMs
|
||||
#ch* at scsibus? target ? lun ? # SCSI changer devices
|
||||
#ss* at scsibus? target ? lun ? # SCSI scanners
|
||||
#uk* at scsibus? target ? lun ? # unknown SCSI
|
||||
sd* at scsibus? target ? lun ? # SCSI disks
|
||||
st* at scsibus? target ? lun ? # SCSI tapes
|
||||
cd* at scsibus? target ? lun ? # SCSI CD-ROMs
|
||||
ch* at scsibus? target ? lun ? # SCSI changer devices
|
||||
ss* at scsibus? target ? lun ? # SCSI scanners
|
||||
uk* at scsibus? target ? lun ? # unknown SCSI
|
||||
|
||||
#########################################################################
|
||||
# Pseudo-devices #
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
# $NetBSD: INSTALL,v 1.40 2001/07/08 16:32:23 abs Exp $
|
||||
# $NetBSD: INSTALL,v 1.41 2001/08/26 11:47:20 simonb Exp $
|
||||
#
|
||||
# Distribution install kernel (any model)
|
||||
# netbsd: cut-down kernel for miniroots.
|
||||
|
@ -130,10 +130,11 @@ sii* at ibus0 addr ? # DC7061 onboard SCSI
|
|||
# SCSI configuration #
|
||||
#########################################################################
|
||||
|
||||
# SCSI configuration for old 4.4BSD/pmax DECstation SCSI driver
|
||||
oldscsibus* at sii?
|
||||
oldscsibus* at asc?
|
||||
include "arch/pmax/conf/scsi.pmax"
|
||||
scsibus* at sii?
|
||||
scsibus* at asc?
|
||||
sd* at scsibus? target ? lun ? # SCSI disks
|
||||
st* at scsibus? target ? lun ? # SCSI tapes
|
||||
cd* at scsibus? target ? lun ? # SCSI CD-ROMs
|
||||
|
||||
#########################################################################
|
||||
# Pseudo-devices #
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
# $NetBSD: SULACO,v 1.8 2001/07/08 16:32:23 abs Exp $
|
||||
# $NetBSD: SULACO,v 1.9 2001/08/26 11:47:20 simonb Exp $
|
||||
#
|
||||
# sulaco.nas.nasa.gov - thorpej's DECstation 5000/200
|
||||
#
|
||||
|
@ -152,10 +152,12 @@ fta* at tc? slot ? offset ? # PMAF-F FDDI
|
|||
#le* at ibus0 addr ? # 3100 onboard LANCE
|
||||
#sii* at ibus0 addr ? # DC7061 onboard SCSI
|
||||
|
||||
# XXX Old DECstation SCSI code.
|
||||
#oldscsibus* at sii?
|
||||
oldscsibus* at asc?
|
||||
include "arch/pmax/conf/scsi.pmax"
|
||||
# SCSI configuration
|
||||
#scsibus* at sii?
|
||||
scsibus* at asc?
|
||||
sd* at scsibus? target ? lun ? # SCSI disks
|
||||
st* at scsibus? target ? lun ? # SCSI tapes
|
||||
cd* at scsibus? target ? lun ? # SCSI CD-ROMs
|
||||
|
||||
pseudo-device loop 1 # network loopback
|
||||
#pseudo-device sl 4 # serial-line IP ports
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
# $NetBSD: files.pmax,v 1.93 2001/08/22 06:59:44 nisimura Exp $
|
||||
# $NetBSD: files.pmax,v 1.94 2001/08/26 11:47:20 simonb Exp $
|
||||
# DECstation-specific configuration info
|
||||
|
||||
# maxpartitions must be first item in files.${ARCH}.
|
||||
|
@ -91,7 +91,6 @@ file arch/pmax/ibus/mcclock_ibus.c mcclock_ibus
|
|||
include "dev/scsipi/files.scsipi"
|
||||
major { sd = 19 }
|
||||
major { cd = 25 }
|
||||
major { rz = 21 }
|
||||
|
||||
# Memory Disk
|
||||
file dev/md_root.c memory_disk_hooks
|
||||
|
@ -100,53 +99,24 @@ major { md = 17 }
|
|||
# RAIDframe
|
||||
major { raid = 32 }
|
||||
|
||||
#
|
||||
# Old 4.4BSD pmax-specific SCSI driver (deprecated).
|
||||
#
|
||||
define oldscsi {}
|
||||
device oldscsibus {target = -1, drive = -1}
|
||||
attach oldscsibus at oldscsi
|
||||
file arch/pmax/dev/scsi.c oldscsi
|
||||
file arch/pmax/pmax/conf-glue.c oldscsi
|
||||
|
||||
# asc: SCSI interface in TC option slot or in IOASIC slot
|
||||
device asc: oldscsi
|
||||
file dev/tc/asc.c asc needs-flag
|
||||
attach asc at ioasic with asc_ioasic
|
||||
file dev/tc/asc_ioasic.c asc_ioasic
|
||||
attach asc at tc with asc_tc
|
||||
file dev/tc/asc_tc.c asc_tc
|
||||
|
||||
# sii: kn01 SCSI interface
|
||||
device sii: oldscsi
|
||||
device xsii: ncr53c9x,scsi
|
||||
file arch/pmax/dev/sii.c sii | xsii needs-flag
|
||||
attach sii at ibus with sii_ds
|
||||
attach xsii at ibus with xsii_ds
|
||||
file arch/pmax/dev/sii_ds.c sii_ds | xsii_ds
|
||||
|
||||
device tz: tape
|
||||
attach tz at oldscsibus
|
||||
file arch/pmax/dev/tz.c tz needs-count
|
||||
|
||||
device rz: disk
|
||||
attach rz at oldscsibus
|
||||
file arch/pmax/dev/rz.c rz needs-count
|
||||
|
||||
#
|
||||
# MI SCSI driver; to be moved into dev/tc/ replacing existings, eventually.
|
||||
#
|
||||
device xasc: ncr53c9x,scsi
|
||||
attach xasc at tc with xasc_pmaz
|
||||
file arch/pmax/tc/asc_pmaz.c xasc_pmaz
|
||||
attach xasc at ioasic with xasc_ioasic
|
||||
file arch/pmax/tc/asc_ioasic.c xasc_ioasic
|
||||
|
||||
# XXX waiting on pmax MI scsi being `asc'.
|
||||
# 53C[F]90 SCSI
|
||||
attach xasc at tcds with asc_tcds
|
||||
device asc: ncr53c9x,scsi
|
||||
attach asc at tc with asc_pmaz
|
||||
file arch/pmax/tc/asc_pmaz.c asc_pmaz
|
||||
attach asc at ioasic with asc_ioasic
|
||||
file arch/pmax/tc/asc_ioasic.c asc_ioasic
|
||||
attach asc at tcds with asc_tcds
|
||||
file dev/tc/asc_tcds.c asc_tcds
|
||||
|
||||
# sii: kn01 SCSI interface
|
||||
device sii: ncr53c9x,scsi
|
||||
file arch/pmax/dev/sii.c sii needs-flag
|
||||
attach sii at ibus with sii_ds
|
||||
file arch/pmax/dev/sii_ds.c sii_ds
|
||||
|
||||
|
||||
# DC7085 (DZ-like four-port serial device) on ibus
|
||||
device dc: tty
|
||||
file arch/pmax/dev/dc.c dc
|
||||
|
|
|
@ -1,28 +0,0 @@
|
|||
# $NetBSD: scsi.pmax,v 1.3 1998/05/08 00:05:19 simonb Exp $
|
||||
#
|
||||
# SCSI configuration for old DECstation SCSI driver
|
||||
# NB: if you change this, you will also need to change conf-glue.c.
|
||||
#
|
||||
|
||||
# disks and tapes for first ASC or SII
|
||||
rz0 at oldscsibus? target ? drive ?
|
||||
rz1 at oldscsibus? target ? drive ?
|
||||
rz2 at oldscsibus? target ? drive ?
|
||||
rz3 at oldscsibus? target ? drive ?
|
||||
rz4 at oldscsibus? target ? drive ?
|
||||
rz5 at oldscsibus? target ? drive ?
|
||||
rz6 at oldscsibus? target ? drive ?
|
||||
rz7 at oldscsibus? target ? drive ?
|
||||
tz0 at oldscsibus? target ? drive ?
|
||||
tz1 at oldscsibus? target ? drive ?
|
||||
|
||||
# disks and tapes for a second ASC
|
||||
rz8 at oldscsibus? target ? drive ?
|
||||
rz9 at oldscsibus? target ? drive ?
|
||||
rz10 at oldscsibus? target ? drive ?
|
||||
rz11 at oldscsibus? target ? drive ?
|
||||
rz12 at oldscsibus? target ? drive ?
|
||||
rz13 at oldscsibus? target ? drive ?
|
||||
rz14 at oldscsibus? target ? drive ?
|
||||
tz2 at oldscsibus? target ? drive ?
|
||||
tz3 at oldscsibus? target ? drive ?
|
|
@ -1,343 +0,0 @@
|
|||
/* $NetBSD: ascreg.h,v 1.9 1999/04/24 08:01:01 simonb Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1992, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to Berkeley by
|
||||
* Ralph Campbell and Rick Macklem.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)ascreg.h 8.1 (Berkeley) 6/10/93
|
||||
*/
|
||||
|
||||
/*
|
||||
* 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 the
|
||||
* rights to redistribute these changes.
|
||||
*/
|
||||
|
||||
/*
|
||||
* HISTORY
|
||||
* Log: scsi_53C94.h,v
|
||||
* Revision 2.4 91/02/05 17:44:59 mrt
|
||||
* Added author notices
|
||||
* [91/02/04 11:18:32 mrt]
|
||||
*
|
||||
* Changed to use new Mach copyright
|
||||
* [91/02/02 12:17:11 mrt]
|
||||
*
|
||||
* Revision 2.3 90/12/05 23:34:46 af
|
||||
* Documented max DMA xfer size.
|
||||
* [90/12/03 23:39:36 af]
|
||||
*
|
||||
* Revision 2.1.1.1 90/11/01 03:38:54 af
|
||||
* Created, from the DEC specs:
|
||||
* "PMAZ-AA TURBOchannel SCSI Module Functional Specification"
|
||||
* Workstation Systems Engineering, Palo Alto, CA. Aug 27, 1990.
|
||||
* And from the NCR data sheets
|
||||
* "NCR 53C94, 53C95, 53C96 Advanced SCSI Controller"
|
||||
* [90/09/03 af]
|
||||
*/
|
||||
|
||||
/*
|
||||
* 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 !
|
||||
*/
|
||||
|
||||
#define ASC_OFFSET_53C94 0x0 /* from module base */
|
||||
#define ASC_OFFSET_DMAR 0x40000 /* DMA Address Register */
|
||||
#define ASC_OFFSET_RAM 0x80000 /* SRAM Buffer */
|
||||
#define ASC_OFFSET_ROM 0xc0000 /* Diagnostic ROM */
|
||||
|
||||
#define ASC_RAM_SIZE 0x20000 /* 128k (32k*32) */
|
||||
#define PER_TGT_DMA_SIZE ((ASC_RAM_SIZE/7) & ~(sizeof(int)-1))
|
||||
#define ASC_NCMD 7
|
||||
|
||||
/*
|
||||
* DMA Address Register
|
||||
*/
|
||||
#define ASC_DMAR_MASK 0x1ffff /* 17 bits, 128k */
|
||||
#define ASC_DMAR_WRITE 0x80000000 /* DMA direction bit */
|
||||
#define ASC_DMA_ADDR(x) ((unsigned)(x) & ASC_DMAR_MASK)
|
||||
|
||||
/*
|
||||
* Synch xfer parameters, and timing conversions
|
||||
*/
|
||||
#define SCSI_MIN_PERIOD 50 /* in 4 nsecs units */
|
||||
#define ASC_MIN_PERIOD25 5 /* in CLKS/BYTE, 1 CLK = 40nsecs */
|
||||
#define ASC_MIN_PERIOD12 3 /* in CLKS/BYTE, 1 CLK = 80nsecs */
|
||||
#define ASC_MAX_PERIOD25 35 /* in CLKS/BYTE, 1 CLK = 40nsecs */
|
||||
#define ASC_MAX_PERIOD12 18 /* in CLKS/BYTE, 1 CLK = 80nsecs */
|
||||
#define ASC_MAX_OFFSET 15 /* pure number */
|
||||
/*
|
||||
* Register map, padded as needed
|
||||
*/
|
||||
|
||||
typedef volatile struct {
|
||||
u_char asc_tc_lsb; /* rw: Transfer Counter LSB */
|
||||
char pad0[3];
|
||||
u_char asc_tc_msb; /* rw: Transfer Counter MSB */
|
||||
char pad1[3];
|
||||
u_char asc_fifo; /* rw: FIFO top */
|
||||
char pad2[3];
|
||||
u_char asc_cmd; /* rw: Command */
|
||||
char pad3[3];
|
||||
u_char asc_status; /* r: Status */
|
||||
#define asc_dbus_id asc_status /* w: Destination Bus ID */
|
||||
char pad4[3];
|
||||
u_char asc_intr; /* r: Interrupt */
|
||||
#define asc_sel_timo asc_intr /* w: (re)select timeout */
|
||||
char pad5[3];
|
||||
u_char asc_ss; /* r: Sequence Step */
|
||||
#define asc_syn_p asc_ss /* w: synchronous period */
|
||||
char pad6[3];
|
||||
u_char asc_flags; /* r: FIFO flags + seq step */
|
||||
#define asc_syn_o asc_flags /* w: synchronous offset */
|
||||
char pad7[3];
|
||||
u_char asc_cnfg1; /* rw: Configuration 1 */
|
||||
char pad8[3];
|
||||
u_char asc_ccf; /* w: Clock Conv. Factor */
|
||||
char pad9[3];
|
||||
u_char asc_test; /* w: Test Mode */
|
||||
char pad10[3];
|
||||
u_char asc_cnfg2; /* rw: Configuration 2 */
|
||||
char pad11[3];
|
||||
u_char asc_cnfg3; /* rw: Configuration 3 */
|
||||
char pad12[3];
|
||||
u_char asc_res_fifo; /* 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 | ((ptr)->asc_tc_msb << 8)
|
||||
#define ASC_TC_PUT(ptr, val) \
|
||||
(ptr)->asc_tc_lsb = (val); \
|
||||
(ptr)->asc_tc_msb = (val) >> 8; \
|
||||
(ptr)->asc_cmd = ASC_CMD_NOP | ASC_CMD_DMA;
|
||||
|
||||
/*
|
||||
* 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
|
||||
|
||||
/*
|
||||
* 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) ((csr) & 0x7)
|
||||
#define SCSI_PHASE_DATAO 0x0
|
||||
#define SCSI_PHASE_DATAI 0x1
|
||||
#define SCSI_PHASE_COMMAND 0x2
|
||||
#define SCSI_PHASE_STATUS 0x3
|
||||
/* 4..5 ANSI reserved */
|
||||
#define SCSI_PHASE_MSG_OUT 0x6
|
||||
#define SCSI_PHASE_MSG_IN 0x7
|
||||
|
||||
/*
|
||||
* 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) (((clk) * 31) / (ccf))
|
||||
|
||||
/*
|
||||
* Sequence Step register
|
||||
*/
|
||||
|
||||
#define ASC_SS_RESERVED 0xf0
|
||||
#define ASC_SS_SOM 0x08
|
||||
#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(clk) ((((clk) - 1) / 5) + 1)
|
||||
|
||||
/*
|
||||
* 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_RESERVED 0xf8
|
||||
#define ASC_CNFG3_SRB 0x04
|
||||
#define ASC_CNFG3_ALT_DMA 0x02
|
||||
#define ASC_CNFG3_T8 0x01
|
|
@ -1,145 +0,0 @@
|
|||
/* $NetBSD: device.h,v 1.16 2000/06/02 20:12:57 mhitch Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1992, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to Berkeley by
|
||||
* Ralph Campbell.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)device.h 8.1 (Berkeley) 6/10/93
|
||||
*/
|
||||
|
||||
#include <sys/callout.h>
|
||||
|
||||
/*
|
||||
* This structure is used to encapsulate the routines for a device driver.
|
||||
* This allows an "object oriented" approach so a controller device driver
|
||||
* can support multiple attached devices or a device can be attached to
|
||||
* different types of controllers.
|
||||
*/
|
||||
struct ScsiCmd;
|
||||
struct device;
|
||||
|
||||
struct pmax_driver {
|
||||
char *d_name; /* device driver name (e.g., "rz") */
|
||||
|
||||
/* routine to probe & initialize device */
|
||||
int (*d_init) __P((void *));
|
||||
/* routine to start operation */
|
||||
void (*d_start) __P((struct ScsiCmd *cmd));
|
||||
/* routine to call when operation complete */
|
||||
void (*d_done) __P(( int unit, int errno, int buflen,
|
||||
int status_byte));
|
||||
/* routine to call when interrupt is seen */
|
||||
int (*d_intr) __P((void* sc));
|
||||
};
|
||||
|
||||
/*
|
||||
* This structure describes controllers directly connected to CPU
|
||||
* and is partially initialized in "ioconf.c" by the 'config' program.
|
||||
*/
|
||||
struct pmax_ctlr {
|
||||
struct pmax_driver *pmax_driver;/* controller driver routines */
|
||||
int pmax_unit; /* controller number */
|
||||
char *pmax_addr; /* address of controller */
|
||||
int pmax_pri; /* interrupt priority */
|
||||
int pmax_flags; /* flags */
|
||||
|
||||
int pmax_alive; /* true if init routine succeeded */
|
||||
};
|
||||
|
||||
/*
|
||||
* This structure describes devices connected to a SCSI interface
|
||||
* and is partially initialized in "ioconf.c" by the 'config' program.
|
||||
*/
|
||||
struct pmax_scsi_device {
|
||||
struct pmax_driver *sd_driver; /* SCSI device driver routines */
|
||||
struct pmax_driver *sd_cdriver; /* SCSI interface driver routines */
|
||||
int sd_unit; /* device unit number */
|
||||
int sd_ctlr; /* SCSI interface number */
|
||||
int sd_drive; /* SCSI address number */
|
||||
int sd_slave; /* LUN if device has multiple units */
|
||||
int sd_flags; /* flags */
|
||||
|
||||
int sd_alive; /* true if init routine succeeded */
|
||||
struct device *sd_devp; /* new config glue kludge */
|
||||
};
|
||||
|
||||
/* Define special unit types used by the config program */
|
||||
#define QUES -1 /* -1 means '?' */
|
||||
#define UNKNOWN -2 /* -2 means not set yet */
|
||||
|
||||
/*
|
||||
* This structure contains information that a SCSI interface controller
|
||||
* needs to execute a SCSI command.
|
||||
*/
|
||||
typedef struct ScsiCmd {
|
||||
#if NXSII == 0 /* Not used for MI SCSI */
|
||||
struct pmax_scsi_device *sd; /* device requesting the command */
|
||||
#endif
|
||||
int unit; /* unit number passed to device done routine */
|
||||
int flags; /* control flags for this command (see below) */
|
||||
int buflen; /* length of the data buffer in bytes */
|
||||
char *buf; /* pointer to data buffer for this command */
|
||||
int cmdlen; /* length of data in cmdbuf */
|
||||
u_char *cmd; /* buffer for the SCSI command */
|
||||
int error; /* compatibility hack for new scsi */
|
||||
int lun; /* LUN for MI SCSI */
|
||||
struct callout timo_ch; /* timeout callout handle */
|
||||
} ScsiCmd;
|
||||
|
||||
/*
|
||||
* Define flags for controlling the SCSI command.
|
||||
*
|
||||
* SCSICMD_DATA_TO_DEVICE
|
||||
* TRUE -> data is to be transferred to the device.
|
||||
* FALSE -> data is to be transferred from the device.
|
||||
* meaningless if buflen is 0.
|
||||
* SCSICMD_USE_SYNC
|
||||
* Attempt to negotiate for a synchronous data transfer.
|
||||
*/
|
||||
#define SCSICMD_DATA_TO_DEVICE 0x01
|
||||
#define SCSICMD_USE_SYNC 0x02
|
||||
|
||||
#ifdef _KERNEL
|
||||
extern struct pmax_ctlr pmax_cinit[];
|
||||
extern struct pmax_scsi_device scsi_dinit[];
|
||||
|
||||
/*
|
||||
* Old-style pmax driver glue:
|
||||
* Callbacks to add known a controller, and to configure all slaves on
|
||||
* all known controllers.
|
||||
*/
|
||||
void pmax_add_scsi __P((struct pmax_driver *dp, int unit));
|
||||
void configure_scsi __P((void));
|
||||
|
||||
#endif /* _KERNEL */
|
File diff suppressed because it is too large
Load Diff
|
@ -1,237 +0,0 @@
|
|||
/* $NetBSD: scsi.c,v 1.11 2001/07/07 14:21:01 simonb Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1992, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to Berkeley by
|
||||
* Ralph Campbell.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)scsi.c 8.1 (Berkeley) 6/10/93
|
||||
*/
|
||||
|
||||
/*
|
||||
* SCSI utility routines for making SCSI device drivers easier.
|
||||
*/
|
||||
|
||||
#include <sys/systm.h>
|
||||
|
||||
#include <pmax/dev/scsi.h>
|
||||
|
||||
/*
|
||||
* The error codes for class 0-6 sense data are class specific.
|
||||
* The follow arrays of strings are used to print error messages.
|
||||
*/
|
||||
static char *Class0Errors[] = {
|
||||
"No sense data",
|
||||
"No index signal",
|
||||
"No seek complete",
|
||||
"Write fault",
|
||||
"Drive not ready",
|
||||
"Drive not selected",
|
||||
"No Track 00",
|
||||
"Multiple drives selected",
|
||||
"No address acknowledged",
|
||||
"Media not loaded",
|
||||
"Insufficient capacity",
|
||||
"Drive timeout",
|
||||
};
|
||||
static char *Class1Errors[] = {
|
||||
"ID CRC error",
|
||||
"Unrecoverable data error",
|
||||
"ID address mark not found",
|
||||
"Data address mark not found",
|
||||
"Record not found",
|
||||
"Seek error",
|
||||
"DMA timeout error",
|
||||
"Write protected",
|
||||
"Correctable data check",
|
||||
"Bad block found",
|
||||
"Interleave error",
|
||||
"Data transfer incomplete",
|
||||
"Unformatted or bad format on drive",
|
||||
"Self test failed",
|
||||
"Defective track (media errors)",
|
||||
};
|
||||
static char *Class2Errors[] = {
|
||||
"Invalid command",
|
||||
"Illegal block address",
|
||||
"Aborted",
|
||||
"Volume overflow",
|
||||
};
|
||||
static char *Class7Errors[] = {
|
||||
"No sense data",
|
||||
"Recoverable error",
|
||||
"Drive not ready",
|
||||
"Media error",
|
||||
"Hardware error",
|
||||
"Illegal request",
|
||||
"Unit attention",
|
||||
"Write protected",
|
||||
"Blank check error",
|
||||
"Vendor error",
|
||||
"Powerup failure",
|
||||
"Abort",
|
||||
"Equal",
|
||||
"Overflow",
|
||||
"Reserved14/miscompare",
|
||||
};
|
||||
static int scsiNumErrors[] = {
|
||||
sizeof(Class0Errors) / sizeof(char *),
|
||||
sizeof(Class1Errors) / sizeof(char *),
|
||||
sizeof(Class2Errors) / sizeof(char *),
|
||||
0, 0, 0, 0, 0,
|
||||
};
|
||||
static char **scsiErrors[] = {
|
||||
Class0Errors,
|
||||
Class1Errors,
|
||||
Class2Errors,
|
||||
};
|
||||
|
||||
/*
|
||||
* Decode the sense data and print a suitable message.
|
||||
*/
|
||||
void
|
||||
scsiPrintSense(sp, len)
|
||||
ScsiClass7Sense *sp;
|
||||
int len;
|
||||
{
|
||||
ScsiClass0Sense *sp0;
|
||||
int class, code;
|
||||
|
||||
if (sp->error7 != 0x70) {
|
||||
sp0 = (ScsiClass0Sense *)sp;
|
||||
class = sp0->error >> 4;
|
||||
code = sp0->error & 0xF;
|
||||
if (code >= scsiNumErrors[class])
|
||||
printf("sense error 0x%x", sp0->error);
|
||||
else
|
||||
printf("%s", scsiErrors[class][code]);
|
||||
if (sp->valid)
|
||||
printf(", blk %d", (sp0->highAddr << 16) |
|
||||
(sp0->midAddr << 8) | sp0->lowAddr);
|
||||
} else {
|
||||
if (sp->key >= sizeof(Class7Errors) / sizeof(char *))
|
||||
printf("sense class 7 error 0x%x", sp->key);
|
||||
else
|
||||
printf("%s", Class7Errors[sp->key]);
|
||||
if (sp->fileMark)
|
||||
printf(", file mark seen");
|
||||
if (sp->endOfMedia)
|
||||
printf(", end of media seen");
|
||||
if (sp->badBlockLen)
|
||||
printf(", block length mis-match");
|
||||
if (sp->valid)
|
||||
printf(", blk %d", (sp->info1 << 24) |
|
||||
(sp->info2 << 16) | (sp->info3 << 8) |
|
||||
sp->info4);
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
/*
|
||||
* Setup a command block for a SCSI Group0 command.
|
||||
*/
|
||||
void
|
||||
scsiGroup0Cmd(cmd, lun, block, count, c)
|
||||
unsigned cmd; /* group0 SCSI command */
|
||||
unsigned lun; /* Logical Unit Number */
|
||||
unsigned block; /* starting block number for transfer */
|
||||
unsigned count; /* # of sectors/bytes to transfer */
|
||||
ScsiGroup0Cmd *c; /* command to be filled in */
|
||||
{
|
||||
|
||||
c->command = cmd;
|
||||
c->unitNumber = lun;
|
||||
c->highAddr = block >> 16;
|
||||
c->midAddr = block >> 8;
|
||||
c->lowAddr = block;
|
||||
c->blockCount = count;
|
||||
c->control = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Setup a command block for a SCSI Group1 command.
|
||||
*/
|
||||
void
|
||||
scsiGroup1Cmd(cmd, lun, block, count, c)
|
||||
unsigned cmd; /* group0 SCSI command */
|
||||
unsigned lun; /* Logical Unit Number */
|
||||
unsigned block; /* starting block number for transfer */
|
||||
unsigned count; /* # of sectors/bytes to transfer */
|
||||
ScsiGroup1Cmd *c; /* command to be filled in */
|
||||
{
|
||||
|
||||
c->command = cmd;
|
||||
c->unitNumber = lun;
|
||||
c->pad1 = 0;
|
||||
c->highAddr = block >> 24;
|
||||
c->midHighAddr = block >> 16;
|
||||
c->midLowAddr = block >> 8;
|
||||
c->lowAddr = block;
|
||||
c->pad2 = 0;
|
||||
c->highBlockCount = count >> 8;
|
||||
c->lowBlockCount = count;
|
||||
c->control = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Print a SCSI identify result.
|
||||
*/
|
||||
void
|
||||
scsiPrintInquiry(inqbuf, i)
|
||||
ScsiInquiryData *inqbuf;
|
||||
int i;
|
||||
{
|
||||
if (inqbuf->version > 1 || i < 36)
|
||||
printf(" type 0x%x, qual 0x%x, ver %d",
|
||||
inqbuf->type, inqbuf->qualifier, inqbuf->version);
|
||||
else {
|
||||
char vid[9], pid[17], revl[5];
|
||||
|
||||
memcpy(vid, inqbuf->vendorID, 8);
|
||||
memcpy(pid, inqbuf->productID, 16);
|
||||
memcpy(revl, inqbuf->revLevel, 4);
|
||||
for (i = 8; --i > 0; )
|
||||
if (vid[i] != ' ')
|
||||
break;
|
||||
vid[i+1] = 0;
|
||||
for (i = 16; --i > 0; )
|
||||
if (pid[i] != ' ')
|
||||
break;
|
||||
pid[i+1] = 0;
|
||||
for (i = 4; --i > 0; )
|
||||
if (revl[i] != ' ')
|
||||
break;
|
||||
revl[i+1] = 0;
|
||||
printf(" %s %s rev %s", vid, pid, revl);
|
||||
}
|
||||
}
|
|
@ -1,584 +0,0 @@
|
|||
/* $NetBSD: scsi.h,v 1.12 2000/03/30 14:45:06 simonb Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1992, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to Berkeley by
|
||||
* Ralph Campbell.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)scsi.h 8.1 (Berkeley) 6/10/93
|
||||
*
|
||||
* scsi.h --
|
||||
*
|
||||
* Common declarations for SCSI command formaters. This file only covers
|
||||
* definitions pertaining to the SCSI common command set that are
|
||||
* common to all SCSI device types (ie disk, tapes, WORM, printers, etc).
|
||||
* Some of the references from the proceedings of the
|
||||
* 1984 Mini/Micro Northeast conference might help in understanding SCSI.
|
||||
*
|
||||
* from: Header: /sprite/src/kernel/dev/RCS/scsi.h,
|
||||
* v 9.1 90/02/13 23:11:24 jhh Exp SPRITE (Berkeley)
|
||||
*/
|
||||
|
||||
#ifndef _SCSI_H
|
||||
#define _SCSI_H
|
||||
|
||||
/*
|
||||
* "Standard" SCSI Commands.
|
||||
* SCSI commands are divided into 8 groups as follows:
|
||||
* Group0 (0x00 - 0x1f). Basic commands. 6 bytes long
|
||||
* Group1 (0x20 - 0x3f). Extended command. 10 bytes.
|
||||
* Group2 (0x40 - 0x5f). Reserved.
|
||||
* Group2 (0x60 - 0x7f). Reserved.
|
||||
* Group2 (0x80 - 0x9f). Reserved.
|
||||
* Group2 (0xa0 - 0xbf). Reserved.
|
||||
* Group6 (0xc0 - 0xdf). Vendor Unique
|
||||
* Group7 (0xe0 - 0xff). Vendor Unique
|
||||
*/
|
||||
|
||||
/*
|
||||
* Scsi Group0 commands all are 6 bytes and have a format according to
|
||||
* struct ScsiGroup0Cmd.
|
||||
*/
|
||||
#define SCSI_TEST_UNIT_READY 0x00
|
||||
#define SCSI_REZERO_UNIT 0x01
|
||||
#define SCSI_REWIND 0x01
|
||||
#define SCSI_REQUEST_SENSE 0x03
|
||||
#define SCSI_FORMAT_UNIT 0x04
|
||||
#define SCSI_READ_BLOCK_LIMITS 0x05
|
||||
#define SCSI_REASSIGN_BLOCKS 0x07
|
||||
#define SCSI_READ 0x08
|
||||
#define SCSI_WRITE 0x0a
|
||||
#define SCSI_SEEK 0x0b
|
||||
#define SCSI_TRACK_SELECT 0x0b
|
||||
#define SCSI_READ_REVERSE 0x0f
|
||||
#define SCSI_WRITE_EOF 0x10
|
||||
#define SCSI_SPACE 0x11
|
||||
#define SCSI_INQUIRY 0x12
|
||||
#define SCSI_VERIFY 0x13
|
||||
#define SCSI_READ_BUFFER 0x14
|
||||
#define SCSI_MODE_SELECT 0x15
|
||||
#define SCSI_RESERVE_UNIT 0x16
|
||||
#define SCSI_RELEASE_UNIT 0x17
|
||||
#define SCSI_COPY 0x18
|
||||
#define SCSI_ERASE_TAPE 0x19
|
||||
#define SCSI_MODE_SENSE 0x1a
|
||||
#define SCSI_START_STOP 0x1b
|
||||
#define SCSI_LOAD_UNLOAD 0x1b
|
||||
#define SCSI_RECV_DIAG_RESULTS 0x1c
|
||||
#define SCSI_SEND_DIAGNOSTIC 0x1d
|
||||
#define SCSI_PREVENT_ALLOW 0x1e
|
||||
|
||||
/*
|
||||
* Arguments to SCSI_LOAD_UNLOAD command. These are passed in byte
|
||||
* 5 (the blockCount) of a Group0 command block.
|
||||
*/
|
||||
#define SCSI_LD_UNLOAD 0x00
|
||||
#define SCSI_LD_LOAD 0x01
|
||||
#define SCSI_LD_RETENSION 0x02
|
||||
|
||||
/*
|
||||
* Group1 commands are all 10 bytes and have a format according to
|
||||
* struct ScsiGroup1Cmd.
|
||||
*/
|
||||
#define SCSI_READ_CAPACITY 0x25
|
||||
#define SCSI_READ_EXT 0x28
|
||||
#define SCSI_WRITE_EXT 0x2a
|
||||
#define SCSI_SEEK_EXT 0x2b
|
||||
#define SCSI_WRITE_VERIFY 0x2e
|
||||
#define SCSI_VERIFY_EXT 0x2f
|
||||
#define SCSI_SEARCH_HIGH 0x30
|
||||
#define SCSI_SEARCH_EQUAL 0x31
|
||||
#define SCSI_SEARCH_LOW 0x32
|
||||
#define SCSI_SET_LIMITS 0x33
|
||||
#define SCSI_COMPARE 0x39
|
||||
#define SCSI_COPY_VERIFY 0x3a
|
||||
|
||||
/*
|
||||
* Control byte flags for Group0 and Group1 commands.
|
||||
*
|
||||
* SCSI_CTRL_LINK - This is used to prevent a bus free phase between commands.
|
||||
* If the command terminates successfully, a SCSI_LINKED_CMD_COMPLETE
|
||||
* message is returned instead of the normal SCSI_COMMAND_COMPLETE message.
|
||||
* The last command in a chain should not have this bit set
|
||||
* (and consequently gets a normal SCSI_COMMAND_COMPLETE message).
|
||||
* SCSI_CTRL_LINK_FLAG - This bit should only set when SCSI_CTRL_LINK is set and
|
||||
* causes a SCSI_LINKED_FLAGED_CMD_COMPLETE to be returned instead of
|
||||
* a SCSI_LINKED_CMD_COMPLETE.
|
||||
*/
|
||||
#define SCSI_CTRL_LINK 0x01 /* Link commands (no bus free phase) */
|
||||
#define SCSI_CTRL_LINK_INTR 0x02 /* Interrupt after linked command */
|
||||
|
||||
/*
|
||||
* The standard group0 6-byte SCSI control block. Note that the
|
||||
* fields between highAddr and blockCount inclusive are command dependent.
|
||||
* The definitions Addr and BlockCount cover most of the commands we will
|
||||
* use.
|
||||
*/
|
||||
typedef struct ScsiGroup0Cmd {
|
||||
u_char command; /* command code, defined below. The
|
||||
* upper three bits of this are zero
|
||||
* to indicate the control block is
|
||||
* only 6 bytes long */
|
||||
#if BYTE_ORDER == BIG_ENDIAN
|
||||
u_char unitNumber :3; /* Logical Unit (LUN) to which to
|
||||
* pass the command. The device
|
||||
* has already been selected using
|
||||
* the "targetID" bit. */
|
||||
u_char highAddr :5; /* High bits of address */
|
||||
#else
|
||||
u_char highAddr :5; /* High bits of address */
|
||||
u_char unitNumber :3; /* Logical Unit (LUN) to which to
|
||||
* pass the command. The device
|
||||
* has already been selected using
|
||||
* the "targetID" bit. */
|
||||
#endif
|
||||
u_char midAddr; /* Middle bits of address */
|
||||
u_char lowAddr; /* Low bits of address */
|
||||
u_char blockCount; /* Blocks to transfer */
|
||||
u_char control; /* See flags for common bits */
|
||||
} ScsiGroup0Cmd;
|
||||
|
||||
/*
|
||||
* Format of a SCSI_START_STOP command. This is a group 0 command, but
|
||||
* the command contents are different.
|
||||
*/
|
||||
typedef struct ScsiStartStopCmd {
|
||||
#if BYTE_ORDER == BIG_ENDIAN
|
||||
u_char command; /* command code, defined below. The
|
||||
* upper three bits of this are zero
|
||||
* to indicate the control block is
|
||||
* only 6 bytes long */
|
||||
u_char unitNumber :3; /* Logical Unit (LUN) to which to
|
||||
* pass the command. The device
|
||||
* has already been selected using
|
||||
* the "targetID" bit. */
|
||||
u_char pad1 :4; /* Reserved */
|
||||
u_char immed :1; /* Immediate status bit */
|
||||
u_char pad2; /* Reserved */
|
||||
u_char pad3; /* Reserved */
|
||||
u_char pad4 :6; /* Reserved */
|
||||
u_char loadEject :1; /* Load or eject medium */
|
||||
u_char start :1; /* Start or stop medium */
|
||||
u_char control; /* See flags for common bits */
|
||||
#else
|
||||
u_char command; /* command code, defined below. The
|
||||
* upper three bits of this are zero
|
||||
* to indicate the control block is
|
||||
* only 6 bytes long */
|
||||
u_char immed :1; /* Immediate status bit */
|
||||
u_char pad1 :4; /* Reserved */
|
||||
u_char unitNumber :3; /* Logical Unit (LUN) to which to
|
||||
* pass the command. The device
|
||||
* has already been selected using
|
||||
* the "targetID" bit. */
|
||||
u_char pad2; /* Reserved */
|
||||
u_char pad3; /* Reserved */
|
||||
u_char start :1; /* Start or stop medium */
|
||||
u_char loadEject :1; /* Load or eject medium */
|
||||
u_char pad4 :6; /* Reserved */
|
||||
u_char control; /* See flags for common bits */
|
||||
#endif
|
||||
} ScsiStartStopCmd;
|
||||
|
||||
/*
|
||||
* The standard group1 10-byte SCSI control block. Note that the
|
||||
* fields between highAddr and blockCount inclusive are command dependent.
|
||||
* The definitions Addr and BlockCount cover most of the commands we will
|
||||
* use.
|
||||
*/
|
||||
typedef struct ScsiGroup1Cmd {
|
||||
u_char command; /* command code, defined below. The
|
||||
* upper three bits of this are zero
|
||||
* to indicate the control block is
|
||||
* only 6 bytes long */
|
||||
#if BYTE_ORDER == BIG_ENDIAN
|
||||
u_char unitNumber :3; /* Logical Unit (LUN) to which to
|
||||
* pass the command. The device
|
||||
* has already been selected using
|
||||
* the "targetID" bit. */
|
||||
u_char pad1 :5; /* Reserved */
|
||||
#else
|
||||
u_char pad1 :5; /* Reserved */
|
||||
u_char unitNumber :3; /* Logical Unit (LUN) to which to
|
||||
* pass the command. The device
|
||||
* has already been selected using
|
||||
* the "targetID" bit. */
|
||||
#endif
|
||||
u_char highAddr; /* High bits of address */
|
||||
u_char midHighAddr; /* Middle high bits of address */
|
||||
u_char midLowAddr; /* Middle low bits of address */
|
||||
u_char lowAddr; /* Low bits of address */
|
||||
u_char pad2; /* Reserved */
|
||||
u_char highBlockCount; /* High bits of blocks to transfer */
|
||||
u_char lowBlockCount; /* Low bits of blocks to transfer */
|
||||
u_char control; /* See flags for common bits */
|
||||
} ScsiGroup1Cmd;
|
||||
|
||||
/*
|
||||
* SCSI status completion information.
|
||||
* This is returned by the device when a command completes.
|
||||
*/
|
||||
#define SCSI_STATUS_CHECKCOND 0x02 /* Check Condition (ie., read sense) */
|
||||
#define SCSI_STATUS_CONDMET 0x04 /* Condition Met (ie., search worked) */
|
||||
#define SCSI_STATUS_BUSY 0x08
|
||||
#define SCSI_STATUS_INTERMED 0x10 /* Intermediate status sent */
|
||||
#define SCSI_STATUS_EXT 0x80 /* Extended status valid */
|
||||
|
||||
/*
|
||||
* Sense information provided after some errors. This is divided into
|
||||
* two kinds, classes 0-6, and class 7. This is 30 bytes big to allow
|
||||
* for the drive specific sense bytes that follow the standard 4 byte header.
|
||||
*
|
||||
* For extended sense, this buffer may be cast into another type. Also
|
||||
* The actual size of the sense data returned is used to detect what
|
||||
* kind of tape drive is out there. Kludgy, but true.
|
||||
*/
|
||||
typedef struct ScsiClass0Sense {
|
||||
#if BYTE_ORDER == BIG_ENDIAN
|
||||
u_char valid :1; /* Sense data is valid */
|
||||
u_char error :7; /* 3 bits class and 4 bits code */
|
||||
#else
|
||||
u_char error :7; /* 3 bits class and 4 bits code */
|
||||
u_char valid :1; /* Sense data is valid */
|
||||
#endif
|
||||
u_char highAddr; /* High byte of block address */
|
||||
u_char midAddr; /* Middle byte of block address */
|
||||
u_char lowAddr; /* Low byte of block address */
|
||||
u_char sense[26]; /* Target specific sense data */
|
||||
} ScsiClass0Sense;
|
||||
|
||||
/*
|
||||
* Definitions for errors in the sense data. The error field is specified
|
||||
* as a 3 bit class and 4 bit code, but it is easier to treat it as a
|
||||
* single 7 bit field.
|
||||
*/
|
||||
#define SCSI_NO_SENSE_DATA 0x00
|
||||
#define SCSI_NOT_READY 0x04
|
||||
#define SCSI_NOT_LOADED 0x09
|
||||
#define SCSI_INSUF_CAPACITY 0x0a
|
||||
#define SCSI_HARD_DATA_ERROR 0x11
|
||||
#define SCSI_WRITE_PROTECT 0x17
|
||||
#define SCSI_CORRECTABLE_ERROR 0x18
|
||||
#define SCSI_FILE_MARK 0x1c
|
||||
#define SCSI_INVALID_COMMAND 0x20
|
||||
#define SCSI_UNIT_ATTENTION 0x30
|
||||
#define SCSI_END_OF_MEDIA 0x34
|
||||
|
||||
/*
|
||||
* The standard "extended" sense data returned by SCSI devices. This
|
||||
* has an error field of 0x70, for a "class 7" error.
|
||||
*/
|
||||
typedef struct ScsiClass7Sense {
|
||||
#if BYTE_ORDER == BIG_ENDIAN
|
||||
u_char valid :1; /* Sense data is valid */
|
||||
u_char error7 :7; /* == 0x70 */
|
||||
u_char pad1; /* Also "segment number" for copy */
|
||||
u_char fileMark :1; /* File mark on device */
|
||||
u_char endOfMedia :1; /* End of media reached */
|
||||
u_char badBlockLen :1; /* Block length mis-match (Exabyte) */
|
||||
u_char pad2 :1;
|
||||
u_char key :4; /* Sense keys defined below */
|
||||
u_char info1; /* Information byte 1 */
|
||||
u_char info2; /* Information byte 2 */
|
||||
u_char info3; /* Information byte 3 */
|
||||
u_char info4; /* Information byte 4 */
|
||||
u_char length; /* Number of additional info bytes */
|
||||
#else
|
||||
u_char error7 :7; /* == 0x70 */
|
||||
u_char valid :1; /* Sense data is valid */
|
||||
u_char pad1; /* Also "segment number" for copy */
|
||||
u_char key :4; /* Sense keys defined below */
|
||||
u_char pad2 :1;
|
||||
u_char badBlockLen :1; /* Block length mis-match (Exabyte) */
|
||||
u_char endOfMedia :1; /* End of media reached */
|
||||
u_char fileMark :1; /* File mark on device */
|
||||
u_char info1; /* Information byte 1 */
|
||||
u_char info2; /* Information byte 2 */
|
||||
u_char info3; /* Information byte 3 */
|
||||
u_char info4; /* Information byte 4 */
|
||||
u_char length; /* Number of additional info bytes */
|
||||
#endif
|
||||
} ScsiClass7Sense; /* 8 Bytes */
|
||||
|
||||
/*
|
||||
* Key values for standardized sense class 7.
|
||||
*/
|
||||
#define SCSI_CLASS7_NO_SENSE 0
|
||||
#define SCSI_CLASS7_RECOVERABLE 1
|
||||
#define SCSI_CLASS7_NOT_READY 2
|
||||
#define SCSI_CLASS7_MEDIA_ERROR 3
|
||||
#define SCSI_CLASS7_HARDWARE_ERROR 4
|
||||
#define SCSI_CLASS7_ILLEGAL_REQUEST 5
|
||||
|
||||
/*
|
||||
* These seem to have different meanings to different vendors....
|
||||
*/
|
||||
#define SCSI_CLASS7_MEDIA_CHANGE 6
|
||||
#define SCSI_CLASS7_UNIT_ATTN 6
|
||||
|
||||
#define SCSI_CLASS7_WRITE_PROTECT 7
|
||||
#define SCSI_CLASS7_BLANK_CHECK 8
|
||||
#define SCSI_CLASS7_VENDOR 9
|
||||
#define SCSI_CLASS7_POWER_UP_FAILURE 10
|
||||
#define SCSI_CLASS7_ABORT 11
|
||||
#define SCSI_CLASS7_EQUAL 12
|
||||
#define SCSI_CLASS7_OVERFLOW 13
|
||||
#define SCSI_CLASS7_RESERVED_14 14
|
||||
#define SCSI_CLASS7_RESERVED_15 15
|
||||
|
||||
/*
|
||||
* Data return by the SCSI inquiry command.
|
||||
*/
|
||||
typedef struct ScsiInquiryData {
|
||||
#if BYTE_ORDER == BIG_ENDIAN
|
||||
u_char type; /* Peripheral Device type. See below. */
|
||||
u_char rmb:1; /* Removable Medium bit. */
|
||||
u_char qualifier:7; /* Device type qualifier. */
|
||||
u_char version; /* Version info. */
|
||||
u_char reserved:4; /* reserved. */
|
||||
u_char format:4; /* Response format. */
|
||||
u_char length; /* length of data returned. */
|
||||
u_char reserved2[2]; /* Reserved */
|
||||
u_char flags; /* SCSI II flags (see below) */
|
||||
u_char vendorID[8]; /* Vendor ID (ASCII) */
|
||||
u_char productID[16]; /* Product ID (ASCII) */
|
||||
u_char revLevel[4]; /* Revision level (ASCII) */
|
||||
u_char revData[8]; /* Revision data (ASCII) */
|
||||
#else
|
||||
u_char type; /* Peripheral Device type. See below. */
|
||||
u_char qualifier:7; /* Device type qualifier. */
|
||||
u_char rmb:1; /* Removable Medium bit. */
|
||||
u_char version; /* Version info. */
|
||||
u_char format:4; /* Response format. */
|
||||
u_char reserved:4; /* reserved. */
|
||||
u_char length; /* length of data returned. */
|
||||
u_char reserved2[2]; /* Reserved */
|
||||
u_char flags; /* SCSI II flags (see below) */
|
||||
u_char vendorID[8]; /* Vendor ID (ASCII) */
|
||||
u_char productID[16]; /* Product ID (ASCII) */
|
||||
u_char revLevel[4]; /* Revision level (ASCII) */
|
||||
u_char revData[8]; /* Revision data (ASCII) */
|
||||
#endif
|
||||
u_char pading[1024]; /* newer SCSI II drives give additional data */
|
||||
} ScsiInquiryData;
|
||||
|
||||
/*
|
||||
* The SCSI Peripheral type ID codes as return by the SCSI_INQUIRY command.
|
||||
*
|
||||
* SCSI_DISK_TYPE - Direct Access Device.
|
||||
* SCSI_TAPE_TYPE - Sequential Access Device.
|
||||
* SCSI_PRINTER_TYPE - Printer Device.
|
||||
* SCSI_HOST_TYPE - Processor Device.
|
||||
* SCSI_WORM_TYPE - Write-Once Read-Multiple Device.
|
||||
* SCSI_ROM_TYPE - Read-Only Direct Access Device.
|
||||
* SCSI_SCANNER_TYPE - Scanner device.
|
||||
* SCSI_OPTICAL_MEM_TYPE - Optical memory device.
|
||||
* SCSI_MEDIUM_CHANGER_TYPE - Medium changer device.
|
||||
* SCSI_COMMUNICATIONS_TYPE - Communications device.
|
||||
* SCSI_NODEVICE_TYPE - Logical Unit not present or implemented.
|
||||
*
|
||||
* Note that codes 0xa-0x7e are reserved and 0x80-0xff are vendor unique.
|
||||
*/
|
||||
#define SCSI_DISK_TYPE 0
|
||||
#define SCSI_TAPE_TYPE 1
|
||||
#define SCSI_PRINTER_TYPE 2
|
||||
#define SCSI_HOST_TYPE 3
|
||||
#define SCSI_WORM_TYPE 4
|
||||
#define SCSI_ROM_TYPE 5
|
||||
#define SCSI_SCANNER_TYPE 6
|
||||
#define SCSI_OPTICAL_MEM_TYPE 7
|
||||
#define SCSI_MEDIUM_CHANGER_TYPE 8
|
||||
#define SCSI_COMMUNICATIONS_TYPE 9
|
||||
#define SCSI_NODEVICE_TYPE 0x7f
|
||||
|
||||
/*
|
||||
* The SCSI I & II inquiry flags.
|
||||
*
|
||||
* SCSI_REL_ADR - Relative addressing supported.
|
||||
* SCSI_WIDE_32 - 32 bit wide SCSI bus transfers supported.
|
||||
* SCSI_WIDE_16 - 16 bit wide SCSI bus transfers supported.
|
||||
* SCSI_SYNC - Synchronous data transfers supported.
|
||||
* SCSI_LINKED - Linked commands supported.
|
||||
* SCSI_CMD_QUEUE - Tagged command queuing supported.
|
||||
* SCSI_SOFT_RESET - Soft RESET alternative suported.
|
||||
*/
|
||||
#define SCSI_REL_ADR 0x80
|
||||
#define SCSI_WIDE_32 0x40
|
||||
#define SCSI_WIDE_16 0x20
|
||||
#define SCSI_SYNC 0x10
|
||||
#define SCSI_LINKED 0x08
|
||||
#define SCSI_CMD_QUEUE 0x02
|
||||
#define SCSI_SOFT_RESET 0x01
|
||||
|
||||
/*
|
||||
* Standard header for SCSI_MODE_SENSE and SCSI_MODE_SELECT commands for tapes.
|
||||
*/
|
||||
typedef struct ScsiTapeModeSelectHdr {
|
||||
u_char len; /* length */
|
||||
u_char media; /* media type */
|
||||
#if BYTE_ORDER == BIG_ENDIAN
|
||||
u_char writeprot:1; /* Write protected media */
|
||||
u_char bufferedMode:3; /* Type of buffer to be done. */
|
||||
u_char speed:4; /* Drive speed. */
|
||||
#else
|
||||
u_char speed:4; /* Drive speed. */
|
||||
u_char bufferedMode:3; /* Type of buffer to be done. */
|
||||
u_char writeprot:1; /* Write protected media */
|
||||
#endif
|
||||
u_char length; /* Block descriptor length. */
|
||||
u_char density; /* tape density code */
|
||||
u_char blocks_2; /* number of blocks (MSB) */
|
||||
u_char blocks_1; /* number of blocks */
|
||||
u_char blocks_0; /* number of blocks (LSB) */
|
||||
u_char reserved; /* */
|
||||
u_char block_size2; /* Tape block size (MSB) */
|
||||
u_char block_size1; /* Tape block size */
|
||||
u_char block_size0; /* Tape block size (LSB) */
|
||||
u_char vendor[6]; /* vendor specific data */
|
||||
} ScsiTapeModeSelectHdr;
|
||||
|
||||
/*
|
||||
* Definitions of SCSI messages.
|
||||
*
|
||||
* SCSI_COMMAND_COMPLETE - After a command has completed, successfully
|
||||
* or not, this is returned to the host from the target.
|
||||
*
|
||||
* SCSI_EXTENDED_MSG - Indicates that a multi-byte message is being sent.
|
||||
*
|
||||
* The following messages are used with connect/disconnect:
|
||||
* SCSI_SAVE_DATA_POINTER - Sent from target to host to request saving
|
||||
* of current DMA address and count. Indicates a pending dis-connect.
|
||||
* SCSI_RESTORE_POINTER - Sent from the target to the host to request
|
||||
* restoring pointers saved before a disconnect
|
||||
* SCSI_DISCONNECT - Sent from the target to the host to disconnect.
|
||||
* SCSI_ABORT - Sent from the host to the target to abort current request.
|
||||
* SCSI_MESSAGE_REJECT - Indicates receipt, by either host or target, of
|
||||
* an unimplemented message.
|
||||
* SCSI_NO_OP - Sent from host to target if it has no real message to send.
|
||||
* SCSI_MESSAGE_PARITY_ERROR - Sent from host to target on message parity error
|
||||
* SCSI_BUS_RESET - Sent from host to target to reset all current I/O
|
||||
*
|
||||
* SCSI_IDENTIFY - The low order two bits of this message type indicate
|
||||
* the Logical Unit of the Target which is requesting a reconnect.
|
||||
* SCSI_DIS_REC_IDENTIFY - Sent from the host to a target to indicate
|
||||
* is supports connect/dis-connect
|
||||
*
|
||||
*/
|
||||
#define SCSI_COMMAND_COMPLETE 0x00
|
||||
#define SCSI_EXTENDED_MSG 0x01
|
||||
#define SCSI_SAVE_DATA_POINTER 0x02
|
||||
#define SCSI_RESTORE_POINTERS 0x03
|
||||
#define SCSI_DISCONNECT 0x04
|
||||
#define SCSI_ABORT 0x06
|
||||
#define SCSI_MESSAGE_REJECT 0x07
|
||||
#define SCSI_NO_OP 0x08
|
||||
#define SCSI_MESSAGE_PARITY_ERROR 0x09
|
||||
#define SCSI_LINKED_CMD_COMPLETE 0x0A
|
||||
#define SCSI_LINKED_FLAGED_CMD_COMPLETE 0x0B
|
||||
#define SCSI_BUS_RESET 0x0C
|
||||
|
||||
#define SCSI_IDENTIFY 0x80
|
||||
#define SCSI_DIS_REC_IDENTIFY 0xc0
|
||||
|
||||
/*
|
||||
* Extended message types (2nd byte of SCSI_EXTENDED_MSG).
|
||||
*/
|
||||
#define SCSI_MODIFY_DATA_PTR 0x00
|
||||
#define SCSI_SYNCHRONOUS_XFER 0x01
|
||||
#define SCSI_EXTENDED_IDENTIFY 0x02 /* only in SCSI I */
|
||||
#define SCSI_WIDE_XFER 0x03
|
||||
|
||||
/* from old scsipiconf.h */
|
||||
#define SCSI_SILENT 0x0020 /* don't announce NOT READY or MEDIA CHANGE */
|
||||
#define SCSI_DATA_IN 0x0800 /* expect data to come INTO memory */
|
||||
|
||||
/*
|
||||
* Driver ioctl's for various scsi operations.
|
||||
*/
|
||||
#ifndef _IOCTL_
|
||||
#include <sys/ioctl.h>
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Control for SCSI "format" mode.
|
||||
*
|
||||
* "Format" mode allows a privileged process to issue direct SCSI
|
||||
* commands to a drive (it is intended primarily to allow on-line
|
||||
* formatting). SDIOCSFORMAT with a non-zero arg will put the drive
|
||||
* into format mode; a zero arg will take it out. When in format
|
||||
* mode, only the process that issued the SDIOCFORMAT can read or
|
||||
* write the drive.
|
||||
*
|
||||
* In format mode, process is expected to
|
||||
* - do SDIOCSCSICOMMAND to supply cdb for next SCSI op
|
||||
* - do read or write as appropriate for cdb
|
||||
* - if i/o error, optionally do SDIOCSENSE to get completion
|
||||
* status and sense data from last scsi operation.
|
||||
*/
|
||||
|
||||
struct scsi_fmt_cdb {
|
||||
int len; /* cdb length (in bytes) */
|
||||
u_char cdb[28]; /* cdb to use on next read/write */
|
||||
};
|
||||
|
||||
struct scsi_fmt_sense {
|
||||
u_int status; /* completion status of last op */
|
||||
u_char sense[32]; /* sense data (if any) from last op */
|
||||
};
|
||||
|
||||
#define SDIOCSFORMAT _IOW('S', 0x1, int)
|
||||
#define SDIOCGFORMAT _IOR('S', 0x2, int)
|
||||
#define SDIOCSCSICOMMAND _IOW('S', 0x3, struct scsi_fmt_cdb)
|
||||
#define SDIOCSENSE _IOR('S', 0x4, struct scsi_fmt_sense)
|
||||
|
||||
#ifdef _KERNEL
|
||||
/*
|
||||
* Routines.
|
||||
*/
|
||||
void scsiGroup0Cmd __P((unsigned cmd, /* group0 SCSI command */
|
||||
unsigned lun, /* Logical Unit Number */
|
||||
unsigned block,
|
||||
unsigned count,
|
||||
ScsiGroup0Cmd *c));
|
||||
|
||||
void scsiGroup1Cmd __P((unsigned cmd, /* group0 SCSI command */
|
||||
unsigned lun, /* Logical Unit Number */
|
||||
unsigned block,
|
||||
unsigned count,
|
||||
ScsiGroup1Cmd *c));
|
||||
|
||||
void scsiPrintSense __P((ScsiClass7Sense *sp, int len));
|
||||
void scsiPrintInquiry __P((ScsiInquiryData *inqbuf, int len));
|
||||
#endif /* _KERNEL */
|
||||
|
||||
#endif /* _SCSI_H */
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: sii.c,v 1.43 2001/04/25 17:53:20 bouyer Exp $ */
|
||||
/* $NetBSD: sii.c,v 1.44 2001/08/26 11:47:23 simonb Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1992, 1993
|
||||
|
@ -54,21 +54,21 @@
|
|||
|
||||
#include <machine/locore.h>
|
||||
|
||||
#if NXSII > 0
|
||||
#include <dev/scsipi/scsi_all.h>
|
||||
#include <dev/scsipi/scsipi_all.h>
|
||||
#include <dev/scsipi/scsiconf.h>
|
||||
#include <dev/scsipi/scsi_message.h>
|
||||
#endif
|
||||
#include <dev/scsipi/scsipi_all.h>
|
||||
#include <dev/scsipi/scsipi_disk.h>
|
||||
#include <dev/scsipi/scsiconf.h>
|
||||
|
||||
/* old 4.4BSD/pmax scsi drivers */
|
||||
#include <pmax/dev/device.h>
|
||||
#include <pmax/dev/scsi.h>
|
||||
#include <pmax/dev/siireg.h> /* device registers */
|
||||
#include <pmax/dev/siivar.h> /* softc and prototypes */
|
||||
|
||||
#include <pmax/pmax/machdep.h> /* prom_scsiid prototype */
|
||||
|
||||
/* XXX not in dev/scsipi/scsi_message.h */
|
||||
#define MSG_EXT_MODIFY_DATA_PTR 0x00
|
||||
|
||||
extern struct cfdriver sii_cd;
|
||||
|
||||
/*
|
||||
|
@ -143,37 +143,18 @@ static int sii_GetByte __P((SIIRegs *regs, int phase, int ack));
|
|||
static void sii_DoSync __P((SIIRegs *regs, State *state));
|
||||
static void sii_StartDMA __P((SIIRegs *regs, int phase, u_short *dmaAddr,
|
||||
int size));
|
||||
#if NXSII == 0
|
||||
static void siistart __P((ScsiCmd *scsicmd));
|
||||
#endif
|
||||
|
||||
#ifdef DEBUG
|
||||
static void sii_DumpLog __P((void));
|
||||
#endif
|
||||
|
||||
|
||||
#if NXSII == 0
|
||||
/*
|
||||
* Definition of the controller for the old-style, non-MI
|
||||
* pmax scsi drivers, and for autoconfiguring devices via those
|
||||
* drivers.
|
||||
*/
|
||||
struct pmax_driver siidriver = {
|
||||
"sii", NULL, siistart, 0,
|
||||
};
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Match driver based on name
|
||||
*/
|
||||
void
|
||||
#if NXSII > 0
|
||||
siiattach(sc)
|
||||
struct siisoftc *sc;
|
||||
#else
|
||||
siiattach(sc)
|
||||
struct siisoftc *sc;
|
||||
#endif
|
||||
{
|
||||
int i;
|
||||
|
||||
|
@ -191,16 +172,9 @@ siiattach(sc)
|
|||
SII_MAX_DMA_XFER_LENGTH;
|
||||
}
|
||||
|
||||
#if NXSII == 0
|
||||
/* Hack for old-sytle SCSI-device probe */
|
||||
(void) pmax_add_scsi(&siidriver, sc->sc_dev.dv_unit);
|
||||
#endif
|
||||
|
||||
sii_Reset(sc, RESET);
|
||||
printf(": target %d\n", sc->sc_regs->id & SII_IDMSK);
|
||||
|
||||
#if NXSII > 0
|
||||
|
||||
sc->sc_adapter.adapt_dev = &sc->sc_dev;
|
||||
sc->sc_adapter.adapt_nchannels = 1;
|
||||
sc->sc_adapter.adapt_openings = 7;
|
||||
|
@ -221,7 +195,6 @@ siiattach(sc)
|
|||
* Now try to attach all the sub-devices
|
||||
*/
|
||||
config_found(&sc->sc_dev, &sc->sc_channel, scsiprint);
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -230,7 +203,6 @@ siiattach(sc)
|
|||
* connect/disconnect during an operation.
|
||||
*/
|
||||
|
||||
#if NXSII > 0
|
||||
void
|
||||
sii_scsi_request(chan, req, arg)
|
||||
struct scsipi_channel *chan;
|
||||
|
@ -294,34 +266,6 @@ sii_scsi_request(chan, req, arg)
|
|||
return;
|
||||
}
|
||||
}
|
||||
#else
|
||||
|
||||
static void
|
||||
siistart(scsicmd)
|
||||
ScsiCmd *scsicmd; /* command to start */
|
||||
{
|
||||
struct pmax_scsi_device *sdp = scsicmd->sd;
|
||||
struct siisoftc *sc = sii_cd.cd_devs[sdp->sd_ctlr];
|
||||
int s;
|
||||
|
||||
s = splbio();
|
||||
/*
|
||||
* Check if another command is already in progress.
|
||||
* We may have to change this if we allow SCSI devices with
|
||||
* separate LUNs.
|
||||
*/
|
||||
if (sc->sc_cmd[sdp->sd_drive]) {
|
||||
printf("%s: device %s busy at start\n", sc->sc_dev.dv_xname,
|
||||
sdp->sd_driver->d_name);
|
||||
(*sdp->sd_driver->d_done)(scsicmd->unit, EBUSY,
|
||||
scsicmd->buflen, 0);
|
||||
splx(s);
|
||||
}
|
||||
sc->sc_cmd[sdp->sd_drive] = scsicmd;
|
||||
sii_StartCmd(sc, sdp->sd_drive);
|
||||
splx(s);
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Check to see if any SII chips have pending interrupts
|
||||
|
@ -446,11 +390,6 @@ sii_StartCmd(sc, target)
|
|||
state->dmaDataPhase = -1; /* illegal phase. shouldn't happen */
|
||||
state->buf = (char *)0;
|
||||
} else {
|
||||
#ifdef check_data_phase /* XXX Let device drive the data phase appropriately */
|
||||
state->dmaDataPhase =
|
||||
(scsicmd->flags & SCSICMD_DATA_TO_DEVICE) ?
|
||||
SII_DATA_OUT_PHASE : SII_DATA_IN_PHASE;
|
||||
#endif
|
||||
state->buf = scsicmd->buf;
|
||||
}
|
||||
|
||||
|
@ -462,8 +401,8 @@ sii_StartCmd(sc, target)
|
|||
state->dmaDataPhase);
|
||||
}
|
||||
sii_debug_cmd = scsicmd->cmd[0];
|
||||
if (scsicmd->cmd[0] == SCSI_READ_EXT ||
|
||||
scsicmd->cmd[0] == SCSI_WRITE_EXT) {
|
||||
if (scsicmd->cmd[0] == READ_BIG ||
|
||||
scsicmd->cmd[0] == WRITE_BIG) {
|
||||
sii_debug_bn = (scsicmd->cmd[2] << 24) |
|
||||
(scsicmd->cmd[3] << 16) |
|
||||
(scsicmd->cmd[4] << 8) |
|
||||
|
@ -496,10 +435,10 @@ sii_StartCmd(sc, target)
|
|||
* Setup to send both the identify message and the synchronous
|
||||
* data transfer request.
|
||||
*/
|
||||
sii_buf[0] = SCSI_DIS_REC_IDENTIFY;
|
||||
sii_buf[1] = SCSI_EXTENDED_MSG;
|
||||
sii_buf[2] = 3; /* message length */
|
||||
sii_buf[3] = SCSI_SYNCHRONOUS_XFER;
|
||||
sii_buf[0] = MSG_IDENTIFYFLAG | MSG_IDENTIFY_DISCFLAG;
|
||||
sii_buf[1] = MSG_EXTENDED;
|
||||
sii_buf[2] = MSG_EXT_SDTR_LEN;
|
||||
sii_buf[3] = MSG_EXT_SDTR;
|
||||
sii_buf[4] = 0;
|
||||
sii_buf[5] = 3; /* maximum SII chip supports */
|
||||
|
||||
|
@ -518,7 +457,8 @@ sii_StartCmd(sc, target)
|
|||
#endif
|
||||
{
|
||||
/* do a chained, select with ATN and programmed I/O command */
|
||||
regs->data = SCSI_DIS_REC_IDENTIFY | scsicmd->lun;
|
||||
regs->data = MSG_IDENTIFYFLAG | MSG_IDENTIFY_DISCFLAG |
|
||||
scsicmd->lun;
|
||||
regs->slcsr = target;
|
||||
regs->dmctrl = state->dmaReqAck;
|
||||
regs->comm = SII_INXFER | SII_SELECT | SII_ATN | SII_CON |
|
||||
|
@ -949,14 +889,6 @@ again:
|
|||
#endif
|
||||
break;
|
||||
}
|
||||
#ifdef check_data_phase /* XXX Let the device drive the data phase appropriately */
|
||||
if (state->dmaDataPhase != (dstat & SII_PHASE_MSK)) {
|
||||
printf("%s: device %d: cmd %x: dma phase doesn't match\n",
|
||||
sc->sc_dev.dv_xname, sc->sc_target,
|
||||
sc->sc_cmd[sc->sc_target]->cmd[0]);
|
||||
goto abort;
|
||||
}
|
||||
#endif
|
||||
#ifdef DEBUG
|
||||
if (sii_debug > 4) {
|
||||
printf("Data %d ", state->dmaDataPhase);
|
||||
|
@ -1135,7 +1067,7 @@ again:
|
|||
|
||||
/* process message */
|
||||
switch (msg) {
|
||||
case SCSI_COMMAND_COMPLETE:
|
||||
case MSG_CMDCOMPLETE:
|
||||
/* acknowledge last byte */
|
||||
regs->comm = SII_INXFER | SII_MSG_IN_PHASE |
|
||||
(comm & SII_STATE_MSK);
|
||||
|
@ -1176,7 +1108,7 @@ again:
|
|||
sii_CmdDone(sc, msg, 0);
|
||||
break;
|
||||
|
||||
case SCSI_EXTENDED_MSG:
|
||||
case MSG_EXTENDED:
|
||||
/* acknowledge last byte */
|
||||
regs->comm = SII_INXFER | SII_MSG_IN_PHASE |
|
||||
(comm & SII_STATE_MSK);
|
||||
|
@ -1209,7 +1141,7 @@ again:
|
|||
}
|
||||
|
||||
switch (sii_buf[2]) {
|
||||
case SCSI_MODIFY_DATA_PTR:
|
||||
case MSG_EXT_MODIFY_DATA_PTR:
|
||||
/* acknowledge last byte */
|
||||
regs->comm = SII_INXFER |
|
||||
SII_MSG_IN_PHASE |
|
||||
|
@ -1229,7 +1161,7 @@ again:
|
|||
}
|
||||
break;
|
||||
|
||||
case SCSI_SYNCHRONOUS_XFER:
|
||||
case MSG_EXT_SDTR_LEN:
|
||||
/*
|
||||
* Acknowledge last byte and
|
||||
* signal a request for MSG_OUT.
|
||||
|
@ -1266,7 +1198,7 @@ again:
|
|||
SII_WAIT_COUNT, i);
|
||||
|
||||
/* send a reject message */
|
||||
regs->data = SCSI_MESSAGE_REJECT;
|
||||
regs->data = MSG_MESSAGE_REJECT;
|
||||
regs->comm = SII_INXFER |
|
||||
(regs->cstat & SII_STATE_MSK) |
|
||||
SII_MSG_OUT_PHASE;
|
||||
|
@ -1278,8 +1210,8 @@ again:
|
|||
}
|
||||
break;
|
||||
|
||||
case SCSI_SAVE_DATA_POINTER:
|
||||
case SCSI_RESTORE_POINTERS:
|
||||
case MSG_SAVEDATAPOINTER:
|
||||
case MSG_RESTOREPOINTERS:
|
||||
/* acknowledge last byte */
|
||||
regs->comm = SII_INXFER | SII_MSG_IN_PHASE |
|
||||
(comm & SII_STATE_MSK);
|
||||
|
@ -1300,7 +1232,7 @@ again:
|
|||
}
|
||||
break;
|
||||
|
||||
case SCSI_DISCONNECT:
|
||||
case MSG_DISCONNECT:
|
||||
/* acknowledge last byte */
|
||||
regs->comm = SII_INXFER | SII_MSG_IN_PHASE |
|
||||
(comm & SII_STATE_MSK);
|
||||
|
@ -1345,7 +1277,7 @@ again:
|
|||
sii_StateChg(sc, i);
|
||||
break;
|
||||
|
||||
case SCSI_MESSAGE_REJECT:
|
||||
case MSG_MESSAGE_REJECT:
|
||||
/* acknowledge last byte */
|
||||
regs->comm = SII_INXFER | SII_MSG_IN_PHASE |
|
||||
(comm & SII_STATE_MSK);
|
||||
|
@ -1358,10 +1290,11 @@ again:
|
|||
break;
|
||||
|
||||
default:
|
||||
if (!(msg & SCSI_IDENTIFY)) {
|
||||
printf("%s: device %d: couldn't handle message 0x%x... rejecting.\n",
|
||||
sc->sc_dev.dv_xname, sc->sc_target,
|
||||
msg);
|
||||
if (!(msg & MSG_IDENTIFYFLAG)) {
|
||||
printf("%s: device %d: couldn't handle "
|
||||
"message 0x%x... rejecting.\n",
|
||||
sc->sc_dev.dv_xname, sc->sc_target,
|
||||
msg);
|
||||
#ifdef DEBUG
|
||||
sii_DumpLog();
|
||||
#endif
|
||||
|
@ -1403,9 +1336,9 @@ again:
|
|||
*/
|
||||
if (state->flags & PARITY_ERR) {
|
||||
state->flags &= ~PARITY_ERR;
|
||||
regs->data = SCSI_MESSAGE_PARITY_ERROR;
|
||||
regs->data = MSG_PARITY_ERROR;
|
||||
} else
|
||||
regs->data = SCSI_NO_OP;
|
||||
regs->data = MSG_NOOP;
|
||||
regs->comm = SII_INXFER | (comm & SII_STATE_MSK) |
|
||||
SII_MSG_OUT_PHASE;
|
||||
wbflush();
|
||||
|
@ -1467,7 +1400,7 @@ abort:
|
|||
if ((cstat = regs->cstat) & SII_CON) {
|
||||
/* try to send an abort msg for awhile */
|
||||
regs->dstat = SII_DNE;
|
||||
regs->data = SCSI_ABORT;
|
||||
regs->data = MSG_ABORT;
|
||||
regs->comm = SII_INXFER | SII_ATN | (cstat & SII_STATE_MSK) |
|
||||
SII_MSG_OUT_PHASE;
|
||||
wbflush();
|
||||
|
@ -1702,9 +1635,9 @@ sii_DoSync(regs, state)
|
|||
if (len > 3)
|
||||
len = 3;
|
||||
|
||||
sii_buf[0] = SCSI_EXTENDED_MSG;
|
||||
sii_buf[1] = 3; /* message length */
|
||||
sii_buf[2] = SCSI_SYNCHRONOUS_XFER;
|
||||
sii_buf[0] = MSG_EXTENDED;
|
||||
sii_buf[1] = MSG_EXT_SDTR_LEN;
|
||||
sii_buf[2] = MSG_EXT_SDTR;
|
||||
sii_buf[4] = len;
|
||||
#if 1
|
||||
comm = SII_INXFER | SII_ATN | SII_MSG_OUT_PHASE |
|
||||
|
@ -1856,7 +1789,6 @@ sii_CmdDone(sc, target, error)
|
|||
break;
|
||||
}
|
||||
|
||||
#if NXSII > 0
|
||||
sc->sc_xs[target]->status = sc->sc_st[target].statusByte;
|
||||
/*
|
||||
* Convert SII driver error code to MI SCSI XS_*.
|
||||
|
@ -1880,10 +1812,6 @@ sii_CmdDone(sc, target, error)
|
|||
sc->sc_xs[target]->resid = sc->sc_st[target].buflen;
|
||||
sc->sc_xs[target]->xs_status |= XS_STS_DONE;
|
||||
scsipi_done(sc->sc_xs[target]);
|
||||
#else
|
||||
(*scsicmd->sd->sd_driver->d_done)(scsicmd->unit, error,
|
||||
sc->sc_st[target].buflen, sc->sc_st[target].statusByte);
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: sii_ds.c,v 1.17 2001/04/25 17:53:21 bouyer Exp $ */
|
||||
/* $NetBSD: sii_ds.c,v 1.18 2001/08/26 11:47:23 simonb Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright 1996 The Board of Trustees of The Leland Stanford
|
||||
|
@ -24,17 +24,12 @@
|
|||
|
||||
#include <machine/locore.h>
|
||||
|
||||
#if NXSII > 0
|
||||
#include <dev/scsipi/scsi_all.h>
|
||||
#include <dev/scsipi/scsipi_all.h>
|
||||
#include <dev/scsipi/scsiconf.h>
|
||||
#include <dev/scsipi/scsi_message.h>
|
||||
|
||||
#include <machine/bus.h>
|
||||
#include <pmax/dev/device.h> /* XXX old pmax SCSI drivers */
|
||||
#else
|
||||
#include <pmax/dev/device.h> /* XXX old pmax SCSI drivers */
|
||||
#endif
|
||||
#include <pmax/dev/siireg.h>
|
||||
#include <pmax/dev/siivar.h>
|
||||
|
||||
|
@ -62,17 +57,9 @@ static int sii_ds_match __P((struct device* parent, struct cfdata *match,
|
|||
static void sii_ds_attach __P((struct device *parent, struct device *self,
|
||||
void *aux));
|
||||
|
||||
#if NXSII > 0
|
||||
struct cfattach xsii_ds_ca = {
|
||||
sizeof(struct siisoftc), sii_ds_match, sii_ds_attach
|
||||
};
|
||||
#else
|
||||
extern struct cfattach sii_ds_ca;
|
||||
struct cfattach sii_ds_ca = {
|
||||
sizeof(struct siisoftc), sii_ds_match, sii_ds_attach
|
||||
};
|
||||
#endif
|
||||
|
||||
|
||||
/* define a safe address in the SCSI buffer for doing status & message DMA */
|
||||
#define SII_BUF_ADDR (MIPS_PHYS_TO_KSEG1(KN01_SYS_SII_B_START) \
|
||||
|
@ -126,10 +113,8 @@ sii_ds_attach(parent, self, aux)
|
|||
}
|
||||
|
||||
/* Do the common parts of attachment. */
|
||||
#if NXSII > 0
|
||||
sc->sc_adapter.adapt_request = sii_scsi_request;
|
||||
sc->sc_adapter.adapt_minphys = minphys;
|
||||
#endif
|
||||
siiattach(sc);
|
||||
|
||||
/* tie pseudo-slot to device */
|
||||
|
|
|
@ -1,8 +1,24 @@
|
|||
/* $NetBSD: siivar.h,v 1.7 2001/04/25 17:53:21 bouyer Exp $ */
|
||||
/* $NetBSD: siivar.h,v 1.8 2001/08/26 11:47:23 simonb Exp $ */
|
||||
|
||||
#ifndef _SIIVAR_H
|
||||
#define _SIIVAR_H
|
||||
|
||||
/*
|
||||
* This structure contains information that a SCSI interface controller
|
||||
* needs to execute a SCSI command.
|
||||
*/
|
||||
typedef struct ScsiCmd {
|
||||
int unit; /* unit number passed to device done routine */
|
||||
int flags; /* control flags for this command (see below) */
|
||||
int buflen; /* length of the data buffer in bytes */
|
||||
char *buf; /* pointer to data buffer for this command */
|
||||
int cmdlen; /* length of data in cmdbuf */
|
||||
u_char *cmd; /* buffer for the SCSI command */
|
||||
int error; /* compatibility hack for new scsi */
|
||||
int lun; /* LUN for MI SCSI */
|
||||
struct callout timo_ch; /* timeout callout handle */
|
||||
} ScsiCmd;
|
||||
|
||||
typedef struct scsi_state {
|
||||
int statusByte; /* status byte returned during STATUS_PHASE */
|
||||
int dmaDataPhase; /* which data phase to expect */
|
||||
|
@ -32,12 +48,10 @@ typedef struct scsi_state {
|
|||
#define SII_NCMD 8
|
||||
struct siisoftc {
|
||||
struct device sc_dev; /* us as a device */
|
||||
#if NXSII > 0
|
||||
struct scsipi_channel sc_channel;
|
||||
struct scsipi_adapter sc_adapter; /* scsipi adapter glue */
|
||||
ScsiCmd sc_cmd_fake[SII_NCMD]; /* XXX - hack!!! */
|
||||
struct scsipi_xfer *sc_xs[SII_NCMD]; /* XXX - hack!!! */
|
||||
#endif
|
||||
void *sc_buf; /* DMA buffer (may be special mem) */
|
||||
SIIRegs *sc_regs; /* HW address of SII controller chip */
|
||||
int sc_flags;
|
||||
|
@ -53,10 +67,8 @@ int siiintr __P((void *sc));
|
|||
|
||||
/* Machine-indepedent back-end attach entry point */
|
||||
|
||||
#if NXSII > 0
|
||||
void sii_scsi_request __P((struct scsipi_channel *,
|
||||
scsipi_adapter_req_t, void *));
|
||||
#endif
|
||||
void siiattach __P((struct siisoftc *));
|
||||
|
||||
#endif /* _SIIVAR_H */
|
||||
|
|
|
@ -1,948 +0,0 @@
|
|||
/* $NetBSD: tz.c,v 1.32 2001/07/07 14:21:01 simonb Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1992, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to Berkeley by
|
||||
* Ralph Campbell.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)tz.c 8.5 (Berkeley) 6/2/95
|
||||
*
|
||||
* from: Header: /sprite/src/kernel/dev/RCS/devSCSITape.c,
|
||||
* v 8.14 89/07/31 17:26:13 mendel Exp SPRITE (Berkeley)
|
||||
*/
|
||||
|
||||
/*
|
||||
* SCSI CCS (Command Command Set) tape driver.
|
||||
*/
|
||||
#include "tz.h"
|
||||
#if NTZ > 0
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/buf.h>
|
||||
#include <sys/conf.h>
|
||||
#include <sys/device.h>
|
||||
#include <sys/file.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/mtio.h>
|
||||
#include <sys/proc.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/tprintf.h>
|
||||
|
||||
#include <machine/conf.h>
|
||||
|
||||
#include <pmax/dev/device.h>
|
||||
#include <pmax/dev/scsi.h>
|
||||
|
||||
static int tzprobe __P((void *sd /*struct pmax_scsi_device *sd*/));
|
||||
static int tzcommand __P((dev_t dev, int command, int code,
|
||||
int count, caddr_t data));
|
||||
static void tzstart __P((int unit));
|
||||
static void tzdone __P((int unit, int error, int resid, int status));
|
||||
static int tzmount __P((dev_t dev));
|
||||
|
||||
struct pmax_driver tzdriver = {
|
||||
"tz", tzprobe,
|
||||
(void (*) __P((struct ScsiCmd *cmd))) tzstart,
|
||||
tzdone,
|
||||
};
|
||||
|
||||
struct tzmodes {
|
||||
u_int quirks;
|
||||
u_int8_t density;
|
||||
};
|
||||
|
||||
struct tzquirk {
|
||||
char *product;
|
||||
u_int page_0_size;
|
||||
u_int quirks;
|
||||
int blklen;
|
||||
struct tzmodes modes[2]; /* low density, high density */
|
||||
};
|
||||
|
||||
#define TZ_Q_FORCE_BLKSIZE 0x0001
|
||||
#define TZ_Q_SENSE_HELP 0x0002 /* must do READ for good MODE SENSE */
|
||||
#define TZ_Q_IGNORE_LOADS 0x0004
|
||||
#define TZ_Q_BLKSIZE 0x0008 /* variable-block media_blksize > 0 */
|
||||
#define TZ_Q_UNIMODAL 0x0010 /* unimode drive rejects mode select */
|
||||
#define TZ_Q_DENSITY 0x0020 /* density codes valid */
|
||||
#define MAX_PAGE_0_SIZE 64
|
||||
|
||||
|
||||
static struct tz_softc {
|
||||
struct device sc_dev; /* new config glue */
|
||||
struct pmax_scsi_device *sc_sd; /* physical unit info */
|
||||
int sc_flags; /* see below */
|
||||
int sc_blklen; /* 0 = variable len records */
|
||||
long sc_numblks; /* number of blocks on tape */
|
||||
tpr_t sc_ctty; /* terminal for error messages */
|
||||
daddr_t sc_fileno; /* file number of current position */
|
||||
daddr_t sc_blkno; /* block number of current position */
|
||||
struct buf_queue sc_tab; /* queue of pending operations */
|
||||
int sc_active; /* number of active operations */
|
||||
struct buf sc_buf; /* buf for doing I/O */
|
||||
struct buf sc_errbuf; /* buf for doing REQUEST_SENSE */
|
||||
struct ScsiCmd sc_cmd; /* command for controller */
|
||||
ScsiGroup0Cmd sc_rwcmd; /* SCSI cmd for read/write */
|
||||
struct scsi_fmt_cdb sc_cdb; /* SCSI cmd if not read/write */
|
||||
struct scsi_fmt_sense sc_sense; /* sense data from last cmd */
|
||||
struct ScsiTapeModeSelectHdr sc_mode; /* SCSI_MODE_SENSE data */
|
||||
char sc_modelen; /* SCSI_MODE_SENSE data length */
|
||||
struct tzquirk *sc_quirks; /* quirks for this drive */
|
||||
|
||||
} tz_softc[NTZ];
|
||||
|
||||
/* sc_flags values */
|
||||
#define TZF_ALIVE 0x001 /* drive found and ready */
|
||||
#define TZF_MOUNTED 0x002 /* device is presently mounted */
|
||||
#define TZF_OPEN 0x004 /* device is open */
|
||||
#define TZF_SENSEINPROGRESS 0x008 /* REQUEST_SENSE command in progress */
|
||||
#define TZF_ALTCMD 0x010 /* alternate command in progress */
|
||||
#define TZF_WRITTEN 0x020 /* tape has been written to */
|
||||
#define TZF_WAIT 0x040 /* waiting for sc_tab to drain */
|
||||
#define TZF_SEENEOF 0x080 /* seen file mark on read */
|
||||
#define TZF_RDONLY 0x100 /* mode sense says write protected */
|
||||
#define TZF_DONTCOUNT 0x200 /* operation isn't to be counted for sc_blkno */
|
||||
|
||||
/* bits in minor device */
|
||||
#define tzunit(x) (minor(x) >> 4) /* tz%d unit number */
|
||||
#define TZ_NOREWIND 0x01 /* don't rewind on close */
|
||||
#define TZ_HIDENSITY 0x02
|
||||
#define TZ_EXSFMK 0x04
|
||||
#define TZ_FIXEDBLK 0x08
|
||||
|
||||
#ifdef DEBUG
|
||||
int tzdebug = 0;
|
||||
#endif
|
||||
|
||||
|
||||
struct tzquirk tz_quirk_table[] = {
|
||||
{ "EXB-8200", 17, 0, 0, {
|
||||
{ 0, 0,},
|
||||
{ 0, 0,}
|
||||
}},
|
||||
{ "TZK08", 17, 0, 0, {
|
||||
{ 0, 0,},
|
||||
{ 0, 0,}
|
||||
}},
|
||||
{ "EXB-8500", 17, 0, 0, {
|
||||
{ 0, 0,},
|
||||
{ 0, 0,}
|
||||
}},
|
||||
{ "TKZ09", 17, 0, 0, {
|
||||
{ 0, 0,},
|
||||
{ 0, 0,}
|
||||
}},
|
||||
|
||||
{ "VIPER 150", 0, TZ_Q_FORCE_BLKSIZE, 512, {
|
||||
{ 0, 0, },
|
||||
{ 0, 0, }
|
||||
}},
|
||||
{ "5150ES SCSI", 0, TZ_Q_FORCE_BLKSIZE, 512, {
|
||||
{ 0, 0, },
|
||||
{ 0, 0, }
|
||||
}},
|
||||
|
||||
/* The next two product ids are faked up in tzprobe() */
|
||||
{ "TK50 0x30", 14, 0, 0, {
|
||||
{ 0, 0,},
|
||||
{ 0, 0,}
|
||||
}},
|
||||
{ "MT02", 0, 0, 0, {
|
||||
{ TZ_Q_DENSITY, 0x4 },
|
||||
{ TZ_Q_DENSITY, 0 }
|
||||
}},
|
||||
};
|
||||
|
||||
#define NQUIRKS (sizeof(tz_quirk_table) / sizeof(tz_quirk_table[0]))
|
||||
|
||||
/*
|
||||
* Test to see if device is present.
|
||||
* Return true if found and initialized ok.
|
||||
*/
|
||||
static int
|
||||
tzprobe(xxxsd)
|
||||
void *xxxsd;
|
||||
{
|
||||
int i;
|
||||
char vid[9], pid[17], revl[5];
|
||||
struct pmax_scsi_device *sd = xxxsd;
|
||||
struct tz_softc *sc = &tz_softc[sd->sd_unit];
|
||||
ScsiInquiryData inqbuf;
|
||||
|
||||
if (sd->sd_unit >= NTZ)
|
||||
return (0);
|
||||
|
||||
BUFQ_INIT(&sc->sc_tab);
|
||||
callout_init(&sc->sc_cmd.timo_ch);
|
||||
|
||||
/* init some parameters that don't change */
|
||||
sc->sc_sd = sd;
|
||||
sc->sc_cmd.sd = sd;
|
||||
sc->sc_cmd.unit = sd->sd_unit;
|
||||
sc->sc_cmd.flags = 0;
|
||||
sc->sc_cmd.lun = 0;
|
||||
sc->sc_rwcmd.unitNumber = sd->sd_slave;
|
||||
|
||||
/* XXX set up device info */ /* XXX */
|
||||
memset(&sc->sc_dev, 0, sizeof(sc->sc_dev)); /* XXX */
|
||||
sprintf(sc->sc_dev.dv_xname, "tz%d", sd->sd_unit); /* XXX */
|
||||
sc->sc_dev.dv_unit = sd->sd_unit; /* XXX */
|
||||
sc->sc_dev.dv_class = DV_TAPE; /* XXX */
|
||||
|
||||
sc->sc_fileno = -1;
|
||||
sc->sc_blkno = -1;
|
||||
|
||||
/* try to find out what type of device this is */
|
||||
sc->sc_flags = TZF_ALTCMD; /* force use of sc_cdb */
|
||||
sc->sc_cdb.len = sizeof(ScsiGroup0Cmd);
|
||||
scsiGroup0Cmd(SCSI_INQUIRY, sd->sd_slave, 0, sizeof(inqbuf),
|
||||
(ScsiGroup0Cmd *)sc->sc_cdb.cdb);
|
||||
sc->sc_buf.b_flags = B_BUSY | B_READ;
|
||||
sc->sc_buf.b_bcount = sizeof(inqbuf);
|
||||
sc->sc_buf.b_data = (caddr_t)&inqbuf;
|
||||
BUFQ_INSERT_HEAD(&sc->sc_tab, &sc->sc_buf);
|
||||
tzstart(sd->sd_unit);
|
||||
if (biowait(&sc->sc_buf) ||
|
||||
(i = sizeof(inqbuf) - sc->sc_buf.b_resid) < 5)
|
||||
goto bad;
|
||||
if (inqbuf.type != SCSI_TAPE_TYPE || !inqbuf.rmb)
|
||||
goto bad;
|
||||
|
||||
/* check for device ready to clear UNIT_ATTN */
|
||||
sc->sc_cdb.len = sizeof(ScsiGroup0Cmd);
|
||||
scsiGroup0Cmd(SCSI_TEST_UNIT_READY, sd->sd_slave, 0, 0,
|
||||
(ScsiGroup0Cmd *)sc->sc_cdb.cdb);
|
||||
sc->sc_buf.b_flags = B_BUSY | B_READ;
|
||||
sc->sc_buf.b_bcount = 0;
|
||||
sc->sc_buf.b_data = NULL;
|
||||
BUFQ_INSERT_HEAD(&sc->sc_tab, &sc->sc_buf);
|
||||
tzstart(sd->sd_unit);
|
||||
(void) biowait(&sc->sc_buf);
|
||||
|
||||
sc->sc_flags = TZF_ALIVE;
|
||||
sc->sc_modelen = 12;
|
||||
sc->sc_buf.b_flags = 0;
|
||||
printf("tz%d at %s%d drive %d slave %d", sd->sd_unit,
|
||||
sd->sd_cdriver->d_name, sd->sd_ctlr, sd->sd_drive,
|
||||
sd->sd_slave);
|
||||
if (i == 5 && inqbuf.version == 1 && (inqbuf.qualifier == 0x50 ||
|
||||
inqbuf.qualifier == 0x30)) {
|
||||
strcpy(pid, "TK50");
|
||||
printf(" %s", pid);
|
||||
if (inqbuf.qualifier == 0x30)
|
||||
strcpy(pid, "TK50 0x30");
|
||||
} else if (i >= 5 && inqbuf.version == 1 && inqbuf.qualifier == 0 &&
|
||||
inqbuf.length == 0) {
|
||||
/* assume Emultex MT02 controller */
|
||||
strcpy(pid, "MT02");
|
||||
printf(" %s", pid);
|
||||
} else if (inqbuf.version > 2 || i < 36) {
|
||||
printf(" GENERIC SCSI tape device: qual 0x%x, ver %d",
|
||||
inqbuf.qualifier, inqbuf.version);
|
||||
} else {
|
||||
|
||||
memcpy(vid, inqbuf.vendorID, 8);
|
||||
memcpy(pid, inqbuf.productID, 16);
|
||||
memcpy(revl, inqbuf.revLevel, 4);
|
||||
for (i = 8; --i > 0; )
|
||||
if (vid[i] != ' ')
|
||||
break;
|
||||
vid[i+1] = 0;
|
||||
for (i = 16; --i > 0; )
|
||||
if (pid[i] != ' ')
|
||||
break;
|
||||
pid[i+1] = 0;
|
||||
for (i = 4; --i > 0; )
|
||||
if (revl[i] != ' ')
|
||||
break;
|
||||
revl[i+1] = 0;
|
||||
printf(" %s %s rev %s (SCSI-%d)", vid, pid, revl,
|
||||
inqbuf.version);
|
||||
}
|
||||
printf("\n");
|
||||
|
||||
sc->sc_quirks = NULL;
|
||||
for (i = 0; i < NQUIRKS; i++) {
|
||||
if (memcmp(pid, tz_quirk_table[i].product,
|
||||
strlen(tz_quirk_table[i].product)) == 0) {
|
||||
sc->sc_quirks = &tz_quirk_table[i];
|
||||
if (tz_quirk_table[i].quirks & TZ_Q_FORCE_BLKSIZE)
|
||||
sc->sc_blklen = tz_quirk_table[i].blklen;
|
||||
if (tz_quirk_table[i].page_0_size > 0) {
|
||||
sc->sc_modelen = tz_quirk_table[i].page_0_size;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
sd->sd_devp = &sc->sc_dev; /* XXX */
|
||||
TAILQ_INSERT_TAIL(&alldevs, &sc->sc_dev, dv_list); /* XXX */
|
||||
|
||||
return (1);
|
||||
|
||||
bad:
|
||||
/* doesn't exist or not a CCS device */
|
||||
sc->sc_flags = 0;
|
||||
sc->sc_buf.b_flags = 0;
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Perform a special tape command on a SCSI Tape drive.
|
||||
*/
|
||||
static int
|
||||
tzcommand(dev, command, code, count, data)
|
||||
dev_t dev;
|
||||
int command;
|
||||
int code;
|
||||
int count;
|
||||
caddr_t data;
|
||||
{
|
||||
struct tz_softc *sc = &tz_softc[tzunit(dev)];
|
||||
ScsiGroup0Cmd *c;
|
||||
int s, error;
|
||||
|
||||
s = splbio();
|
||||
/* wait for pending operations to finish */
|
||||
while (BUFQ_FIRST(&sc->sc_tab) != NULL) {
|
||||
sc->sc_flags |= TZF_WAIT;
|
||||
(void) tsleep(&sc->sc_flags, PZERO, "tzcmd", 0);
|
||||
}
|
||||
sc->sc_flags |= TZF_DONTCOUNT; /* don't count any operations in blkno */
|
||||
sc->sc_flags |= TZF_ALTCMD; /* force use of sc_cdb */
|
||||
sc->sc_cdb.len = sizeof(ScsiGroup0Cmd);
|
||||
c = (ScsiGroup0Cmd *)sc->sc_cdb.cdb;
|
||||
c->command = command;
|
||||
c->unitNumber = sc->sc_sd->sd_slave;
|
||||
c->highAddr = code;
|
||||
c->midAddr = count >> 16;
|
||||
c->lowAddr = count >> 8;
|
||||
c->blockCount = count;
|
||||
c->control = 0;
|
||||
if (command == SCSI_MODE_SELECT)
|
||||
sc->sc_buf.b_flags = B_BUSY;
|
||||
else {
|
||||
sc->sc_buf.b_flags = B_BUSY | B_READ;
|
||||
}
|
||||
sc->sc_buf.b_bcount = data ? count : 0;
|
||||
sc->sc_buf.b_data = data;
|
||||
BUFQ_INSERT_HEAD(&sc->sc_tab, &sc->sc_buf);
|
||||
tzstart(sc->sc_sd->sd_unit);
|
||||
error = biowait(&sc->sc_buf);
|
||||
sc->sc_flags &= ~TZF_DONTCOUNT; /* clear don't count flag */
|
||||
sc->sc_flags &= ~TZF_ALTCMD; /* force use of sc_cdb */
|
||||
sc->sc_buf.b_flags = 0;
|
||||
sc->sc_cmd.flags = 0;
|
||||
if (sc->sc_buf.b_resid)
|
||||
printf("tzcommand: resid %ld\n", sc->sc_buf.b_resid); /* XXX */
|
||||
if (error == 0) {
|
||||
switch (command) {
|
||||
case SCSI_SPACE:
|
||||
if (sc->sc_blkno != -1) {
|
||||
if (code == 0) {
|
||||
sc->sc_blkno += count;
|
||||
} else {
|
||||
sc->sc_fileno += count;
|
||||
sc->sc_blkno = 0;
|
||||
}
|
||||
}
|
||||
sc->sc_flags &= ~TZF_SEENEOF;
|
||||
break;
|
||||
|
||||
case SCSI_WRITE_EOF:
|
||||
if (sc->sc_blkno != -1) {
|
||||
sc->sc_fileno += count;
|
||||
sc->sc_blkno = 0;
|
||||
}
|
||||
sc->sc_flags &= ~TZF_SEENEOF;
|
||||
break;
|
||||
case SCSI_LOAD_UNLOAD:
|
||||
case SCSI_REWIND:
|
||||
sc->sc_fileno = 0;
|
||||
sc->sc_blkno = 0;
|
||||
sc->sc_flags &= ~TZF_SEENEOF;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
switch (command) {
|
||||
case SCSI_SPACE:
|
||||
case SCSI_WRITE_EOF:
|
||||
case SCSI_LOAD_UNLOAD:
|
||||
case SCSI_REWIND:
|
||||
sc->sc_fileno = -1;
|
||||
sc->sc_blkno = -1;
|
||||
}
|
||||
}
|
||||
splx(s);
|
||||
return (error);
|
||||
}
|
||||
|
||||
static void
|
||||
tzstart(unit)
|
||||
int unit;
|
||||
{
|
||||
struct tz_softc *sc = &tz_softc[unit];
|
||||
struct buf *bp = BUFQ_FIRST(&sc->sc_tab);
|
||||
int n;
|
||||
|
||||
sc->sc_cmd.buf = bp->b_data;
|
||||
sc->sc_cmd.buflen = bp->b_bcount;
|
||||
|
||||
if (sc->sc_flags & (TZF_SENSEINPROGRESS | TZF_ALTCMD)) {
|
||||
if (bp->b_flags & B_READ)
|
||||
sc->sc_cmd.flags &= ~SCSICMD_DATA_TO_DEVICE;
|
||||
else
|
||||
sc->sc_cmd.flags |= SCSICMD_DATA_TO_DEVICE;
|
||||
sc->sc_cmd.cmd = sc->sc_cdb.cdb;
|
||||
sc->sc_cmd.cmdlen = sc->sc_cdb.len;
|
||||
} else {
|
||||
if (bp->b_flags & B_READ) {
|
||||
sc->sc_cmd.flags = 0;
|
||||
sc->sc_rwcmd.command = SCSI_READ;
|
||||
sc->sc_flags &= ~TZF_WRITTEN;
|
||||
} else {
|
||||
sc->sc_cmd.flags = SCSICMD_DATA_TO_DEVICE;
|
||||
sc->sc_rwcmd.command = SCSI_WRITE;
|
||||
sc->sc_flags |= TZF_WRITTEN;
|
||||
}
|
||||
sc->sc_cmd.cmd = (u_char *)&sc->sc_rwcmd;
|
||||
sc->sc_cmd.cmdlen = sizeof(sc->sc_rwcmd);
|
||||
if (sc->sc_blklen) {
|
||||
/* fixed sized records */
|
||||
n = bp->b_bcount / sc->sc_blklen;
|
||||
if (bp->b_bcount % sc->sc_blklen) {
|
||||
tprintf(sc->sc_ctty,
|
||||
"tz%d: I/O not block aligned %d/%ld\n",
|
||||
unit, sc->sc_blklen, bp->b_bcount);
|
||||
tzdone(unit, EIO, bp->b_bcount, 0);
|
||||
}
|
||||
sc->sc_rwcmd.highAddr = 1;
|
||||
} else {
|
||||
/* variable sized records */
|
||||
n = bp->b_bcount;
|
||||
sc->sc_rwcmd.highAddr = 0;
|
||||
}
|
||||
sc->sc_rwcmd.midAddr = n >> 16;
|
||||
sc->sc_rwcmd.lowAddr = n >> 8;
|
||||
sc->sc_rwcmd.blockCount = n;
|
||||
}
|
||||
|
||||
/* tell controller to start this command */
|
||||
(*sc->sc_sd->sd_cdriver->d_start)(&sc->sc_cmd);
|
||||
}
|
||||
|
||||
/*
|
||||
* This is called by the controller driver when the command is done.
|
||||
*/
|
||||
static void
|
||||
tzdone(unit, error, resid, status)
|
||||
int unit;
|
||||
int error; /* error number from errno.h */
|
||||
int resid; /* amount not transfered */
|
||||
int status; /* SCSI status byte */
|
||||
{
|
||||
struct tz_softc *sc = &tz_softc[unit];
|
||||
struct buf *bp = BUFQ_FIRST(&sc->sc_tab);
|
||||
|
||||
if (bp == NULL) {
|
||||
printf("tz%d: bp == NULL\n", unit);
|
||||
return;
|
||||
}
|
||||
if (sc->sc_flags & TZF_SENSEINPROGRESS) {
|
||||
sc->sc_flags &= ~TZF_SENSEINPROGRESS;
|
||||
BUFQ_REMOVE(&sc->sc_tab, bp); /* remove sc_errbuf */
|
||||
bp = BUFQ_FIRST(&sc->sc_tab);
|
||||
#ifdef DIAGNOSTIC
|
||||
if (bp == NULL)
|
||||
panic("tzdone");
|
||||
#endif
|
||||
|
||||
if (error || (status & SCSI_STATUS_CHECKCOND)) {
|
||||
printf("tz%d: error reading sense data: error %d scsi status 0x%x\n",
|
||||
unit, error, status);
|
||||
/*
|
||||
* We got an error during the REQUEST_SENSE,
|
||||
* fill in no sense for data.
|
||||
*/
|
||||
sc->sc_sense.sense[0] = 0x70;
|
||||
sc->sc_sense.sense[2] = SCSI_CLASS7_NO_SENSE;
|
||||
} else if (!cold) {
|
||||
ScsiClass7Sense *sp;
|
||||
long resid = 0;
|
||||
|
||||
sp = (ScsiClass7Sense *)sc->sc_sense.sense;
|
||||
if (sp->error7 != 0x70)
|
||||
goto prerr;
|
||||
if (sp->valid) {
|
||||
resid = (sp->info1 << 24) | (sp->info2 << 16) |
|
||||
(sp->info3 << 8) | sp->info4;
|
||||
if (sc->sc_blklen)
|
||||
resid *= sc->sc_blklen;
|
||||
} else
|
||||
resid = 0;
|
||||
switch (sp->key) {
|
||||
case SCSI_CLASS7_NO_SENSE:
|
||||
/*
|
||||
* Hit a filemark, end of media, or
|
||||
* end of record.
|
||||
* Fixed length blocks, an error.
|
||||
*/
|
||||
if (sp->endOfMedia) {
|
||||
bp->b_error = ENOSPC;
|
||||
bp->b_resid = resid;
|
||||
break;
|
||||
}
|
||||
if (sp->fileMark) {
|
||||
if (sc->sc_fileno != -1) {
|
||||
sc->sc_fileno++;
|
||||
sc->sc_blkno = 0;
|
||||
}
|
||||
}
|
||||
if (sc->sc_blklen && sp->badBlockLen) {
|
||||
tprintf(sc->sc_ctty,
|
||||
"tz%d: Incorrect Block Length, expected %d got %ld\n",
|
||||
unit, sc->sc_blklen, resid);
|
||||
break;
|
||||
}
|
||||
if (resid < 0) {
|
||||
/*
|
||||
* Variable length records but
|
||||
* attempted to read less than a
|
||||
* full record.
|
||||
*/
|
||||
tprintf(sc->sc_ctty,
|
||||
"tz%d: Partial Read of Variable Length Tape Block, expected %ld read %ld\n",
|
||||
unit, bp->b_bcount - resid,
|
||||
bp->b_bcount);
|
||||
bp->b_resid = 0;
|
||||
break;
|
||||
}
|
||||
if (sp->fileMark)
|
||||
sc->sc_flags |= TZF_SEENEOF;
|
||||
/*
|
||||
* Attempting to read more than a record is
|
||||
* OK. Just record how much was actually read.
|
||||
*/
|
||||
bp->b_flags &= ~B_ERROR;
|
||||
bp->b_error = 0;
|
||||
bp->b_resid = resid;
|
||||
break;
|
||||
|
||||
case SCSI_CLASS7_UNIT_ATTN:
|
||||
if (!(sc->sc_flags & TZF_OPEN))
|
||||
break;
|
||||
|
||||
default:
|
||||
prerr:
|
||||
printf("tz%d: ", unit);
|
||||
scsiPrintSense((ScsiClass7Sense *)
|
||||
sc->sc_sense.sense,
|
||||
sizeof(sc->sc_sense.sense) - resid);
|
||||
}
|
||||
}
|
||||
} else if (error || (status & SCSI_STATUS_CHECKCOND)) {
|
||||
#ifdef DEBUG
|
||||
if (!cold && tzdebug)
|
||||
printf("tz%d: error %d scsi status 0x%x\n",
|
||||
unit, error, status);
|
||||
#endif
|
||||
/* save error info */
|
||||
sc->sc_sense.status = status;
|
||||
bp->b_flags |= B_ERROR;
|
||||
bp->b_error = error;
|
||||
bp->b_resid = resid;
|
||||
|
||||
if (status & SCSI_STATUS_CHECKCOND) {
|
||||
/*
|
||||
* Start a REQUEST_SENSE command.
|
||||
* Since we are called at interrupt time, we can't
|
||||
* wait for the command to finish; that's why we use
|
||||
* the sc_flags field.
|
||||
*/
|
||||
sc->sc_flags |= TZF_SENSEINPROGRESS;
|
||||
sc->sc_cdb.len = sizeof(ScsiGroup0Cmd);
|
||||
scsiGroup0Cmd(SCSI_REQUEST_SENSE, sc->sc_sd->sd_slave,
|
||||
0, sizeof(sc->sc_sense.sense),
|
||||
(ScsiGroup0Cmd *)sc->sc_cdb.cdb);
|
||||
sc->sc_errbuf.b_flags = B_BUSY | B_PHYS | B_READ;
|
||||
sc->sc_errbuf.b_bcount = sizeof(sc->sc_sense.sense);
|
||||
sc->sc_errbuf.b_data = (caddr_t)sc->sc_sense.sense;
|
||||
BUFQ_INSERT_HEAD(&sc->sc_tab, &sc->sc_errbuf);
|
||||
tzstart(unit);
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
sc->sc_sense.status = status;
|
||||
bp->b_resid = resid;
|
||||
if (!(sc->sc_flags & TZF_DONTCOUNT) && sc->sc_blkno != -1) {
|
||||
if (sc->sc_blklen != 0)
|
||||
sc->sc_blkno += bp->b_bcount / sc->sc_blklen;
|
||||
else
|
||||
sc->sc_blkno++;
|
||||
}
|
||||
}
|
||||
|
||||
BUFQ_REMOVE(&sc->sc_tab, bp);
|
||||
biodone(bp);
|
||||
if (BUFQ_FIRST(&sc->sc_tab) != NULL)
|
||||
tzstart(unit);
|
||||
else {
|
||||
sc->sc_active = 0;
|
||||
if (sc->sc_flags & TZF_WAIT) {
|
||||
sc->sc_flags &= ~TZF_WAIT;
|
||||
wakeup(&sc->sc_flags);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
tzmount(dev)
|
||||
dev_t dev;
|
||||
{
|
||||
int unit = tzunit(dev);
|
||||
struct tz_softc *sc = &tz_softc[unit];
|
||||
int densmode, error;
|
||||
|
||||
/* clear UNIT_ATTENTION */
|
||||
error = tzcommand(dev, SCSI_TEST_UNIT_READY, 0, 0, 0);
|
||||
while (error) {
|
||||
ScsiClass7Sense *sp = (ScsiClass7Sense *)sc->sc_sense.sense;
|
||||
|
||||
/* return error if last error was not UNIT_ATTENTION */
|
||||
if (!(sc->sc_sense.status & SCSI_STATUS_CHECKCOND) ||
|
||||
sp->error7 != 0x70 || sp->key != SCSI_CLASS7_UNIT_ATTN)
|
||||
return (error);
|
||||
|
||||
/*
|
||||
* Try it again just to be sure and
|
||||
* try to negotiate synchonous transfers.
|
||||
*/
|
||||
error = tzcommand(dev, SCSI_TEST_UNIT_READY, 0, 0, 0);
|
||||
}
|
||||
|
||||
if ((sc->sc_flags & TZF_MOUNTED) == 0) {
|
||||
/* get the current mode settings */
|
||||
error = tzcommand(dev, SCSI_MODE_SENSE, 0,
|
||||
sc->sc_modelen, (caddr_t)&sc->sc_mode);
|
||||
if (error)
|
||||
return (error);
|
||||
|
||||
sc->sc_flags = TZF_ALIVE;
|
||||
|
||||
/* *Very* first off, make sure we're loaded to BOT. */
|
||||
error = tzcommand(dev, SCSI_LOAD_UNLOAD, 0, SCSI_LD_LOAD, 0);
|
||||
/* In case this doesn't work, do a REWIND instead */
|
||||
if (error)
|
||||
error = tzcommand(dev, SCSI_REWIND, 0, 0, 0);
|
||||
if (error)
|
||||
return (error);
|
||||
|
||||
/* check for write protected tape */
|
||||
if (sc->sc_mode.writeprot)
|
||||
sc->sc_flags |= TZF_RDONLY;
|
||||
else
|
||||
sc->sc_flags &= ~TZF_RDONLY;
|
||||
#if 0 /* XXX not the right place! Do we need to check at all? */
|
||||
if ((flags & FWRITE) && sc->sc_mode.writeprot) {
|
||||
uprintf("tz%d: write protected\n", unit);
|
||||
return (EACCES);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* save total number of blocks on tape */
|
||||
sc->sc_numblks = (sc->sc_mode.blocks_2 << 16) |
|
||||
(sc->sc_mode.blocks_1 << 8) | sc->sc_mode.blocks_0;
|
||||
|
||||
/* setup for mode select */
|
||||
sc->sc_mode.len = 0;
|
||||
sc->sc_mode.media = 0;
|
||||
sc->sc_mode.bufferedMode = 1;
|
||||
sc->sc_mode.blocks_0 = 0;
|
||||
sc->sc_mode.blocks_1 = 0;
|
||||
sc->sc_mode.blocks_2 = 0;
|
||||
sc->sc_mode.block_size0 = sc->sc_blklen >> 16;
|
||||
sc->sc_mode.block_size1 = sc->sc_blklen >> 8;
|
||||
sc->sc_mode.block_size2 = sc->sc_blklen;
|
||||
|
||||
/* check for tape density changes */
|
||||
densmode = (minor(dev) & TZ_HIDENSITY) ? 1 : 0;
|
||||
if ((sc->sc_quirks != NULL) &&
|
||||
(sc->sc_quirks->modes[densmode].quirks & TZ_Q_DENSITY))
|
||||
sc->sc_mode.density = sc->sc_quirks->modes[densmode].density;
|
||||
else {
|
||||
if (densmode != 0)
|
||||
uprintf("tz%d: Only one density supported\n", unit);
|
||||
}
|
||||
|
||||
/* set the current mode settings */
|
||||
error = tzcommand(dev, SCSI_MODE_SELECT, 0,
|
||||
sc->sc_modelen, (caddr_t)&sc->sc_mode);
|
||||
|
||||
if (error == 0) {
|
||||
sc->sc_flags |= TZF_MOUNTED;
|
||||
sc->sc_fileno = 0;
|
||||
sc->sc_blkno = 0;
|
||||
}
|
||||
}
|
||||
return(error);
|
||||
}
|
||||
|
||||
/* ARGSUSED */
|
||||
int
|
||||
tzopen(dev, flags, type, p)
|
||||
dev_t dev;
|
||||
int flags, type;
|
||||
struct proc *p;
|
||||
{
|
||||
int unit = tzunit(dev);
|
||||
struct tz_softc *sc = &tz_softc[unit];
|
||||
int error;
|
||||
|
||||
if (unit >= NTZ || sc->sc_sd == NULL)
|
||||
return (ENXIO);
|
||||
if (!(sc->sc_flags & TZF_ALIVE)) {
|
||||
/* check again, tape may have been turned off at boot time */
|
||||
if (!tzprobe(sc->sc_sd))
|
||||
return (ENXIO);
|
||||
}
|
||||
if (sc->sc_flags & TZF_OPEN)
|
||||
return (EBUSY);
|
||||
|
||||
error = tzmount(dev);
|
||||
if (error)
|
||||
return (error);
|
||||
|
||||
sc->sc_ctty = tprintf_open(p);
|
||||
sc->sc_flags |= TZF_OPEN;
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
tzclose(dev, flag, mode, p)
|
||||
dev_t dev;
|
||||
int flag, mode;
|
||||
struct proc *p;
|
||||
|
||||
{
|
||||
struct tz_softc *sc = &tz_softc[tzunit(dev)];
|
||||
int error = 0;
|
||||
|
||||
if (!(sc->sc_flags & TZF_OPEN))
|
||||
return (0);
|
||||
if (flag == FWRITE ||
|
||||
((flag & FWRITE) && (sc->sc_flags & TZF_WRITTEN)))
|
||||
error = tzcommand(dev, SCSI_WRITE_EOF, 0, 1, 0);
|
||||
if ((minor(dev) & TZ_NOREWIND) == 0)
|
||||
(void) tzcommand(dev, SCSI_REWIND, 0, 0, 0);
|
||||
sc->sc_flags &= ~(TZF_OPEN | TZF_WRITTEN);
|
||||
tprintf_close(sc->sc_ctty);
|
||||
return (error);
|
||||
}
|
||||
|
||||
int
|
||||
tzread(dev, uio, iomode)
|
||||
dev_t dev;
|
||||
struct uio *uio;
|
||||
int iomode;
|
||||
{
|
||||
|
||||
return (physio(tzstrategy, NULL, dev, B_READ, minphys, uio));
|
||||
}
|
||||
|
||||
int
|
||||
tzwrite(dev, uio, iomode)
|
||||
dev_t dev;
|
||||
struct uio *uio;
|
||||
int iomode;
|
||||
{
|
||||
|
||||
/* XXX: check for hardware write-protect? */
|
||||
return (physio(tzstrategy, NULL, dev, B_WRITE, minphys, uio));
|
||||
}
|
||||
|
||||
int
|
||||
tzioctl(dev, cmd, data, flag, p)
|
||||
dev_t dev;
|
||||
u_long cmd;
|
||||
caddr_t data;
|
||||
int flag;
|
||||
struct proc *p;
|
||||
{
|
||||
struct tz_softc *sc = &tz_softc[tzunit(dev)];
|
||||
struct mtop *mtop;
|
||||
struct mtget *mtget;
|
||||
int code, count;
|
||||
static int tzops[] = {
|
||||
SCSI_WRITE_EOF, /* MTWEOF */
|
||||
SCSI_SPACE, /* MTFSF */
|
||||
SCSI_SPACE, /* MTBSF */
|
||||
SCSI_SPACE, /* MTFSR */
|
||||
SCSI_SPACE, /* MTBSR */
|
||||
SCSI_REWIND, /* MTREW */
|
||||
SCSI_LOAD_UNLOAD, /* MTOFFL */
|
||||
SCSI_TEST_UNIT_READY, /* MTNOP */
|
||||
SCSI_LOAD_UNLOAD, /* MTRETEN */
|
||||
SCSI_ERASE_TAPE, /* MTERASE */
|
||||
MTEOM, /* MTEOM */
|
||||
MTNBSF, /* MTNBSF */
|
||||
SCSI_TEST_UNIT_READY, /* MTCACHE */
|
||||
SCSI_TEST_UNIT_READY, /* MTNOCACHE */
|
||||
MTSETBSIZ, /* MTSETBSIZ */
|
||||
MTSETDNSTY, /* MTSETDNSTY */
|
||||
MTCMPRESS, /* MTCMPRESS */
|
||||
MTEWARN /* MTEWARN */
|
||||
};
|
||||
|
||||
switch (cmd) {
|
||||
|
||||
case MTIOCTOP: /* tape operation */
|
||||
mtop = (struct mtop *)data;
|
||||
count = mtop->mt_count;
|
||||
code = 0;
|
||||
|
||||
if ((unsigned)mtop->mt_op < MTREW && mtop->mt_count <= 0)
|
||||
return (EINVAL);
|
||||
switch (mtop->mt_op) {
|
||||
|
||||
case MTWEOF:
|
||||
if (sc->sc_blkno != -1) {
|
||||
sc->sc_fileno += count;
|
||||
sc->sc_blkno = 0;
|
||||
}
|
||||
break;
|
||||
|
||||
case MTBSF:
|
||||
count = -count;
|
||||
/* FALLTHROUGH */
|
||||
case MTFSF:
|
||||
code = 1;
|
||||
if (sc->sc_blkno != -1) {
|
||||
sc->sc_fileno += count;
|
||||
sc->sc_blkno = 0;
|
||||
}
|
||||
break;
|
||||
|
||||
case MTBSR:
|
||||
count = -count;
|
||||
/* FALLTHROUGH */
|
||||
case MTFSR:
|
||||
if (sc->sc_blkno != -1)
|
||||
sc->sc_blkno += count;
|
||||
break;
|
||||
|
||||
case MTREW:
|
||||
case MTNOP:
|
||||
case MTCACHE:
|
||||
case MTNOCACHE:
|
||||
count = 0;
|
||||
break;
|
||||
|
||||
case MTOFFL:
|
||||
count = SCSI_LD_UNLOAD;
|
||||
break;
|
||||
|
||||
case MTRETEN:
|
||||
count = SCSI_LD_RETENSION;
|
||||
break;
|
||||
|
||||
default:
|
||||
return (EINVAL);
|
||||
}
|
||||
return (tzcommand(dev, tzops[mtop->mt_op], code, count, 0));
|
||||
|
||||
case MTIOCGET:
|
||||
mtget = (struct mtget *)data;
|
||||
mtget->mt_type = MT_ISAR; /* "GENERIC" SCSI */
|
||||
mtget->mt_dsreg = 0;
|
||||
if (sc->sc_flags & TZF_RDONLY)
|
||||
mtget->mt_dsreg |= MT_DS_RDONLY;
|
||||
if (sc->sc_flags & TZF_MOUNTED)
|
||||
mtget->mt_dsreg |= MT_DS_MOUNTED;
|
||||
mtget->mt_erreg = sc->sc_sense.status;
|
||||
mtget->mt_resid = sc->sc_buf.b_resid;
|
||||
mtget->mt_fileno = sc->sc_fileno;
|
||||
mtget->mt_blkno = sc->sc_blkno;
|
||||
|
||||
/* clear latched errors */
|
||||
sc->sc_sense.status = 0;
|
||||
sc->sc_buf.b_resid = 0;
|
||||
|
||||
break;
|
||||
|
||||
case MTIOCIEOT:
|
||||
case MTIOCEEOT:
|
||||
break;
|
||||
|
||||
default:
|
||||
return (EINVAL);
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
void
|
||||
tzstrategy(bp)
|
||||
struct buf *bp;
|
||||
{
|
||||
int unit = tzunit(bp->b_dev);
|
||||
struct tz_softc *sc = &tz_softc[unit];
|
||||
int s;
|
||||
|
||||
if (sc->sc_flags & TZF_SEENEOF) {
|
||||
bp->b_resid = bp->b_bcount;
|
||||
biodone(bp);
|
||||
return;
|
||||
}
|
||||
s = splbio();
|
||||
BUFQ_INSERT_TAIL(&sc->sc_tab, bp);
|
||||
if (sc->sc_active == 0) {
|
||||
sc->sc_active = 1;
|
||||
tzstart(unit);
|
||||
}
|
||||
splx(s);
|
||||
}
|
||||
|
||||
/*
|
||||
* Non-interrupt driven, non-dma dump routine.
|
||||
*/
|
||||
int
|
||||
tzdump(dev, blkno, va, size)
|
||||
dev_t dev;
|
||||
daddr_t blkno;
|
||||
caddr_t va;
|
||||
size_t size;
|
||||
{
|
||||
|
||||
/* Not implemented. */
|
||||
return (ENXIO);
|
||||
}
|
||||
#endif
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: conf.h,v 1.4 2000/01/09 15:34:42 ad Exp $ */
|
||||
/* $NetBSD: conf.h,v 1.5 2001/08/26 11:47:24 simonb Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright 1996 The Board of Trustees of The Leland Stanford
|
||||
|
@ -25,12 +25,6 @@ cdev_decl(mm);
|
|||
cdev_decl(scc); /* pmax (also alpha m-d z8530 SCC */
|
||||
cdev_decl(dc); /* dc7085 dz11-on-a-chip */
|
||||
|
||||
bdev_decl(rz); /* antique 4.4bsd/pmax SCSI disk */
|
||||
cdev_decl(rz);
|
||||
|
||||
bdev_decl(tz); /* antique 4.4bsd/pmax SCSI tape driver */
|
||||
cdev_decl(tz);
|
||||
|
||||
cdev_decl(dtop); /* Personal Decstation (MAXINE) desktop bus */
|
||||
cdev_decl(fb); /* generic framebuffer pseudo-device */
|
||||
cdev_decl(rcons); /* framebuffer-based raster console pseudo-device */
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: autoconf.c,v 1.59 2001/08/22 06:59:38 nisimura Exp $ */
|
||||
/* $NetBSD: autoconf.c,v 1.60 2001/08/26 11:47:24 simonb Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1988 University of Utah.
|
||||
|
@ -43,7 +43,7 @@
|
|||
*/
|
||||
|
||||
#include <sys/cdefs.h> /* RCS ID & Copyright macro defns */
|
||||
__KERNEL_RCSID(0, "$NetBSD: autoconf.c,v 1.59 2001/08/22 06:59:38 nisimura Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: autoconf.c,v 1.60 2001/08/26 11:47:24 simonb Exp $");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
|
@ -63,20 +63,14 @@ __KERNEL_RCSID(0, "$NetBSD: autoconf.c,v 1.59 2001/08/22 06:59:38 nisimura Exp $
|
|||
#include <dev/scsipi/scsipi_all.h>
|
||||
#include <dev/scsipi/scsiconf.h>
|
||||
|
||||
#include "rz.h"
|
||||
#include "tz.h"
|
||||
#include "opt_dec_3100.h"
|
||||
#include "opt_dec_5100.h"
|
||||
|
||||
#if NRZ > 0 || NTZ > 0
|
||||
#include <pmax/dev/device.h>
|
||||
#endif
|
||||
|
||||
struct intrhand intrtab[MAX_DEV_NCOOKIES];
|
||||
struct device *booted_device;
|
||||
static struct device *booted_controller;
|
||||
static int booted_slot, booted_unit, booted_partition;
|
||||
static char *booted_protocol;
|
||||
struct intrhand intrtab[MAX_DEV_NCOOKIES];
|
||||
struct device *booted_device;
|
||||
static struct device *booted_controller;
|
||||
static int booted_slot, booted_unit, booted_partition;
|
||||
static char *booted_protocol;
|
||||
|
||||
/*
|
||||
* Configure all devices on system
|
||||
|
@ -99,10 +93,6 @@ cpu_configure()
|
|||
|
||||
/* Configuration is finished, turn on interrupts. */
|
||||
_splnone(); /* enable all source forcing SOFT_INTs cleared */
|
||||
#if NRZ > 0 || NTZ > 0
|
||||
printf("Beginning old-style SCSI device autoconfiguration\n");
|
||||
configure_scsi();
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -163,26 +153,6 @@ makebootdev(cp)
|
|||
void
|
||||
cpu_rootconf()
|
||||
{
|
||||
#if NRZ > 0
|
||||
struct device *dv;
|
||||
char name[5];
|
||||
|
||||
if (booted_device == NULL && strcmp(booted_protocol, "SCSI") == 0) {
|
||||
int ctlr_no;
|
||||
|
||||
if (booted_controller)
|
||||
ctlr_no = booted_controller->dv_unit;
|
||||
else
|
||||
ctlr_no = 0;
|
||||
snprintf(name, sizeof(name), "rz%d", booted_unit + ctlr_no * 8);
|
||||
for (dv = TAILQ_FIRST(&alldevs); dv; dv = TAILQ_NEXT(dv, dv_list)) {
|
||||
if (dv->dv_class == DV_DISK && !strcmp(dv->dv_xname, name)) {
|
||||
booted_device = dv;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
printf("boot device: %s\n",
|
||||
booted_device ? booted_device->dv_xname : "<unknown>");
|
||||
|
||||
|
@ -227,9 +197,7 @@ device_register(dev, aux)
|
|||
/*
|
||||
* Check for ASC controller on either IOASIC or TC option card.
|
||||
*/
|
||||
if (scsiboot && (
|
||||
strcmp(cd->cd_name, "asc") == 0 ||
|
||||
strcmp(cd->cd_name, "xasc") == 0)) {
|
||||
if (scsiboot && strcmp(cd->cd_name, "asc") == 0) {
|
||||
struct tc_attach_args *ta = aux;
|
||||
|
||||
/*
|
||||
|
@ -249,9 +217,7 @@ device_register(dev, aux)
|
|||
* If an SII device is configured, it's currently the only
|
||||
* possible SCSI boot device.
|
||||
*/
|
||||
if (scsiboot && (
|
||||
strcmp(cd->cd_name, "sii") == 0 ||
|
||||
strcmp(cd->cd_name, "xsii") == 0)) {
|
||||
if (scsiboot && strcmp(cd->cd_name, "sii") == 0) {
|
||||
booted_controller = dev;
|
||||
return;
|
||||
}
|
||||
|
@ -274,21 +240,6 @@ device_register(dev, aux)
|
|||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* XXX rz devices don't call device_register?
|
||||
*/
|
||||
if (booted_controller && (strcmp(cd->cd_name, "rz") == 0 ||
|
||||
strcmp(cd->cd_name, "tz") == 0)) {
|
||||
int sd_ctlr = (int)aux;
|
||||
|
||||
if (booted_unit == (dev->dv_unit & 7)) {
|
||||
if (booted_controller->dv_unit == sd_ctlr)
|
||||
booted_device = dev;
|
||||
found = 1;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Check if netboot device.
|
||||
*/
|
||||
|
|
|
@ -1,232 +0,0 @@
|
|||
/* $NetBSD: conf-glue.c,v 1.23 2000/01/10 03:24:36 simonb Exp $ */
|
||||
|
||||
/*
|
||||
* conf-glue.c:
|
||||
* A hand-edited ioconf.c, as generated by config.old program
|
||||
*
|
||||
* Seriously munged to support old-stype pmax configurations
|
||||
* configured and compiled with new config.
|
||||
* Since new config doesn't yet support most pmax drivers,
|
||||
* this file contains an driver configuration table produced
|
||||
* by config.old run on a `generic' configuration.
|
||||
* This table uses device counts produced by the new config
|
||||
* ``needs-count'' keyword, that tells us at compile time
|
||||
* the maximum number of each device that were configured.
|
||||
*
|
||||
* THIS MAY NOT WORK FOR ALL MACHINES.
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/device.h>
|
||||
|
||||
#include <pmax/dev/device.h>
|
||||
|
||||
#define C (char *)
|
||||
|
||||
/*
|
||||
* Get old-style count of how many devices were configured
|
||||
* for each driver.
|
||||
*/
|
||||
#include "asc.h"
|
||||
#include "sii.h"
|
||||
#include "rz.h"
|
||||
#include "tz.h"
|
||||
|
||||
/* declarations for glue to 4.4bsd pmax port SCSI drivers and autoconfig */
|
||||
#if NASC > 0
|
||||
extern struct pmax_driver ascdriver; /* XXX */
|
||||
#endif
|
||||
#if NSII > 0
|
||||
extern struct pmax_driver siidriver; /* XXX */
|
||||
#endif
|
||||
#if NRZ > 0
|
||||
extern struct pmax_driver rzdriver; /* XXX */
|
||||
#endif
|
||||
#if NTZ > 0
|
||||
extern struct pmax_driver tzdriver; /* XXX */
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* A fixed-at-compile-time disk configuration for the pmax-specific
|
||||
* scsi code.
|
||||
*
|
||||
* If you want to change this, fix the pmax kernel to use new-style
|
||||
* config code and the machine-independent NetBSD scsi drivers.
|
||||
*/
|
||||
|
||||
struct pmax_scsi_device scsi_dinit[] = {
|
||||
/*driver, cdriver, unit, ctlr, drive, slave, dk, flags*/
|
||||
|
||||
#if NSII > 0
|
||||
# if NRZ > 0
|
||||
{ &rzdriver, &siidriver, 0, 0, 0, 0, 1, 0x0 },
|
||||
{ &rzdriver, &siidriver, 1, 0, 1, 0, 1, 0x0 },
|
||||
{ &rzdriver, &siidriver, 2, 0, 2, 0, 1, 0x0 },
|
||||
{ &rzdriver, &siidriver, 3, 0, 3, 0, 1, 0x0 },
|
||||
{ &rzdriver, &siidriver, 4, 0, 4, 0, 1, 0x0 },
|
||||
{ &rzdriver, &siidriver, 5, 0, 5, 0, 1, 0x0 },
|
||||
{ &rzdriver, &siidriver, 6, 0, 6, 0, 1, 0x0 },
|
||||
{ &rzdriver, &siidriver, 7, 0, 7, 0, 1, 0x0 },
|
||||
# endif /* NTZ */
|
||||
|
||||
# if NTZ > 0
|
||||
{ &tzdriver, &siidriver, 0, 0, 5, 0, 0, 0x0 },
|
||||
{ &tzdriver, &siidriver, 1, 0, 6, 0, 0, 0x0 },
|
||||
# endif /* NTZ */
|
||||
#endif /* NSII */
|
||||
|
||||
|
||||
#if NASC > 0
|
||||
# if NRZ > 0
|
||||
{ &rzdriver, &ascdriver, 0, 0, 0, 0, 1, 0x0 },
|
||||
{ &rzdriver, &ascdriver, 1, 0, 1, 0, 1, 0x0 },
|
||||
{ &rzdriver, &ascdriver, 2, 0, 2, 0, 1, 0x0 },
|
||||
{ &rzdriver, &ascdriver, 3, 0, 3, 0, 1, 0x0 },
|
||||
{ &rzdriver, &ascdriver, 4, 0, 4, 0, 1, 0x0 },
|
||||
{ &rzdriver, &ascdriver, 5, 0, 5, 0, 1, 0x0 },
|
||||
{ &rzdriver, &ascdriver, 6, 0, 6, 0, 1, 0x0 },
|
||||
|
||||
# if NRZ > 7
|
||||
{ &rzdriver, &ascdriver, 8, 1, 0, 0, 1, 0x0 },
|
||||
{ &rzdriver, &ascdriver, 9, 1, 1, 0, 1, 0x0 },
|
||||
{ &rzdriver, &ascdriver, 10, 1, 2, 0, 1, 0x0 },
|
||||
{ &rzdriver, &ascdriver, 11, 1, 3, 0, 1, 0x0 },
|
||||
{ &rzdriver, &ascdriver, 12, 1, 4, 0, 1, 0x0 },
|
||||
{ &rzdriver, &ascdriver, 13, 1, 5, 0, 1, 0x0 },
|
||||
{ &rzdriver, &ascdriver, 14, 1, 6, 0, 1, 0x0 },
|
||||
# endif /* NRZ > 7 */
|
||||
# endif /* NRZ */
|
||||
|
||||
# if NTZ > 0
|
||||
{ &tzdriver, &ascdriver, 0, 0, 5, 0, 0, 0x0 },
|
||||
{ &tzdriver, &ascdriver, 1, 0, 6, 0, 0, 0x0 },
|
||||
|
||||
# if NTZ > 2
|
||||
{ &tzdriver, &ascdriver, 2, 1, 5, 0, 0, 0x0 },
|
||||
{ &tzdriver, &ascdriver, 3, 1, 6, 0, 0, 0x0 },
|
||||
# endif /* NTZ > 2 */
|
||||
# endif /* NTZ */
|
||||
#endif /* NASC */
|
||||
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
|
||||
static int nomatch __P((struct device *parent, struct cfdata *cf,
|
||||
void *aux));
|
||||
static void noattach __P((struct device *parent, struct device *self,
|
||||
void *aux));
|
||||
|
||||
|
||||
/* placeholder definitions for new-style scsi bus/disk/tape drivers */
|
||||
|
||||
struct cfattach oldscsibus_ca = { 0, nomatch, noattach };
|
||||
|
||||
struct cfattach rz_ca = { 0, nomatch, noattach };
|
||||
|
||||
struct cfattach tz_ca = { 0, nomatch, noattach };
|
||||
|
||||
|
||||
#define MAX_SCSI 4
|
||||
static int nscsi;
|
||||
static struct pmax_ctlr pmax_scsi_table[MAX_SCSI+1] = {
|
||||
/* driver, unit, addr, flags */
|
||||
|
||||
{ NULL, }, { NULL, }, { NULL, }, { NULL, },
|
||||
{ NULL, } /* sentinel */
|
||||
};
|
||||
|
||||
/*
|
||||
* Callback for scsi controllers to register themselves with this
|
||||
* config glue. Construct an old-style pmax autoconfiguration
|
||||
* SCSI-driver table entry for a DECstation SCSI controller, and add it
|
||||
* to the table of known SCSI drivers. Needed for old-style pmax
|
||||
* SCSI-bus probing. configure() will call us back to probe
|
||||
* each known controller for the statically-configured drives, above.
|
||||
*/
|
||||
void
|
||||
pmax_add_scsi(dp, unit)
|
||||
struct pmax_driver *dp;
|
||||
int unit;
|
||||
{
|
||||
struct pmax_ctlr *cp = &pmax_scsi_table[nscsi++];
|
||||
if (nscsi > MAX_SCSI) {
|
||||
panic("Too many old-style SCSI adaptors\n");
|
||||
}
|
||||
cp->pmax_driver = dp;
|
||||
cp->pmax_unit = unit;
|
||||
}
|
||||
|
||||
/*
|
||||
* Configure scsi devices on old-style pmax scsi drivers.
|
||||
* Interrupts must be enabled or this will hang.
|
||||
*
|
||||
* Called by configure() after all possible controllers have been
|
||||
* found. The controllers really should invoke new-style
|
||||
* autoconfiguration on themselves, probing their SCSI buses,
|
||||
* but the pmax drivers don't yet have polled SCSI.
|
||||
*/
|
||||
void
|
||||
configure_scsi()
|
||||
{
|
||||
struct pmax_ctlr *cp;
|
||||
struct pmax_scsi_device *dp;
|
||||
struct pmax_driver *drp;
|
||||
|
||||
/* probe and initialize SCSI buses */
|
||||
for (cp = &pmax_scsi_table[0]; (drp = cp->pmax_driver) != NULL; cp++) {
|
||||
|
||||
/* probe and initialize devices connected to controller */
|
||||
for (dp = scsi_dinit; (drp = dp->sd_driver) != NULL; dp++) {
|
||||
/* might want to get fancier later */
|
||||
if (dp->sd_cdriver != cp->pmax_driver ||
|
||||
dp->sd_ctlr != cp->pmax_unit)
|
||||
continue; /* not connected */
|
||||
if (!(*drp->d_init)(dp))
|
||||
continue;
|
||||
dp->sd_alive = 1;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Match function in struct cfattach of old-conf drivers: never matches.
|
||||
*/
|
||||
static int
|
||||
nomatch(parent, cf, aux)
|
||||
struct device *parent;
|
||||
struct cfdata *cf;
|
||||
void *aux;
|
||||
{
|
||||
#if /*def DEBUG*/ 0
|
||||
printf("nomatch %s: %s not yet done\n",
|
||||
parent->dv_cfdata->cf_driver->cd_name,
|
||||
parent->dv_xname);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Attach function in struct cfattach of old-conf drivers: never called.
|
||||
*/
|
||||
static void
|
||||
noattach(parent, self, aux)
|
||||
struct device *parent;
|
||||
struct device *self;
|
||||
void *aux;
|
||||
{
|
||||
#ifdef DEBUG
|
||||
printf("new attach %s from %s: not yet done\n",
|
||||
self->dv_xname, parent->dv_xname);
|
||||
#else
|
||||
panic("Can't do new-config attach of old device %s\n",
|
||||
self->dv_xname);
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: conf.c,v 1.41 2001/03/26 12:33:25 lukem Exp $ */
|
||||
/* $NetBSD: conf.c,v 1.42 2001/08/26 11:47:25 simonb Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1992, 1993
|
||||
|
@ -60,10 +60,6 @@ bdev_decl(sw);
|
|||
bdev_decl(vnd);
|
||||
#include "audio.h"
|
||||
cdev_decl(audio);
|
||||
#include "rz.h"
|
||||
#include "tz.h"
|
||||
bdev_decl(rz);
|
||||
bdev_decl(tz);
|
||||
|
||||
struct bdevsw bdevsw[] =
|
||||
{
|
||||
|
@ -87,8 +83,8 @@ struct bdevsw bdevsw[] =
|
|||
bdev_disk_init(NMD,md), /* 17: memory disk driver */
|
||||
bdev_tape_init(NST,st), /* 18: MI SCSI tape */
|
||||
bdev_disk_init(NSD,sd), /* 19: MI SCSI disk */
|
||||
bdev_tape_init(NTZ, tz), /* 20: ULTRIX tz tape */
|
||||
bdev_disk_init(NRZ,rz), /* 21: ULTRIX rz disk & CD-ROM */
|
||||
bdev_notdef(), /* 20: ULTRIX tz tape */
|
||||
bdev_notdef(), /* 21: ULTRIX rz disk & CD-ROM */
|
||||
bdev_notdef(), /* 22: nodev */
|
||||
bdev_notdef(), /* 23: ULTRIX mscp */
|
||||
|
||||
|
@ -169,9 +165,7 @@ cdev_decl(dtop);
|
|||
cdev_decl(fb);
|
||||
cdev_decl(px);
|
||||
cdev_decl(rcons);
|
||||
cdev_decl(rz);
|
||||
cdev_decl(scc);
|
||||
cdev_decl(tz);
|
||||
|
||||
/* a framebuffer with an attached mouse: */
|
||||
|
||||
|
@ -190,7 +184,7 @@ struct cdevsw cdevsw[] =
|
|||
cdev_fd_init(1,filedesc), /* 7: file descriptor pseudo-dev */
|
||||
cdev_notdef(), /* 8: ULTRIX fl */
|
||||
cdev_disk_init(NSD,sd), /* 9: MI SCSI disk */
|
||||
cdev_tape_init(NTZ,tz), /* 10: ULTRIX tz tape */
|
||||
cdev_notdef(), /* 10: ULTRIX tz tape */
|
||||
cdev_disk_init(NVND,vnd), /* 11: vnode disk driver */
|
||||
cdev_bpftun_init(NBPFILTER,bpf),/* 12: Berkeley packet filter */
|
||||
cdev_notdef(), /* 13: ULTRIX up */
|
||||
|
@ -236,9 +230,9 @@ struct cdevsw cdevsw[] =
|
|||
cdev_notdef(), /* 51: ULTRIX sh tty */
|
||||
cdev_notdef(), /* 52: ULTRIX its */
|
||||
cdev_scanner_init(NSS,ss), /* 53: MI SCSI scanner */
|
||||
cdev_ch_init(NCH,ch), /* 54: MI SCSI autochanger */
|
||||
cdev_uk_init(NUK,uk), /* 55: MI SCSI unknown */
|
||||
cdev_disk_init(NRZ,rz), /* 56: ULTRIX rz SCSI, gross coupling to PrestoServe driver */
|
||||
cdev_ch_init(NCH,ch), /* 54: MI SCSI autochanger */
|
||||
cdev_uk_init(NUK,uk), /* 55: MI SCSI unknown */
|
||||
cdev_notdef(), /* 56: ULTRIX rz SCSI, gross coupling to PrestoServe driver */
|
||||
cdev_notdef(), /* 57: nodev */
|
||||
cdev_notdef(), /* 58: ULTRIX fc */
|
||||
cdev_notdef(), /* 59: ULTRIX fg, again gross coupling to PrestoServe driver */
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: locore_machdep.S,v 1.16 2001/08/22 08:23:10 nisimura Exp $ */
|
||||
/* $NetBSD: locore_machdep.S,v 1.17 2001/08/26 11:47:25 simonb Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1992, 1993
|
||||
|
@ -66,7 +66,7 @@
|
|||
|
||||
.set noreorder
|
||||
|
||||
#if NSII > 0 || NXSII > 0
|
||||
#if NSII > 0
|
||||
/*
|
||||
* Copy data to a DMA buffer padded with 16 bits of data, 16
|
||||
* bits of padding per 32bit word (e.g., for pmin/pmax sii DMA).
|
||||
|
@ -139,7 +139,7 @@ LEAF(CopyFromBuffer)
|
|||
j ra
|
||||
nop
|
||||
END(CopyFromBuffer)
|
||||
#endif /* NSII > 0 || NXSII > 0 */
|
||||
#endif /* NSII > 0 */
|
||||
|
||||
/*
|
||||
* Write-buffer flush for writebuffer hardware on DEC mips r2000a
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: asc_ioasic.c,v 1.11 2001/04/25 17:53:22 bouyer Exp $ */
|
||||
/* $NetBSD: asc_ioasic.c,v 1.12 2001/08/26 11:47:25 simonb Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2000 The NetBSD Foundation, Inc.
|
||||
|
@ -37,7 +37,7 @@
|
|||
*/
|
||||
|
||||
#include <sys/cdefs.h> /* RCS ID & Copyright macro defns */
|
||||
__KERNEL_RCSID(0, "$NetBSD: asc_ioasic.c,v 1.11 2001/04/25 17:53:22 bouyer Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: asc_ioasic.c,v 1.12 2001/08/26 11:47:25 simonb Exp $");
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/param.h>
|
||||
|
@ -78,7 +78,7 @@ struct asc_softc {
|
|||
static int asc_ioasic_match __P((struct device *, struct cfdata *, void *));
|
||||
static void asc_ioasic_attach __P((struct device *, struct device *, void *));
|
||||
|
||||
struct cfattach xasc_ioasic_ca = {
|
||||
struct cfattach asc_ioasic_ca = {
|
||||
sizeof(struct asc_softc), asc_ioasic_match, asc_ioasic_attach
|
||||
};
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: asc_pmaz.c,v 1.7 2001/04/25 17:53:22 bouyer Exp $ */
|
||||
/* $NetBSD: asc_pmaz.c,v 1.8 2001/08/26 11:47:25 simonb Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2000 The NetBSD Foundation, Inc.
|
||||
|
@ -37,7 +37,7 @@
|
|||
*/
|
||||
|
||||
#include <sys/cdefs.h> /* RCS ID & Copyright macro defns */
|
||||
__KERNEL_RCSID(0, "$NetBSD: asc_pmaz.c,v 1.7 2001/04/25 17:53:22 bouyer Exp $");
|
||||
__KERNEL_RCSID(0, "$NetBSD: asc_pmaz.c,v 1.8 2001/08/26 11:47:25 simonb Exp $");
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/param.h>
|
||||
|
@ -76,7 +76,7 @@ struct asc_softc {
|
|||
static int asc_pmaz_match __P((struct device *, struct cfdata *, void *));
|
||||
static void asc_pmaz_attach __P((struct device *, struct device *, void *));
|
||||
|
||||
struct cfattach xasc_pmaz_ca = {
|
||||
struct cfattach asc_pmaz_ca = {
|
||||
sizeof(struct asc_softc), asc_pmaz_match, asc_pmaz_attach
|
||||
};
|
||||
|
||||
|
@ -118,7 +118,7 @@ static struct ncr53c9x_glue asc_pmaz_glue = {
|
|||
|
||||
#define PMAZ_DMAR_WRITE 0x80000000 /* DMA direction bit */
|
||||
#define PMAZ_DMAR_MASK 0x1ffff /* 17 bits, 128k */
|
||||
#define PMAZ_DMA_ADDR(x) ((unsigned)(x) & PMAZ_DMAR_MASK)
|
||||
#define PMAZ_DMA_ADDR(x) ((unsigned long)(x) & PMAZ_DMAR_MASK)
|
||||
|
||||
static int
|
||||
asc_pmaz_match(parent, cfdata, aux)
|
||||
|
@ -256,15 +256,15 @@ asc_pmaz_setup(sc, addr, len, datain, dmasize)
|
|||
asc->sc_dmalen = len;
|
||||
asc->sc_ispullup = datain;
|
||||
|
||||
NCR_DMA(("pmaz_setup: start %d@%p, %s\n",
|
||||
*asc->sc_dmalen, *asc->sc_dmaaddr, datain ? "IN" : "OUT"));
|
||||
NCR_DMA(("pmaz_setup: start %ld@%p, %s\n", (long)*asc->sc_dmalen,
|
||||
*asc->sc_dmaaddr, datain ? "IN" : "OUT"));
|
||||
|
||||
size = *dmasize;
|
||||
if (size > PER_TGT_DMA_SIZE)
|
||||
size = PER_TGT_DMA_SIZE;
|
||||
*dmasize = asc->sc_dmasize = size;
|
||||
|
||||
NCR_DMA(("pmaz_setup: dmasize = %d\n", asc->sc_dmasize));
|
||||
NCR_DMA(("pmaz_setup: dmasize = %ld\n", (long)asc->sc_dmasize));
|
||||
|
||||
asc->sc_bounce = asc->sc_base + PMAZ_OFFSET_RAM;
|
||||
asc->sc_bounce += PER_TGT_DMA_SIZE *
|
||||
|
|
2159
sys/dev/tc/asc.c
2159
sys/dev/tc/asc.c
File diff suppressed because it is too large
Load Diff
|
@ -1,280 +0,0 @@
|
|||
/* $NetBSD: asc_ioasic.c,v 1.23 2000/11/05 21:02:13 mhitch Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright 1996 The Board of Trustees of The Leland Stanford
|
||||
* Junior University. 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 appear in all copies. Stanford University
|
||||
* makes no representations about the suitability of this
|
||||
* software for any purpose. It is provided "as is" without
|
||||
* express or implied warranty.
|
||||
*
|
||||
*/
|
||||
#define USE_CACHED_BUFFER 0
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/device.h>
|
||||
|
||||
#include <machine/cpu.h>
|
||||
#include <machine/bus.h>
|
||||
|
||||
#include <dev/tc/tcvar.h>
|
||||
#include <dev/tc/ioasicvar.h>
|
||||
#include <dev/tc/ioasicreg.h>
|
||||
|
||||
#include <pmax/dev/device.h> /* XXX */
|
||||
#include <pmax/dev/scsi.h> /* XXX */
|
||||
|
||||
#include <pmax/dev/ascreg.h>
|
||||
#include <dev/tc/ascvar.h>
|
||||
|
||||
extern paddr_t kvtophys __P((vaddr_t));
|
||||
|
||||
/*
|
||||
* Autoconfiguration data for config.
|
||||
*/
|
||||
int asc_ioasic_match __P((struct device *, struct cfdata *, void *));
|
||||
void asc_ioasic_attach __P((struct device *, struct device *, void *));
|
||||
|
||||
struct cfattach asc_ioasic_ca = {
|
||||
sizeof(struct asc_softc), asc_ioasic_match, asc_ioasic_attach
|
||||
};
|
||||
|
||||
/*
|
||||
* DMA callback declarations
|
||||
*/
|
||||
|
||||
static int
|
||||
asic_dma_start __P((asc_softc_t asc, State *state, caddr_t cp, int flag,
|
||||
int len, int off));
|
||||
|
||||
static void
|
||||
asic_dma_end __P((asc_softc_t asc, State *state, int flag));
|
||||
|
||||
int
|
||||
asc_ioasic_match(parent, match, aux)
|
||||
struct device *parent;
|
||||
struct cfdata *match;
|
||||
void *aux;
|
||||
{
|
||||
struct ioasicdev_attach_args *d = aux;
|
||||
|
||||
if (strncmp(d->iada_modname, "asc", TC_ROM_LLEN) != 0)
|
||||
return (0);
|
||||
|
||||
return (1);
|
||||
}
|
||||
|
||||
void
|
||||
asc_ioasic_attach(parent, self, aux)
|
||||
struct device *parent;
|
||||
struct device *self;
|
||||
void *aux;
|
||||
{
|
||||
asc_softc_t asc = (asc_softc_t)self;
|
||||
struct ioasicdev_attach_args *d = aux;
|
||||
|
||||
asc->sc_bst = ((struct ioasic_softc *)parent)->sc_bst;
|
||||
asc->sc_bsh = ((struct ioasic_softc *)parent)->sc_bsh;
|
||||
asc->sc_dmat = ((struct ioasic_softc *)parent)->sc_dmat;
|
||||
if (bus_space_subregion(asc->sc_bst,
|
||||
asc->sc_bsh,
|
||||
IOASIC_SLOT_12_START, 0x100, &asc->sc_scsi_bsh)) {
|
||||
printf("%s: unable to map device\n", asc->sc_dev.dv_xname);
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Initialize hw descriptor, cache some pointers
|
||||
*/
|
||||
asc->regs = (asc_regmap_t *)(MIPS_PHYS_TO_KSEG1(d->iada_addr) + ASC_OFFSET_53C94);
|
||||
|
||||
/*
|
||||
* Set up machine dependencies.
|
||||
* (1) how to do dma
|
||||
* (2) timing based on turbochannel frequency
|
||||
*/
|
||||
bus_space_write_4(asc->sc_bst, asc->sc_bsh, IOASIC_SCSI_DMAPTR, -1);
|
||||
bus_space_write_4(asc->sc_bst, asc->sc_bsh, IOASIC_SCSI_NEXTPTR, -1);
|
||||
bus_space_write_4(asc->sc_bst, asc->sc_bsh, IOASIC_SCSI_SCR, 0);
|
||||
|
||||
asc->dma_start = asic_dma_start;
|
||||
asc->dma_end = asic_dma_end;
|
||||
|
||||
/* digital meters show IOASIC 53c94s are clocked at approx 25MHz */
|
||||
ascattach(asc, ASC_SPEED_25_MHZ);
|
||||
|
||||
/* tie pseudo-slot to device */
|
||||
|
||||
ioasic_intr_establish(parent, d->iada_cookie, IPL_BIO, asc_intr, asc);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* DMA handling routines. For a turbochannel device, just set the dmar.
|
||||
* For the I/O ASIC, handle the actual DMA interface.
|
||||
*/
|
||||
static int
|
||||
asic_dma_start(asc, state, cp, flag, len, off)
|
||||
asc_softc_t asc;
|
||||
State *state;
|
||||
caddr_t cp;
|
||||
int flag;
|
||||
int len;
|
||||
int off;
|
||||
{
|
||||
u_int32_t ssr, phys, nphys;
|
||||
|
||||
/* stop DMA engine first */
|
||||
ssr = bus_space_read_4(asc->sc_bst, asc->sc_bsh, IOASIC_CSR);
|
||||
ssr &= ~IOASIC_CSR_DMAEN_SCSI;
|
||||
bus_space_write_4(asc->sc_bst, asc->sc_bsh, IOASIC_CSR, ssr);
|
||||
bus_space_write_4(asc->sc_bst, asc->sc_bsh, IOASIC_SCSI_SCR, 0);
|
||||
|
||||
/* restrict len to the maximum the IOASIC can transfer */
|
||||
if (len > ((caddr_t)mips_trunc_page(cp + NBPG * 2) - cp))
|
||||
len = (caddr_t)mips_trunc_page(cp + NBPG * 2) - cp;
|
||||
|
||||
/* Get physical address of buffer start, no next phys addr */
|
||||
phys = (u_int)kvtophys((vaddr_t)cp);
|
||||
nphys = -1;
|
||||
|
||||
/* Compute 2nd DMA pointer only if next page is part of this I/O */
|
||||
if ((NBPG - (phys & (NBPG - 1))) < len) {
|
||||
nphys = (u_int)kvtophys((vaddr_t)mips_trunc_page(cp + NBPG));
|
||||
}
|
||||
|
||||
if ((vaddr_t)cp & 7) {
|
||||
u_int32_t *p;
|
||||
u_int32_t scrval;
|
||||
|
||||
p = (u_int32_t *)((vaddr_t)cp & ~7);
|
||||
bus_space_write_4(asc->sc_bst, asc->sc_bsh,
|
||||
IOASIC_SCSI_SDR0, p[0]);
|
||||
bus_space_write_4(asc->sc_bst, asc->sc_bsh,
|
||||
IOASIC_SCSI_SDR1, p[1]);
|
||||
scrval = ((vaddr_t)cp >> 1) & 3;
|
||||
phys &= ~7;
|
||||
if (flag != ASCDMA_READ) {
|
||||
scrval |= 4;
|
||||
phys += 8;
|
||||
}
|
||||
bus_space_write_4(asc->sc_bst, asc->sc_bsh,
|
||||
IOASIC_SCSI_SCR, scrval);
|
||||
}
|
||||
|
||||
/* If R4K, writeback and invalidate the buffer */
|
||||
if (CPUISMIPS3)
|
||||
mips3_HitFlushDCache((vaddr_t)cp, len);
|
||||
|
||||
/* If not R4K, need to invalidate cache lines for both physical segments */
|
||||
if (!CPUISMIPS3 && flag == ASCDMA_READ) {
|
||||
MachFlushDCache(MIPS_PHYS_TO_KSEG0(phys),
|
||||
nphys == 0xffffffff ? len + ((vaddr_t)cp & 7) :
|
||||
NBPG - (phys & (NBPG - 1)));
|
||||
if (nphys != 0xffffffff)
|
||||
MachFlushDCache(MIPS_PHYS_TO_KSEG0(nphys),
|
||||
NBPG); /* XXX */
|
||||
}
|
||||
|
||||
#ifdef notyet
|
||||
asc->dma_next = cp;
|
||||
asc->dma_xfer = state->dmalen - (nphys - phys);
|
||||
#endif
|
||||
|
||||
ssr = bus_space_read_4(asc->sc_bst, asc->sc_bsh, IOASIC_CSR);
|
||||
bus_space_write_4(asc->sc_bst, asc->sc_bsh,
|
||||
IOASIC_SCSI_DMAPTR, IOASIC_DMA_ADDR(phys));
|
||||
bus_space_write_4(asc->sc_bst, asc->sc_bsh,
|
||||
IOASIC_SCSI_NEXTPTR, IOASIC_DMA_ADDR(nphys));
|
||||
if (flag == ASCDMA_READ)
|
||||
ssr |= (IOASIC_CSR_SCSI_DIR | IOASIC_CSR_DMAEN_SCSI);
|
||||
else
|
||||
ssr = (ssr & ~IOASIC_CSR_SCSI_DIR) | IOASIC_CSR_DMAEN_SCSI;
|
||||
bus_space_write_4(asc->sc_bst, asc->sc_bsh, IOASIC_CSR, ssr);
|
||||
return (len);
|
||||
}
|
||||
|
||||
static void
|
||||
asic_dma_end(asc, state, flag)
|
||||
asc_softc_t asc;
|
||||
State *state;
|
||||
int flag;
|
||||
{
|
||||
u_int32_t ssr, ptr, halfwords;
|
||||
|
||||
ssr = bus_space_read_4(asc->sc_bst, asc->sc_bsh, IOASIC_CSR);
|
||||
ssr &= ~IOASIC_CSR_DMAEN_SCSI;
|
||||
bus_space_write_4(asc->sc_bst, asc->sc_bsh, IOASIC_CSR, ssr);
|
||||
ptr = bus_space_read_4(asc->sc_bst, asc->sc_bsh, IOASIC_SCSI_DMAPTR);
|
||||
#if USE_CACHED_BUFFER /* XXX - Should uncached address always be used? */
|
||||
ptr = MIPS_PHYS_TO_KSEG0(ptr >> 3);
|
||||
#else
|
||||
ptr = MIPS_PHYS_TO_KSEG1(ptr >> 3);
|
||||
#endif
|
||||
bus_space_write_4(asc->sc_bst, asc->sc_bsh, IOASIC_SCSI_DMAPTR, -1);
|
||||
bus_space_write_4(asc->sc_bst, asc->sc_bsh, IOASIC_SCSI_NEXTPTR, -1);
|
||||
|
||||
if (flag == ASCDMA_READ) {
|
||||
#if !defined(ASC_IOASIC_BOUNCE) && USE_CACHED_BUFFER
|
||||
/* Invalidate cache for the buffer */
|
||||
#ifdef MIPS3
|
||||
if (CPUISMIPS3)
|
||||
MachFlushDCache(MIPS_KSEG1_TO_PHYS(state->dmaBufAddr),
|
||||
state->dmalen);
|
||||
else
|
||||
#endif /* MIPS3 */
|
||||
MachFlushDCache(MIPS_PHYS_TO_KSEG0(
|
||||
MIPS_KSEG1_TO_PHYS(state->dmaBufAddr)),
|
||||
state->dmalen);
|
||||
#endif /* USE_CACHED_BUFFER */
|
||||
halfwords = bus_space_read_4(asc->sc_bst, asc->sc_bsh,
|
||||
IOASIC_SCSI_SCR);
|
||||
if (halfwords != 0) {
|
||||
int sdr[2];
|
||||
/* pick up last upto 6 bytes, sigh. */
|
||||
|
||||
/* Copy untransferred data from IOASIC */
|
||||
sdr[0] = bus_space_read_4(asc->sc_bst, asc->sc_bsh,
|
||||
IOASIC_SCSI_SDR0);
|
||||
sdr[1] = bus_space_read_4(asc->sc_bst, asc->sc_bsh,
|
||||
IOASIC_SCSI_SDR1);
|
||||
memcpy((caddr_t)ptr, (caddr_t)sdr, halfwords * 2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef notdef
|
||||
/*
|
||||
* XXX Below is just informational for how IOASIC DMA is handled. XXX
|
||||
*/
|
||||
|
||||
extern struct cfdriver asc_cd;
|
||||
|
||||
/*
|
||||
* Called by asic_intr() for scsi dma pointer update interrupts.
|
||||
*/
|
||||
void
|
||||
asc_dma_intr()
|
||||
{
|
||||
asc_softc_t asc = &asc_cd.cd_devs[0]; /*XXX*/
|
||||
u_int next_phys;
|
||||
|
||||
asc->dma_xfer -= NBPG;
|
||||
if (asc->dma_xfer <= -NBPG) {
|
||||
volatile u_int *ssr = (volatile u_int *)
|
||||
IOASIC_REG_CSR(ioasic_base);
|
||||
*ssr &= ~IOASIC_CSR_DMAEN_SCSI;
|
||||
} else {
|
||||
asc->dma_next += NBPG;
|
||||
next_phys = MIPS_KSEG0_TO_PHYS(asc->dma_next);
|
||||
}
|
||||
*(volatile int *)IOASIC_REG_SCSI_DMANPTR(ioasic_base) =
|
||||
IOASIC_DMA_ADDR(next_phys);
|
||||
wbflush();
|
||||
}
|
||||
#endif /*notdef*/
|
|
@ -1,180 +0,0 @@
|
|||
/* $NetBSD: asc_tc.c,v 1.14 2000/03/06 03:08:32 mhitch Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright 1996 The Board of Trustees of The Leland Stanford
|
||||
* Junior University. 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 appear in all copies. Stanford University
|
||||
* makes no representations about the suitability of this
|
||||
* software for any purpose. It is provided "as is" without
|
||||
* express or implied warranty.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/device.h>
|
||||
|
||||
#include <dev/tc/tcvar.h>
|
||||
#include <dev/tc/ioasicvar.h>
|
||||
|
||||
#include <pmax/dev/device.h> /* XXX */
|
||||
#include <pmax/dev/scsi.h> /* XXX */
|
||||
|
||||
#include <pmax/dev/ascreg.h> /* XXX */
|
||||
#include <dev/tc/ascvar.h>
|
||||
|
||||
/*XXX*/
|
||||
|
||||
|
||||
/*
|
||||
* Autoconfiguration data for config.
|
||||
*/
|
||||
int asc_tc_match __P((struct device *, struct cfdata *, void *));
|
||||
void asc_tc_attach __P((struct device *, struct device *, void *));
|
||||
|
||||
struct cfattach asc_tc_ca = {
|
||||
sizeof(struct asc_softc), asc_tc_match, asc_tc_attach
|
||||
};
|
||||
|
||||
/*
|
||||
* DMA callbacks
|
||||
*/
|
||||
|
||||
static int
|
||||
tc_dma_start __P((struct asc_softc *asc, struct scsi_state *state,
|
||||
caddr_t cp, int flag, int len, int off));
|
||||
|
||||
static void
|
||||
tc_dma_end __P((struct asc_softc *asc, struct scsi_state *state,
|
||||
int flag));
|
||||
|
||||
|
||||
int
|
||||
asc_tc_match(parent, match, aux)
|
||||
struct device *parent;
|
||||
struct cfdata *match;
|
||||
void *aux;
|
||||
{
|
||||
struct tc_attach_args *t = aux;
|
||||
|
||||
if (strncmp(t->ta_modname, "PMAZ-AA ", TC_ROM_LLEN))
|
||||
return (0);
|
||||
|
||||
return (1);
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
asc_tc_attach(parent, self, aux)
|
||||
struct device *parent;
|
||||
struct device *self;
|
||||
void *aux;
|
||||
{
|
||||
register struct tc_attach_args *t = aux;
|
||||
register asc_softc_t asc = (asc_softc_t) self;
|
||||
u_char *buff;
|
||||
int i, speed;
|
||||
int unit;
|
||||
|
||||
unit = asc->sc_dev.dv_unit;
|
||||
|
||||
/*
|
||||
* Initialize hw descriptor, cache some pointers
|
||||
*/
|
||||
asc->regs = (asc_regmap_t *)(t->ta_addr + ASC_OFFSET_53C94);
|
||||
|
||||
/*
|
||||
* Set up machine dependencies.
|
||||
* (1) how to do dma
|
||||
* (2) timing based on turbochannel frequency
|
||||
*/
|
||||
|
||||
/*
|
||||
* Fall through for turbochannel option.
|
||||
*/
|
||||
asc->dmar = (volatile int *)(t->ta_addr + ASC_OFFSET_DMAR);
|
||||
buff = (u_char *)(t->ta_addr + ASC_OFFSET_RAM);
|
||||
|
||||
/*
|
||||
* Statically partition the DMA buffer between targets.
|
||||
* This way we will eventually be able to attach/detach
|
||||
* drives on-fly. And 18k/target is plenty for normal use.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Give each target its own DMA buffer region.
|
||||
* We may want to try ping ponging buffers later.
|
||||
*/
|
||||
for (i = 0; i < ASC_NCMD; i++)
|
||||
asc->st[i].dmaBufAddr = buff + PER_TGT_DMA_SIZE * i;
|
||||
|
||||
asc->dma_start = tc_dma_start;
|
||||
asc->dma_end = tc_dma_end;
|
||||
|
||||
/*
|
||||
* Now for timing. The 3max has a 25Mhz tb whereas the 3min and
|
||||
* maxine are 12.5Mhz.
|
||||
*/
|
||||
printf(" (bus speed: %s MHz) ", t->ta_busspeed? "25" : "12.5");
|
||||
|
||||
switch (t->ta_busspeed) {
|
||||
case TC_SPEED_25_MHZ:
|
||||
speed = ASC_SPEED_25_MHZ;
|
||||
break;
|
||||
|
||||
default:
|
||||
printf(" (unknown TC speed, assuming 12.5MHz) ");
|
||||
/* FALLTHROUGH*/
|
||||
case TC_SPEED_12_5_MHZ:
|
||||
speed = ASC_SPEED_12_5_MHZ;
|
||||
break;
|
||||
};
|
||||
|
||||
ascattach(asc, speed);
|
||||
|
||||
/* tie pseudo-slot to device */
|
||||
tc_intr_establish(parent, t->ta_cookie, TC_IPL_BIO,
|
||||
asc_intr, asc);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* DMA handling routines. For a turbochannel device, just set the dmar.
|
||||
* For the I/O ASIC, handle the actual DMA interface.
|
||||
*/
|
||||
static int
|
||||
tc_dma_start(asc, state, cp, flag, len, off)
|
||||
asc_softc_t asc;
|
||||
State *state;
|
||||
caddr_t cp;
|
||||
int flag;
|
||||
int len;
|
||||
int off;
|
||||
{
|
||||
|
||||
if (len > PER_TGT_DMA_SIZE)
|
||||
len = PER_TGT_DMA_SIZE;
|
||||
if (flag == ASCDMA_WRITE)
|
||||
bcopy(cp, state->dmaBufAddr + off, len);
|
||||
if (flag == ASCDMA_WRITE)
|
||||
*asc->dmar = ASC_DMAR_WRITE | ASC_DMA_ADDR(state->dmaBufAddr + off);
|
||||
else
|
||||
*asc->dmar = ASC_DMA_ADDR(state->dmaBufAddr + off);
|
||||
return (len);
|
||||
}
|
||||
|
||||
static void
|
||||
tc_dma_end(asc, state, flag)
|
||||
asc_softc_t asc;
|
||||
State *state;
|
||||
int flag;
|
||||
{
|
||||
if (flag == ASCDMA_READ)
|
||||
bcopy(state->dmaBufAddr, state->buf, state->dmalen);
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
# $NetBSD: files.tc,v 1.22 2001/01/16 05:49:41 nisimura Exp $
|
||||
# $NetBSD: files.tc,v 1.23 2001/08/26 11:47:19 simonb Exp $
|
||||
#
|
||||
# Config file and device description for machine-independent
|
||||
# TURBOchannel code. Included by ports that need it.
|
||||
|
@ -79,7 +79,8 @@ attach tcds at tc
|
|||
file dev/tc/tcds.c tcds
|
||||
|
||||
# XXX waiting on pmax MI scsi being `asc'.
|
||||
# 53C[F]90 SCSI
|
||||
# ref arch/alpha/conf/files.alpha
|
||||
# 53C[F]90 PMAZ single channel SCSI
|
||||
#device asc: scsi, ncr53c9x
|
||||
#attach asc at tcds with asc_tcds
|
||||
#file dev/tc/asc_tcds.c asc_tcds
|
||||
|
|
Loading…
Reference in New Issue