PageRenderTime 37ms CodeModel.GetById 7ms app.highlight 22ms RepoModel.GetById 1ms app.codeStats 0ms

/drivers/char/ftape/lowlevel/fc-10.c

https://bitbucket.org/evzijst/gittest
C | 175 lines | 80 code | 14 blank | 81 comment | 29 complexity | c78d105fb138b5b002cdd0b3c9a4c408 MD5 | raw file
  1/*
  2 *
  3
  4   Copyright (C) 1993,1994 Jon Tombs.
  5
  6   This program is distributed in the hope that it will be useful,
  7   but WITHOUT ANY WARRANTY; without even the implied warranty of
  8   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  9   GNU General Public License for more details.
 10
 11   The entire guts of this program was written by dosemu, modified to
 12   record reads and writes to the ports in the 0x180-0x188 address space,
 13   while running the CMS program TAPE.EXE V2.0.5 supplied with the drive.
 14
 15   Modified to use an array of addresses and generally cleaned up (made
 16   much shorter) 4 June 94, dosemu isn't that good at writing short code it
 17   would seem :-). Made independent of 0x180, but I doubt it will work
 18   at any other address.
 19
 20   Modified for distribution with ftape source. 21 June 94, SJL.
 21
 22   Modifications on 20 October 95, by Daniel Cohen (catman@wpi.edu):
 23   Modified to support different DMA, IRQ, and IO Ports.  Borland's
 24   Turbo Debugger in virtual 8086 mode (TD386.EXE with hardware breakpoints
 25   provided by the TDH386.SYS Device Driver) was used on the CMS program
 26   TAPE V4.0.5.  I set breakpoints on I/O to ports 0x180-0x187.  Note that
 27   CMS's program will not successfully configure the tape drive if you set
 28   breakpoints on IO Reads, but you can set them on IO Writes without problems.
 29   Known problems:
 30   - You can not use DMA Channels 5 or 7.
 31
 32   Modification on 29 January 96, by Daniel Cohen (catman@wpi.edu):
 33   Modified to only accept IRQs 3 - 7, or 9.  Since we can only send a 3 bit
 34   number representing the IRQ to the card, special handling is required when
 35   IRQ 9 is selected.  IRQ 2 and 9 are the same, and we should request IRQ 9
 36   from the kernel while telling the card to use IRQ 2.  Thanks to Greg
 37   Crider (gcrider@iclnet.org) for finding and locating this bug, as well as
 38   testing the patch.
 39
 40   Modification on 11 December 96, by Claus Heine (claus@momo.math.rwth-aachen.de):
 41   Modified a little to use variahle ft_fdc_base, ft_fdc_irq, ft_fdc_dma 
 42   instead of preprocessor symbols. Thus we can compile this into the module
 43   or kernel and let the user specify the options as command line arguments.
 44
 45 *
 46 * $Source: /homes/cvs/ftape-stacked/ftape/lowlevel/fc-10.c,v $
 47 * $Revision: 1.2 $
 48 * $Date: 1997/10/05 19:18:04 $
 49 *
 50 *      This file contains code for the CMS FC-10/FC-20 card.
 51 */
 52
 53#include <asm/io.h>
 54#include <linux/ftape.h>
 55#include "../lowlevel/ftape-tracing.h"
 56#include "../lowlevel/fdc-io.h"
 57#include "../lowlevel/fc-10.h"
 58
 59static __u16 inbs_magic[] = {
 60	0x3, 0x3, 0x0, 0x4, 0x7, 0x2, 0x5, 0x3, 0x1, 0x4,
 61	0x3, 0x5, 0x2, 0x0, 0x3, 0x7, 0x4, 0x2,
 62	0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7
 63};
 64
 65static __u16 fc10_ports[] = {
 66	0x180, 0x210, 0x2A0, 0x300, 0x330, 0x340, 0x370
 67};
 68
 69int fc10_enable(void)
 70{
 71	int i;
 72	__u8 cardConfig = 0x00;
 73	__u8 x;
 74	TRACE_FUN(ft_t_flow);
 75
 76/*  This code will only work if the FC-10 (or FC-20) is set to
 77 *  use DMA channels 1, 2, or 3.  DMA channels 5 and 7 seem to be 
 78 *  initialized by the same command as channels 1 and 3, respectively.
 79 */
 80	if (ft_fdc_dma > 3) {
 81		TRACE_ABORT(0, ft_t_err,
 82"Error: The FC-10/20 must be set to use DMA channels 1, 2, or 3!");
 83	}
 84/*  Only allow the FC-10/20 to use IRQ 3-7, or 9.  Note that CMS's program
 85 *  only accepts IRQ's 2-7, but in linux, IRQ 2 is the same as IRQ 9.
 86 */
 87	if (ft_fdc_irq < 3 || ft_fdc_irq == 8 || ft_fdc_irq > 9) {
 88		TRACE_ABORT(0, ft_t_err, 
 89"Error: The FC-10/20 must be set to use IRQ levels 3 - 7, or 9!\n"
 90KERN_INFO "Note: IRQ 9 is the same as IRQ 2");
 91	}
 92	/*  Clear state machine ???
 93	 */
 94	for (i = 0; i < NR_ITEMS(inbs_magic); i++) {
 95		inb(ft_fdc_base + inbs_magic[i]);
 96	}
 97	outb(0x0, ft_fdc_base);
 98
 99	x = inb(ft_fdc_base);
100	if (x == 0x13 || x == 0x93) {
101		for (i = 1; i < 8; i++) {
102			if (inb(ft_fdc_base + i) != x) {
103				TRACE_EXIT 0;
104			}
105		}
106	} else {
107		TRACE_EXIT 0;
108	}
109
110	outb(0x8, ft_fdc_base);
111
112	for (i = 0; i < 8; i++) {
113		if (inb(ft_fdc_base + i) != 0x0) {
114			TRACE_EXIT 0;
115		}
116	}
117	outb(0x10, ft_fdc_base);
118
119	for (i = 0; i < 8; i++) {
120		if (inb(ft_fdc_base + i) != 0xff) {
121			TRACE_EXIT 0;
122		}
123	}
124
125	/*  Okay, we found a FC-10 card ! ???
126	 */
127	outb(0x0, fdc.ccr);
128
129	/*  Clear state machine again ???
130	 */
131	for (i = 0; i < NR_ITEMS(inbs_magic); i++) {
132		inb(ft_fdc_base + inbs_magic[i]);
133	}
134	/* Send io port */
135	for (i = 0; i < NR_ITEMS(fc10_ports); i++)
136		if (ft_fdc_base == fc10_ports[i])
137			cardConfig = i + 1;
138	if (cardConfig == 0) {
139		TRACE_EXIT 0;	/* Invalid I/O Port */
140	}
141	/* and IRQ - If using IRQ 9, tell the FC card it is actually IRQ 2 */
142	if (ft_fdc_irq != 9)
143		cardConfig |= ft_fdc_irq << 3;
144	else
145		cardConfig |= 2 << 3;
146
147	/* and finally DMA Channel */
148	cardConfig |= ft_fdc_dma << 6;
149	outb(cardConfig, ft_fdc_base);	/* DMA [2 bits]/IRQ [3 bits]/BASE [3 bits] */
150
151	/*  Enable FC-10 ???
152	 */
153	outb(0, fdc.ccr);
154	outb(0, fdc.dor2);
155	outb(FDC_DMA_MODE /* 8 */, fdc.dor);
156	outb(FDC_DMA_MODE /* 8 */, fdc.dor);
157	outb(1, fdc.dor2);
158
159	/*************************************
160	 *
161	 * cH: why the hell should this be necessary? This is done 
162	 *     by fdc_reset()!!!
163	 *
164	 *************************************/
165	/*  Initialize fdc, select drive B:
166	 */
167	outb(FDC_DMA_MODE, fdc.dor);	/* assert reset, dma & irq enabled */
168	/*       0x08    */
169	outb(FDC_DMA_MODE|FDC_RESET_NOT, fdc.dor);	/* release reset */
170	/*       0x08    |   0x04   = 0x0c */
171	outb(FDC_DMA_MODE|FDC_RESET_NOT|FDC_MOTOR_1|FTAPE_SEL_B, fdc.dor);
172	/*       0x08    |   0x04      |  0x20     |  0x01  = 0x2d */    
173	/* select drive 1 */ /* why not drive 0 ???? */
174	TRACE_EXIT (x == 0x93) ? 2 : 1;
175}