Blame view

drivers/tty/isicom.c 41.3 KB
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1
2
3
4
5
6
7
8
9
  /*
   *	This program is free software; you can redistribute it and/or
   *	modify it under the terms of the GNU General Public License
   *	as published by the Free Software Foundation; either version
   *	2 of the License, or (at your option) any later version.
   *
   *	Original driver code supplied by Multi-Tech
   *
   *	Changes
8eb04cf34   Alan Cox   tty: trivial - fi...
10
11
   *	1/9/98	alan@lxorguk.ukuu.org.uk
   *					Merge to 2.0.x kernel tree
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
12
13
14
15
   *					Obtain and use official major/minors
   *					Loader switched to a misc device
   *					(fixed range check bug as a side effect)
   *					Printk clean up
8eb04cf34   Alan Cox   tty: trivial - fi...
16
17
   *	9/12/98	alan@lxorguk.ukuu.org.uk
   *					Rough port to 2.1.x
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
18
19
20
21
22
23
24
   *
   *	10/6/99 sameer			Merged the ISA and PCI drivers to
   *					a new unified driver.
   *
   *	3/9/99	sameer			Added support for ISI4616 cards.
   *
   *	16/9/99	sameer			We do not force RTS low anymore.
d8d16e474   Jiri Slaby   [PATCH] char/isic...
25
   *					This is to prevent the firmware
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
26
27
28
29
30
31
32
33
34
35
   *					from getting confused.
   *
   *	26/10/99 sameer			Cosmetic changes:The driver now
   *					dumps the Port Count information
   *					along with I/O address and IRQ.
   *
   *	13/12/99 sameer			Fixed the problem with IRQ sharing.
   *
   *	10/5/00  sameer			Fixed isicom_shutdown_board()
   *					to not lower DTR on all the ports
d8d16e474   Jiri Slaby   [PATCH] char/isic...
36
   *					when the last port on the card is
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
37
38
39
   *					closed.
   *
   *	10/5/00  sameer			Signal mask setup command added
d8d16e474   Jiri Slaby   [PATCH] char/isic...
40
   *					to  isicom_setup_port and
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
41
42
43
   *					isicom_shutdown_port.
   *
   *	24/5/00  sameer			The driver is now SMP aware.
d8d16e474   Jiri Slaby   [PATCH] char/isic...
44
45
   *
   *
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
46
   *	27/11/00 Vinayak P Risbud	Fixed the Driver Crash Problem
d8d16e474   Jiri Slaby   [PATCH] char/isic...
47
48
   *
   *
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
49
50
51
52
53
54
   *	03/01/01  anil .s		Added support for resetting the
   *					internal modems on ISI cards.
   *
   *	08/02/01  anil .s		Upgraded the driver for kernel
   *					2.4.x
   *
d8d16e474   Jiri Slaby   [PATCH] char/isic...
55
   *	11/04/01  Kevin			Fixed firmware load problem with
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
56
   *					ISIHP-4X card
d8d16e474   Jiri Slaby   [PATCH] char/isic...
57
   *
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
58
59
60
61
62
63
64
65
66
   *	30/04/01  anil .s		Fixed the remote login through
   *					ISI port problem. Now the link
   *					does not go down before password
   *					prompt.
   *
   *	03/05/01  anil .s		Fixed the problem with IRQ sharing
   *					among ISI-PCI cards.
   *
   *	03/05/01  anil .s		Added support to display the version
d8d16e474   Jiri Slaby   [PATCH] char/isic...
67
   *					info during insmod as well as module
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
68
   *					listing by lsmod.
d8d16e474   Jiri Slaby   [PATCH] char/isic...
69
   *
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
70
71
72
73
74
75
76
77
   *	10/05/01  anil .s		Done the modifications to the source
   *					file and Install script so that the
   *					same installation can be used for
   *					2.2.x and 2.4.x kernel.
   *
   *	06/06/01  anil .s		Now we drop both dtr and rts during
   *					shutdown_port as well as raise them
   *					during isicom_config_port.
d8d16e474   Jiri Slaby   [PATCH] char/isic...
78
   *
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
79
80
81
82
83
   *	09/06/01 acme@conectiva.com.br	use capable, not suser, do
   *					restore_flags on failure in
   *					isicom_send_break, verify put_user
   *					result
   *
d8d16e474   Jiri Slaby   [PATCH] char/isic...
84
85
86
87
88
89
90
   *	11/02/03  ranjeeth		Added support for 230 Kbps and 460 Kbps
   *					Baud index extended to 21
   *
   *	20/03/03  ranjeeth		Made to work for Linux Advanced server.
   *					Taken care of license warning.
   *
   *	10/12/03  Ravindra		Made to work for Fedora Core 1 of
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
91
92
93
94
95
96
97
   *					Red Hat Distribution
   *
   *	06/01/05  Alan Cox 		Merged the ISI and base kernel strands
   *					into a single 2.6 driver
   *
   *	***********************************************************
   *
d8d16e474   Jiri Slaby   [PATCH] char/isic...
98
   *	To use this driver you also need the support package. You
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
99
100
   *	can find this in RPM format on
   *		ftp://ftp.linux.org.uk/pub/linux/alan
d8d16e474   Jiri Slaby   [PATCH] char/isic...
101
   *
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
102
103
104
   *	You can find the original tools for this direct from Multitech
   *		ftp://ftp.multitech.com/ISI-Cards/
   *
970e24864   Lucas De Marchi   Documentation: re...
105
   *	Having installed the cards the module options (/etc/modprobe.d/)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
106
107
108
109
110
111
   *
   *	options isicom   io=card1,card2,card3,card4 irq=card1,card2,card3,card4
   *
   *	Omit those entries for boards you don't have installed.
   *
   *	TODO
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
112
113
114
   *		Merge testing
   *		64-bit verification
   */
db91340b2   Joe Perches   serial: isicom.c:...
115
  #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
116
  #include <linux/module.h>
e65c1db19   Jiri Slaby   [PATCH] char/isic...
117
  #include <linux/firmware.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
118
119
  #include <linux/kernel.h>
  #include <linux/tty.h>
33f0f88f1   Alan Cox   [PATCH] TTY layer...
120
  #include <linux/tty_flip.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
121
122
123
124
125
  #include <linux/termios.h>
  #include <linux/fs.h>
  #include <linux/sched.h>
  #include <linux/serial.h>
  #include <linux/mm.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
126
127
128
129
  #include <linux/interrupt.h>
  #include <linux/timer.h>
  #include <linux/delay.h>
  #include <linux/ioport.h>
5a0e3ad6a   Tejun Heo   include cleanup: ...
130
  #include <linux/slab.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
131

251b8dd7e   Alan Cox   isicom: bring int...
132
133
  #include <linux/uaccess.h>
  #include <linux/io.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
134
135
136
137
  
  #include <linux/pci.h>
  
  #include <linux/isicom.h>
aaa246ea7   Jiri Slaby   [PATCH] char/isic...
138
139
140
141
  #define InterruptTheCard(base) outw(0, (base) + 0xc)
  #define ClearInterrupt(base) inw((base) + 0x0a)
  
  #ifdef DEBUG
aaa246ea7   Jiri Slaby   [PATCH] char/isic...
142
143
  #define isicom_paranoia_check(a, b, c) __isicom_paranoia_check((a), (b), (c))
  #else
aaa246ea7   Jiri Slaby   [PATCH] char/isic...
144
145
  #define isicom_paranoia_check(a, b, c) 0
  #endif
9ac0948b2   Jiri Slaby   [PATCH] char/isic...
146
  static int isicom_probe(struct pci_dev *, const struct pci_device_id *);
ae8d8a146   Bill Pemberton   tty: remove use o...
147
  static void isicom_remove(struct pci_dev *);
9ac0948b2   Jiri Slaby   [PATCH] char/isic...
148

763653d7d   Arvind Yadav   tty: isicom: cons...
149
  static const struct pci_device_id isicom_pci_tbl[] = {
9ac0948b2   Jiri Slaby   [PATCH] char/isic...
150
151
152
153
154
155
156
157
158
  	{ PCI_DEVICE(VENDOR_ID, 0x2028) },
  	{ PCI_DEVICE(VENDOR_ID, 0x2051) },
  	{ PCI_DEVICE(VENDOR_ID, 0x2052) },
  	{ PCI_DEVICE(VENDOR_ID, 0x2053) },
  	{ PCI_DEVICE(VENDOR_ID, 0x2054) },
  	{ PCI_DEVICE(VENDOR_ID, 0x2055) },
  	{ PCI_DEVICE(VENDOR_ID, 0x2056) },
  	{ PCI_DEVICE(VENDOR_ID, 0x2057) },
  	{ PCI_DEVICE(VENDOR_ID, 0x2058) },
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
159
160
161
  	{ 0 }
  };
  MODULE_DEVICE_TABLE(pci, isicom_pci_tbl);
9ac0948b2   Jiri Slaby   [PATCH] char/isic...
162
163
164
165
  static struct pci_driver isicom_driver = {
  	.name		= "isicom",
  	.id_table	= isicom_pci_tbl,
  	.probe		= isicom_probe,
91116cba5   Bill Pemberton   tty: remove use o...
166
  	.remove		= isicom_remove
9ac0948b2   Jiri Slaby   [PATCH] char/isic...
167
  };
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
168
169
  static int prev_card = 3;	/*	start servicing isi_card[0]	*/
  static struct tty_driver *isicom_normal;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
170
  static void isicom_tx(unsigned long _data);
d8d16e474   Jiri Slaby   [PATCH] char/isic...
171
  static void isicom_start(struct tty_struct *tty);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
172

34b55b865   Jiri Slaby   [PATCH] Char: isi...
173
  static DEFINE_TIMER(tx, isicom_tx, 0, 0);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
174
175
176
  /*   baud index mappings from linux defns to isi */
  
  static signed char linuxb_to_isib[] = {
7edc136ab   Jiri Slaby   [PATCH] Char: isi...
177
  	-1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 13, 15, 16, 17, 18, 19, 20, 21
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
178
179
180
  };
  
  struct	isi_board {
8070e35c6   Jiri Slaby   [PATCH] char/isic...
181
  	unsigned long		base;
4969b3a43   Jiri Slaby   Char: isicom, pro...
182
  	int			irq;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
183
184
  	unsigned char		port_count;
  	unsigned short		status;
a547dfe95   Jiri Slaby   [PATCH] char/isic...
185
  	unsigned short		port_status; /* each bit for each port */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
186
  	unsigned short		shift_count;
251b8dd7e   Alan Cox   isicom: bring int...
187
  	struct isi_port		*ports;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
188
  	signed char		count;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
189
190
  	spinlock_t		card_lock; /* Card wide lock 11/5/00 -sameer */
  	unsigned long		flags;
938a7023b   Jiri Slaby   [PATCH] Char: isi...
191
  	unsigned int		index;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
192
193
194
195
  };
  
  struct	isi_port {
  	unsigned short		magic;
f1d03228e   Alan Cox   isicom: use tty_port
196
  	struct tty_port		port;
8070e35c6   Jiri Slaby   [PATCH] char/isic...
197
198
  	u16			channel;
  	u16			status;
251b8dd7e   Alan Cox   isicom: bring int...
199
  	struct isi_board	*card;
251b8dd7e   Alan Cox   isicom: bring int...
200
  	unsigned char		*xmit_buf;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
201
202
203
204
205
206
207
208
209
210
211
212
213
  	int			xmit_head;
  	int			xmit_tail;
  	int			xmit_cnt;
  };
  
  static struct isi_board isi_card[BOARD_COUNT];
  static struct isi_port  isi_ports[PORT_COUNT];
  
  /*
   *	Locking functions for card level locking. We need to own both
   *	the kernel lock for the card and have the card in a position that
   *	it wants to talk.
   */
d8d16e474   Jiri Slaby   [PATCH] char/isic...
214

810e20e70   Denys Vlasenko   isicom: Deinline ...
215
  static int WaitTillCardIsFree(unsigned long base)
cfe7c09ac   Jiri Slaby   [PATCH] Char: isi...
216
217
218
219
220
221
222
223
224
225
226
227
  {
  	unsigned int count = 0;
  	unsigned int a = in_atomic(); /* do we run under spinlock? */
  
  	while (!(inw(base + 0xe) & 0x1) && count++ < 100)
  		if (a)
  			mdelay(1);
  		else
  			msleep(1);
  
  	return !(inw(base + 0xe) & 0x1);
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
228
229
  static int lock_card(struct isi_board *card)
  {
8070e35c6   Jiri Slaby   [PATCH] char/isic...
230
  	unsigned long base = card->base;
5b21f9ddd   Jiri Slaby   Char: isicom, cle...
231
  	unsigned int retries, a;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
232

5b21f9ddd   Jiri Slaby   Char: isicom, cle...
233
  	for (retries = 0; retries < 10; retries++) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
234
  		spin_lock_irqsave(&card->card_lock, card->flags);
5b21f9ddd   Jiri Slaby   Char: isicom, cle...
235
236
237
238
  		for (a = 0; a < 10; a++) {
  			if (inw(base + 0xe) & 0x1)
  				return 1;
  			udelay(10);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
239
  		}
5b21f9ddd   Jiri Slaby   Char: isicom, cle...
240
241
  		spin_unlock_irqrestore(&card->card_lock, card->flags);
  		msleep(10);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
242
  	}
e620e5488   Joe Perches   tty: pr_warning->...
243
244
  	pr_warn("Failed to lock Card (0x%lx)
  ", card->base);
a547dfe95   Jiri Slaby   [PATCH] char/isic...
245

0418726bb   Adrian Bunk   typo fixes: aquir...
246
  	return 0;	/* Failed to acquire the card! */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
247
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
248
249
250
251
252
253
254
255
  static void unlock_card(struct isi_board *card)
  {
  	spin_unlock_irqrestore(&card->card_lock, card->flags);
  }
  
  /*
   *  ISI Card specific ops ...
   */
d8d16e474   Jiri Slaby   [PATCH] char/isic...
256

cfe7c09ac   Jiri Slaby   [PATCH] Char: isi...
257
  /* card->lock HAS to be held */
d8d16e474   Jiri Slaby   [PATCH] char/isic...
258
  static void raise_dtr(struct isi_port *port)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
259
  {
d8d16e474   Jiri Slaby   [PATCH] char/isic...
260
  	struct isi_board *card = port->card;
8070e35c6   Jiri Slaby   [PATCH] char/isic...
261
262
  	unsigned long base = card->base;
  	u16 channel = port->channel;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
263

cfe7c09ac   Jiri Slaby   [PATCH] Char: isi...
264
  	if (WaitTillCardIsFree(base))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
265
  		return;
d8d16e474   Jiri Slaby   [PATCH] char/isic...
266
  	outw(0x8000 | (channel << card->shift_count) | 0x02, base);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
267
268
269
  	outw(0x0504, base);
  	InterruptTheCard(base);
  	port->status |= ISI_DTR;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
270
  }
cfe7c09ac   Jiri Slaby   [PATCH] Char: isi...
271
  /* card->lock HAS to be held */
9428d712d   Denys Vlasenko   isicom: Deinline ...
272
  static void drop_dtr(struct isi_port *port)
d8d16e474   Jiri Slaby   [PATCH] char/isic...
273
274
  {
  	struct isi_board *card = port->card;
8070e35c6   Jiri Slaby   [PATCH] char/isic...
275
276
  	unsigned long base = card->base;
  	u16 channel = port->channel;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
277

cfe7c09ac   Jiri Slaby   [PATCH] Char: isi...
278
  	if (WaitTillCardIsFree(base))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
279
  		return;
d8d16e474   Jiri Slaby   [PATCH] char/isic...
280
  	outw(0x8000 | (channel << card->shift_count) | 0x02, base);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
281
  	outw(0x0404, base);
d8d16e474   Jiri Slaby   [PATCH] char/isic...
282
  	InterruptTheCard(base);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
283
  	port->status &= ~ISI_DTR;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
284
  }
cfe7c09ac   Jiri Slaby   [PATCH] Char: isi...
285
  /* card->lock HAS to be held */
d8d16e474   Jiri Slaby   [PATCH] char/isic...
286
  static inline void raise_rts(struct isi_port *port)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
287
  {
d8d16e474   Jiri Slaby   [PATCH] char/isic...
288
  	struct isi_board *card = port->card;
8070e35c6   Jiri Slaby   [PATCH] char/isic...
289
290
  	unsigned long base = card->base;
  	u16 channel = port->channel;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
291

cfe7c09ac   Jiri Slaby   [PATCH] Char: isi...
292
  	if (WaitTillCardIsFree(base))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
293
  		return;
d8d16e474   Jiri Slaby   [PATCH] char/isic...
294
  	outw(0x8000 | (channel << card->shift_count) | 0x02, base);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
295
  	outw(0x0a04, base);
d8d16e474   Jiri Slaby   [PATCH] char/isic...
296
  	InterruptTheCard(base);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
297
  	port->status |= ISI_RTS;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
298
  }
cfe7c09ac   Jiri Slaby   [PATCH] Char: isi...
299
300
  
  /* card->lock HAS to be held */
d8d16e474   Jiri Slaby   [PATCH] char/isic...
301
  static inline void drop_rts(struct isi_port *port)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
302
  {
d8d16e474   Jiri Slaby   [PATCH] char/isic...
303
  	struct isi_board *card = port->card;
8070e35c6   Jiri Slaby   [PATCH] char/isic...
304
305
  	unsigned long base = card->base;
  	u16 channel = port->channel;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
306

cfe7c09ac   Jiri Slaby   [PATCH] Char: isi...
307
  	if (WaitTillCardIsFree(base))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
308
  		return;
d8d16e474   Jiri Slaby   [PATCH] char/isic...
309
  	outw(0x8000 | (channel << card->shift_count) | 0x02, base);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
310
  	outw(0x0804, base);
d8d16e474   Jiri Slaby   [PATCH] char/isic...
311
  	InterruptTheCard(base);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
312
  	port->status &= ~ISI_RTS;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
313
  }
cfe7c09ac   Jiri Slaby   [PATCH] Char: isi...
314
  /* card->lock MUST NOT be held */
5d951fb45   Alan Cox   tty: Pull the dtr...
315

fcc8ac182   Alan Cox   tty: Add carrier ...
316
  static void isicom_dtr_rts(struct tty_port *port, int on)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
317
  {
5d951fb45   Alan Cox   tty: Pull the dtr...
318
319
  	struct isi_port *ip = container_of(port, struct isi_port, port);
  	struct isi_board *card = ip->card;
8070e35c6   Jiri Slaby   [PATCH] char/isic...
320
  	unsigned long base = card->base;
5d951fb45   Alan Cox   tty: Pull the dtr...
321
  	u16 channel = ip->channel;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
322
323
324
  
  	if (!lock_card(card))
  		return;
fcc8ac182   Alan Cox   tty: Add carrier ...
325
326
327
328
329
330
331
332
333
334
335
  	if (on) {
  		outw(0x8000 | (channel << card->shift_count) | 0x02, base);
  		outw(0x0f04, base);
  		InterruptTheCard(base);
  		ip->status |= (ISI_DTR | ISI_RTS);
  	} else {
  		outw(0x8000 | (channel << card->shift_count) | 0x02, base);
  		outw(0x0C04, base);
  		InterruptTheCard(base);
  		ip->status &= ~(ISI_DTR | ISI_RTS);
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
336
337
  	unlock_card(card);
  }
cfe7c09ac   Jiri Slaby   [PATCH] Char: isi...
338
  /* card->lock HAS to be held */
d8d16e474   Jiri Slaby   [PATCH] char/isic...
339
  static void drop_dtr_rts(struct isi_port *port)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
340
  {
d8d16e474   Jiri Slaby   [PATCH] char/isic...
341
  	struct isi_board *card = port->card;
8070e35c6   Jiri Slaby   [PATCH] char/isic...
342
343
  	unsigned long base = card->base;
  	u16 channel = port->channel;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
344

cfe7c09ac   Jiri Slaby   [PATCH] Char: isi...
345
  	if (WaitTillCardIsFree(base))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
346
  		return;
d8d16e474   Jiri Slaby   [PATCH] char/isic...
347
  	outw(0x8000 | (channel << card->shift_count) | 0x02, base);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
348
  	outw(0x0c04, base);
d8d16e474   Jiri Slaby   [PATCH] char/isic...
349
  	InterruptTheCard(base);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
350
  	port->status &= ~(ISI_RTS | ISI_DTR);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
351
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
352
353
354
355
  /*
   *	ISICOM Driver specific routines ...
   *
   */
d8d16e474   Jiri Slaby   [PATCH] char/isic...
356

aaa246ea7   Jiri Slaby   [PATCH] char/isic...
357
358
  static inline int __isicom_paranoia_check(struct isi_port const *port,
  	char *name, const char *routine)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
359
  {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
360
  	if (!port) {
e620e5488   Joe Perches   tty: pr_warning->...
361
362
363
  		pr_warn("Warning: bad isicom magic for dev %s in %s
  ",
  			name, routine);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
364
365
366
  		return 1;
  	}
  	if (port->magic != ISICOM_MAGIC) {
e620e5488   Joe Perches   tty: pr_warning->...
367
368
369
  		pr_warn("Warning: NULL isicom port for dev %s in %s
  ",
  			name, routine);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
370
  		return 1;
d8d16e474   Jiri Slaby   [PATCH] char/isic...
371
  	}
aaa246ea7   Jiri Slaby   [PATCH] char/isic...
372

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
373
374
  	return 0;
  }
d8d16e474   Jiri Slaby   [PATCH] char/isic...
375

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
376
  /*
d8d16e474   Jiri Slaby   [PATCH] char/isic...
377
   *	Transmitter.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
378
379
380
381
382
383
384
   *
   *	We shovel data into the card buffers on a regular basis. The card
   *	will do the rest of the work for us.
   */
  
  static void isicom_tx(unsigned long _data)
  {
4969b3a43   Jiri Slaby   Char: isicom, pro...
385
  	unsigned long flags, base;
5b21f9ddd   Jiri Slaby   Char: isicom, cle...
386
  	unsigned int retries;
4969b3a43   Jiri Slaby   Char: isicom, pro...
387
  	short count = (BOARD_COUNT-1), card;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
388
  	short txcount, wrd, residue, word_count, cnt;
d8d16e474   Jiri Slaby   [PATCH] char/isic...
389
390
  	struct isi_port *port;
  	struct tty_struct *tty;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
391
392
  	/*	find next active board	*/
  	card = (prev_card + 1) & 0x0003;
251b8dd7e   Alan Cox   isicom: bring int...
393
  	while (count-- > 0) {
d8d16e474   Jiri Slaby   [PATCH] char/isic...
394
  		if (isi_card[card].status & BOARD_ACTIVE)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
395
  			break;
d8d16e474   Jiri Slaby   [PATCH] char/isic...
396
  		card = (card + 1) & 0x0003;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
397
398
399
  	}
  	if (!(isi_card[card].status & BOARD_ACTIVE))
  		goto sched_again;
d8d16e474   Jiri Slaby   [PATCH] char/isic...
400

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
401
  	prev_card = card;
d8d16e474   Jiri Slaby   [PATCH] char/isic...
402

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
403
404
405
  	count = isi_card[card].port_count;
  	port = isi_card[card].ports;
  	base = isi_card[card].base;
5b21f9ddd   Jiri Slaby   Char: isicom, cle...
406
407
408
409
410
411
412
413
414
  
  	spin_lock_irqsave(&isi_card[card].card_lock, flags);
  	for (retries = 0; retries < 100; retries++) {
  		if (inw(base + 0xe) & 0x1)
  			break;
  		udelay(2);
  	}
  	if (retries >= 100)
  		goto unlock;
d450b5a01   Alan Cox   tty: kref usage f...
415
416
417
  	tty = tty_port_tty_get(&port->port);
  	if (tty == NULL)
  		goto put_unlock;
251b8dd7e   Alan Cox   isicom: bring int...
418
  	for (; count > 0; count--, port++) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
419
  		/* port not active or tx disabled to force flow control */
d41861ca1   Peter Hurley   tty: Replace ASYN...
420
421
  		if (!tty_port_initialized(&port->port) ||
  			!(port->status & ISI_TXOK))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
422
  			continue;
d8d16e474   Jiri Slaby   [PATCH] char/isic...
423

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
424
  		txcount = min_t(short, TX_SIZE, port->xmit_cnt);
5b21f9ddd   Jiri Slaby   Char: isicom, cle...
425
  		if (txcount <= 0 || tty->stopped || tty->hw_stopped)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
426
  			continue;
5b21f9ddd   Jiri Slaby   Char: isicom, cle...
427
428
  
  		if (!(inw(base + 0x02) & (1 << port->channel)))
d8d16e474   Jiri Slaby   [PATCH] char/isic...
429
  			continue;
5b21f9ddd   Jiri Slaby   Char: isicom, cle...
430

db91340b2   Joe Perches   serial: isicom.c:...
431
432
433
  		pr_debug("txing %d bytes, port%d.
  ",
  			 txcount, port->channel + 1);
aaa246ea7   Jiri Slaby   [PATCH] char/isic...
434
435
  		outw((port->channel << isi_card[card].shift_count) | txcount,
  			base);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
436
  		residue = NO;
d8d16e474   Jiri Slaby   [PATCH] char/isic...
437
  		wrd = 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
438
  		while (1) {
a547dfe95   Jiri Slaby   [PATCH] char/isic...
439
440
  			cnt = min_t(int, txcount, (SERIAL_XMIT_SIZE
  					- port->xmit_tail));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
441
442
443
  			if (residue == YES) {
  				residue = NO;
  				if (cnt > 0) {
f1d03228e   Alan Cox   isicom: use tty_port
444
  					wrd |= (port->port.xmit_buf[port->xmit_tail]
a547dfe95   Jiri Slaby   [PATCH] char/isic...
445
446
447
  									<< 8);
  					port->xmit_tail = (port->xmit_tail + 1)
  						& (SERIAL_XMIT_SIZE - 1);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
448
449
450
  					port->xmit_cnt--;
  					txcount--;
  					cnt--;
d8d16e474   Jiri Slaby   [PATCH] char/isic...
451
  					outw(wrd, base);
a547dfe95   Jiri Slaby   [PATCH] char/isic...
452
  				} else {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
453
454
455
  					outw(wrd, base);
  					break;
  				}
d8d16e474   Jiri Slaby   [PATCH] char/isic...
456
  			}
251b8dd7e   Alan Cox   isicom: bring int...
457
458
  			if (cnt <= 0)
  				break;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
459
  			word_count = cnt >> 1;
f1d03228e   Alan Cox   isicom: use tty_port
460
  			outsw(base, port->port.xmit_buf+port->xmit_tail, word_count);
a547dfe95   Jiri Slaby   [PATCH] char/isic...
461
462
  			port->xmit_tail = (port->xmit_tail
  				+ (word_count << 1)) & (SERIAL_XMIT_SIZE - 1);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
463
464
465
466
  			txcount -= (word_count << 1);
  			port->xmit_cnt -= (word_count << 1);
  			if (cnt & 0x0001) {
  				residue = YES;
f1d03228e   Alan Cox   isicom: use tty_port
467
  				wrd = port->port.xmit_buf[port->xmit_tail];
a547dfe95   Jiri Slaby   [PATCH] char/isic...
468
469
  				port->xmit_tail = (port->xmit_tail + 1)
  					& (SERIAL_XMIT_SIZE - 1);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
470
471
472
473
474
475
476
477
478
  				port->xmit_cnt--;
  				txcount--;
  			}
  		}
  
  		InterruptTheCard(base);
  		if (port->xmit_cnt <= 0)
  			port->status &= ~ISI_TXOK;
  		if (port->xmit_cnt <= WAKEUP_CHARS)
0aa5de859   Jiri Slaby   [PATCH] Char: isi...
479
  			tty_wakeup(tty);
d8d16e474   Jiri Slaby   [PATCH] char/isic...
480
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
481

d450b5a01   Alan Cox   tty: kref usage f...
482
483
  put_unlock:
  	tty_kref_put(tty);
5b21f9ddd   Jiri Slaby   Char: isicom, cle...
484
485
  unlock:
  	spin_unlock_irqrestore(&isi_card[card].card_lock, flags);
d8d16e474   Jiri Slaby   [PATCH] char/isic...
486
487
  	/*	schedule another tx for hopefully in about 10ms	*/
  sched_again:
34b55b865   Jiri Slaby   [PATCH] Char: isi...
488
  	mod_timer(&tx, jiffies + msecs_to_jiffies(10));
d8d16e474   Jiri Slaby   [PATCH] char/isic...
489
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
490
  /*
d8d16e474   Jiri Slaby   [PATCH] char/isic...
491
   *	Main interrupt handler routine
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
492
   */
d8d16e474   Jiri Slaby   [PATCH] char/isic...
493

7d12e780e   David Howells   IRQ: Maintain reg...
494
  static irqreturn_t isicom_interrupt(int irq, void *dev_id)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
495
  {
8070e35c6   Jiri Slaby   [PATCH] char/isic...
496
  	struct isi_board *card = dev_id;
d8d16e474   Jiri Slaby   [PATCH] char/isic...
497
498
  	struct isi_port *port;
  	struct tty_struct *tty;
8070e35c6   Jiri Slaby   [PATCH] char/isic...
499
500
  	unsigned long base;
  	u16 header, word_count, count, channel;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
501
  	short byte_count;
33f0f88f1   Alan Cox   [PATCH] TTY layer...
502
  	unsigned char *rp;
d8d16e474   Jiri Slaby   [PATCH] char/isic...
503

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
504
505
  	if (!card || !(card->status & FIRMWARE_LOADED))
  		return IRQ_NONE;
d8d16e474   Jiri Slaby   [PATCH] char/isic...
506

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
507
  	base = card->base;
cb4a10ccb   Jiri Slaby   [PATCH] Char: isi...
508
509
510
511
  
  	/* did the card interrupt us? */
  	if (!(inw(base + 0x0e) & 0x02))
  		return IRQ_NONE;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
512
  	spin_lock(&card->card_lock);
d8d16e474   Jiri Slaby   [PATCH] char/isic...
513

18234f88b   Jiri Slaby   [PATCH] Char: isi...
514
515
516
517
518
519
  	/*
  	 * disable any interrupts from the PCI card and lower the
  	 * interrupt line
  	 */
  	outw(0x8000, base+0x04);
  	ClearInterrupt(base);
d8d16e474   Jiri Slaby   [PATCH] char/isic...
520

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
521
522
523
524
525
526
  	inw(base);		/* get the dummy word out */
  	header = inw(base);
  	channel = (header & 0x7800) >> card->shift_count;
  	byte_count = header & 0xff;
  
  	if (channel + 1 > card->port_count) {
e620e5488   Joe Perches   tty: pr_warning->...
527
528
529
  		pr_warn("%s(0x%lx): %d(channel) > port_count
  ",
  			__func__, base, channel + 1);
18234f88b   Jiri Slaby   [PATCH] Char: isi...
530
  		outw(0x0000, base+0x04); /* enable interrupts */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
531
  		spin_unlock(&card->card_lock);
d8d16e474   Jiri Slaby   [PATCH] char/isic...
532
  		return IRQ_HANDLED;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
533
534
  	}
  	port = card->ports + channel;
d41861ca1   Peter Hurley   tty: Replace ASYN...
535
  	if (!tty_port_initialized(&port->port)) {
18234f88b   Jiri Slaby   [PATCH] Char: isi...
536
  		outw(0x0000, base+0x04); /* enable interrupts */
174f13076   Jiri Slaby   [PATCH] Char: isi...
537
  		spin_unlock(&card->card_lock);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
538
  		return IRQ_HANDLED;
d8d16e474   Jiri Slaby   [PATCH] char/isic...
539
  	}
d450b5a01   Alan Cox   tty: kref usage f...
540
  	tty = tty_port_tty_get(&port->port);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
541
542
  	if (tty == NULL) {
  		word_count = byte_count >> 1;
251b8dd7e   Alan Cox   isicom: bring int...
543
  		while (byte_count > 1) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
544
545
546
547
548
  			inw(base);
  			byte_count -= 2;
  		}
  		if (byte_count & 0x01)
  			inw(base);
18234f88b   Jiri Slaby   [PATCH] Char: isi...
549
  		outw(0x0000, base+0x04); /* enable interrupts */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
550
551
552
  		spin_unlock(&card->card_lock);
  		return IRQ_HANDLED;
  	}
d8d16e474   Jiri Slaby   [PATCH] char/isic...
553

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
554
555
  	if (header & 0x8000) {		/* Status Packet */
  		header = inw(base);
251b8dd7e   Alan Cox   isicom: bring int...
556
  		switch (header & 0xff) {
d8d16e474   Jiri Slaby   [PATCH] char/isic...
557
  		case 0:	/* Change in EIA signals */
2d68655d1   Peter Hurley   tty: Replace ASYN...
558
  			if (tty_port_check_carrier(&port->port)) {
d8d16e474   Jiri Slaby   [PATCH] char/isic...
559
560
561
  				if (port->status & ISI_DCD) {
  					if (!(header & ISI_DCD)) {
  					/* Carrier has been lost  */
db91340b2   Joe Perches   serial: isicom.c:...
562
563
564
  						pr_debug("%s: DCD->low.
  ",
  							 __func__);
d8d16e474   Jiri Slaby   [PATCH] char/isic...
565
  						port->status &= ~ISI_DCD;
0aa5de859   Jiri Slaby   [PATCH] Char: isi...
566
  						tty_hangup(tty);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
567
  					}
a547dfe95   Jiri Slaby   [PATCH] char/isic...
568
569
  				} else if (header & ISI_DCD) {
  				/* Carrier has been detected */
db91340b2   Joe Perches   serial: isicom.c:...
570
571
572
  					pr_debug("%s: DCD->high.
  ",
  						__func__);
a547dfe95   Jiri Slaby   [PATCH] char/isic...
573
  					port->status |= ISI_DCD;
f1d03228e   Alan Cox   isicom: use tty_port
574
  					wake_up_interruptible(&port->port.open_wait);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
575
  				}
a547dfe95   Jiri Slaby   [PATCH] char/isic...
576
  			} else {
d8d16e474   Jiri Slaby   [PATCH] char/isic...
577
578
579
580
581
  				if (header & ISI_DCD)
  					port->status |= ISI_DCD;
  				else
  					port->status &= ~ISI_DCD;
  			}
f21ec3d2d   Huang Shijie   serial: add a new...
582
  			if (tty_port_cts_enabled(&port->port)) {
d450b5a01   Alan Cox   tty: kref usage f...
583
  				if (tty->hw_stopped) {
d8d16e474   Jiri Slaby   [PATCH] char/isic...
584
  					if (header & ISI_CTS) {
7342c59a4   Jiri Slaby   TTY: isicom, stop...
585
  						tty->hw_stopped = 0;
d8d16e474   Jiri Slaby   [PATCH] char/isic...
586
  						/* start tx ing */
a547dfe95   Jiri Slaby   [PATCH] char/isic...
587
588
  						port->status |= (ISI_TXOK
  							| ISI_CTS);
0aa5de859   Jiri Slaby   [PATCH] Char: isi...
589
  						tty_wakeup(tty);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
590
  					}
a547dfe95   Jiri Slaby   [PATCH] char/isic...
591
  				} else if (!(header & ISI_CTS)) {
d450b5a01   Alan Cox   tty: kref usage f...
592
  					tty->hw_stopped = 1;
a547dfe95   Jiri Slaby   [PATCH] char/isic...
593
594
  					/* stop tx ing */
  					port->status &= ~(ISI_TXOK | ISI_CTS);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
595
  				}
a547dfe95   Jiri Slaby   [PATCH] char/isic...
596
  			} else {
d8d16e474   Jiri Slaby   [PATCH] char/isic...
597
598
  				if (header & ISI_CTS)
  					port->status |= ISI_CTS;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
599
  				else
d8d16e474   Jiri Slaby   [PATCH] char/isic...
600
601
602
603
604
605
606
607
608
609
610
611
612
613
  					port->status &= ~ISI_CTS;
  			}
  
  			if (header & ISI_DSR)
  				port->status |= ISI_DSR;
  			else
  				port->status &= ~ISI_DSR;
  
  			if (header & ISI_RI)
  				port->status |= ISI_RI;
  			else
  				port->status &= ~ISI_RI;
  
  			break;
a547dfe95   Jiri Slaby   [PATCH] char/isic...
614
  		case 1:	/* Received Break !!! */
92a19f9ce   Jiri Slaby   TTY: switch tty_i...
615
  			tty_insert_flip_char(&port->port, 0, TTY_BREAK);
f1d03228e   Alan Cox   isicom: use tty_port
616
  			if (port->port.flags & ASYNC_SAK)
d8d16e474   Jiri Slaby   [PATCH] char/isic...
617
  				do_SAK(tty);
2e124b4a3   Jiri Slaby   TTY: switch tty_f...
618
  			tty_flip_buffer_push(&port->port);
d8d16e474   Jiri Slaby   [PATCH] char/isic...
619
620
621
  			break;
  
  		case 2:	/* Statistics		 */
db91340b2   Joe Perches   serial: isicom.c:...
622
623
  			pr_debug("%s: stats!!!
  ", __func__);
d8d16e474   Jiri Slaby   [PATCH] char/isic...
624
625
626
  			break;
  
  		default:
db91340b2   Joe Perches   serial: isicom.c:...
627
628
629
  			pr_debug("%s: Unknown code in status packet.
  ",
  				 __func__);
d8d16e474   Jiri Slaby   [PATCH] char/isic...
630
631
  			break;
  		}
a547dfe95   Jiri Slaby   [PATCH] char/isic...
632
  	} else {				/* Data   Packet */
2f6933571   Jiri Slaby   TTY: convert more...
633
634
  		count = tty_prepare_flip_string(&port->port, &rp,
  				byte_count & ~1);
db91340b2   Joe Perches   serial: isicom.c:...
635
636
637
  		pr_debug("%s: Can rx %d of %d bytes.
  ",
  			 __func__, count, byte_count);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
638
  		word_count = count >> 1;
33f0f88f1   Alan Cox   [PATCH] TTY layer...
639
  		insw(base, rp, word_count);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
640
641
  		byte_count -= (word_count << 1);
  		if (count & 0x0001) {
92a19f9ce   Jiri Slaby   TTY: switch tty_i...
642
  			tty_insert_flip_char(&port->port, inw(base) & 0xff,
a547dfe95   Jiri Slaby   [PATCH] char/isic...
643
  				TTY_NORMAL);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
644
  			byte_count -= 2;
d8d16e474   Jiri Slaby   [PATCH] char/isic...
645
  		}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
646
  		if (byte_count > 0) {
db91340b2   Joe Perches   serial: isicom.c:...
647
648
649
  			pr_debug("%s(0x%lx:%d): Flip buffer overflow! dropping bytes...
  ",
  				 __func__, base, channel + 1);
251b8dd7e   Alan Cox   isicom: bring int...
650
651
  		/* drain out unread xtra data */
  		while (byte_count > 0) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
652
653
654
655
  				inw(base);
  				byte_count -= 2;
  			}
  		}
2e124b4a3   Jiri Slaby   TTY: switch tty_f...
656
  		tty_flip_buffer_push(&port->port);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
657
  	}
18234f88b   Jiri Slaby   [PATCH] Char: isi...
658
  	outw(0x0000, base+0x04); /* enable interrupts */
174f13076   Jiri Slaby   [PATCH] Char: isi...
659
  	spin_unlock(&card->card_lock);
d450b5a01   Alan Cox   tty: kref usage f...
660
  	tty_kref_put(tty);
a547dfe95   Jiri Slaby   [PATCH] char/isic...
661

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
662
  	return IRQ_HANDLED;
d8d16e474   Jiri Slaby   [PATCH] char/isic...
663
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
664

d450b5a01   Alan Cox   tty: kref usage f...
665
  static void isicom_config_port(struct tty_struct *tty)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
666
  {
d450b5a01   Alan Cox   tty: kref usage f...
667
  	struct isi_port *port = tty->driver_data;
d8d16e474   Jiri Slaby   [PATCH] char/isic...
668
  	struct isi_board *card = port->card;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
669
  	unsigned long baud;
8070e35c6   Jiri Slaby   [PATCH] char/isic...
670
671
672
  	unsigned long base = card->base;
  	u16 channel_setup, channel = port->channel,
  		shift_count = card->shift_count;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
673
  	unsigned char flow_ctrl;
d8d16e474   Jiri Slaby   [PATCH] char/isic...
674

251b8dd7e   Alan Cox   isicom: bring int...
675
  	/* FIXME: Switch to new tty baud API */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
676
677
678
  	baud = C_BAUD(tty);
  	if (baud & CBAUDEX) {
  		baud &= ~CBAUDEX;
d8d16e474   Jiri Slaby   [PATCH] char/isic...
679

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
680
681
682
  		/*  if CBAUDEX bit is on and the baud is set to either 50 or 75
  		 *  then the card is programmed for 57.6Kbps or 115Kbps
  		 *  respectively.
d8d16e474   Jiri Slaby   [PATCH] char/isic...
683
  		 */
7edc136ab   Jiri Slaby   [PATCH] Char: isi...
684
685
  		/* 1,2,3,4 => 57.6, 115.2, 230, 460 kbps resp. */
  		if (baud < 1 || baud > 4)
adc8d746c   Alan Cox   tty: move the ter...
686
  			tty->termios.c_cflag &= ~CBAUDEX;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
687
688
  		else
  			baud += 15;
d8d16e474   Jiri Slaby   [PATCH] char/isic...
689
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
690
  	if (baud == 15) {
d8d16e474   Jiri Slaby   [PATCH] char/isic...
691
692
  
  		/*  the ASYNC_SPD_HI and ASYNC_SPD_VHI options are set
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
693
694
  		 *  by the set_serial_info ioctl ... this is done by
  		 *  the 'setserial' utility.
d8d16e474   Jiri Slaby   [PATCH] char/isic...
695
  		 */
f1d03228e   Alan Cox   isicom: use tty_port
696
  		if ((port->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI)
d8d16e474   Jiri Slaby   [PATCH] char/isic...
697
  			baud++; /*  57.6 Kbps */
f1d03228e   Alan Cox   isicom: use tty_port
698
  		if ((port->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_VHI)
251b8dd7e   Alan Cox   isicom: bring int...
699
  			baud += 2; /*  115  Kbps */
f1d03228e   Alan Cox   isicom: use tty_port
700
  		if ((port->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_SHI)
7edc136ab   Jiri Slaby   [PATCH] Char: isi...
701
  			baud += 3; /* 230 kbps*/
f1d03228e   Alan Cox   isicom: use tty_port
702
  		if ((port->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_WARP)
7edc136ab   Jiri Slaby   [PATCH] Char: isi...
703
  			baud += 4; /* 460 kbps*/
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
704
705
706
  	}
  	if (linuxb_to_isib[baud] == -1) {
  		/* hang up */
d8d16e474   Jiri Slaby   [PATCH] char/isic...
707
708
  		drop_dtr(port);
  		return;
251b8dd7e   Alan Cox   isicom: bring int...
709
  	} else
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
710
  		raise_dtr(port);
d8d16e474   Jiri Slaby   [PATCH] char/isic...
711

cfe7c09ac   Jiri Slaby   [PATCH] Char: isi...
712
  	if (WaitTillCardIsFree(base) == 0) {
251b8dd7e   Alan Cox   isicom: bring int...
713
  		outw(0x8000 | (channel << shift_count) | 0x03, base);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
714
715
  		outw(linuxb_to_isib[baud] << 8 | 0x03, base);
  		channel_setup = 0;
251b8dd7e   Alan Cox   isicom: bring int...
716
  		switch (C_CSIZE(tty)) {
d8d16e474   Jiri Slaby   [PATCH] char/isic...
717
718
719
720
721
722
723
724
725
726
727
728
  		case CS5:
  			channel_setup |= ISICOM_CS5;
  			break;
  		case CS6:
  			channel_setup |= ISICOM_CS6;
  			break;
  		case CS7:
  			channel_setup |= ISICOM_CS7;
  			break;
  		case CS8:
  			channel_setup |= ISICOM_CS8;
  			break;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
729
  		}
d8d16e474   Jiri Slaby   [PATCH] char/isic...
730

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
731
732
733
734
735
  		if (C_CSTOPB(tty))
  			channel_setup |= ISICOM_2SB;
  		if (C_PARENB(tty)) {
  			channel_setup |= ISICOM_EVPAR;
  			if (C_PARODD(tty))
d8d16e474   Jiri Slaby   [PATCH] char/isic...
736
  				channel_setup |= ISICOM_ODPAR;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
737
  		}
d8d16e474   Jiri Slaby   [PATCH] char/isic...
738
  		outw(channel_setup, base);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
739
  		InterruptTheCard(base);
d8d16e474   Jiri Slaby   [PATCH] char/isic...
740
  	}
2d68655d1   Peter Hurley   tty: Replace ASYN...
741
  	tty_port_set_check_carrier(&port->port, !C_CLOCAL(tty));
d8d16e474   Jiri Slaby   [PATCH] char/isic...
742

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
743
744
  	/* flow control settings ...*/
  	flow_ctrl = 0;
5604a98e2   Peter Hurley   tty: Replace ASYN...
745
746
  	tty_port_set_cts_flow(&port->port, C_CRTSCTS(tty));
  	if (C_CRTSCTS(tty))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
747
  		flow_ctrl |= ISICOM_CTSRTS;
d8d16e474   Jiri Slaby   [PATCH] char/isic...
748
  	if (I_IXON(tty))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
749
750
  		flow_ctrl |= ISICOM_RESPOND_XONXOFF;
  	if (I_IXOFF(tty))
d8d16e474   Jiri Slaby   [PATCH] char/isic...
751
  		flow_ctrl |= ISICOM_INITIATE_XONXOFF;
cfe7c09ac   Jiri Slaby   [PATCH] Char: isi...
752
  	if (WaitTillCardIsFree(base) == 0) {
251b8dd7e   Alan Cox   isicom: bring int...
753
  		outw(0x8000 | (channel << shift_count) | 0x04, base);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
754
755
756
  		outw(flow_ctrl << 8 | 0x05, base);
  		outw((STOP_CHAR(tty)) << 8 | (START_CHAR(tty)), base);
  		InterruptTheCard(base);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
757
  	}
d8d16e474   Jiri Slaby   [PATCH] char/isic...
758

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
759
760
761
762
763
764
  	/*	rx enabled -> enable port for rx on the card	*/
  	if (C_CREAD(tty)) {
  		card->port_status |= (1 << channel);
  		outw(card->port_status, base + 0x02);
  	}
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
765

d8d16e474   Jiri Slaby   [PATCH] char/isic...
766
767
768
  /* open et all */
  
  static inline void isicom_setup_board(struct isi_board *bp)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
769
770
  {
  	int channel;
d8d16e474   Jiri Slaby   [PATCH] char/isic...
771
  	struct isi_port *port;
d8d16e474   Jiri Slaby   [PATCH] char/isic...
772

baaa08acb   Alan Cox   tty: isicom: swit...
773
  	bp->count++;
6ed847d8e   Alan Cox   tty: isicom: sort...
774
775
776
777
778
779
  	if (!(bp->status & BOARD_INIT)) {
  		port = bp->ports;
  		for (channel = 0; channel < bp->port_count; channel++, port++)
  			drop_dtr_rts(port);
  	}
  	bp->status |= BOARD_ACTIVE | BOARD_INIT;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
780
  }
d8d16e474   Jiri Slaby   [PATCH] char/isic...
781

6ed847d8e   Alan Cox   tty: isicom: sort...
782
783
  /* Activate and thus setup board are protected from races against shutdown
     by the tty_port mutex */
baaa08acb   Alan Cox   tty: isicom: swit...
784
  static int isicom_activate(struct tty_port *tport, struct tty_struct *tty)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
785
  {
baaa08acb   Alan Cox   tty: isicom: swit...
786
  	struct isi_port *port = container_of(tport, struct isi_port, port);
d8d16e474   Jiri Slaby   [PATCH] char/isic...
787
  	struct isi_board *card = port->card;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
788
  	unsigned long flags;
d8d16e474   Jiri Slaby   [PATCH] char/isic...
789

baaa08acb   Alan Cox   tty: isicom: swit...
790
  	if (tty_port_alloc_xmit_buf(tport) < 0)
f1d03228e   Alan Cox   isicom: use tty_port
791
  		return -ENOMEM;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
792
793
  
  	spin_lock_irqsave(&card->card_lock, flags);
baaa08acb   Alan Cox   tty: isicom: swit...
794
  	isicom_setup_board(card);
d8d16e474   Jiri Slaby   [PATCH] char/isic...
795

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
796
  	port->xmit_cnt = port->xmit_head = port->xmit_tail = 0;
d8d16e474   Jiri Slaby   [PATCH] char/isic...
797

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
798
  	/*	discard any residual data	*/
cfe7c09ac   Jiri Slaby   [PATCH] Char: isi...
799
800
801
802
803
804
  	if (WaitTillCardIsFree(card->base) == 0) {
  		outw(0x8000 | (port->channel << card->shift_count) | 0x02,
  				card->base);
  		outw(((ISICOM_KILLTX | ISICOM_KILLRX) << 8) | 0x06, card->base);
  		InterruptTheCard(card->base);
  	}
d450b5a01   Alan Cox   tty: kref usage f...
805
  	isicom_config_port(tty);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
806
  	spin_unlock_irqrestore(&card->card_lock, flags);
d8d16e474   Jiri Slaby   [PATCH] char/isic...
807
808
809
  
  	return 0;
  }
31f35939d   Alan Cox   tty_port: Add a p...
810
811
812
813
814
  static int isicom_carrier_raised(struct tty_port *port)
  {
  	struct isi_port *ip = container_of(port, struct isi_port, port);
  	return (ip->status & ISI_DCD)?1 : 0;
  }
11d85d7b2   Alan Cox   isicom: split the...
815
  static struct tty_port *isicom_find_port(struct tty_struct *tty)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
816
  {
d8d16e474   Jiri Slaby   [PATCH] char/isic...
817
818
  	struct isi_port *port;
  	struct isi_board *card;
17c4edf0c   Jiri Slaby   [PATCH] Char: isi...
819
  	unsigned int board;
11d85d7b2   Alan Cox   isicom: split the...
820
  	int line = tty->index;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
821

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
822
823
  	board = BOARD(line);
  	card = &isi_card[board];
d8d16e474   Jiri Slaby   [PATCH] char/isic...
824

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
825
  	if (!(card->status & FIRMWARE_LOADED))
11d85d7b2   Alan Cox   isicom: split the...
826
  		return NULL;
d8d16e474   Jiri Slaby   [PATCH] char/isic...
827

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
828
829
  	/*  open on a port greater than the port count for the card !!! */
  	if (line > ((board * 16) + card->port_count - 1))
11d85d7b2   Alan Cox   isicom: split the...
830
  		return NULL;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
831

d8d16e474   Jiri Slaby   [PATCH] char/isic...
832
  	port = &isi_ports[line];
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
833
  	if (isicom_paranoia_check(port, tty->name, "isicom_open"))
11d85d7b2   Alan Cox   isicom: split the...
834
835
836
837
  		return NULL;
  
  	return &port->port;
  }
baaa08acb   Alan Cox   tty: isicom: swit...
838

11d85d7b2   Alan Cox   isicom: split the...
839
840
841
  static int isicom_open(struct tty_struct *tty, struct file *filp)
  {
  	struct isi_port *port;
11d85d7b2   Alan Cox   isicom: split the...
842
  	struct tty_port *tport;
d8d16e474   Jiri Slaby   [PATCH] char/isic...
843

11d85d7b2   Alan Cox   isicom: split the...
844
845
846
847
  	tport = isicom_find_port(tty);
  	if (tport == NULL)
  		return -ENODEV;
  	port = container_of(tport, struct isi_port, port);
d8d16e474   Jiri Slaby   [PATCH] char/isic...
848

a2d1e3516   Alan Cox   tty: Fix regressi...
849
  	tty->driver_data = port;
baaa08acb   Alan Cox   tty: isicom: swit...
850
  	return tty_port_open(tport, tty, filp);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
851
  }
d8d16e474   Jiri Slaby   [PATCH] char/isic...
852

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
853
  /* close et all */
cfe7c09ac   Jiri Slaby   [PATCH] Char: isi...
854
  /* card->lock HAS to be held */
d8d16e474   Jiri Slaby   [PATCH] char/isic...
855
  static void isicom_shutdown_port(struct isi_port *port)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
856
  {
d8d16e474   Jiri Slaby   [PATCH] char/isic...
857
  	struct isi_board *card = port->card;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
858

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
859
  	if (--card->count < 0) {
db91340b2   Joe Perches   serial: isicom.c:...
860
861
862
  		pr_debug("%s: bad board(0x%lx) count %d.
  ",
  			 __func__, card->base, card->count);
d8d16e474   Jiri Slaby   [PATCH] char/isic...
863
  		card->count = 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
864
  	}
baaa08acb   Alan Cox   tty: isicom: swit...
865
  	/* last port was closed, shutdown that board too */
6ed847d8e   Alan Cox   tty: isicom: sort...
866
867
  	if (!card->count)
  		card->status &= BOARD_ACTIVE;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
868
  }
978e595f8   Alan Cox   tty/serial: lay t...
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
  static void isicom_flush_buffer(struct tty_struct *tty)
  {
  	struct isi_port *port = tty->driver_data;
  	struct isi_board *card = port->card;
  	unsigned long flags;
  
  	if (isicom_paranoia_check(port, tty->name, "isicom_flush_buffer"))
  		return;
  
  	spin_lock_irqsave(&card->card_lock, flags);
  	port->xmit_cnt = port->xmit_head = port->xmit_tail = 0;
  	spin_unlock_irqrestore(&card->card_lock, flags);
  
  	tty_wakeup(tty);
  }
baaa08acb   Alan Cox   tty: isicom: swit...
884
  static void isicom_shutdown(struct tty_port *port)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
885
  {
6f6412b4c   Alan Cox   isicom: Split the...
886
887
  	struct isi_port *ip = container_of(port, struct isi_port, port);
  	struct isi_board *card = ip->card;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
888
  	unsigned long flags;
d8d16e474   Jiri Slaby   [PATCH] char/isic...
889

d8d16e474   Jiri Slaby   [PATCH] char/isic...
890
  	/* indicate to the card that no more data can be received
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
891
892
  	   on this port */
  	spin_lock_irqsave(&card->card_lock, flags);
baaa08acb   Alan Cox   tty: isicom: swit...
893
894
  	card->port_status &= ~(1 << ip->channel);
  	outw(card->port_status, card->base + 0x02);
a6614999e   Alan Cox   tty: Introduce so...
895
  	isicom_shutdown_port(ip);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
896
  	spin_unlock_irqrestore(&card->card_lock, flags);
2493c0c16   Alan Cox   tty: isicom: fix ...
897
  	tty_port_free_xmit_buf(port);
6f6412b4c   Alan Cox   isicom: Split the...
898
  }
d8d16e474   Jiri Slaby   [PATCH] char/isic...
899

6f6412b4c   Alan Cox   isicom: Split the...
900
901
902
  static void isicom_close(struct tty_struct *tty, struct file *filp)
  {
  	struct isi_port *ip = tty->driver_data;
a2d1e3516   Alan Cox   tty: Fix regressi...
903
904
905
906
907
908
  	struct tty_port *port;
  
  	if (ip == NULL)
  		return;
  
  	port = &ip->port;
6f6412b4c   Alan Cox   isicom: Split the...
909
910
  	if (isicom_paranoia_check(ip, tty->name, "isicom_close"))
  		return;
baaa08acb   Alan Cox   tty: isicom: swit...
911
  	tty_port_close(port, tty, filp);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
912
913
914
  }
  
  /* write et all */
d8d16e474   Jiri Slaby   [PATCH] char/isic...
915
916
  static int isicom_write(struct tty_struct *tty,	const unsigned char *buf,
  	int count)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
917
  {
8070e35c6   Jiri Slaby   [PATCH] char/isic...
918
  	struct isi_port *port = tty->driver_data;
d8d16e474   Jiri Slaby   [PATCH] char/isic...
919
  	struct isi_board *card = port->card;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
920
921
922
923
924
  	unsigned long flags;
  	int cnt, total = 0;
  
  	if (isicom_paranoia_check(port, tty->name, "isicom_write"))
  		return 0;
d8d16e474   Jiri Slaby   [PATCH] char/isic...
925

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
926
  	spin_lock_irqsave(&card->card_lock, flags);
d8d16e474   Jiri Slaby   [PATCH] char/isic...
927

251b8dd7e   Alan Cox   isicom: bring int...
928
  	while (1) {
a547dfe95   Jiri Slaby   [PATCH] char/isic...
929
930
  		cnt = min_t(int, count, min(SERIAL_XMIT_SIZE - port->xmit_cnt
  				- 1, SERIAL_XMIT_SIZE - port->xmit_head));
d8d16e474   Jiri Slaby   [PATCH] char/isic...
931
  		if (cnt <= 0)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
932
  			break;
d8d16e474   Jiri Slaby   [PATCH] char/isic...
933

f1d03228e   Alan Cox   isicom: use tty_port
934
  		memcpy(port->port.xmit_buf + port->xmit_head, buf, cnt);
a547dfe95   Jiri Slaby   [PATCH] char/isic...
935
936
  		port->xmit_head = (port->xmit_head + cnt) & (SERIAL_XMIT_SIZE
  			- 1);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
937
938
939
940
  		port->xmit_cnt += cnt;
  		buf += cnt;
  		count -= cnt;
  		total += cnt;
d8d16e474   Jiri Slaby   [PATCH] char/isic...
941
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
942
943
944
  	if (port->xmit_cnt && !tty->stopped && !tty->hw_stopped)
  		port->status |= ISI_TXOK;
  	spin_unlock_irqrestore(&card->card_lock, flags);
d8d16e474   Jiri Slaby   [PATCH] char/isic...
945
  	return total;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
946
947
948
  }
  
  /* put_char et all */
f34d7a5b7   Alan Cox   tty: The big oper...
949
  static int isicom_put_char(struct tty_struct *tty, unsigned char ch)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
950
  {
8070e35c6   Jiri Slaby   [PATCH] char/isic...
951
  	struct isi_port *port = tty->driver_data;
d8d16e474   Jiri Slaby   [PATCH] char/isic...
952
  	struct isi_board *card = port->card;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
953
  	unsigned long flags;
d8d16e474   Jiri Slaby   [PATCH] char/isic...
954

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
955
  	if (isicom_paranoia_check(port, tty->name, "isicom_put_char"))
f34d7a5b7   Alan Cox   tty: The big oper...
956
  		return 0;
d8d16e474   Jiri Slaby   [PATCH] char/isic...
957

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
958
  	spin_lock_irqsave(&card->card_lock, flags);
f34d7a5b7   Alan Cox   tty: The big oper...
959
960
961
962
  	if (port->xmit_cnt >= SERIAL_XMIT_SIZE - 1) {
  		spin_unlock_irqrestore(&card->card_lock, flags);
  		return 0;
  	}
d8d16e474   Jiri Slaby   [PATCH] char/isic...
963

f1d03228e   Alan Cox   isicom: use tty_port
964
  	port->port.xmit_buf[port->xmit_head++] = ch;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
965
966
967
  	port->xmit_head &= (SERIAL_XMIT_SIZE - 1);
  	port->xmit_cnt++;
  	spin_unlock_irqrestore(&card->card_lock, flags);
f34d7a5b7   Alan Cox   tty: The big oper...
968
  	return 1;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
969
970
971
  }
  
  /* flush_chars et all */
d8d16e474   Jiri Slaby   [PATCH] char/isic...
972
  static void isicom_flush_chars(struct tty_struct *tty)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
973
  {
8070e35c6   Jiri Slaby   [PATCH] char/isic...
974
  	struct isi_port *port = tty->driver_data;
d8d16e474   Jiri Slaby   [PATCH] char/isic...
975

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
976
977
  	if (isicom_paranoia_check(port, tty->name, "isicom_flush_chars"))
  		return;
d8d16e474   Jiri Slaby   [PATCH] char/isic...
978

a547dfe95   Jiri Slaby   [PATCH] char/isic...
979
  	if (port->xmit_cnt <= 0 || tty->stopped || tty->hw_stopped ||
f1d03228e   Alan Cox   isicom: use tty_port
980
  			!port->port.xmit_buf)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
981
  		return;
d8d16e474   Jiri Slaby   [PATCH] char/isic...
982

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
983
984
  	/* this tells the transmitter to consider this port for
  	   data output to the card ... that's the best we can do. */
d8d16e474   Jiri Slaby   [PATCH] char/isic...
985
  	port->status |= ISI_TXOK;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
986
987
988
  }
  
  /* write_room et all */
d8d16e474   Jiri Slaby   [PATCH] char/isic...
989
  static int isicom_write_room(struct tty_struct *tty)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
990
  {
8070e35c6   Jiri Slaby   [PATCH] char/isic...
991
  	struct isi_port *port = tty->driver_data;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
992
993
994
995
  	int free;
  
  	if (isicom_paranoia_check(port, tty->name, "isicom_write_room"))
  		return 0;
d8d16e474   Jiri Slaby   [PATCH] char/isic...
996

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
997
998
999
1000
1001
1002
1003
  	free = SERIAL_XMIT_SIZE - port->xmit_cnt - 1;
  	if (free < 0)
  		free = 0;
  	return free;
  }
  
  /* chars_in_buffer et all */
d8d16e474   Jiri Slaby   [PATCH] char/isic...
1004
  static int isicom_chars_in_buffer(struct tty_struct *tty)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1005
  {
8070e35c6   Jiri Slaby   [PATCH] char/isic...
1006
  	struct isi_port *port = tty->driver_data;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1007
1008
1009
1010
1011
1012
  	if (isicom_paranoia_check(port, tty->name, "isicom_chars_in_buffer"))
  		return 0;
  	return port->xmit_cnt;
  }
  
  /* ioctl et all */
6d8897243   Alan Cox   isicom: restore u...
1013
  static int isicom_send_break(struct tty_struct *tty, int length)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1014
  {
6d8897243   Alan Cox   isicom: restore u...
1015
  	struct isi_port *port = tty->driver_data;
d8d16e474   Jiri Slaby   [PATCH] char/isic...
1016
  	struct isi_board *card = port->card;
8070e35c6   Jiri Slaby   [PATCH] char/isic...
1017
  	unsigned long base = card->base;
d8d16e474   Jiri Slaby   [PATCH] char/isic...
1018

6d8897243   Alan Cox   isicom: restore u...
1019
1020
  	if (length == -1)
  		return -EOPNOTSUPP;
d8d16e474   Jiri Slaby   [PATCH] char/isic...
1021
  	if (!lock_card(card))
6d8897243   Alan Cox   isicom: restore u...
1022
  		return -EINVAL;
d8d16e474   Jiri Slaby   [PATCH] char/isic...
1023

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1024
1025
  	outw(0x8000 | ((port->channel) << (card->shift_count)) | 0x3, base);
  	outw((length & 0xff) << 8 | 0x00, base);
f3e2d56dc   Arnd Bergmann   tty/isicom: fix b...
1026
  	outw((length & 0xff00u), base);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1027
1028
1029
  	InterruptTheCard(base);
  
  	unlock_card(card);
6d8897243   Alan Cox   isicom: restore u...
1030
  	return 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1031
  }
60b33c133   Alan Cox   tiocmget: kill of...
1032
  static int isicom_tiocmget(struct tty_struct *tty)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1033
  {
8070e35c6   Jiri Slaby   [PATCH] char/isic...
1034
  	struct isi_port *port = tty->driver_data;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1035
  	/* just send the port status */
8070e35c6   Jiri Slaby   [PATCH] char/isic...
1036
  	u16 status = port->status;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1037
1038
1039
  
  	if (isicom_paranoia_check(port, tty->name, "isicom_ioctl"))
  		return -ENODEV;
d8d16e474   Jiri Slaby   [PATCH] char/isic...
1040

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1041
1042
1043
1044
1045
1046
1047
  	return  ((status & ISI_RTS) ? TIOCM_RTS : 0) |
  		((status & ISI_DTR) ? TIOCM_DTR : 0) |
  		((status & ISI_DCD) ? TIOCM_CAR : 0) |
  		((status & ISI_DSR) ? TIOCM_DSR : 0) |
  		((status & ISI_CTS) ? TIOCM_CTS : 0) |
  		((status & ISI_RI ) ? TIOCM_RI  : 0);
  }
20b9d1771   Alan Cox   tiocmset: kill th...
1048
1049
  static int isicom_tiocmset(struct tty_struct *tty,
  					unsigned int set, unsigned int clear)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1050
  {
8070e35c6   Jiri Slaby   [PATCH] char/isic...
1051
  	struct isi_port *port = tty->driver_data;
cfe7c09ac   Jiri Slaby   [PATCH] Char: isi...
1052
  	unsigned long flags;
d8d16e474   Jiri Slaby   [PATCH] char/isic...
1053

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1054
1055
  	if (isicom_paranoia_check(port, tty->name, "isicom_ioctl"))
  		return -ENODEV;
d8d16e474   Jiri Slaby   [PATCH] char/isic...
1056

cfe7c09ac   Jiri Slaby   [PATCH] Char: isi...
1057
  	spin_lock_irqsave(&port->card->card_lock, flags);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1058
1059
1060
1061
1062
1063
1064
1065
1066
  	if (set & TIOCM_RTS)
  		raise_rts(port);
  	if (set & TIOCM_DTR)
  		raise_dtr(port);
  
  	if (clear & TIOCM_RTS)
  		drop_rts(port);
  	if (clear & TIOCM_DTR)
  		drop_dtr(port);
cfe7c09ac   Jiri Slaby   [PATCH] Char: isi...
1067
  	spin_unlock_irqrestore(&port->card->card_lock, flags);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1068
1069
  
  	return 0;
d8d16e474   Jiri Slaby   [PATCH] char/isic...
1070
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1071

d450b5a01   Alan Cox   tty: kref usage f...
1072
1073
  static int isicom_set_serial_info(struct tty_struct *tty,
  					struct serial_struct __user *info)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1074
  {
d450b5a01   Alan Cox   tty: kref usage f...
1075
  	struct isi_port *port = tty->driver_data;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1076
1077
  	struct serial_struct newinfo;
  	int reconfig_port;
d8d16e474   Jiri Slaby   [PATCH] char/isic...
1078
  	if (copy_from_user(&newinfo, info, sizeof(newinfo)))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1079
  		return -EFAULT;
d8d16e474   Jiri Slaby   [PATCH] char/isic...
1080

ec82db129   Alan Cox   isicom: kill off ...
1081
  	mutex_lock(&port->port.mutex);
f1d03228e   Alan Cox   isicom: use tty_port
1082
  	reconfig_port = ((port->port.flags & ASYNC_SPD_MASK) !=
d8d16e474   Jiri Slaby   [PATCH] char/isic...
1083
  		(newinfo.flags & ASYNC_SPD_MASK));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1084
  	if (!capable(CAP_SYS_ADMIN)) {
44b7d1b37   Alan Cox   tty: add more tty...
1085
1086
  		if ((newinfo.close_delay != port->port.close_delay) ||
  				(newinfo.closing_wait != port->port.closing_wait) ||
d8d16e474   Jiri Slaby   [PATCH] char/isic...
1087
  				((newinfo.flags & ~ASYNC_USR_MASK) !=
f1d03228e   Alan Cox   isicom: use tty_port
1088
  				(port->port.flags & ~ASYNC_USR_MASK))) {
ec82db129   Alan Cox   isicom: kill off ...
1089
  			mutex_unlock(&port->port.mutex);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1090
  			return -EPERM;
1eac49473   Alan Cox   isicom: prepare f...
1091
  		}
f1d03228e   Alan Cox   isicom: use tty_port
1092
  		port->port.flags = ((port->port.flags & ~ASYNC_USR_MASK) |
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1093
  				(newinfo.flags & ASYNC_USR_MASK));
251b8dd7e   Alan Cox   isicom: bring int...
1094
  	} else {
44b7d1b37   Alan Cox   tty: add more tty...
1095
1096
  		port->port.close_delay = newinfo.close_delay;
  		port->port.closing_wait = newinfo.closing_wait;
f1d03228e   Alan Cox   isicom: use tty_port
1097
  		port->port.flags = ((port->port.flags & ~ASYNC_FLAGS) |
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1098
1099
1100
  				(newinfo.flags & ASYNC_FLAGS));
  	}
  	if (reconfig_port) {
cfe7c09ac   Jiri Slaby   [PATCH] Char: isi...
1101
1102
  		unsigned long flags;
  		spin_lock_irqsave(&port->card->card_lock, flags);
d450b5a01   Alan Cox   tty: kref usage f...
1103
  		isicom_config_port(tty);
cfe7c09ac   Jiri Slaby   [PATCH] Char: isi...
1104
  		spin_unlock_irqrestore(&port->card->card_lock, flags);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1105
  	}
ec82db129   Alan Cox   isicom: kill off ...
1106
  	mutex_unlock(&port->port.mutex);
d8d16e474   Jiri Slaby   [PATCH] char/isic...
1107
1108
  	return 0;
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1109

d8d16e474   Jiri Slaby   [PATCH] char/isic...
1110
1111
  static int isicom_get_serial_info(struct isi_port *port,
  	struct serial_struct __user *info)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1112
1113
  {
  	struct serial_struct out_info;
d8d16e474   Jiri Slaby   [PATCH] char/isic...
1114

ec82db129   Alan Cox   isicom: kill off ...
1115
  	mutex_lock(&port->port.mutex);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1116
1117
1118
1119
1120
  	memset(&out_info, 0, sizeof(out_info));
  /*	out_info.type = ? */
  	out_info.line = port - isi_ports;
  	out_info.port = port->card->base;
  	out_info.irq = port->card->irq;
f1d03228e   Alan Cox   isicom: use tty_port
1121
  	out_info.flags = port->port.flags;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1122
  /*	out_info.baud_base = ? */
44b7d1b37   Alan Cox   tty: add more tty...
1123
1124
  	out_info.close_delay = port->port.close_delay;
  	out_info.closing_wait = port->port.closing_wait;
ec82db129   Alan Cox   isicom: kill off ...
1125
  	mutex_unlock(&port->port.mutex);
d8d16e474   Jiri Slaby   [PATCH] char/isic...
1126
  	if (copy_to_user(info, &out_info, sizeof(out_info)))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1127
1128
  		return -EFAULT;
  	return 0;
d8d16e474   Jiri Slaby   [PATCH] char/isic...
1129
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1130

6caa76b77   Alan Cox   tty: now phase ou...
1131
  static int isicom_ioctl(struct tty_struct *tty,
d8d16e474   Jiri Slaby   [PATCH] char/isic...
1132
  	unsigned int cmd, unsigned long arg)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1133
  {
8070e35c6   Jiri Slaby   [PATCH] char/isic...
1134
  	struct isi_port *port = tty->driver_data;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1135
  	void __user *argp = (void __user *)arg;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1136
1137
1138
  
  	if (isicom_paranoia_check(port, tty->name, "isicom_ioctl"))
  		return -ENODEV;
251b8dd7e   Alan Cox   isicom: bring int...
1139
  	switch (cmd) {
d8d16e474   Jiri Slaby   [PATCH] char/isic...
1140
1141
1142
1143
  	case TIOCGSERIAL:
  		return isicom_get_serial_info(port, argp);
  
  	case TIOCSSERIAL:
d450b5a01   Alan Cox   tty: kref usage f...
1144
  		return isicom_set_serial_info(tty, argp);
d8d16e474   Jiri Slaby   [PATCH] char/isic...
1145
1146
1147
  
  	default:
  		return -ENOIOCTLCMD;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1148
1149
1150
1151
1152
  	}
  	return 0;
  }
  
  /* set_termios et all */
d8d16e474   Jiri Slaby   [PATCH] char/isic...
1153
  static void isicom_set_termios(struct tty_struct *tty,
606d099cd   Alan Cox   [PATCH] tty: swit...
1154
  	struct ktermios *old_termios)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1155
  {
8070e35c6   Jiri Slaby   [PATCH] char/isic...
1156
  	struct isi_port *port = tty->driver_data;
cfe7c09ac   Jiri Slaby   [PATCH] Char: isi...
1157
  	unsigned long flags;
d8d16e474   Jiri Slaby   [PATCH] char/isic...
1158

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1159
1160
  	if (isicom_paranoia_check(port, tty->name, "isicom_set_termios"))
  		return;
d8d16e474   Jiri Slaby   [PATCH] char/isic...
1161

adc8d746c   Alan Cox   tty: move the ter...
1162
1163
  	if (tty->termios.c_cflag == old_termios->c_cflag &&
  			tty->termios.c_iflag == old_termios->c_iflag)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1164
  		return;
d8d16e474   Jiri Slaby   [PATCH] char/isic...
1165

cfe7c09ac   Jiri Slaby   [PATCH] Char: isi...
1166
  	spin_lock_irqsave(&port->card->card_lock, flags);
d450b5a01   Alan Cox   tty: kref usage f...
1167
  	isicom_config_port(tty);
cfe7c09ac   Jiri Slaby   [PATCH] Char: isi...
1168
  	spin_unlock_irqrestore(&port->card->card_lock, flags);
d8d16e474   Jiri Slaby   [PATCH] char/isic...
1169

9db276f8f   Peter Hurley   tty: Use termios ...
1170
  	if ((old_termios->c_cflag & CRTSCTS) && !C_CRTSCTS(tty)) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1171
  		tty->hw_stopped = 0;
d8d16e474   Jiri Slaby   [PATCH] char/isic...
1172
1173
  		isicom_start(tty);
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1174
1175
1176
  }
  
  /* throttle et all */
d8d16e474   Jiri Slaby   [PATCH] char/isic...
1177
  static void isicom_throttle(struct tty_struct *tty)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1178
  {
8070e35c6   Jiri Slaby   [PATCH] char/isic...
1179
  	struct isi_port *port = tty->driver_data;
d8d16e474   Jiri Slaby   [PATCH] char/isic...
1180
  	struct isi_board *card = port->card;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1181
1182
  	if (isicom_paranoia_check(port, tty->name, "isicom_throttle"))
  		return;
d8d16e474   Jiri Slaby   [PATCH] char/isic...
1183

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1184
1185
1186
1187
1188
1189
  	/* tell the card that this port cannot handle any more data for now */
  	card->port_status &= ~(1 << port->channel);
  	outw(card->port_status, card->base + 0x02);
  }
  
  /* unthrottle et all */
d8d16e474   Jiri Slaby   [PATCH] char/isic...
1190
  static void isicom_unthrottle(struct tty_struct *tty)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1191
  {
8070e35c6   Jiri Slaby   [PATCH] char/isic...
1192
  	struct isi_port *port = tty->driver_data;
d8d16e474   Jiri Slaby   [PATCH] char/isic...
1193
  	struct isi_board *card = port->card;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1194
1195
  	if (isicom_paranoia_check(port, tty->name, "isicom_unthrottle"))
  		return;
d8d16e474   Jiri Slaby   [PATCH] char/isic...
1196

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1197
1198
1199
1200
1201
1202
  	/* tell the card that this port is ready to accept more data */
  	card->port_status |= (1 << port->channel);
  	outw(card->port_status, card->base + 0x02);
  }
  
  /* stop et all */
d8d16e474   Jiri Slaby   [PATCH] char/isic...
1203
  static void isicom_stop(struct tty_struct *tty)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1204
  {
8070e35c6   Jiri Slaby   [PATCH] char/isic...
1205
  	struct isi_port *port = tty->driver_data;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1206
1207
1208
  
  	if (isicom_paranoia_check(port, tty->name, "isicom_stop"))
  		return;
d8d16e474   Jiri Slaby   [PATCH] char/isic...
1209

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1210
1211
1212
1213
1214
1215
  	/* this tells the transmitter not to consider this port for
  	   data output to the card. */
  	port->status &= ~ISI_TXOK;
  }
  
  /* start et all */
d8d16e474   Jiri Slaby   [PATCH] char/isic...
1216
  static void isicom_start(struct tty_struct *tty)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1217
  {
8070e35c6   Jiri Slaby   [PATCH] char/isic...
1218
  	struct isi_port *port = tty->driver_data;
d8d16e474   Jiri Slaby   [PATCH] char/isic...
1219

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1220
1221
  	if (isicom_paranoia_check(port, tty->name, "isicom_start"))
  		return;
d8d16e474   Jiri Slaby   [PATCH] char/isic...
1222

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1223
1224
1225
1226
  	/* this tells the transmitter to consider this port for
  	   data output to the card. */
  	port->status |= ISI_TXOK;
  }
d8d16e474   Jiri Slaby   [PATCH] char/isic...
1227
  static void isicom_hangup(struct tty_struct *tty)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1228
  {
8070e35c6   Jiri Slaby   [PATCH] char/isic...
1229
  	struct isi_port *port = tty->driver_data;
d8d16e474   Jiri Slaby   [PATCH] char/isic...
1230

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1231
1232
  	if (isicom_paranoia_check(port, tty->name, "isicom_hangup"))
  		return;
3e61696bd   Alan Cox   isicom: redo lock...
1233
  	tty_port_hangup(&port->port);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1234
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1235

9ac0948b2   Jiri Slaby   [PATCH] char/isic...
1236
1237
1238
  /*
   * Driver init and deinit functions
   */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1239

b68e31d0e   Jeff Dike   [PATCH] const str...
1240
  static const struct tty_operations isicom_ops = {
d8d16e474   Jiri Slaby   [PATCH] char/isic...
1241
1242
1243
1244
1245
1246
  	.open			= isicom_open,
  	.close			= isicom_close,
  	.write			= isicom_write,
  	.put_char		= isicom_put_char,
  	.flush_chars		= isicom_flush_chars,
  	.write_room		= isicom_write_room,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1247
  	.chars_in_buffer	= isicom_chars_in_buffer,
d8d16e474   Jiri Slaby   [PATCH] char/isic...
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
  	.ioctl			= isicom_ioctl,
  	.set_termios		= isicom_set_termios,
  	.throttle		= isicom_throttle,
  	.unthrottle		= isicom_unthrottle,
  	.stop			= isicom_stop,
  	.start			= isicom_start,
  	.hangup			= isicom_hangup,
  	.flush_buffer		= isicom_flush_buffer,
  	.tiocmget		= isicom_tiocmget,
  	.tiocmset		= isicom_tiocmset,
6d8897243   Alan Cox   isicom: restore u...
1258
  	.break_ctl		= isicom_send_break,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1259
  };
31f35939d   Alan Cox   tty_port: Add a p...
1260
1261
  static const struct tty_port_operations isicom_port_ops = {
  	.carrier_raised		= isicom_carrier_raised,
fcc8ac182   Alan Cox   tty: Add carrier ...
1262
  	.dtr_rts		= isicom_dtr_rts,
baaa08acb   Alan Cox   tty: isicom: swit...
1263
1264
  	.activate		= isicom_activate,
  	.shutdown		= isicom_shutdown,
31f35939d   Alan Cox   tty_port: Add a p...
1265
  };
9671f0992   Bill Pemberton   tty: remove use o...
1266
  static int reset_card(struct pci_dev *pdev,
9ac0948b2   Jiri Slaby   [PATCH] char/isic...
1267
  	const unsigned int card, unsigned int *signature)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1268
  {
9ac0948b2   Jiri Slaby   [PATCH] char/isic...
1269
1270
  	struct isi_board *board = pci_get_drvdata(pdev);
  	unsigned long base = board->base;
f0a0ba6d6   Jiri Slaby   [PATCH] Char: isi...
1271
  	unsigned int sig, portcount = 0;
9ac0948b2   Jiri Slaby   [PATCH] char/isic...
1272
  	int retval = 0;
d8d16e474   Jiri Slaby   [PATCH] char/isic...
1273

9ac0948b2   Jiri Slaby   [PATCH] char/isic...
1274
1275
1276
  	dev_dbg(&pdev->dev, "ISILoad:Resetting Card%d at 0x%lx
  ", card + 1,
  		base);
d8d16e474   Jiri Slaby   [PATCH] char/isic...
1277

9ac0948b2   Jiri Slaby   [PATCH] char/isic...
1278
  	inw(base + 0x8);
d8d16e474   Jiri Slaby   [PATCH] char/isic...
1279

f0a0ba6d6   Jiri Slaby   [PATCH] Char: isi...
1280
  	msleep(10);
9ac0948b2   Jiri Slaby   [PATCH] char/isic...
1281
1282
  
  	outw(0, base + 0x8); /* Reset */
f0a0ba6d6   Jiri Slaby   [PATCH] Char: isi...
1283
  	msleep(1000);
9ac0948b2   Jiri Slaby   [PATCH] char/isic...
1284

f0a0ba6d6   Jiri Slaby   [PATCH] Char: isi...
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
  	sig = inw(base + 0x4) & 0xff;
  
  	if (sig != 0xa5 && sig != 0xbb && sig != 0xcc && sig != 0xdd &&
  			sig != 0xee) {
  		dev_warn(&pdev->dev, "ISILoad:Card%u reset failure (Possible "
  			"bad I/O Port Address 0x%lx).
  ", card + 1, base);
  		dev_dbg(&pdev->dev, "Sig=0x%x
  ", sig);
  		retval = -EIO;
  		goto end;
  	}
  
  	msleep(10);
9ac0948b2   Jiri Slaby   [PATCH] char/isic...
1299

18234f88b   Jiri Slaby   [PATCH] Char: isi...
1300
  	portcount = inw(base + 0x2);
07fb6f26b   Julia Lawall   drivers/char/isic...
1301
  	if (!(inw(base + 0xe) & 0x1) || (portcount != 0 && portcount != 4 &&
f0a0ba6d6   Jiri Slaby   [PATCH] Char: isi...
1302
  				portcount != 8 && portcount != 16)) {
898eb71cb   Joe Perches   Add missing newli...
1303
1304
  		dev_err(&pdev->dev, "ISILoad:PCI Card%d reset failure.
  ",
f0a0ba6d6   Jiri Slaby   [PATCH] Char: isi...
1305
  			card + 1);
18234f88b   Jiri Slaby   [PATCH] Char: isi...
1306
1307
  		retval = -EIO;
  		goto end;
9ac0948b2   Jiri Slaby   [PATCH] char/isic...
1308
  	}
f0a0ba6d6   Jiri Slaby   [PATCH] Char: isi...
1309
  	switch (sig) {
9ac0948b2   Jiri Slaby   [PATCH] char/isic...
1310
1311
1312
  	case 0xa5:
  	case 0xbb:
  	case 0xdd:
18234f88b   Jiri Slaby   [PATCH] Char: isi...
1313
  		board->port_count = (portcount == 4) ? 4 : 8;
9ac0948b2   Jiri Slaby   [PATCH] char/isic...
1314
1315
1316
  		board->shift_count = 12;
  		break;
  	case 0xcc:
f0a0ba6d6   Jiri Slaby   [PATCH] Char: isi...
1317
  	case 0xee:
9ac0948b2   Jiri Slaby   [PATCH] char/isic...
1318
1319
1320
  		board->port_count = 16;
  		board->shift_count = 11;
  		break;
d8d16e474   Jiri Slaby   [PATCH] char/isic...
1321
  	}
9ac0948b2   Jiri Slaby   [PATCH] char/isic...
1322
1323
  	dev_info(&pdev->dev, "-Done
  ");
f0a0ba6d6   Jiri Slaby   [PATCH] Char: isi...
1324
  	*signature = sig;
d8d16e474   Jiri Slaby   [PATCH] char/isic...
1325

9ac0948b2   Jiri Slaby   [PATCH] char/isic...
1326
1327
  end:
  	return retval;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1328
  }
9671f0992   Bill Pemberton   tty: remove use o...
1329
  static int load_firmware(struct pci_dev *pdev,
e65c1db19   Jiri Slaby   [PATCH] char/isic...
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
  	const unsigned int index, const unsigned int signature)
  {
  	struct isi_board *board = pci_get_drvdata(pdev);
  	const struct firmware *fw;
  	unsigned long base = board->base;
  	unsigned int a;
  	u16 word_count, status;
  	int retval = -EIO;
  	char *name;
  	u8 *data;
  
  	struct stframe {
  		u16	addr;
  		u16	count;
  		u8	data[0];
  	} *frame;
  
  	switch (signature) {
  	case 0xa5:
  		name = "isi608.bin";
  		break;
  	case 0xbb:
  		name = "isi608em.bin";
  		break;
  	case 0xcc:
  		name = "isi616em.bin";
  		break;
  	case 0xdd:
  		name = "isi4608.bin";
  		break;
  	case 0xee:
  		name = "isi4616.bin";
  		break;
  	default:
  		dev_err(&pdev->dev, "Unknown signature.
  ");
  		goto end;
251b8dd7e   Alan Cox   isicom: bring int...
1367
  	}
e65c1db19   Jiri Slaby   [PATCH] char/isic...
1368
1369
1370
1371
  
  	retval = request_firmware(&fw, name, &pdev->dev);
  	if (retval)
  		goto end;
e4e040887   Jiri Slaby   [PATCH] isicom: c...
1372
  	retval = -EIO;
e65c1db19   Jiri Slaby   [PATCH] char/isic...
1373
1374
  	for (frame = (struct stframe *)fw->data;
  			frame < (struct stframe *)(fw->data + fw->size);
e4e040887   Jiri Slaby   [PATCH] isicom: c...
1375
1376
  			frame = (struct stframe *)((u8 *)(frame + 1) +
  				frame->count)) {
e65c1db19   Jiri Slaby   [PATCH] char/isic...
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
  		if (WaitTillCardIsFree(base))
  			goto errrelfw;
  
  		outw(0xf0, base);	/* start upload sequence */
  		outw(0x00, base);
  		outw(frame->addr, base); /* lsb of address */
  
  		word_count = frame->count / 2 + frame->count % 2;
  		outw(word_count, base);
  		InterruptTheCard(base);
  
  		udelay(100); /* 0x2f */
  
  		if (WaitTillCardIsFree(base))
  			goto errrelfw;
251b8dd7e   Alan Cox   isicom: bring int...
1392
1393
  		status = inw(base + 0x4);
  		if (status != 0) {
e65c1db19   Jiri Slaby   [PATCH] char/isic...
1394
1395
  			dev_warn(&pdev->dev, "Card%d rejected load header:
  "
ad361c988   Joe Perches   Remove multiple K...
1396
1397
1398
1399
1400
1401
1402
  				 "Address:0x%x
  "
  				 "Count:0x%x
  "
  				 "Status:0x%x
  ",
  				 index + 1, frame->addr, frame->count, status);
e65c1db19   Jiri Slaby   [PATCH] char/isic...
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
  			goto errrelfw;
  		}
  		outsw(base, frame->data, word_count);
  
  		InterruptTheCard(base);
  
  		udelay(50); /* 0x0f */
  
  		if (WaitTillCardIsFree(base))
  			goto errrelfw;
251b8dd7e   Alan Cox   isicom: bring int...
1413
1414
  		status = inw(base + 0x4);
  		if (status != 0) {
e65c1db19   Jiri Slaby   [PATCH] char/isic...
1415
1416
1417
1418
1419
  			dev_err(&pdev->dev, "Card%d got out of sync.Card "
  				"Status:0x%x
  ", index + 1, status);
  			goto errrelfw;
  		}
251b8dd7e   Alan Cox   isicom: bring int...
1420
  	}
e65c1db19   Jiri Slaby   [PATCH] char/isic...
1421

e65c1db19   Jiri Slaby   [PATCH] char/isic...
1422
1423
  /* XXX: should we test it by reading it back and comparing with original like
   * in load firmware package? */
e4e040887   Jiri Slaby   [PATCH] isicom: c...
1424
1425
1426
1427
  	for (frame = (struct stframe *)fw->data;
  			frame < (struct stframe *)(fw->data + fw->size);
  			frame = (struct stframe *)((u8 *)(frame + 1) +
  				frame->count)) {
e65c1db19   Jiri Slaby   [PATCH] char/isic...
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
  		if (WaitTillCardIsFree(base))
  			goto errrelfw;
  
  		outw(0xf1, base); /* start download sequence */
  		outw(0x00, base);
  		outw(frame->addr, base); /* lsb of address */
  
  		word_count = (frame->count >> 1) + frame->count % 2;
  		outw(word_count + 1, base);
  		InterruptTheCard(base);
  
  		udelay(50); /* 0xf */
  
  		if (WaitTillCardIsFree(base))
  			goto errrelfw;
251b8dd7e   Alan Cox   isicom: bring int...
1443
1444
  		status = inw(base + 0x4);
  		if (status != 0) {
e65c1db19   Jiri Slaby   [PATCH] char/isic...
1445
1446
  			dev_warn(&pdev->dev, "Card%d rejected verify header:
  "
ad361c988   Joe Perches   Remove multiple K...
1447
1448
1449
1450
1451
1452
1453
  				 "Address:0x%x
  "
  				 "Count:0x%x
  "
  				 "Status: 0x%x
  ",
  				 index + 1, frame->addr, frame->count, status);
e65c1db19   Jiri Slaby   [PATCH] char/isic...
1454
1455
1456
1457
  			goto errrelfw;
  		}
  
  		data = kmalloc(word_count * 2, GFP_KERNEL);
f06713784   Jiri Slaby   [PATCH] Char: isi...
1458
1459
1460
1461
1462
1463
  		if (data == NULL) {
  			dev_err(&pdev->dev, "Card%d, firmware upload "
  				"failed, not enough memory
  ", index + 1);
  			goto errrelfw;
  		}
e65c1db19   Jiri Slaby   [PATCH] char/isic...
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
  		inw(base);
  		insw(base, data, word_count);
  		InterruptTheCard(base);
  
  		for (a = 0; a < frame->count; a++)
  			if (data[a] != frame->data[a]) {
  				kfree(data);
  				dev_err(&pdev->dev, "Card%d, firmware upload "
  					"failed
  ", index + 1);
  				goto errrelfw;
  			}
  		kfree(data);
  
  		udelay(50); /* 0xf */
  
  		if (WaitTillCardIsFree(base))
  			goto errrelfw;
251b8dd7e   Alan Cox   isicom: bring int...
1482
1483
  		status = inw(base + 0x4);
  		if (status != 0) {
e65c1db19   Jiri Slaby   [PATCH] char/isic...
1484
1485
1486
1487
1488
1489
  			dev_err(&pdev->dev, "Card%d verify got out of sync. "
  				"Card Status:0x%x
  ", index + 1, status);
  			goto errrelfw;
  		}
  	}
e4e040887   Jiri Slaby   [PATCH] isicom: c...
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
  	/* xfer ctrl */
  	if (WaitTillCardIsFree(base))
  		goto errrelfw;
  
  	outw(0xf2, base);
  	outw(0x800, base);
  	outw(0x0, base);
  	outw(0x0, base);
  	InterruptTheCard(base);
  	outw(0x0, base + 0x4); /* for ISI4608 cards */
e65c1db19   Jiri Slaby   [PATCH] char/isic...
1500
1501
1502
1503
1504
1505
1506
1507
  	board->status |= FIRMWARE_LOADED;
  	retval = 0;
  
  errrelfw:
  	release_firmware(fw);
  end:
  	return retval;
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1508
1509
1510
  /*
   *	Insmod can set static symbols so keep these static
   */
1ed0c0b73   Jiri Slaby   [PATCH] Char: isi...
1511
  static unsigned int card_count;
9ac0948b2   Jiri Slaby   [PATCH] char/isic...
1512

9671f0992   Bill Pemberton   tty: remove use o...
1513
  static int isicom_probe(struct pci_dev *pdev,
9ac0948b2   Jiri Slaby   [PATCH] char/isic...
1514
1515
  	const struct pci_device_id *ent)
  {
9653a69e9   Jiri Slaby   Char: isicom: fix...
1516
  	unsigned int uninitialized_var(signature), index;
9ac0948b2   Jiri Slaby   [PATCH] char/isic...
1517
  	int retval = -EPERM;
9ac0948b2   Jiri Slaby   [PATCH] char/isic...
1518
  	struct isi_board *board = NULL;
1ed0c0b73   Jiri Slaby   [PATCH] Char: isi...
1519
  	if (card_count >= BOARD_COUNT)
9ac0948b2   Jiri Slaby   [PATCH] char/isic...
1520
  		goto err;
e1e5770bb   Jiri Slaby   tty: isicom, enab...
1521
1522
1523
1524
1525
1526
  	retval = pci_enable_device(pdev);
  	if (retval) {
  		dev_err(&pdev->dev, "failed to enable
  ");
  		goto err;
  	}
9ac0948b2   Jiri Slaby   [PATCH] char/isic...
1527
1528
1529
1530
  	dev_info(&pdev->dev, "ISI PCI Card(Device ID 0x%x)
  ", ent->device);
  
  	/* allot the first empty slot in the array */
26e1e8d1d   Dan Carpenter   serial: isicomm: ...
1531
  	for (index = 0; index < BOARD_COUNT; index++) {
9ac0948b2   Jiri Slaby   [PATCH] char/isic...
1532
1533
1534
1535
  		if (isi_card[index].base == 0) {
  			board = &isi_card[index];
  			break;
  		}
26e1e8d1d   Dan Carpenter   serial: isicomm: ...
1536
1537
1538
1539
1540
  	}
  	if (index == BOARD_COUNT) {
  		retval = -ENODEV;
  		goto err_disable;
  	}
9ac0948b2   Jiri Slaby   [PATCH] char/isic...
1541

938a7023b   Jiri Slaby   [PATCH] Char: isi...
1542
  	board->index = index;
4969b3a43   Jiri Slaby   Char: isicom, pro...
1543
1544
  	board->base = pci_resource_start(pdev, 3);
  	board->irq = pdev->irq;
1ed0c0b73   Jiri Slaby   [PATCH] Char: isi...
1545
  	card_count++;
9ac0948b2   Jiri Slaby   [PATCH] char/isic...
1546
1547
  
  	pci_set_drvdata(pdev, board);
78028da91   Jiri Slaby   [PATCH] Char: isi...
1548
1549
  	retval = pci_request_region(pdev, 3, ISICOM_NAME);
  	if (retval) {
09a4a1125   Jiri Slaby   [PATCH] Char: isi...
1550
1551
1552
1553
1554
  		dev_err(&pdev->dev, "I/O Region 0x%lx-0x%lx is busy. Card%d "
  			"will be disabled.
  ", board->base, board->base + 15,
  			index + 1);
  		retval = -EBUSY;
1ed0c0b73   Jiri Slaby   [PATCH] Char: isi...
1555
  		goto errdec;
251b8dd7e   Alan Cox   isicom: bring int...
1556
  	}
9ac0948b2   Jiri Slaby   [PATCH] char/isic...
1557

09a4a1125   Jiri Slaby   [PATCH] Char: isi...
1558
  	retval = request_irq(board->irq, isicom_interrupt,
9cfb5c05f   Yong Zhang   TTY: irq: Remove ...
1559
  			IRQF_SHARED, ISICOM_NAME, board);
09a4a1125   Jiri Slaby   [PATCH] Char: isi...
1560
1561
1562
1563
  	if (retval < 0) {
  		dev_err(&pdev->dev, "Could not install handler at Irq %d. "
  			"Card%d will be disabled.
  ", board->irq, index + 1);
9ac0948b2   Jiri Slaby   [PATCH] char/isic...
1564
  		goto errunrr;
09a4a1125   Jiri Slaby   [PATCH] Char: isi...
1565
  	}
9ac0948b2   Jiri Slaby   [PATCH] char/isic...
1566
1567
1568
1569
  
  	retval = reset_card(pdev, index, &signature);
  	if (retval < 0)
  		goto errunri;
e65c1db19   Jiri Slaby   [PATCH] char/isic...
1570
1571
1572
  	retval = load_firmware(pdev, index, signature);
  	if (retval < 0)
  		goto errunri;
d0f59141c   Jiri Slaby   TTY: isicom, fix ...
1573
1574
1575
1576
1577
1578
1579
1580
1581
  	for (index = 0; index < board->port_count; index++) {
  		struct tty_port *tport = &board->ports[index].port;
  		tty_port_init(tport);
  		tport->ops = &isicom_port_ops;
  		tport->close_delay = 50 * HZ/100;
  		tport->closing_wait = 3000 * HZ/100;
  		tty_port_register_device(tport, isicom_normal,
  				board->index * 16 + index, &pdev->dev);
  	}
938a7023b   Jiri Slaby   [PATCH] Char: isi...
1582

9ac0948b2   Jiri Slaby   [PATCH] char/isic...
1583
1584
1585
1586
1587
  	return 0;
  
  errunri:
  	free_irq(board->irq, board);
  errunrr:
78028da91   Jiri Slaby   [PATCH] Char: isi...
1588
  	pci_release_region(pdev, 3);
1ed0c0b73   Jiri Slaby   [PATCH] Char: isi...
1589
  errdec:
9ac0948b2   Jiri Slaby   [PATCH] char/isic...
1590
  	board->base = 0;
1ed0c0b73   Jiri Slaby   [PATCH] Char: isi...
1591
  	card_count--;
26e1e8d1d   Dan Carpenter   serial: isicomm: ...
1592
  err_disable:
e1e5770bb   Jiri Slaby   tty: isicom, enab...
1593
  	pci_disable_device(pdev);
1ed0c0b73   Jiri Slaby   [PATCH] Char: isi...
1594
  err:
9ac0948b2   Jiri Slaby   [PATCH] char/isic...
1595
1596
  	return retval;
  }
ae8d8a146   Bill Pemberton   tty: remove use o...
1597
  static void isicom_remove(struct pci_dev *pdev)
9ac0948b2   Jiri Slaby   [PATCH] char/isic...
1598
1599
  {
  	struct isi_board *board = pci_get_drvdata(pdev);
938a7023b   Jiri Slaby   [PATCH] Char: isi...
1600
  	unsigned int i;
d0f59141c   Jiri Slaby   TTY: isicom, fix ...
1601
  	for (i = 0; i < board->port_count; i++) {
938a7023b   Jiri Slaby   [PATCH] Char: isi...
1602
  		tty_unregister_device(isicom_normal, board->index * 16 + i);
d0f59141c   Jiri Slaby   TTY: isicom, fix ...
1603
1604
  		tty_port_destroy(&board->ports[i].port);
  	}
9ac0948b2   Jiri Slaby   [PATCH] char/isic...
1605
1606
  
  	free_irq(board->irq, board);
78028da91   Jiri Slaby   [PATCH] Char: isi...
1607
  	pci_release_region(pdev, 3);
1ed0c0b73   Jiri Slaby   [PATCH] Char: isi...
1608
1609
  	board->base = 0;
  	card_count--;
e1e5770bb   Jiri Slaby   tty: isicom, enab...
1610
  	pci_disable_device(pdev);
9ac0948b2   Jiri Slaby   [PATCH] char/isic...
1611
  }
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1612

ca2620051   Jiri Slaby   [PATCH] Char: isi...
1613
  static int __init isicom_init(void)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1614
  {
9ac0948b2   Jiri Slaby   [PATCH] char/isic...
1615
1616
  	int retval, idx, channel;
  	struct isi_port *port;
d8d16e474   Jiri Slaby   [PATCH] char/isic...
1617

251b8dd7e   Alan Cox   isicom: bring int...
1618
  	for (idx = 0; idx < BOARD_COUNT; idx++) {
9ac0948b2   Jiri Slaby   [PATCH] char/isic...
1619
1620
1621
1622
1623
1624
1625
  		port = &isi_ports[idx * 16];
  		isi_card[idx].ports = port;
  		spin_lock_init(&isi_card[idx].card_lock);
  		for (channel = 0; channel < 16; channel++, port++) {
  			port->magic = ISICOM_MAGIC;
  			port->card = &isi_card[idx];
  			port->channel = channel;
9ac0948b2   Jiri Slaby   [PATCH] char/isic...
1626
  			port->status = 0;
9ac0948b2   Jiri Slaby   [PATCH] char/isic...
1627
  			/*  . . .  */
251b8dd7e   Alan Cox   isicom: bring int...
1628
  		}
9ac0948b2   Jiri Slaby   [PATCH] char/isic...
1629
1630
  		isi_card[idx].base = 0;
  		isi_card[idx].irq = 0;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1631
  	}
d8d16e474   Jiri Slaby   [PATCH] char/isic...
1632

09a4a1125   Jiri Slaby   [PATCH] Char: isi...
1633
1634
1635
1636
  	/* tty driver structure initialization */
  	isicom_normal = alloc_tty_driver(PORT_COUNT);
  	if (!isicom_normal) {
  		retval = -ENOMEM;
9ac0948b2   Jiri Slaby   [PATCH] char/isic...
1637
  		goto error;
09a4a1125   Jiri Slaby   [PATCH] Char: isi...
1638
  	}
09a4a1125   Jiri Slaby   [PATCH] Char: isi...
1639
1640
1641
1642
1643
1644
1645
1646
  	isicom_normal->name 			= "ttyM";
  	isicom_normal->major			= ISICOM_NMAJOR;
  	isicom_normal->minor_start		= 0;
  	isicom_normal->type			= TTY_DRIVER_TYPE_SERIAL;
  	isicom_normal->subtype			= SERIAL_TYPE_NORMAL;
  	isicom_normal->init_termios		= tty_std_termios;
  	isicom_normal->init_termios.c_cflag	= B9600 | CS8 | CREAD | HUPCL |
  		CLOCAL;
938a7023b   Jiri Slaby   [PATCH] Char: isi...
1647
  	isicom_normal->flags			= TTY_DRIVER_REAL_RAW |
6d8897243   Alan Cox   isicom: restore u...
1648
  		TTY_DRIVER_DYNAMIC_DEV | TTY_DRIVER_HARDWARE_BREAK;
09a4a1125   Jiri Slaby   [PATCH] Char: isi...
1649
1650
1651
1652
  	tty_set_operations(isicom_normal, &isicom_ops);
  
  	retval = tty_register_driver(isicom_normal);
  	if (retval) {
db91340b2   Joe Perches   serial: isicom.c:...
1653
1654
  		pr_debug("Couldn't register the dialin driver
  ");
09a4a1125   Jiri Slaby   [PATCH] Char: isi...
1655
1656
  		goto err_puttty;
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1657

9ac0948b2   Jiri Slaby   [PATCH] char/isic...
1658
  	retval = pci_register_driver(&isicom_driver);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1659
  	if (retval < 0) {
db91340b2   Joe Perches   serial: isicom.c:...
1660
1661
  		pr_err("Unable to register pci driver.
  ");
09a4a1125   Jiri Slaby   [PATCH] Char: isi...
1662
  		goto err_unrtty;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1663
  	}
d8d16e474   Jiri Slaby   [PATCH] char/isic...
1664

34b55b865   Jiri Slaby   [PATCH] Char: isi...
1665
  	mod_timer(&tx, jiffies + 1);
d8d16e474   Jiri Slaby   [PATCH] char/isic...
1666

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1667
  	return 0;
09a4a1125   Jiri Slaby   [PATCH] Char: isi...
1668
1669
1670
1671
  err_unrtty:
  	tty_unregister_driver(isicom_normal);
  err_puttty:
  	put_tty_driver(isicom_normal);
9ac0948b2   Jiri Slaby   [PATCH] char/isic...
1672
1673
  error:
  	return retval;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1674
1675
1676
1677
  }
  
  static void __exit isicom_exit(void)
  {
e327325f4   Jiri Slaby   Char: isicom, del...
1678
  	del_timer_sync(&tx);
aaa246ea7   Jiri Slaby   [PATCH] char/isic...
1679

9ac0948b2   Jiri Slaby   [PATCH] char/isic...
1680
  	pci_unregister_driver(&isicom_driver);
09a4a1125   Jiri Slaby   [PATCH] Char: isi...
1681
1682
  	tty_unregister_driver(isicom_normal);
  	put_tty_driver(isicom_normal);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1683
  }
ca2620051   Jiri Slaby   [PATCH] Char: isi...
1684
  module_init(isicom_init);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1685
  module_exit(isicom_exit);
aaa246ea7   Jiri Slaby   [PATCH] char/isic...
1686
1687
1688
1689
  
  MODULE_AUTHOR("MultiTech");
  MODULE_DESCRIPTION("Driver for the ISI series of cards by MultiTech");
  MODULE_LICENSE("GPL");
e6c4ef984   Ben Hutchings   tty: declare MODU...
1690
1691
1692
1693
1694
  MODULE_FIRMWARE("isi608.bin");
  MODULE_FIRMWARE("isi608em.bin");
  MODULE_FIRMWARE("isi616em.bin");
  MODULE_FIRMWARE("isi4608.bin");
  MODULE_FIRMWARE("isi4616.bin");