Switch to MI SCSI and drop old pmax MD SCSI support completely.

This commit is contained in:
simonb 2001-08-26 11:47:18 +00:00
parent 47bb32d470
commit cddf6cf55b
25 changed files with 127 additions and 7169 deletions

View File

@ -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 #

View File

@ -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 #

View File

@ -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

View File

@ -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

View File

@ -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 ?

View File

@ -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

View File

@ -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

View File

@ -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);
}
}

View File

@ -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 */

View File

@ -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

View File

@ -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 */

View File

@ -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 */

View File

@ -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

View File

@ -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 */

View File

@ -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.
*/

View File

@ -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;
}

View File

@ -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 */

View File

@ -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

View File

@ -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
};

View File

@ -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 *

File diff suppressed because it is too large Load Diff

View File

@ -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*/

View File

@ -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);
}

View File

@ -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