Index: head/ObsoleteFiles.inc =================================================================== --- head/ObsoleteFiles.inc +++ head/ObsoleteFiles.inc @@ -36,6 +36,10 @@ # xargs -n1 | sort | uniq -d; # done +# 20200127: vpo removed +OLD_FILES+=usr/share/man/man4/imm.4.gz +OLD_FILES+=usr/share/man/man4/vpo.4.gz + # 20200104: gcc libssp removed OLD_FILES+=usr/include/ssp/ssp.h OLD_FILES+=usr/include/ssp/stdio.h Index: head/share/man/man4/Makefile =================================================================== --- head/share/man/man4/Makefile +++ head/share/man/man4/Makefile @@ -553,7 +553,6 @@ ${_vmd.4} \ ${_vmm.4} \ ${_vmx.4} \ - vpo.4 \ vr.4 \ vt.4 \ vte.4 \ @@ -740,7 +739,6 @@ MLINKS+=vlan.4 if_vlan.4 MLINKS+=vxlan.4 if_vxlan.4 MLINKS+=${_vmx.4} ${_if_vmx.4} -MLINKS+=vpo.4 imm.4 MLINKS+=vr.4 if_vr.4 MLINKS+=vte.4 if_vte.4 MLINKS+=${_vtnet.4} ${_if_vtnet.4} Index: head/share/man/man4/ppbus.4 =================================================================== --- head/share/man/man4/ppbus.4 +++ head/share/man/man4/ppbus.4 @@ -33,8 +33,6 @@ .Sh SYNOPSIS .Cd "device ppbus" .Pp -.Cd "device vpo" -.Pp .Cd "device lpt" .Cd "device plip" .Cd "device ppi" @@ -66,8 +64,6 @@ .Pp .Bl -column "Driver" -compact .It Em Driver Ta Em Description -.It Sy vpo Ta "VPI0 parallel to Adaptec AIC-7110 SCSI controller driver" . -It uses standard and non-standard parallel port accesses. .It Sy ppi Ta "Parallel port interface for general I/O" .It Sy pps Ta "Pulse per second Timing Interface" .It Sy lpbb Ta "Philips official parallel port I2C bit-banging interface" @@ -336,22 +332,11 @@ .Xr microseq 9 ) . Standard I/O operations are implemented at ppbus level whereas basic I/O operations and microseq language are coded at adapter level for efficiency. -.Pp -As an example, the -.Xr vpo 4 -driver uses microsequences to implement: -.Bl -bullet -offset indent -.It -a modified version of the NIBBLE transfer mode -.It -various I/O sequences to initialize, select and allocate the peripheral -.El .Sh SEE ALSO .Xr lpt 4 , .Xr plip 4 , .Xr ppc 4 , .Xr ppi 4 , -.Xr vpo 4 .Sh HISTORY The .Nm Index: head/share/man/man4/vpo.4 =================================================================== --- head/share/man/man4/vpo.4 +++ head/share/man/man4/vpo.4 @@ -1,111 +0,0 @@ -.\" Copyright (c) 1998, 1999, Nicolas Souchu -.\" All rights reserved. -.\" -.\" Redistribution and use in source and binary forms, with or without -.\" modification, are permitted provided that the following conditions -.\" are met: -.\" 1. Redistributions of source code must retain the above copyright -.\" notice, this list of conditions and the following disclaimer. -.\" 2. Redistributions in binary form must reproduce the above copyright -.\" notice, this list of conditions and the following disclaimer in the -.\" documentation and/or other materials provided with the distribution. -.\" -.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. -.\" -.\" $FreeBSD$ -.\" -.Dd December 21, 2019 -.Dt VPO 4 -.Os -.Sh NAME -.Nm vpo -.Nd parallel to SCSI interface driver -.Sh SYNOPSIS -.Cd "device vpo" -.Pp -For one or more SCSI busses: -.Cd "device scbus" -.Sh DESCRIPTION -The -.Nm -driver provide access to parallel port Iomega Zip and Jaz drives. -.Sh DEPRECATED -The -.Nm -driver is now deprecated. -It will be removed in -.Fx 13.0 . -.Sh HARDWARE -The -.Nm -driver supports the following parallel to SCSI interfaces: -.Pp -.Bl -bullet -compact -.It -Adaptec AIC-7110 Parallel to SCSI interface (built-in to Iomega ZIP -drives) -.It -Iomega Jaz Traveller interface -.It -Iomega MatchMaker SCSI interface (built-in to Iomega ZIP+ drives) -.El -.Sh USAGE -The driver should let you use a printer connected to the drive while -transferring data. -.Pp -DOS and -.Fx -file systems are supported. -When mounting a DOS file system or -formatting a -.Fx -file system, check the slice of the disk with the -.Xr gpart 8 -utility. -.Pp -In order to unixify a ZIP disk, put the following in /etc/disktab: -.Bd -literal -zip|zip 100:\\ - :ty=removable:se#512:nc#96:nt#64:ns#32:\\ - :pa#196608:oa#0:ba#4096:fa#512:\\ - :pb#196608:ob#0:bb#4096:fb#512:\\ - :pc#196608:oc#0:bc#4096:fc#512: -.Ed -.Pp -and use -.Xr bsdlabel 8 . -.Pp -If you have trouble with your driver, your parallel chipset may not run -properly at the detected mode (NIBBLE, PS2 or EPP). -Tune the -.Xr ppc 4 -bootflags to force other modes. -.Sh SEE ALSO -.Xr da 4 , -.Xr lpt 4 , -.Xr ppbus 4 , -.Xr ppc 4 , -.Xr scsi 4 -.Sh HISTORY -The -.Nm -manual page first appeared in -.Fx 3.0 . -.Sh AUTHORS -This -manual page was written by -.An Nicolas Souchu . -.Sh BUGS -During boot, the driver first tries to detect a classic ZIP, then a ZIP+. -The ZIP+ detection is intrusive and may send erroneous characters to your -printer if the drive is not connected to your parallel port. Index: head/share/man/man9/microseq.9 =================================================================== --- head/share/man/man9/microseq.9 +++ head/share/man/man9/microseq.9 @@ -51,7 +51,7 @@ Before using microsequences, you are encouraged to look at .Xr ppc 4 microsequencer implementation and an example of how using it in -.Xr vpo 4 . +.Xr ppi 4 . .Sh PPBUS register model .Ss Background The parallel port model chosen for ppbus is the PC parallel port model. @@ -477,7 +477,7 @@ .Sh SEE ALSO .Xr ppbus 4 , .Xr ppc 4 , -.Xr vpo 4 +.Xr ppi 4 .Sh HISTORY The .Nm Index: head/sys/conf/NOTES =================================================================== --- head/sys/conf/NOTES +++ head/sys/conf/NOTES @@ -2358,9 +2358,6 @@ # are automatically probed and attached when found. # # Supported devices: -# vpo Iomega Zip Drive -# Requires SCSI disk support ('scbus' and 'da'), best -# performance is achieved with ports in EPP 1.9 mode. # lpt Parallel Printer # plip Parallel network interface # ppi General-purpose I/O ("Geek Port") + IEEE1284 I/O @@ -2378,7 +2375,6 @@ options PERIPH_1284 # Makes your computer act as an IEEE1284 # compliant peripheral options DONTPROBE_1284 # Avoid boot detection of PnP parallel devices -options VP0_DEBUG # ZIP/ZIP+ debug options LPT_DEBUG # Printer driver debug options PPC_DEBUG # Parallel chipset level debug options PLIP_DEBUG # Parallel network IP interface debug @@ -2389,7 +2385,6 @@ hint.ppc.0.at="isa" hint.ppc.0.irq="7" device ppbus -device vpo device lpt device plip device ppi Index: head/sys/conf/files =================================================================== --- head/sys/conf/files +++ head/sys/conf/files @@ -2672,7 +2672,6 @@ dev/pms/RefTisa/tisa/sassata/sata/host/sathw.c optional pmspcv \ compile-with "${NORMAL_C} -Wunused-variable -Woverflow -Wparentheses -w" dev/ppbus/if_plip.c optional plip -dev/ppbus/immio.c optional vpo dev/ppbus/lpbb.c optional lpbb dev/ppbus/lpt.c optional lpt dev/ppbus/pcfclock.c optional pcfclock @@ -2683,8 +2682,6 @@ dev/ppbus/ppbus_if.m optional ppbus dev/ppbus/ppi.c optional ppi dev/ppbus/pps.c optional pps -dev/ppbus/vpo.c optional vpo -dev/ppbus/vpoio.c optional vpo dev/ppc/ppc.c optional ppc dev/ppc/ppc_acpi.c optional ppc acpi dev/ppc/ppc_isa.c optional ppc isa Index: head/sys/conf/options =================================================================== --- head/sys/conf/options +++ head/sys/conf/options @@ -569,7 +569,6 @@ # with 'make CC="cc -DDEBUG"'. CLUSTERDEBUG opt_debug_cluster.h DEBUG_1284 opt_ppb_1284.h -VP0_DEBUG opt_vpo.h LPT_DEBUG opt_lpt.h PLIP_DEBUG opt_plip.h LOCKF_DEBUG opt_debug_lockf.h Index: head/sys/dev/ppbus/immio.c =================================================================== --- head/sys/dev/ppbus/immio.c +++ head/sys/dev/ppbus/immio.c @@ -1,818 +0,0 @@ -/*- - * SPDX-License-Identifier: BSD-2-Clause-FreeBSD - * - * Copyright (c) 1998, 1999 Nicolas Souchu - * Copyright (c) 2001 Alcove - Nicolas Souchu - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. - * - * - */ - -#include -__FBSDID("$FreeBSD$"); - -/* - * Iomega ZIP+ Matchmaker Parallel Port Interface driver - * - * Thanks to David Campbell work on the Linux driver and the Iomega specs - * Thanks to Thiebault Moeglin for the drive - */ -#ifdef _KERNEL -#include -#include -#include -#include -#include - -#endif /* _KERNEL */ - -#include "opt_vpo.h" - -#include -#include -#include -#include -#include - -#include "ppbus_if.h" - -#define VP0_SELTMO 5000 /* select timeout */ -#define VP0_FAST_SPINTMO 500000 /* wait status timeout */ -#define VP0_LOW_SPINTMO 5000000 /* wait status timeout */ - -#define VP0_SECTOR_SIZE 512 - -/* - * Microcode to execute very fast I/O sequences at the lowest bus level. - */ - -#define WAIT_RET MS_PARAM(7, 2, MS_TYP_PTR) -#define WAIT_TMO MS_PARAM(1, 0, MS_TYP_INT) - -#define DECLARE_WAIT_MICROSEQUENCE \ -struct ppb_microseq wait_microseq[] = { \ - MS_CASS(0x0c), \ - MS_SET(MS_UNKNOWN), \ - /* loop */ \ - MS_BRSET(nBUSY, 4 /* ready */), \ - MS_DBRA(-2 /* loop */), \ - MS_CASS(0x04), \ - MS_RET(1), /* timed out */ \ - /* ready */ \ - MS_CASS(0x04), \ - MS_RFETCH(MS_REG_STR, 0xb8, MS_UNKNOWN ), \ - MS_RET(0) /* no error */ \ -} - -#define SELECT_TARGET MS_PARAM(6, 1, MS_TYP_CHA) - -#define DECLARE_SELECT_MICROSEQUENCE \ -struct ppb_microseq select_microseq[] = { \ - MS_CASS(0xc), \ - /* first, check there is nothing holding onto the bus */ \ - MS_SET(VP0_SELTMO), \ -/* _loop: */ \ - MS_BRCLEAR(0x8, 2 /* _ready */), \ - MS_DBRA(-2 /* _loop */), \ - MS_RET(2), /* bus busy */ \ -/* _ready: */ \ - MS_CASS(0x4), \ - MS_DASS(MS_UNKNOWN /* 0x80 | 1 << target */), \ - MS_DELAY(1), \ - MS_CASS(0xc), \ - MS_CASS(0xd), \ - /* now, wait until the drive is ready */ \ - MS_SET(VP0_SELTMO), \ -/* loop: */ \ - MS_BRSET(0x8, 3 /* ready */), \ - MS_DBRA(-2 /* loop */), \ -/* error: */ \ - MS_CASS(0xc), \ - MS_RET(VP0_ESELECT_TIMEOUT), \ -/* ready: */ \ - MS_CASS(0xc), \ - MS_RET(0) \ -} - -static struct ppb_microseq transfer_epilog[] = { - MS_CASS(0x4), - MS_CASS(0xc), - MS_CASS(0xe), - MS_CASS(0x4), - MS_RET(0) -}; - -#define CPP_S1 MS_PARAM(10, 2, MS_TYP_PTR) -#define CPP_S2 MS_PARAM(13, 2, MS_TYP_PTR) -#define CPP_S3 MS_PARAM(16, 2, MS_TYP_PTR) -#define CPP_PARAM MS_PARAM(17, 1, MS_TYP_CHA) - -#define DECLARE_CPP_MICROSEQ \ -struct ppb_microseq cpp_microseq[] = { \ - MS_CASS(0x0c), MS_DELAY(2), \ - MS_DASS(0xaa), MS_DELAY(10), \ - MS_DASS(0x55), MS_DELAY(10), \ - MS_DASS(0x00), MS_DELAY(10), \ - MS_DASS(0xff), MS_DELAY(10), \ - MS_RFETCH(MS_REG_STR, 0xb8, MS_UNKNOWN /* &s1 */), \ - MS_DASS(0x87), MS_DELAY(10), \ - MS_RFETCH(MS_REG_STR, 0xb8, MS_UNKNOWN /* &s2 */), \ - MS_DASS(0x78), MS_DELAY(10), \ - MS_RFETCH(MS_REG_STR, 0x38, MS_UNKNOWN /* &s3 */), \ - MS_DASS(MS_UNKNOWN /* param */), \ - MS_DELAY(2), \ - MS_CASS(0x0c), MS_DELAY(10), \ - MS_CASS(0x0d), MS_DELAY(2), \ - MS_CASS(0x0c), MS_DELAY(10), \ - MS_DASS(0xff), MS_DELAY(10), \ - MS_RET(0) \ -} - -#define NEGOCIATED_MODE MS_PARAM(2, 1, MS_TYP_CHA) - -#define DECLARE_NEGOCIATE_MICROSEQ \ -struct ppb_microseq negociate_microseq[] = { \ - MS_CASS(0x4), \ - MS_DELAY(5), \ - MS_DASS(MS_UNKNOWN /* mode */), \ - MS_DELAY(100), \ - MS_CASS(0x6), \ - MS_DELAY(5), \ - MS_BRSET(0x20, 5 /* continue */), \ - MS_DELAY(5), \ - MS_CASS(0x7), \ - MS_DELAY(5), \ - MS_CASS(0x6), \ - MS_RET(VP0_ENEGOCIATE), \ -/* continue: */ \ - MS_DELAY(5), \ - MS_CASS(0x7), \ - MS_DELAY(5), \ - MS_CASS(0x6), \ - MS_RET(0) \ -} - -#define INB_NIBBLE_L MS_PARAM(3, 2, MS_TYP_PTR) -#define INB_NIBBLE_H MS_PARAM(6, 2, MS_TYP_PTR) -#define INB_NIBBLE_F MS_PARAM(9, 0, MS_TYP_FUN) -#define INB_NIBBLE_P MS_PARAM(9, 1, MS_TYP_PTR) - -/* - * This is the sub-microseqence for MS_GET in NIBBLE mode - * Retrieve the two nibbles and call the C function to generate the character - * and store it in the buffer (see nibble_inbyte_hook()) - */ - -#define DECLARE_NIBBLE_INBYTE_SUBMICROSEQ \ -struct ppb_microseq nibble_inbyte_submicroseq[] = { \ - MS_CASS(0x4), \ -/* loop: */ \ - MS_CASS(0x6), \ - MS_DELAY(1), \ - MS_RFETCH(MS_REG_STR, MS_FETCH_ALL, MS_UNKNOWN /* low nibble */),\ - MS_CASS(0x5), \ - MS_DELAY(1), \ - MS_RFETCH(MS_REG_STR, MS_FETCH_ALL, MS_UNKNOWN /* high nibble */),\ - MS_CASS(0x4), \ - MS_DELAY(1), \ - /* do a C call to format the received nibbles */ \ - MS_C_CALL(MS_UNKNOWN /* C hook */, MS_UNKNOWN /* param */), \ - MS_DBRA(-7 /* loop */), \ - MS_RET(0) \ -} - -static struct ppb_microseq reset_microseq[] = { - MS_CASS(0x04), - MS_DASS(0x40), - MS_DELAY(1), - MS_CASS(0x0c), - MS_CASS(0x0d), - MS_DELAY(50), - MS_CASS(0x0c), - MS_CASS(0x04), - MS_RET(0) -}; - -/* - * nibble_inbyte_hook() - * - * Formats high and low nibble into a character - */ -static int -nibble_inbyte_hook (void *p, char *ptr) -{ - struct vpo_nibble *s = (struct vpo_nibble *)p; - - /* increment the buffer pointer */ - *ptr = ((s->l >> 4) & 0x0f) + (s->h & 0xf0); - - return (0); -} - -/* - * This is the sub-microseqence for MS_GET in PS2 mode - */ -static struct ppb_microseq ps2_inbyte_submicroseq[] = { - MS_CASS(0x4), - -/* loop: */ - MS_CASS(PCD | 0x6), - MS_RFETCH_P(1, MS_REG_DTR, MS_FETCH_ALL), - MS_CASS(PCD | 0x5), - MS_DBRA(-4 /* loop */), - - MS_RET(0) -}; - -/* - * This is the sub-microsequence for MS_PUT in both NIBBLE and PS2 modes - */ -static struct ppb_microseq spp_outbyte_submicroseq[] = { - MS_CASS(0x4), - -/* loop: */ - MS_RASSERT_P(1, MS_REG_DTR), - MS_CASS(0x5), - MS_DBRA(0), /* decrement counter */ - MS_RASSERT_P(1, MS_REG_DTR), - MS_CASS(0x0), - MS_DBRA(-6 /* loop */), - - /* return from the put call */ - MS_CASS(0x4), - MS_RET(0) -}; - -/* EPP 1.7 microsequences, ptr and len set at runtime */ -static struct ppb_microseq epp17_outstr[] = { - MS_CASS(0x4), - MS_RASSERT_P(MS_ACCUM, MS_REG_EPP_D), - MS_CASS(0xc), - MS_RET(0), -}; - -static struct ppb_microseq epp17_instr[] = { - MS_CASS(PCD | 0x4), - MS_RFETCH_P(MS_ACCUM, MS_REG_EPP_D, MS_FETCH_ALL), - MS_CASS(PCD | 0xc), - MS_RET(0), -}; - -static int -imm_disconnect(struct vpoio_data *vpo, int *connected, int release_bus) -{ - DECLARE_CPP_MICROSEQ; - - device_t ppbus = device_get_parent(vpo->vpo_dev); - char s1, s2, s3; - int ret; - - /* all should be ok */ - if (connected) - *connected = 0; - - ppb_MS_init_msq(cpp_microseq, 4, CPP_S1, (void *)&s1, - CPP_S2, (void *)&s2, CPP_S3, (void *)&s3, - CPP_PARAM, 0x30); - - ppb_MS_microseq(ppbus, vpo->vpo_dev, cpp_microseq, &ret); - - if ((s1 != (char)0xb8 || s2 != (char)0x18 || s3 != (char)0x38)) { - if (bootverbose) - device_printf(vpo->vpo_dev, - "(disconnect) s1=0x%x s2=0x%x, s3=0x%x\n", - s1 & 0xff, s2 & 0xff, s3 & 0xff); - if (connected) - *connected = VP0_ECONNECT; - } - - if (release_bus) - return (ppb_release_bus(ppbus, vpo->vpo_dev)); - else - return (0); -} - -/* - * how : PPB_WAIT or PPB_DONTWAIT - */ -static int -imm_connect(struct vpoio_data *vpo, int how, int *disconnected, int request_bus) -{ - DECLARE_CPP_MICROSEQ; - - device_t ppbus = device_get_parent(vpo->vpo_dev); - char s1, s2, s3; - int error; - int ret; - - /* all should be ok */ - if (disconnected) - *disconnected = 0; - - if (request_bus) - if ((error = ppb_request_bus(ppbus, vpo->vpo_dev, how))) - return (error); - - ppb_MS_init_msq(cpp_microseq, 3, CPP_S1, (void *)&s1, - CPP_S2, (void *)&s2, CPP_S3, (void *)&s3); - - /* select device 0 in compatible mode */ - ppb_MS_init_msq(cpp_microseq, 1, CPP_PARAM, 0xe0); - ppb_MS_microseq(ppbus, vpo->vpo_dev, cpp_microseq, &ret); - - /* disconnect all devices */ - ppb_MS_init_msq(cpp_microseq, 1, CPP_PARAM, 0x30); - ppb_MS_microseq(ppbus, vpo->vpo_dev, cpp_microseq, &ret); - - if (PPB_IN_EPP_MODE(ppbus)) - ppb_MS_init_msq(cpp_microseq, 1, CPP_PARAM, 0x28); - else - ppb_MS_init_msq(cpp_microseq, 1, CPP_PARAM, 0xe0); - - ppb_MS_microseq(ppbus, vpo->vpo_dev, cpp_microseq, &ret); - - if ((s1 != (char)0xb8 || s2 != (char)0x18 || s3 != (char)0x30)) { - if (bootverbose) - device_printf(vpo->vpo_dev, - "(connect) s1=0x%x s2=0x%x, s3=0x%x\n", - s1 & 0xff, s2 & 0xff, s3 & 0xff); - if (disconnected) - *disconnected = VP0_ECONNECT; - } - - return (0); -} - -/* - * imm_detect() - * - * Detect and initialise the VP0 adapter. - */ -static int -imm_detect(struct vpoio_data *vpo) -{ - device_t ppbus = device_get_parent(vpo->vpo_dev); - int error; - - if ((error = ppb_request_bus(ppbus, vpo->vpo_dev, PPB_DONTWAIT))) - return (error); - - /* disconnect the drive, keep the bus */ - imm_disconnect(vpo, NULL, 0); - - vpo->vpo_mode_found = VP0_MODE_UNDEFINED; - error = 1; - - /* try to enter EPP mode since vpoio failure put the bus in NIBBLE */ - if (ppb_set_mode(ppbus, PPB_EPP) != -1) { - imm_connect(vpo, PPB_DONTWAIT, &error, 0); - } - - /* if connection failed try PS/2 then NIBBLE modes */ - if (error) { - if (ppb_set_mode(ppbus, PPB_PS2) != -1) { - imm_connect(vpo, PPB_DONTWAIT, &error, 0); - } - if (error) { - if (ppb_set_mode(ppbus, PPB_NIBBLE) != -1) { - imm_connect(vpo, PPB_DONTWAIT, &error, 0); - if (error) - goto error; - vpo->vpo_mode_found = VP0_MODE_NIBBLE; - } else { - device_printf(vpo->vpo_dev, - "NIBBLE mode unavailable!\n"); - goto error; - } - } else { - vpo->vpo_mode_found = VP0_MODE_PS2; - } - } else { - vpo->vpo_mode_found = VP0_MODE_EPP; - } - - /* send SCSI reset signal */ - ppb_MS_microseq(ppbus, vpo->vpo_dev, reset_microseq, NULL); - - /* release the bus now */ - imm_disconnect(vpo, &error, 1); - - /* ensure we are disconnected or daisy chained peripheral - * may cause serious problem to the disk */ - - if (error) { - if (bootverbose) - device_printf(vpo->vpo_dev, - "can't disconnect from the drive\n"); - goto error; - } - - return (0); - -error: - ppb_release_bus(ppbus, vpo->vpo_dev); - return (VP0_EINITFAILED); -} - -/* - * imm_outstr() - */ -static int -imm_outstr(struct vpoio_data *vpo, char *buffer, int size) -{ - device_t ppbus = device_get_parent(vpo->vpo_dev); - int error = 0; - - if (PPB_IN_EPP_MODE(ppbus)) - ppb_reset_epp_timeout(ppbus); - - ppb_MS_exec(ppbus, vpo->vpo_dev, MS_OP_PUT, (union ppb_insarg)buffer, - (union ppb_insarg)size, (union ppb_insarg)MS_UNKNOWN, &error); - - return (error); -} - -/* - * imm_instr() - */ -static int -imm_instr(struct vpoio_data *vpo, char *buffer, int size) -{ - device_t ppbus = device_get_parent(vpo->vpo_dev); - int error = 0; - - if (PPB_IN_EPP_MODE(ppbus)) - ppb_reset_epp_timeout(ppbus); - - ppb_MS_exec(ppbus, vpo->vpo_dev, MS_OP_GET, (union ppb_insarg)buffer, - (union ppb_insarg)size, (union ppb_insarg)MS_UNKNOWN, &error); - - return (error); -} - -static char -imm_select(struct vpoio_data *vpo, int initiator, int target) -{ - DECLARE_SELECT_MICROSEQUENCE; - device_t ppbus = device_get_parent(vpo->vpo_dev); - int ret; - - /* initialize the select microsequence */ - ppb_MS_init_msq(select_microseq, 1, - SELECT_TARGET, 1 << initiator | 1 << target); - - ppb_MS_microseq(ppbus, vpo->vpo_dev, select_microseq, &ret); - - return (ret); -} - -/* - * imm_wait() - * - * H_SELIN must be low. - * - */ -static char -imm_wait(struct vpoio_data *vpo, int tmo) -{ - DECLARE_WAIT_MICROSEQUENCE; - - device_t ppbus = device_get_parent(vpo->vpo_dev); - int ret, err; - - /* - * Return some status information. - * Semantics : 0x88 = ZIP+ wants more data - * 0x98 = ZIP+ wants to send more data - * 0xa8 = ZIP+ wants command - * 0xb8 = end of transfer, ZIP+ is sending status - */ - - ppb_MS_init_msq(wait_microseq, 2, - WAIT_RET, (void *)&ret, - WAIT_TMO, tmo); - - ppb_MS_microseq(ppbus, vpo->vpo_dev, wait_microseq, &err); - - if (err) - return (0); /* command timed out */ - - return(ret); -} - -static int -imm_negociate(struct vpoio_data *vpo) -{ - DECLARE_NEGOCIATE_MICROSEQ; - device_t ppbus = device_get_parent(vpo->vpo_dev); - int negociate_mode; - int ret; - - if (PPB_IN_NIBBLE_MODE(ppbus)) - negociate_mode = 0; - else if (PPB_IN_PS2_MODE(ppbus)) - negociate_mode = 1; - else - return (0); - -#if 0 /* XXX use standalone code not to depend on ppb_1284 code yet */ - ret = ppb_1284_negociate(ppbus, negociate_mode); - - if (ret) - return (VP0_ENEGOCIATE); -#endif - - ppb_MS_init_msq(negociate_microseq, 1, - NEGOCIATED_MODE, negociate_mode); - - ppb_MS_microseq(ppbus, vpo->vpo_dev, negociate_microseq, &ret); - - return (ret); -} - -/* - * imm_probe() - * - * Low level probe of vpo device - * - */ -int -imm_probe(device_t dev, struct vpoio_data *vpo) -{ - int error; - - /* ppbus dependent initialisation */ - vpo->vpo_dev = dev; - - /* now, try to initialise the drive */ - if ((error = imm_detect(vpo))) { - return (error); - } - - return (0); -} - -/* - * imm_attach() - * - * Low level attachment of vpo device - * - */ -int -imm_attach(struct vpoio_data *vpo) -{ - DECLARE_NIBBLE_INBYTE_SUBMICROSEQ; - device_t ppbus = device_get_parent(vpo->vpo_dev); - int error = 0; - - /* - * Initialize microsequence code - */ - vpo->vpo_nibble_inbyte_msq = (struct ppb_microseq *)malloc( - sizeof(nibble_inbyte_submicroseq), M_DEVBUF, M_NOWAIT); - - if (!vpo->vpo_nibble_inbyte_msq) - return (ENXIO); - - bcopy((void *)nibble_inbyte_submicroseq, - (void *)vpo->vpo_nibble_inbyte_msq, - sizeof(nibble_inbyte_submicroseq)); - - ppb_MS_init_msq(vpo->vpo_nibble_inbyte_msq, 4, - INB_NIBBLE_H, (void *)&(vpo)->vpo_nibble.h, - INB_NIBBLE_L, (void *)&(vpo)->vpo_nibble.l, - INB_NIBBLE_F, nibble_inbyte_hook, - INB_NIBBLE_P, (void *)&(vpo)->vpo_nibble); - - /* - * Initialize mode dependent in/out microsequences - */ - ppb_lock(ppbus); - if ((error = ppb_request_bus(ppbus, vpo->vpo_dev, PPB_WAIT))) - goto error; - - /* ppbus automatically restore the last mode entered during detection */ - switch (vpo->vpo_mode_found) { - case VP0_MODE_EPP: - ppb_MS_GET_init(ppbus, vpo->vpo_dev, epp17_instr); - ppb_MS_PUT_init(ppbus, vpo->vpo_dev, epp17_outstr); - device_printf(vpo->vpo_dev, "EPP mode\n"); - break; - case VP0_MODE_PS2: - ppb_MS_GET_init(ppbus, vpo->vpo_dev, ps2_inbyte_submicroseq); - ppb_MS_PUT_init(ppbus, vpo->vpo_dev, spp_outbyte_submicroseq); - device_printf(vpo->vpo_dev, "PS2 mode\n"); - break; - case VP0_MODE_NIBBLE: - ppb_MS_GET_init(ppbus, vpo->vpo_dev, vpo->vpo_nibble_inbyte_msq); - ppb_MS_PUT_init(ppbus, vpo->vpo_dev, spp_outbyte_submicroseq); - device_printf(vpo->vpo_dev, "NIBBLE mode\n"); - break; - default: - panic("imm: unknown mode %d", vpo->vpo_mode_found); - } - - ppb_release_bus(ppbus, vpo->vpo_dev); - error: - ppb_unlock(ppbus); - return (error); -} - -/* - * imm_reset_bus() - * - */ -int -imm_reset_bus(struct vpoio_data *vpo) -{ - device_t ppbus = device_get_parent(vpo->vpo_dev); - int disconnected; - - /* first, connect to the drive and request the bus */ - imm_connect(vpo, PPB_WAIT|PPB_INTR, &disconnected, 1); - - if (!disconnected) { - - /* reset the SCSI bus */ - ppb_MS_microseq(ppbus, vpo->vpo_dev, reset_microseq, NULL); - - /* then disconnect */ - imm_disconnect(vpo, NULL, 1); - } - - return (0); -} - -/* - * imm_do_scsi() - * - * Send an SCSI command - * - */ -int -imm_do_scsi(struct vpoio_data *vpo, int host, int target, char *command, - int clen, char *buffer, int blen, int *result, int *count, - int *ret) -{ - device_t ppbus = device_get_parent(vpo->vpo_dev); - char r; - char l, h = 0; - int len, error = 0, not_connected = 0; - int k; - int negociated = 0; - - /* - * enter disk state, allocate the ppbus - * - * XXX - * Should we allow this call to be interruptible? - * The only way to report the interruption is to return - * EIO to upper SCSI code :^( - */ - if ((error = imm_connect(vpo, PPB_WAIT|PPB_INTR, ¬_connected, 1))) - return (error); - - if (not_connected) { - *ret = VP0_ECONNECT; - goto error; - } - - /* - * Select the drive ... - */ - if ((*ret = imm_select(vpo,host,target))) - goto error; - - /* - * Send the command ... - */ - for (k = 0; k < clen; k+=2) { - if (imm_wait(vpo, VP0_FAST_SPINTMO) != (char)0xa8) { - *ret = VP0_ECMD_TIMEOUT; - goto error; - } - if (imm_outstr(vpo, &command[k], 2)) { - *ret = VP0_EPPDATA_TIMEOUT; - goto error; - } - } - - if (!(r = imm_wait(vpo, VP0_LOW_SPINTMO))) { - *ret = VP0_ESTATUS_TIMEOUT; - goto error; - } - - if ((r & 0x30) == 0x10) { - if (imm_negociate(vpo)) { - *ret = VP0_ENEGOCIATE; - goto error; - } else - negociated = 1; - } - - /* - * Complete transfer ... - */ - *count = 0; - for (;;) { - - if (!(r = imm_wait(vpo, VP0_LOW_SPINTMO))) { - *ret = VP0_ESTATUS_TIMEOUT; - goto error; - } - - /* stop when the ZIP+ wants to send status */ - if (r == (char)0xb8) - break; - - if (*count >= blen) { - *ret = VP0_EDATA_OVERFLOW; - goto error; - } - - /* ZIP+ wants to send data? */ - if (r == (char)0x88) { - len = (((blen - *count) >= VP0_SECTOR_SIZE)) ? - VP0_SECTOR_SIZE : 2; - - error = imm_outstr(vpo, &buffer[*count], len); - } else { - if (!PPB_IN_EPP_MODE(ppbus)) - len = 1; - else - len = (((blen - *count) >= VP0_SECTOR_SIZE)) ? - VP0_SECTOR_SIZE : 1; - - error = imm_instr(vpo, &buffer[*count], len); - } - - if (error) { - *ret = error; - goto error; - } - - *count += len; - } - - if ((PPB_IN_NIBBLE_MODE(ppbus) || - PPB_IN_PS2_MODE(ppbus)) && negociated) - ppb_MS_microseq(ppbus, vpo->vpo_dev, transfer_epilog, NULL); - - /* - * Retrieve status ... - */ - if (imm_negociate(vpo)) { - *ret = VP0_ENEGOCIATE; - goto error; - } else - negociated = 1; - - if (imm_instr(vpo, &l, 1)) { - *ret = VP0_EOTHER; - goto error; - } - - /* check if the ZIP+ wants to send more status */ - if (imm_wait(vpo, VP0_FAST_SPINTMO) == (char)0xb8) - if (imm_instr(vpo, &h, 1)) { - *ret = VP0_EOTHER + 2; - goto error; - } - - /* Experience showed that we should discard this */ - if (h == (char) -1) - h = 0; - - *result = ((int) h << 8) | ((int) l & 0xff); - -error: - if ((PPB_IN_NIBBLE_MODE(ppbus) || - PPB_IN_PS2_MODE(ppbus)) && negociated) - ppb_MS_microseq(ppbus, vpo->vpo_dev, transfer_epilog, NULL); - - /* return to printer state, release the ppbus */ - imm_disconnect(vpo, NULL, 1); - - return (0); -} Index: head/sys/dev/ppbus/vpo.c =================================================================== --- head/sys/dev/ppbus/vpo.c +++ head/sys/dev/ppbus/vpo.c @@ -1,441 +0,0 @@ -/*- - * SPDX-License-Identifier: BSD-2-Clause-FreeBSD - * - * Copyright (c) 1997, 1998, 1999 Nicolas Souchu - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. - * - */ - -#include -__FBSDID("$FreeBSD$"); - -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#include - -#include "opt_vpo.h" - -#include -#include - -#include "ppbus_if.h" - -struct vpo_sense { - struct scsi_sense cmd; - unsigned int stat; - unsigned int count; -}; - -struct vpo_data { - device_t vpo_dev; - int vpo_stat; - int vpo_count; - int vpo_error; - - int vpo_isplus; - - struct cam_sim *sim; - - struct vpo_sense vpo_sense; - - struct vpoio_data vpo_io; /* interface to low level functions */ -}; - -#define DEVTOSOFTC(dev) \ - ((struct vpo_data *)device_get_softc(dev)) - -/* cam related functions */ -static void vpo_action(struct cam_sim *sim, union ccb *ccb); -static void vpo_poll(struct cam_sim *sim); - -static void -vpo_identify(driver_t *driver, device_t parent) -{ - - device_t dev; - - dev = device_find_child(parent, "vpo", -1); - if (!dev) - BUS_ADD_CHILD(parent, 0, "vpo", -1); -} - -/* - * vpo_probe() - */ -static int -vpo_probe(device_t dev) -{ - device_t ppbus = device_get_parent(dev); - struct vpo_data *vpo; - int error; - - vpo = DEVTOSOFTC(dev); - vpo->vpo_dev = dev; - - /* check ZIP before ZIP+ or imm_probe() will send controls to - * the printer or whatelse connected to the port */ - ppb_lock(ppbus); - if ((error = vpoio_probe(dev, &vpo->vpo_io)) == 0) { - vpo->vpo_isplus = 0; - device_set_desc(dev, - "Iomega VPI0 Parallel to SCSI interface"); - } else if ((error = imm_probe(dev, &vpo->vpo_io)) == 0) { - vpo->vpo_isplus = 1; - device_set_desc(dev, - "Iomega Matchmaker Parallel to SCSI interface"); - } else { - ppb_unlock(ppbus); - return (error); - } - ppb_unlock(ppbus); - gone_in_dev(dev, 13, "Hardware no longer relevant"); - - return (0); -} - -/* - * vpo_attach() - */ -static int -vpo_attach(device_t dev) -{ - struct vpo_data *vpo = DEVTOSOFTC(dev); - device_t ppbus = device_get_parent(dev); - struct ppb_data *ppb = device_get_softc(ppbus); /* XXX: layering */ - struct cam_devq *devq; - int error; - - /* low level attachment */ - if (vpo->vpo_isplus) { - if ((error = imm_attach(&vpo->vpo_io))) - return (error); - } else { - if ((error = vpoio_attach(&vpo->vpo_io))) - return (error); - } - - /* - ** Now tell the generic SCSI layer - ** about our bus. - */ - devq = cam_simq_alloc(/*maxopenings*/1); - /* XXX What about low-level detach on error? */ - if (devq == NULL) - return (ENXIO); - - vpo->sim = cam_sim_alloc(vpo_action, vpo_poll, "vpo", vpo, - device_get_unit(dev), ppb->ppc_lock, - /*untagged*/1, /*tagged*/0, devq); - if (vpo->sim == NULL) { - cam_simq_free(devq); - return (ENXIO); - } - - ppb_lock(ppbus); - if (xpt_bus_register(vpo->sim, dev, /*bus*/0) != CAM_SUCCESS) { - cam_sim_free(vpo->sim, /*free_devq*/TRUE); - ppb_unlock(ppbus); - return (ENXIO); - } - ppb_unlock(ppbus); - - return (0); -} - -/* - * vpo_intr() - */ -static void -vpo_intr(struct vpo_data *vpo, struct ccb_scsiio *csio) -{ - int errno; /* error in errno.h */ -#ifdef VP0_DEBUG - int i; -#endif - uint8_t *ptr; - - ptr = scsiio_cdb_ptr(csio); - if (vpo->vpo_isplus) { - errno = imm_do_scsi(&vpo->vpo_io, VP0_INITIATOR, - csio->ccb_h.target_id, - ptr, csio->cdb_len, - (char *)csio->data_ptr, csio->dxfer_len, - &vpo->vpo_stat, &vpo->vpo_count, &vpo->vpo_error); - } else { - errno = vpoio_do_scsi(&vpo->vpo_io, VP0_INITIATOR, - csio->ccb_h.target_id, - ptr, csio->cdb_len, - (char *)csio->data_ptr, csio->dxfer_len, - &vpo->vpo_stat, &vpo->vpo_count, &vpo->vpo_error); - } - -#ifdef VP0_DEBUG - printf("vpo_do_scsi = %d, status = 0x%x, count = %d, vpo_error = %d\n", - errno, vpo->vpo_stat, vpo->vpo_count, vpo->vpo_error); - - /* dump of command */ - for (i=0; icdb_len; i++) - printf("%x ", ((char *)ptr)[i]); - - printf("\n"); -#endif - - if (errno) { - /* connection to ppbus interrupted */ - csio->ccb_h.status = CAM_CMD_TIMEOUT; - return; - } - - /* if a timeout occurred, no sense */ - if (vpo->vpo_error) { - if (vpo->vpo_error != VP0_ESELECT_TIMEOUT) - device_printf(vpo->vpo_dev, "VP0 error/timeout (%d)\n", - vpo->vpo_error); - - csio->ccb_h.status = CAM_CMD_TIMEOUT; - return; - } - - /* check scsi status */ - if (vpo->vpo_stat != SCSI_STATUS_OK) { - csio->scsi_status = vpo->vpo_stat; - - /* check if we have to sense the drive */ - if ((vpo->vpo_stat & SCSI_STATUS_CHECK_COND) != 0) { - - vpo->vpo_sense.cmd.opcode = REQUEST_SENSE; - vpo->vpo_sense.cmd.length = csio->sense_len; - vpo->vpo_sense.cmd.control = 0; - - if (vpo->vpo_isplus) { - errno = imm_do_scsi(&vpo->vpo_io, VP0_INITIATOR, - csio->ccb_h.target_id, - (char *)&vpo->vpo_sense.cmd, - sizeof(vpo->vpo_sense.cmd), - (char *)&csio->sense_data, csio->sense_len, - &vpo->vpo_sense.stat, &vpo->vpo_sense.count, - &vpo->vpo_error); - } else { - errno = vpoio_do_scsi(&vpo->vpo_io, VP0_INITIATOR, - csio->ccb_h.target_id, - (char *)&vpo->vpo_sense.cmd, - sizeof(vpo->vpo_sense.cmd), - (char *)&csio->sense_data, csio->sense_len, - &vpo->vpo_sense.stat, &vpo->vpo_sense.count, - &vpo->vpo_error); - } - - -#ifdef VP0_DEBUG - printf("(sense) vpo_do_scsi = %d, status = 0x%x, count = %d, vpo_error = %d\n", - errno, vpo->vpo_sense.stat, vpo->vpo_sense.count, vpo->vpo_error); -#endif - - /* check sense return status */ - if (errno == 0 && vpo->vpo_sense.stat == SCSI_STATUS_OK) { - /* sense ok */ - csio->ccb_h.status = CAM_AUTOSNS_VALID | CAM_SCSI_STATUS_ERROR; - csio->sense_resid = csio->sense_len - vpo->vpo_sense.count; - -#ifdef VP0_DEBUG - /* dump of sense info */ - printf("(sense) "); - for (i=0; ivpo_sense.count; i++) - printf("%x ", ((char *)&csio->sense_data)[i]); - printf("\n"); -#endif - - } else { - /* sense failed */ - csio->ccb_h.status = CAM_AUTOSENSE_FAIL; - } - } else { - /* no sense */ - csio->ccb_h.status = CAM_SCSI_STATUS_ERROR; - } - - return; - } - - csio->resid = csio->dxfer_len - vpo->vpo_count; - csio->ccb_h.status = CAM_REQ_CMP; -} - -static void -vpo_action(struct cam_sim *sim, union ccb *ccb) -{ - struct vpo_data *vpo = (struct vpo_data *)sim->softc; - - ppb_assert_locked(device_get_parent(vpo->vpo_dev)); - switch (ccb->ccb_h.func_code) { - case XPT_SCSI_IO: - { - struct ccb_scsiio *csio; - - csio = &ccb->csio; - - if (ccb->ccb_h.flags & CAM_CDB_PHYS) { - ccb->ccb_h.status = CAM_REQ_INVALID; - xpt_done(ccb); - break; - } -#ifdef VP0_DEBUG - device_printf(vpo->vpo_dev, "XPT_SCSI_IO (0x%x) request\n", - *scsiio_cdb_ptr(csio)); -#endif - vpo_intr(vpo, csio); - - xpt_done(ccb); - - break; - } - case XPT_CALC_GEOMETRY: - { - struct ccb_calc_geometry *ccg; - - ccg = &ccb->ccg; - -#ifdef VP0_DEBUG - device_printf(vpo->vpo_dev, "XPT_CALC_GEOMETRY (bs=%d,vs=%jd,c=%d,h=%d,spt=%d) request\n", - ccg->block_size, - (intmax_t)ccg->volume_size, - ccg->cylinders, - ccg->heads, - ccg->secs_per_track); -#endif - - ccg->heads = 64; - ccg->secs_per_track = 32; - ccg->cylinders = ccg->volume_size / - (ccg->heads * ccg->secs_per_track); - - ccb->ccb_h.status = CAM_REQ_CMP; - xpt_done(ccb); - break; - } - case XPT_RESET_BUS: /* Reset the specified SCSI bus */ - { - -#ifdef VP0_DEBUG - device_printf(vpo->vpo_dev, "XPT_RESET_BUS request\n"); -#endif - - if (vpo->vpo_isplus) { - if (imm_reset_bus(&vpo->vpo_io)) { - ccb->ccb_h.status = CAM_REQ_CMP_ERR; - xpt_done(ccb); - return; - } - } else { - if (vpoio_reset_bus(&vpo->vpo_io)) { - ccb->ccb_h.status = CAM_REQ_CMP_ERR; - xpt_done(ccb); - return; - } - } - - ccb->ccb_h.status = CAM_REQ_CMP; - xpt_done(ccb); - break; - } - case XPT_PATH_INQ: /* Path routing inquiry */ - { - struct ccb_pathinq *cpi = &ccb->cpi; - -#ifdef VP0_DEBUG - device_printf(vpo->vpo_dev, "XPT_PATH_INQ request\n"); -#endif - cpi->version_num = 1; /* XXX??? */ - cpi->hba_inquiry = 0; - cpi->target_sprt = 0; - cpi->hba_misc = 0; - cpi->hba_eng_cnt = 0; - cpi->max_target = 7; - cpi->max_lun = 0; - cpi->initiator_id = VP0_INITIATOR; - cpi->bus_id = sim->bus_id; - cpi->base_transfer_speed = 93; - strlcpy(cpi->sim_vid, "FreeBSD", SIM_IDLEN); - strlcpy(cpi->hba_vid, "Iomega", HBA_IDLEN); - strlcpy(cpi->dev_name, sim->sim_name, DEV_IDLEN); - cpi->unit_number = sim->unit_number; - cpi->transport = XPORT_PPB; - cpi->transport_version = 0; - - cpi->ccb_h.status = CAM_REQ_CMP; - xpt_done(ccb); - break; - } - default: - ccb->ccb_h.status = CAM_REQ_INVALID; - xpt_done(ccb); - break; - } - - return; -} - -static void -vpo_poll(struct cam_sim *sim) -{ - - /* The ZIP is actually always polled throw vpo_action(). */ -} - -static devclass_t vpo_devclass; - -static device_method_t vpo_methods[] = { - /* device interface */ - DEVMETHOD(device_identify, vpo_identify), - DEVMETHOD(device_probe, vpo_probe), - DEVMETHOD(device_attach, vpo_attach), - - { 0, 0 } -}; - -static driver_t vpo_driver = { - "vpo", - vpo_methods, - sizeof(struct vpo_data), -}; -DRIVER_MODULE(vpo, ppbus, vpo_driver, vpo_devclass, 0, 0); -MODULE_DEPEND(vpo, ppbus, 1, 1, 1); -MODULE_DEPEND(vpo, cam, 1, 1, 1); Index: head/sys/dev/ppbus/vpoio.h =================================================================== --- head/sys/dev/ppbus/vpoio.h +++ head/sys/dev/ppbus/vpoio.h @@ -1,99 +0,0 @@ -/*- - * SPDX-License-Identifier: BSD-2-Clause-FreeBSD - * - * Copyright (c) 1998 Nicolas Souchu - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. - * - * $FreeBSD$ - * - */ -#ifndef __VP0IO_H -#define __VP0IO_H - -/* - * The ZIP drive cannot act as an initiator. - */ -#define VP0_INITIATOR 0x7 - -#define VP0_ESELECT_TIMEOUT 1 -#define VP0_ECMD_TIMEOUT 2 -#define VP0_ECONNECT 3 -#define VP0_ESTATUS_TIMEOUT 4 -#define VP0_EDATA_OVERFLOW 5 -#define VP0_EDISCONNECT 6 -#define VP0_EPPDATA_TIMEOUT 7 -#define VP0_ENEGOCIATE 8 -#define VP0_ENOPORT 9 -#define VP0_EINITFAILED 10 -#define VP0_EINTR 12 - -#define VP0_EOTHER 13 - -#define VP0_OPENNINGS 1 - -/* - * Data structure used during microsequence execution - * when characters are received in nibble mode - */ -struct vpo_nibble { - char h; /* most significant nibble */ - char l; /* less significant nibble */ -}; - -/* Mode found during initialisation */ -#define VP0_MODE_UNDEFINED 0x0 -#define VP0_MODE_NIBBLE 0x1 -#define VP0_MODE_PS2 0x2 -#define VP0_MODE_EPP 0x3 - -struct vpoio_data { - int vpo_mode_found; /* Mode found during init */ - - struct vpo_nibble vpo_nibble; - - /* each device must have its own nibble inbyte microsequence */ - struct ppb_microseq *vpo_nibble_inbyte_msq; - - device_t vpo_dev; -}; - -int vpoio_probe(device_t dev, struct vpoio_data *vpo); - -int vpoio_attach(struct vpoio_data *vpo); -int vpoio_reset_bus(struct vpoio_data *vpo); - -int vpoio_do_scsi(struct vpoio_data *vpo, int host, int target, char *command, - int clen, char *buffer, int blen, int *result, int *count, - int *ret); - -int imm_probe(device_t dev, struct vpoio_data *vpo); - -int imm_attach(struct vpoio_data *vpo); -int imm_reset_bus(struct vpoio_data *vpo); - -int imm_do_scsi(struct vpoio_data *vpo, int host, int target, char *command, - int clen, char *buffer, int blen, int *result, int *count, - int *ret); - -#endif Index: head/sys/dev/ppbus/vpoio.c =================================================================== --- head/sys/dev/ppbus/vpoio.c +++ head/sys/dev/ppbus/vpoio.c @@ -1,789 +0,0 @@ -/*- - * SPDX-License-Identifier: BSD-2-Clause-FreeBSD - * - * Copyright (c) 1998, 1999 Nicolas Souchu - * Copyright (c) 2000 Alcove - Nicolas Souchu - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. - * - * - */ - -#include -__FBSDID("$FreeBSD$"); - -#ifdef _KERNEL -#include -#include -#include -#include -#include - - -#endif - -#include "opt_vpo.h" - -#include -#include -#include -#include - -#include "ppbus_if.h" - -/* - * The driver pools the drive. We may add a timeout queue to avoid - * active polling on nACK. I've tried this but it leads to unreliable - * transfers - */ -#define VP0_SELTMO 5000 /* select timeout */ -#define VP0_FAST_SPINTMO 500000 /* wait status timeout */ -#define VP0_LOW_SPINTMO 5000000 /* wait status timeout */ - -/* - * Actually, VP0 timings are more accurate (about few 16MHZ cycles), - * but succeeding in respecting such timings leads to architecture - * dependent considerations. - */ -#define VP0_PULSE 1 - -#define VP0_SECTOR_SIZE 512 -#define VP0_BUFFER_SIZE 0x12000 - -#define n(flags) (~(flags) & (flags)) - -/* - * VP0 connections. - */ -#define H_AUTO n(AUTOFEED) -#define H_nAUTO AUTOFEED -#define H_STROBE n(STROBE) -#define H_nSTROBE STROBE -#define H_BSY n(nBUSY) -#define H_nBSY nBUSY -#define H_SEL SELECT -#define H_nSEL n(SELECT) -#define H_ERR PERROR -#define H_nERR n(PERROR) -#define H_ACK nACK -#define H_nACK n(nACK) -#define H_FLT nFAULT -#define H_nFLT n(nFAULT) -#define H_SELIN n(SELECTIN) -#define H_nSELIN SELECTIN -#define H_INIT nINIT -#define H_nINIT n(nINIT) - -/* - * Microcode to execute very fast I/O sequences at the lowest bus level. - */ - -#define WAIT_RET MS_PARAM(4, 2, MS_TYP_PTR) -#define WAIT_TMO MS_PARAM(0, 0, MS_TYP_INT) - -#define DECLARE_WAIT_MICROSEQUENCE \ -struct ppb_microseq wait_microseq[] = { \ - MS_SET(MS_UNKNOWN), \ - /* loop */ \ - MS_BRSET(nBUSY, 2 /* ready */), \ - MS_DBRA(-2 /* loop */), \ - MS_RET(1), /* timed out */ \ - /* ready */ \ - MS_RFETCH(MS_REG_STR, 0xf0, MS_UNKNOWN), \ - MS_RET(0) /* no error */ \ -} - -/* call this macro to initialize connect/disconnect microsequences */ -#define INIT_TRIG_MICROSEQ { \ - int i; \ - for (i=1; i <= 7; i+=2) { \ - disconnect_microseq[i].arg[2] = (union ppb_insarg)d_pulse; \ - connect_epp_microseq[i].arg[2] = \ - connect_spp_microseq[i].arg[2] = (union ppb_insarg)c_pulse; \ - } \ -} - -#define trig_d_pulse MS_TRIG(MS_REG_CTR,5,MS_UNKNOWN /* d_pulse */) -static char d_pulse[] = { - H_AUTO | H_nSELIN | H_INIT | H_STROBE, 0, - H_nAUTO | H_nSELIN | H_INIT | H_STROBE, VP0_PULSE, - H_AUTO | H_nSELIN | H_INIT | H_STROBE, 0, - H_AUTO | H_SELIN | H_INIT | H_STROBE, VP0_PULSE, - H_AUTO | H_nSELIN | H_INIT | H_STROBE, VP0_PULSE -}; - -#define trig_c_pulse MS_TRIG(MS_REG_CTR,5,MS_UNKNOWN /* c_pulse */) -static char c_pulse[] = { - H_AUTO | H_nSELIN | H_INIT | H_STROBE, 0, - H_AUTO | H_SELIN | H_INIT | H_STROBE, 0, - H_nAUTO | H_SELIN | H_INIT | H_STROBE, VP0_PULSE, - H_AUTO | H_SELIN | H_INIT | H_STROBE, 0, - H_AUTO | H_nSELIN | H_INIT | H_STROBE, VP0_PULSE -}; - -static struct ppb_microseq disconnect_microseq[] = { - MS_DASS(0x0), trig_d_pulse, MS_DASS(0x3c), trig_d_pulse, - MS_DASS(0x20), trig_d_pulse, MS_DASS(0xf), trig_d_pulse, MS_RET(0) -}; - -static struct ppb_microseq connect_epp_microseq[] = { - MS_DASS(0x0), trig_c_pulse, MS_DASS(0x3c), trig_c_pulse, - MS_DASS(0x20), trig_c_pulse, MS_DASS(0xcf), trig_c_pulse, MS_RET(0) -}; - -static struct ppb_microseq connect_spp_microseq[] = { - MS_DASS(0x0), trig_c_pulse, MS_DASS(0x3c), trig_c_pulse, - MS_DASS(0x20), trig_c_pulse, MS_DASS(0x8f), trig_c_pulse, MS_RET(0) -}; - -/* - * nibble_inbyte_hook() - * - * Formats high and low nibble into a character - */ -static int -nibble_inbyte_hook (void *p, char *ptr) -{ - struct vpo_nibble *s = (struct vpo_nibble *)p; - - /* increment the buffer pointer */ - *ptr++ = ((s->l >> 4) & 0x0f) + (s->h & 0xf0); - - return (0); -} - -#define INB_NIBBLE_H MS_PARAM(2, 2, MS_TYP_PTR) -#define INB_NIBBLE_L MS_PARAM(4, 2, MS_TYP_PTR) -#define INB_NIBBLE_F MS_PARAM(5, 0, MS_TYP_FUN) -#define INB_NIBBLE_P MS_PARAM(5, 1, MS_TYP_PTR) - -/* - * This is the sub-microseqence for MS_GET in NIBBLE mode - * Retrieve the two nibbles and call the C function to generate the character - * and store it in the buffer (see nibble_inbyte_hook()) - */ - -#define DECLARE_NIBBLE_INBYTE_SUBMICROSEQ \ -struct ppb_microseq nibble_inbyte_submicroseq[] = { \ -/* loop: */ \ - MS_CASS( H_AUTO | H_SELIN | H_INIT | H_STROBE), \ - MS_DELAY(VP0_PULSE), \ - MS_RFETCH(MS_REG_STR, MS_FETCH_ALL, MS_UNKNOWN /* high nibble */),\ - MS_CASS(H_nAUTO | H_SELIN | H_INIT | H_STROBE), \ - MS_RFETCH(MS_REG_STR, MS_FETCH_ALL, MS_UNKNOWN /* low nibble */),\ - /* do a C call to format the received nibbles */ \ - MS_C_CALL(MS_UNKNOWN /* C hook */, MS_UNKNOWN /* param */),\ - MS_DBRA(-7 /* loop */), \ - MS_CASS(H_AUTO | H_nSELIN | H_INIT | H_STROBE), \ - MS_RET(0) \ -} - -/* - * This is the sub-microseqence for MS_GET in PS2 mode - */ -static struct ppb_microseq ps2_inbyte_submicroseq[] = { - MS_CASS(PCD | H_AUTO | H_SELIN | H_INIT | H_nSTROBE), - -/* loop: */ - MS_RFETCH_P(1, MS_REG_DTR, MS_FETCH_ALL), - MS_CASS(PCD | H_nAUTO | H_SELIN | H_INIT | H_nSTROBE), - MS_CASS(PCD | H_AUTO | H_SELIN | H_INIT | H_nSTROBE), - MS_DBRA(-4 /* loop */), - - MS_CASS(H_AUTO | H_nSELIN | H_INIT | H_STROBE), - MS_RET(0) -}; - -/* - * This is the sub-microsequence for MS_PUT in both NIBBLE and PS2 modes - */ -static struct ppb_microseq spp_outbyte_submicroseq[] = { - -/* loop: */ - MS_RASSERT_P(1, MS_REG_DTR), - MS_CASS(H_nAUTO | H_nSELIN | H_INIT | H_STROBE), - MS_CASS( H_AUTO | H_nSELIN | H_INIT | H_STROBE), - MS_DELAY(VP0_PULSE), - MS_DBRA(-5 /* loop */), - - /* return from the put call */ - MS_RET(0) -}; - -/* EPP 1.7 microsequences, ptr and len set at runtime */ -static struct ppb_microseq epp17_outstr_body[] = { - MS_CASS(H_AUTO | H_SELIN | H_INIT | H_STROBE), - -/* loop: */ - MS_RASSERT_P(1, MS_REG_EPP_D), - MS_BRSET(TIMEOUT, 3 /* error */), /* EPP timeout? */ - MS_DBRA(-3 /* loop */), - - MS_CASS(H_AUTO | H_nSELIN | H_INIT | H_STROBE), - MS_RET(0), -/* error: */ - MS_CASS(H_AUTO | H_nSELIN | H_INIT | H_STROBE), - MS_RET(1) -}; - -static struct ppb_microseq epp17_instr_body[] = { - MS_CASS(PCD | H_AUTO | H_SELIN | H_INIT | H_STROBE), - -/* loop: */ - MS_RFETCH_P(1, MS_REG_EPP_D, MS_FETCH_ALL), - MS_BRSET(TIMEOUT, 3 /* error */), /* EPP timeout? */ - MS_DBRA(-3 /* loop */), - - MS_CASS(PCD | H_AUTO | H_nSELIN | H_INIT | H_STROBE), - MS_RET(0), -/* error: */ - MS_CASS(PCD | H_AUTO | H_nSELIN | H_INIT | H_STROBE), - MS_RET(1) -}; - -static struct ppb_microseq in_disk_mode[] = { - MS_CASS( H_AUTO | H_nSELIN | H_INIT | H_STROBE), - MS_CASS(H_nAUTO | H_nSELIN | H_INIT | H_STROBE), - - MS_BRCLEAR(H_FLT, 3 /* error */), - MS_CASS( H_AUTO | H_nSELIN | H_INIT | H_STROBE), - MS_BRSET(H_FLT, 1 /* error */), - - MS_RET(1), -/* error: */ - MS_RET(0) -}; - -static int -vpoio_disconnect(struct vpoio_data *vpo) -{ - device_t ppbus = device_get_parent(vpo->vpo_dev); - int ret; - - ppb_MS_microseq(ppbus, vpo->vpo_dev, disconnect_microseq, &ret); - return (ppb_release_bus(ppbus, vpo->vpo_dev)); -} - -/* - * how : PPB_WAIT or PPB_DONTWAIT - */ -static int -vpoio_connect(struct vpoio_data *vpo, int how) -{ - device_t ppbus = device_get_parent(vpo->vpo_dev); - int error; - int ret; - - if ((error = ppb_request_bus(ppbus, vpo->vpo_dev, how))) { - -#ifdef VP0_DEBUG - printf("%s: can't request bus!\n", __func__); -#endif - return (error); - } - - if (PPB_IN_EPP_MODE(ppbus)) - ppb_MS_microseq(ppbus, vpo->vpo_dev, connect_epp_microseq, &ret); - else - ppb_MS_microseq(ppbus, vpo->vpo_dev, connect_spp_microseq, &ret); - - return (0); -} - -/* - * vpoio_reset() - * - * SCSI reset signal, the drive must be in disk mode - */ -static void -vpoio_reset(struct vpoio_data *vpo) -{ - device_t ppbus = device_get_parent(vpo->vpo_dev); - int ret; - - struct ppb_microseq reset_microseq[] = { - - #define INITIATOR MS_PARAM(0, 1, MS_TYP_INT) - - MS_DASS(MS_UNKNOWN), - MS_CASS(H_AUTO | H_nSELIN | H_nINIT | H_STROBE), - MS_DELAY(25), - MS_CASS(H_AUTO | H_nSELIN | H_INIT | H_STROBE), - MS_RET(0) - }; - - ppb_MS_init_msq(reset_microseq, 1, INITIATOR, 1 << VP0_INITIATOR); - ppb_MS_microseq(ppbus, vpo->vpo_dev, reset_microseq, &ret); - - return; -} - -/* - * vpoio_in_disk_mode() - */ -static int -vpoio_in_disk_mode(struct vpoio_data *vpo) -{ - device_t ppbus = device_get_parent(vpo->vpo_dev); - int ret; - - ppb_MS_microseq(ppbus, vpo->vpo_dev, in_disk_mode, &ret); - - return (ret); -} - -/* - * vpoio_detect() - * - * Detect and initialise the VP0 adapter. - */ -static int -vpoio_detect(struct vpoio_data *vpo) -{ - device_t ppbus = device_get_parent(vpo->vpo_dev); - int error, ret; - - /* allocate the bus, then apply microsequences */ - if ((error = ppb_request_bus(ppbus, vpo->vpo_dev, PPB_DONTWAIT))) - return (error); - - /* Force disconnection */ - ppb_MS_microseq(ppbus, vpo->vpo_dev, disconnect_microseq, &ret); - - /* Try to enter EPP mode, then connect to the drive in EPP mode */ - if (ppb_set_mode(ppbus, PPB_EPP) != -1) { - /* call manually the microseq instead of using the appropriate function - * since we already requested the ppbus */ - ppb_MS_microseq(ppbus, vpo->vpo_dev, connect_epp_microseq, &ret); - } - - /* If EPP mode switch failed or ZIP connection in EPP mode failed, - * try to connect in NIBBLE mode */ - if (!vpoio_in_disk_mode(vpo)) { - - /* The interface must be at least PS/2 or NIBBLE capable. - * There is no way to know if the ZIP will work with - * PS/2 mode since PS/2 and SPP both use the same connect - * sequence. One must suppress PS/2 with boot flags if - * PS/2 mode fails (see ppc(4)). - */ - if (ppb_set_mode(ppbus, PPB_PS2) != -1) { - vpo->vpo_mode_found = VP0_MODE_PS2; - } else { - if (ppb_set_mode(ppbus, PPB_NIBBLE) == -1) - goto error; - - vpo->vpo_mode_found = VP0_MODE_NIBBLE; - } - - /* Can't know if the interface is capable of PS/2 yet */ - ppb_MS_microseq(ppbus, vpo->vpo_dev, connect_spp_microseq, &ret); - if (!vpoio_in_disk_mode(vpo)) { - vpo->vpo_mode_found = VP0_MODE_UNDEFINED; - if (bootverbose) - device_printf(vpo->vpo_dev, - "can't connect to the drive\n"); - - /* disconnect and release the bus */ - ppb_MS_microseq(ppbus, vpo->vpo_dev, disconnect_microseq, - &ret); - goto error; - } - } else { - vpo->vpo_mode_found = VP0_MODE_EPP; - } - - /* send SCSI reset signal */ - vpoio_reset(vpo); - - ppb_MS_microseq(ppbus, vpo->vpo_dev, disconnect_microseq, &ret); - - /* ensure we are disconnected or daisy chained peripheral - * may cause serious problem to the disk */ - if (vpoio_in_disk_mode(vpo)) { - if (bootverbose) - device_printf(vpo->vpo_dev, - "can't disconnect from the drive\n"); - goto error; - } - - ppb_release_bus(ppbus, vpo->vpo_dev); - return (0); - -error: - ppb_release_bus(ppbus, vpo->vpo_dev); - return (VP0_EINITFAILED); -} - -/* - * vpoio_outstr() - */ -static int -vpoio_outstr(struct vpoio_data *vpo, char *buffer, int size) -{ - device_t ppbus = device_get_parent(vpo->vpo_dev); - int error = 0; - - ppb_MS_exec(ppbus, vpo->vpo_dev, MS_OP_PUT, (union ppb_insarg)buffer, - (union ppb_insarg)size, (union ppb_insarg)MS_UNKNOWN, &error); - - ppb_ecp_sync(ppbus); - - return (error); -} - -/* - * vpoio_instr() - */ -static int -vpoio_instr(struct vpoio_data *vpo, char *buffer, int size) -{ - device_t ppbus = device_get_parent(vpo->vpo_dev); - int error = 0; - - ppb_MS_exec(ppbus, vpo->vpo_dev, MS_OP_GET, (union ppb_insarg)buffer, - (union ppb_insarg)size, (union ppb_insarg)MS_UNKNOWN, &error); - - ppb_ecp_sync(ppbus); - - return (error); -} - -static char -vpoio_select(struct vpoio_data *vpo, int initiator, int target) -{ - device_t ppbus = device_get_parent(vpo->vpo_dev); - int ret; - - struct ppb_microseq select_microseq[] = { - - /* parameter list - */ - #define SELECT_TARGET MS_PARAM(0, 1, MS_TYP_INT) - #define SELECT_INITIATOR MS_PARAM(3, 1, MS_TYP_INT) - - /* send the select command to the drive */ - MS_DASS(MS_UNKNOWN), - MS_CASS(H_nAUTO | H_nSELIN | H_INIT | H_STROBE), - MS_CASS( H_AUTO | H_nSELIN | H_INIT | H_STROBE), - MS_DASS(MS_UNKNOWN), - MS_CASS( H_AUTO | H_nSELIN | H_nINIT | H_STROBE), - - /* now, wait until the drive is ready */ - MS_SET(VP0_SELTMO), -/* loop: */ MS_BRSET(H_ACK, 2 /* ready */), - MS_DBRA(-2 /* loop */), -/* error: */ MS_RET(1), -/* ready: */ MS_RET(0) - }; - - /* initialize the select microsequence */ - ppb_MS_init_msq(select_microseq, 2, - SELECT_TARGET, 1 << target, - SELECT_INITIATOR, 1 << initiator); - - ppb_MS_microseq(ppbus, vpo->vpo_dev, select_microseq, &ret); - - if (ret) - return (VP0_ESELECT_TIMEOUT); - - return (0); -} - -/* - * vpoio_wait() - * - * H_SELIN must be low. - * - * XXX should be ported to microseq - */ -static char -vpoio_wait(struct vpoio_data *vpo, int tmo) -{ - DECLARE_WAIT_MICROSEQUENCE; - - device_t ppbus = device_get_parent(vpo->vpo_dev); - int ret, err; - -#if 0 /* broken */ - if (ppb_poll_device(ppbus, 150, nBUSY, nBUSY, PPB_INTR)) - return (0); - - return (ppb_rstr(ppbus) & 0xf0); -#endif - - /* - * Return some status information. - * Semantics : 0xc0 = ZIP wants more data - * 0xd0 = ZIP wants to send more data - * 0xe0 = ZIP wants command - * 0xf0 = end of transfer, ZIP is sending status - */ - - ppb_MS_init_msq(wait_microseq, 2, - WAIT_RET, (void *)&ret, - WAIT_TMO, tmo); - - ppb_MS_microseq(ppbus, vpo->vpo_dev, wait_microseq, &err); - - if (err) - return (0); /* command timed out */ - - return(ret); -} - -/* - * vpoio_probe() - * - * Low level probe of vpo device - * - */ -int -vpoio_probe(device_t dev, struct vpoio_data *vpo) -{ - int error; - - /* ppbus dependent initialisation */ - vpo->vpo_dev = dev; - - /* - * Initialize microsequence code - */ - INIT_TRIG_MICROSEQ; - - /* now, try to initialise the drive */ - if ((error = vpoio_detect(vpo))) { - return (error); - } - - return (0); -} - -/* - * vpoio_attach() - * - * Low level attachment of vpo device - * - */ -int -vpoio_attach(struct vpoio_data *vpo) -{ - DECLARE_NIBBLE_INBYTE_SUBMICROSEQ; - device_t ppbus = device_get_parent(vpo->vpo_dev); - int error = 0; - - vpo->vpo_nibble_inbyte_msq = (struct ppb_microseq *)malloc( - sizeof(nibble_inbyte_submicroseq), M_DEVBUF, M_NOWAIT); - - if (!vpo->vpo_nibble_inbyte_msq) - return (ENXIO); - - bcopy((void *)nibble_inbyte_submicroseq, - (void *)vpo->vpo_nibble_inbyte_msq, - sizeof(nibble_inbyte_submicroseq)); - - ppb_MS_init_msq(vpo->vpo_nibble_inbyte_msq, 4, - INB_NIBBLE_H, (void *)&(vpo)->vpo_nibble.h, - INB_NIBBLE_L, (void *)&(vpo)->vpo_nibble.l, - INB_NIBBLE_F, nibble_inbyte_hook, - INB_NIBBLE_P, (void *)&(vpo)->vpo_nibble); - - /* - * Initialize mode dependent in/out microsequences - */ - ppb_lock(ppbus); - if ((error = ppb_request_bus(ppbus, vpo->vpo_dev, PPB_WAIT))) - goto error; - - /* ppbus sets automatically the last mode entered during detection */ - switch (vpo->vpo_mode_found) { - case VP0_MODE_EPP: - ppb_MS_GET_init(ppbus, vpo->vpo_dev, epp17_instr_body); - ppb_MS_PUT_init(ppbus, vpo->vpo_dev, epp17_outstr_body); - device_printf(vpo->vpo_dev, "EPP mode\n"); - break; - case VP0_MODE_PS2: - ppb_MS_GET_init(ppbus, vpo->vpo_dev, ps2_inbyte_submicroseq); - ppb_MS_PUT_init(ppbus, vpo->vpo_dev, spp_outbyte_submicroseq); - device_printf(vpo->vpo_dev, "PS2 mode\n"); - break; - case VP0_MODE_NIBBLE: - ppb_MS_GET_init(ppbus, vpo->vpo_dev, vpo->vpo_nibble_inbyte_msq); - ppb_MS_PUT_init(ppbus, vpo->vpo_dev, spp_outbyte_submicroseq); - device_printf(vpo->vpo_dev, "NIBBLE mode\n"); - break; - default: - panic("vpo: unknown mode %d", vpo->vpo_mode_found); - } - - ppb_release_bus(ppbus, vpo->vpo_dev); - -error: - ppb_unlock(ppbus); - return (error); -} - -/* - * vpoio_reset_bus() - * - */ -int -vpoio_reset_bus(struct vpoio_data *vpo) -{ - /* first, connect to the drive */ - if (vpoio_connect(vpo, PPB_WAIT|PPB_INTR) || !vpoio_in_disk_mode(vpo)) { - -#ifdef VP0_DEBUG - printf("%s: not in disk mode!\n", __func__); -#endif - /* release ppbus */ - vpoio_disconnect(vpo); - return (1); - } - - /* reset the SCSI bus */ - vpoio_reset(vpo); - - /* then disconnect */ - vpoio_disconnect(vpo); - - return (0); -} - -/* - * vpoio_do_scsi() - * - * Send an SCSI command - * - */ -int -vpoio_do_scsi(struct vpoio_data *vpo, int host, int target, char *command, - int clen, char *buffer, int blen, int *result, int *count, - int *ret) -{ - device_t ppbus = device_get_parent(vpo->vpo_dev); - char r; - char l, h = 0; - int len, error = 0; - int k; - - /* - * enter disk state, allocate the ppbus - * - * XXX - * Should we allow this call to be interruptible? - * The only way to report the interruption is to return - * EIO do upper SCSI code :^( - */ - if ((error = vpoio_connect(vpo, PPB_WAIT|PPB_INTR))) - return (error); - - if (!vpoio_in_disk_mode(vpo)) { - *ret = VP0_ECONNECT; - goto error; - } - - if ((*ret = vpoio_select(vpo,host,target))) - goto error; - - /* - * Send the command ... - * - * set H_SELIN low for vpoio_wait(). - */ - ppb_wctr(ppbus, H_AUTO | H_nSELIN | H_INIT | H_STROBE); - - for (k = 0; k < clen; k++) { - if (vpoio_wait(vpo, VP0_FAST_SPINTMO) != (char)0xe0) { - *ret = VP0_ECMD_TIMEOUT; - goto error; - } - if (vpoio_outstr(vpo, &command[k], 1)) { - *ret = VP0_EPPDATA_TIMEOUT; - goto error; - } - } - - /* - * Completion ... - */ - - *count = 0; - for (;;) { - - if (!(r = vpoio_wait(vpo, VP0_LOW_SPINTMO))) { - *ret = VP0_ESTATUS_TIMEOUT; - goto error; - } - - /* stop when the ZIP wants to send status */ - if (r == (char)0xf0) - break; - - if (*count >= blen) { - *ret = VP0_EDATA_OVERFLOW; - goto error; - } - - /* if in EPP mode or writing bytes, try to transfer a sector - * otherwise, just send one byte - */ - if (PPB_IN_EPP_MODE(ppbus) || r == (char)0xc0) - len = (((blen - *count) >= VP0_SECTOR_SIZE)) ? - VP0_SECTOR_SIZE : 1; - else - len = 1; - - /* ZIP wants to send data? */ - if (r == (char)0xc0) - error = vpoio_outstr(vpo, &buffer[*count], len); - else - error = vpoio_instr(vpo, &buffer[*count], len); - - if (error) { - *ret = error; - goto error; - } - - *count += len; - } - - if (vpoio_instr(vpo, &l, 1)) { - *ret = VP0_EOTHER; - goto error; - } - - /* check if the ZIP wants to send more status */ - if (vpoio_wait(vpo, VP0_FAST_SPINTMO) == (char)0xf0) - if (vpoio_instr(vpo, &h, 1)) { - *ret = VP0_EOTHER + 2; - goto error; - } - - *result = ((int) h << 8) | ((int) l & 0xff); - -error: - /* return to printer state, release the ppbus */ - vpoio_disconnect(vpo); - return (0); -} Index: head/sys/modules/Makefile =================================================================== --- head/sys/modules/Makefile +++ head/sys/modules/Makefile @@ -372,7 +372,6 @@ ${_vmd} \ ${_vmm} \ ${_vmware} \ - ${_vpo} \ vr \ vte \ ${_wbwd} \ @@ -558,7 +557,6 @@ ${MACHINE_CPUARCH} != "mips" && ${MACHINE_CPUARCH} != "powerpc" && \ ${MACHINE_CPUARCH} != "riscv" _syscons= syscons -_vpo= vpo .endif .if ${MACHINE_CPUARCH} != "mips" Index: head/sys/modules/vpo/Makefile =================================================================== --- head/sys/modules/vpo/Makefile +++ head/sys/modules/vpo/Makefile @@ -1,10 +0,0 @@ -# $FreeBSD$ - -.PATH: ${SRCTOP}/sys/dev/ppbus - -KMOD= vpo -SRCS= bus_if.h device_if.h ppbus_if.h \ - opt_cam.h opt_scsi.h opt_vpo.h \ - immio.c vpo.c vpoio.c - -.include