File Index
Files and directories
Sign in
FILE

hp_82341.c

File preview with syntax highlighting.

linux-6.19.14/drivers/gpib/hp_82341/hp_82341.c C
  1// SPDX-License-Identifier: GPL-2.0
  2
  3/***************************************************************************
  4 *     Driver for hp 82341a/b/c/d boards.                                  *
  5 * Might be worth merging with Agilent 82350b driver.                      *
  6 *   copyright            : (C) 2002, 2005 by Frank Mori Hess              *
  7 ***************************************************************************/
  8
  9#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
 10#define dev_fmt pr_fmt
 11#define DRV_NAME KBUILD_MODNAME
 12
 13#include "hp_82341.h"
 14#include <linux/delay.h>
 15#include <linux/ioport.h>
 16#include <linux/sched.h>
 17#include <linux/module.h>
 18#include <linux/slab.h>
 19#include <linux/init.h>
 20#include <linux/isapnp.h>
 21
 22MODULE_LICENSE("GPL");
 23MODULE_DESCRIPTION("GPIB driver for hp 82341a/b/c/d boards");
 24
 25static unsigned short read_and_clear_event_status(struct gpib_board *board);
 26static void set_transfer_counter(struct hp_82341_priv *hp_priv, int count);
 27static int read_transfer_counter(struct hp_82341_priv *hp_priv);
 28static int hp_82341_write(struct gpib_board *board, u8 *buffer, size_t length, int send_eoi,
 29			  size_t *bytes_written);
 30static irqreturn_t hp_82341_interrupt(int irq, void *arg);
 31
 32static int hp_82341_accel_read(struct gpib_board *board, u8 *buffer, size_t length, int *end,
 33			       size_t *bytes_read)
 34{
 35	struct hp_82341_priv *hp_priv = board->private_data;
 36	struct tms9914_priv *tms_priv = &hp_priv->tms9914_priv;
 37	int retval = 0;
 38	unsigned short event_status;
 39	int i;
 40	int num_fifo_bytes;
 41	// hardware doesn't support checking for end-of-string character when using fifo
 42	if (tms_priv->eos_flags & REOS)
 43		return tms9914_read(board, tms_priv, buffer, length, end, bytes_read);
 44
 45	clear_bit(DEV_CLEAR_BN, &tms_priv->state);
 46
 47	read_and_clear_event_status(board);
 48	*end = 0;
 49	*bytes_read = 0;
 50	if (length == 0)
 51		return 0;
 52	// disable fifo for the moment
 53	outb(DIRECTION_GPIB_TO_HOST_BIT, hp_priv->iobase[3] + BUFFER_CONTROL_REG);
 54	/*
 55	 * Handle corner case of board not in holdoff and one byte has slipped in already.
 56	 * Also, board sometimes has problems (spurious 1 byte reads) when read fifo is
 57	 * started up with board in TACS under certain data holdoff conditions.
 58	 * Doing a 1 byte tms9914-style read avoids these problems.
 59	 */
 60	if (/*tms_priv->holdoff_active == 0 && */length > 1) {
 61		size_t num_bytes;
 62
 63		retval = tms9914_read(board, tms_priv, buffer, 1, end, &num_bytes);
 64		*bytes_read += num_bytes;
 65		if (retval < 0)
 66			dev_err(board->gpib_dev, "tms9914_read failed retval=%i\n", retval);
 67		if (retval < 0 || *end)
 68			return retval;
 69		++buffer;
 70		--length;
 71	}
 72	tms9914_set_holdoff_mode(tms_priv, TMS9914_HOLDOFF_EOI);
 73	tms9914_release_holdoff(tms_priv);
 74	outb(0x00, hp_priv->iobase[3] + BUFFER_FLUSH_REG);
 75	i = 0;
 76	num_fifo_bytes = length - 1;
 77	while (i < num_fifo_bytes && *end == 0)	{
 78		int block_size;
 79		int j;
 80		int count;
 81
 82		block_size = min(num_fifo_bytes - i, hp_82341_fifo_size);
 83		set_transfer_counter(hp_priv, block_size);
 84		outb(ENABLE_TI_BUFFER_BIT | DIRECTION_GPIB_TO_HOST_BIT, hp_priv->iobase[3] +
 85		     BUFFER_CONTROL_REG);
 86		if (inb(hp_priv->iobase[0] + STREAM_STATUS_REG) & HALTED_STATUS_BIT)
 87			outb(RESTART_STREAM_BIT, hp_priv->iobase[0] + STREAM_STATUS_REG);
 88
 89		clear_bit(READ_READY_BN, &tms_priv->state);
 90
 91		retval = wait_event_interruptible(board->wait,
 92						  ((event_status =
 93						    read_and_clear_event_status(board)) &
 94						   (TERMINAL_COUNT_EVENT_BIT |
 95						    BUFFER_END_EVENT_BIT)) ||
 96						  test_bit(DEV_CLEAR_BN, &tms_priv->state) ||
 97						  test_bit(TIMO_NUM, &board->status));
 98		if (retval)  {
 99			retval = -ERESTARTSYS;
100			break;
101		}
102		// have to disable buffer before we can read from buffer port
103		outb(DIRECTION_GPIB_TO_HOST_BIT, hp_priv->iobase[3] + BUFFER_CONTROL_REG);
104		count = block_size - read_transfer_counter(hp_priv);
105		j = 0;
106		while (j < count && i < num_fifo_bytes) {
107			unsigned short data_word = inw(hp_priv->iobase[3] + BUFFER_PORT_LOW_REG);
108
109			buffer[i++] = data_word & 0xff;
110			++j;
111			if (j < count && i < num_fifo_bytes) {
112				buffer[i++] = (data_word >> 8) & 0xff;
113				++j;
114			}
115		}
116		if (event_status & BUFFER_END_EVENT_BIT) {
117			clear_bit(RECEIVED_END_BN, &tms_priv->state);
118
119			*end = 1;
120			tms_priv->holdoff_active = 1;
121		}
122		if (test_bit(TIMO_NUM, &board->status))	{
123			retval = -ETIMEDOUT;
124			break;
125		}
126		if (test_bit(DEV_CLEAR_BN, &tms_priv->state)) {
127			retval = -EINTR;
128			break;
129		}
130	}
131	*bytes_read += i;
132	buffer += i;
133	length -= i;
134	if (retval < 0)
135		return retval;
136	// read last byte if we havn't received an END yet
137	if (*end == 0) {
138		size_t num_bytes;
139		// try to make sure we holdoff after last byte read
140		retval = tms9914_read(board, tms_priv, buffer, length, end, &num_bytes);
141		*bytes_read += num_bytes;
142		if (retval < 0)
143			return retval;
144	}
145	return 0;
146}
147
148static int restart_write_fifo(struct gpib_board *board, struct hp_82341_priv *hp_priv)
149{
150	struct tms9914_priv *tms_priv = &hp_priv->tms9914_priv;
151
152	if ((inb(hp_priv->iobase[0] + STREAM_STATUS_REG) & HALTED_STATUS_BIT) == 0)
153		return 0;
154	while (1) {
155		int status;
156
157		// restart doesn't work if data holdoff is in effect
158		status = tms9914_line_status(board, tms_priv);
159		if ((status & BUS_NRFD) == 0) {
160			outb(RESTART_STREAM_BIT, hp_priv->iobase[0] + STREAM_STATUS_REG);
161			return 0;
162		}
163		if (test_bit(DEV_CLEAR_BN, &tms_priv->state))
164			return -EINTR;
165		if (test_bit(TIMO_NUM, &board->status))
166			return -ETIMEDOUT;
167		if (msleep_interruptible(1))
168			return -EINTR;
169	}
170	return 0;
171}
172
173static int hp_82341_accel_write(struct gpib_board *board, u8 *buffer, size_t length,
174				int send_eoi, size_t *bytes_written)
175{
176	struct hp_82341_priv *hp_priv = board->private_data;
177	struct tms9914_priv *tms_priv = &hp_priv->tms9914_priv;
178	int i, j;
179	unsigned short event_status;
180	int retval = 0;
181	int fifo_xfer_len = length;
182
183	*bytes_written = 0;
184	if (send_eoi)
185		--fifo_xfer_len;
186
187	clear_bit(DEV_CLEAR_BN, &tms_priv->state);
188
189	read_and_clear_event_status(board);
190	outb(0, hp_priv->iobase[3] + BUFFER_CONTROL_REG);
191	outb(0x00, hp_priv->iobase[3] + BUFFER_FLUSH_REG);
192	for (i = 0; i < fifo_xfer_len;) {
193		int block_size;
194
195		block_size = min(fifo_xfer_len - i, hp_82341_fifo_size);
196		set_transfer_counter(hp_priv, block_size);
197		// load data into board's fifo
198		for (j = 0; j < block_size;) {
199			unsigned short data_word = buffer[i++];
200			++j;
201			if (j < block_size) {
202				data_word |= buffer[i++] << 8;
203				++j;
204			}
205			outw(data_word, hp_priv->iobase[3] + BUFFER_PORT_LOW_REG);
206		}
207		clear_bit(WRITE_READY_BN, &tms_priv->state);
208		outb(ENABLE_TI_BUFFER_BIT, hp_priv->iobase[3] + BUFFER_CONTROL_REG);
209		retval = restart_write_fifo(board, hp_priv);
210		if (retval < 0)	{
211			dev_err(board->gpib_dev, "failed to restart write stream\n");
212			break;
213		}
214		retval = wait_event_interruptible(board->wait,
215						  ((event_status =
216						    read_and_clear_event_status(board)) &
217						   TERMINAL_COUNT_EVENT_BIT) ||
218						  test_bit(DEV_CLEAR_BN, &tms_priv->state) ||
219						  test_bit(TIMO_NUM, &board->status));
220		outb(0, hp_priv->iobase[3] + BUFFER_CONTROL_REG);
221		*bytes_written += block_size - read_transfer_counter(hp_priv);
222		if (retval) {
223			retval = -ERESTARTSYS;
224			break;
225		}
226		if (test_bit(TIMO_NUM, &board->status))	{
227			retval = -ETIMEDOUT;
228			break;
229		}
230		if (test_bit(DEV_CLEAR_BN, &tms_priv->state)) {
231			retval = -EINTR;
232			break;
233		}
234	}
235	if (retval)
236		return retval;
237	if (send_eoi) {
238		size_t num_bytes;
239
240		retval = hp_82341_write(board, buffer + fifo_xfer_len, 1, 1, &num_bytes);
241		*bytes_written += num_bytes;
242		if (retval < 0)
243			return retval;
244	}
245	return 0;
246}
247
248static int hp_82341_attach(struct gpib_board *board, const struct gpib_board_config *config);
249
250static void hp_82341_detach(struct gpib_board *board);
251
252// wrappers for interface functions
253static int hp_82341_read(struct gpib_board *board, u8 *buffer, size_t length, int *end,
254			 size_t *bytes_read)
255{
256	struct hp_82341_priv *priv = board->private_data;
257
258	return tms9914_read(board, &priv->tms9914_priv, buffer, length, end, bytes_read);
259}
260
261static int hp_82341_write(struct gpib_board *board, u8 *buffer, size_t length, int send_eoi,
262			  size_t *bytes_written)
263{
264	struct hp_82341_priv *priv = board->private_data;
265
266	return tms9914_write(board, &priv->tms9914_priv, buffer, length, send_eoi, bytes_written);
267}
268
269static int hp_82341_command(struct gpib_board *board, u8 *buffer, size_t length,
270			    size_t *bytes_written)
271{
272	struct hp_82341_priv *priv = board->private_data;
273
274	return tms9914_command(board, &priv->tms9914_priv, buffer, length, bytes_written);
275}
276
277static int hp_82341_take_control(struct gpib_board *board, int synchronous)
278{
279	struct hp_82341_priv *priv = board->private_data;
280
281	return tms9914_take_control(board, &priv->tms9914_priv, synchronous);
282}
283
284static int hp_82341_go_to_standby(struct gpib_board *board)
285{
286	struct hp_82341_priv *priv = board->private_data;
287
288	return tms9914_go_to_standby(board, &priv->tms9914_priv);
289}
290
291static int hp_82341_request_system_control(struct gpib_board *board, int request_control)
292{
293	struct hp_82341_priv *priv = board->private_data;
294
295	if (request_control)
296		priv->mode_control_bits |= SYSTEM_CONTROLLER_BIT;
297	else
298		priv->mode_control_bits &= ~SYSTEM_CONTROLLER_BIT;
299	outb(priv->mode_control_bits, priv->iobase[0] + MODE_CONTROL_STATUS_REG);
300	return tms9914_request_system_control(board, &priv->tms9914_priv, request_control);
301}
302
303static void hp_82341_interface_clear(struct gpib_board *board, int assert)
304{
305	struct hp_82341_priv *priv = board->private_data;
306
307	tms9914_interface_clear(board, &priv->tms9914_priv, assert);
308}
309
310static void hp_82341_remote_enable(struct gpib_board *board, int enable)
311{
312	struct hp_82341_priv *priv = board->private_data;
313
314	tms9914_remote_enable(board, &priv->tms9914_priv, enable);
315}
316
317static int hp_82341_enable_eos(struct gpib_board *board, u8 eos_byte, int compare_8_bits)
318{
319	struct hp_82341_priv *priv = board->private_data;
320
321	return tms9914_enable_eos(board, &priv->tms9914_priv, eos_byte, compare_8_bits);
322}
323
324static void hp_82341_disable_eos(struct gpib_board *board)
325{
326	struct hp_82341_priv *priv = board->private_data;
327
328	tms9914_disable_eos(board, &priv->tms9914_priv);
329}
330
331static unsigned int hp_82341_update_status(struct gpib_board *board, unsigned int clear_mask)
332{
333	struct hp_82341_priv *priv = board->private_data;
334
335	return tms9914_update_status(board, &priv->tms9914_priv, clear_mask);
336}
337
338static int hp_82341_primary_address(struct gpib_board *board, unsigned int address)
339{
340	struct hp_82341_priv *priv = board->private_data;
341
342	return tms9914_primary_address(board, &priv->tms9914_priv, address);
343}
344
345static int hp_82341_secondary_address(struct gpib_board *board, unsigned int address, int enable)
346{
347	struct hp_82341_priv *priv = board->private_data;
348
349	return tms9914_secondary_address(board, &priv->tms9914_priv, address, enable);
350}
351
352static int hp_82341_parallel_poll(struct gpib_board *board, u8 *result)
353{
354	struct hp_82341_priv *priv = board->private_data;
355
356	return tms9914_parallel_poll(board, &priv->tms9914_priv, result);
357}
358
359static void hp_82341_parallel_poll_configure(struct gpib_board *board, u8 config)
360{
361	struct hp_82341_priv *priv = board->private_data;
362
363	tms9914_parallel_poll_configure(board, &priv->tms9914_priv, config);
364}
365
366static void hp_82341_parallel_poll_response(struct gpib_board *board, int ist)
367{
368	struct hp_82341_priv *priv = board->private_data;
369
370	tms9914_parallel_poll_response(board, &priv->tms9914_priv, ist);
371}
372
373static void hp_82341_serial_poll_response(struct gpib_board *board, u8 status)
374{
375	struct hp_82341_priv *priv = board->private_data;
376
377	tms9914_serial_poll_response(board, &priv->tms9914_priv, status);
378}
379
380static u8 hp_82341_serial_poll_status(struct gpib_board *board)
381{
382	struct hp_82341_priv *priv = board->private_data;
383
384	return tms9914_serial_poll_status(board, &priv->tms9914_priv);
385}
386
387static int hp_82341_line_status(const struct gpib_board *board)
388{
389	struct hp_82341_priv *priv = board->private_data;
390
391	return tms9914_line_status(board, &priv->tms9914_priv);
392}
393
394static int hp_82341_t1_delay(struct gpib_board *board, unsigned int nano_sec)
395{
396	struct hp_82341_priv *priv = board->private_data;
397
398	return tms9914_t1_delay(board, &priv->tms9914_priv, nano_sec);
399}
400
401static void hp_82341_return_to_local(struct gpib_board *board)
402{
403	struct hp_82341_priv *priv = board->private_data;
404
405	tms9914_return_to_local(board, &priv->tms9914_priv);
406}
407
408static struct gpib_interface hp_82341_unaccel_interface = {
409	.name = "hp_82341_unaccel",
410	.attach = hp_82341_attach,
411	.detach = hp_82341_detach,
412	.read = hp_82341_read,
413	.write = hp_82341_write,
414	.command = hp_82341_command,
415	.request_system_control = hp_82341_request_system_control,
416	.take_control = hp_82341_take_control,
417	.go_to_standby = hp_82341_go_to_standby,
418	.interface_clear = hp_82341_interface_clear,
419	.remote_enable = hp_82341_remote_enable,
420	.enable_eos = hp_82341_enable_eos,
421	.disable_eos = hp_82341_disable_eos,
422	.parallel_poll = hp_82341_parallel_poll,
423	.parallel_poll_configure = hp_82341_parallel_poll_configure,
424	.parallel_poll_response = hp_82341_parallel_poll_response,
425	.local_parallel_poll_mode = NULL, // XXX
426	.line_status = hp_82341_line_status,
427	.update_status = hp_82341_update_status,
428	.primary_address = hp_82341_primary_address,
429	.secondary_address = hp_82341_secondary_address,
430	.serial_poll_response = hp_82341_serial_poll_response,
431	.serial_poll_status = hp_82341_serial_poll_status,
432	.t1_delay = hp_82341_t1_delay,
433	.return_to_local = hp_82341_return_to_local,
434};
435
436static struct gpib_interface hp_82341_interface = {
437	.name = "hp_82341",
438	.attach = hp_82341_attach,
439	.detach = hp_82341_detach,
440	.read = hp_82341_accel_read,
441	.write = hp_82341_accel_write,
442	.command = hp_82341_command,
443	.request_system_control = hp_82341_request_system_control,
444	.take_control = hp_82341_take_control,
445	.go_to_standby = hp_82341_go_to_standby,
446	.interface_clear = hp_82341_interface_clear,
447	.remote_enable = hp_82341_remote_enable,
448	.enable_eos = hp_82341_enable_eos,
449	.disable_eos = hp_82341_disable_eos,
450	.parallel_poll = hp_82341_parallel_poll,
451	.parallel_poll_configure = hp_82341_parallel_poll_configure,
452	.parallel_poll_response = hp_82341_parallel_poll_response,
453	.local_parallel_poll_mode = NULL, // XXX
454	.line_status = hp_82341_line_status,
455	.update_status = hp_82341_update_status,
456	.primary_address = hp_82341_primary_address,
457	.secondary_address = hp_82341_secondary_address,
458	.serial_poll_response = hp_82341_serial_poll_response,
459	.t1_delay = hp_82341_t1_delay,
460	.return_to_local = hp_82341_return_to_local,
461};
462
463static int hp_82341_allocate_private(struct gpib_board *board)
464{
465	board->private_data = kzalloc(sizeof(struct hp_82341_priv), GFP_KERNEL);
466	if (!board->private_data)
467		return -ENOMEM;
468	return 0;
469}
470
471static void hp_82341_free_private(struct gpib_board *board)
472{
473	kfree(board->private_data);
474	board->private_data = NULL;
475}
476
477static u8 hp_82341_read_byte(struct tms9914_priv *priv, unsigned int register_num)
478{
479	return inb(priv->iobase + register_num);
480}
481
482static void hp_82341_write_byte(struct tms9914_priv *priv, u8 data, unsigned int register_num)
483{
484	outb(data, priv->iobase + register_num);
485}
486
487static int hp_82341_find_isapnp_board(struct pnp_dev **dev)
488{
489	*dev = pnp_find_dev(NULL, ISAPNP_VENDOR('H', 'W', 'P'),
490			    ISAPNP_FUNCTION(0x1411), NULL);
491	if (!*dev || !(*dev)->card) {
492		pr_err("failed to find isapnp board\n");
493		return -ENODEV;
494	}
495	if (pnp_device_attach(*dev) < 0) {
496		pr_err("board already active, skipping\n");
497		return -EBUSY;
498	}
499	if (pnp_activate_dev(*dev) < 0) {
500		pnp_device_detach(*dev);
501		pr_err("failed to activate(), aborting\n");
502		return -EAGAIN;
503	}
504	if (!pnp_port_valid(*dev, 0) || !pnp_irq_valid(*dev, 0)) {
505		pnp_device_detach(*dev);
506		pr_err("invalid port or irq, aborting\n");
507		return -ENOMEM;
508	}
509	return 0;
510}
511
512static int xilinx_ready(struct hp_82341_priv *hp_priv)
513{
514	switch (hp_priv->hw_version) {
515	case HW_VERSION_82341C:
516		if (inb(hp_priv->iobase[0] + CONFIG_CONTROL_STATUS_REG) & XILINX_READY_BIT)
517			return 1;
518		else
519			return 0;
520		break;
521	case HW_VERSION_82341D:
522		if (isapnp_read_byte(PIO_DATA_REG) & HP_82341D_XILINX_READY_BIT)
523			return 1;
524		else
525			return 0;
526	default:
527		pr_err("bug! unknown hw_version\n");
528		break;
529	}
530	return 0;
531}
532
533static int xilinx_done(struct hp_82341_priv *hp_priv)
534{
535	switch (hp_priv->hw_version) {
536	case HW_VERSION_82341C:
537		if (inb(hp_priv->iobase[0] + CONFIG_CONTROL_STATUS_REG) & DONE_PGL_BIT)
538			return 1;
539		else
540			return 0;
541	case HW_VERSION_82341D:
542		if (isapnp_read_byte(PIO_DATA_REG) & HP_82341D_XILINX_DONE_BIT)
543			return 1;
544		else
545			return 0;
546	default:
547		pr_err("bug! unknown hw_version\n");
548		break;
549	}
550	return 0;
551}
552
553static int irq_valid(struct hp_82341_priv *hp_priv, int irq)
554{
555	switch (hp_priv->hw_version) {
556	case HW_VERSION_82341C:
557		switch (irq) {
558		case 3:
559		case 5:
560		case 7:
561		case 9:
562		case 10:
563		case 11:
564		case 12:
565		case 15:
566			return 1;
567		default:
568			pr_err("invalid irq=%i for 82341C, irq must be 3, 5, 7, 9, 10, 11, 12, or 15.\n",
569			       irq);
570			return 0;
571		}
572		break;
573	case HW_VERSION_82341D:
574		return 1;
575	default:
576		pr_err("bug! unknown hw_version\n");
577		break;
578	}
579	return 0;
580}
581
582static int hp_82341_load_firmware_array(struct hp_82341_priv *hp_priv,
583					const unsigned char *firmware_data,
584					unsigned int firmware_length)
585{
586	int i, j;
587	static const int timeout = 100;
588
589	for (i = 0; i < firmware_length; ++i) {
590		for (j = 0; j < timeout; ++j) {
591			if (need_resched())
592				schedule();
593			if (xilinx_ready(hp_priv))
594				break;
595			usleep_range(10, 15);
596		}
597		if (j == timeout) {
598			pr_err("timed out waiting for Xilinx ready.\n");
599			return -ETIMEDOUT;
600		}
601		outb(firmware_data[i], hp_priv->iobase[0] + XILINX_DATA_REG);
602	}
603	for (j = 0; j < timeout; ++j) {
604		if (xilinx_done(hp_priv))
605			break;
606		if (need_resched())
607			schedule();
608		usleep_range(10, 15);
609	}
610	if (j == timeout) {
611		pr_err("timed out waiting for Xilinx done.\n");
612		return -ETIMEDOUT;
613	}
614	return 0;
615}
616
617static int hp_82341_load_firmware(struct hp_82341_priv *hp_priv,
618				  const struct gpib_board_config *config)
619{
620	if (config->init_data_length == 0) {
621		if (xilinx_done(hp_priv))
622			return 0;
623		pr_err("board needs be initialized with firmware upload.\n"
624		       "\tUse the --init-data option of gpib_config.\n");
625		return -EINVAL;
626	}
627	switch (hp_priv->hw_version) {
628	case HW_VERSION_82341C:
629		if (config->init_data_length != hp_82341c_firmware_length) {
630			pr_err("bad firmware length=%i for 82341c (expected %i).\n",
631			       config->init_data_length, hp_82341c_firmware_length);
632			return -EINVAL;
633		}
634		break;
635	case HW_VERSION_82341D:
636		if (config->init_data_length != hp_82341d_firmware_length) {
637			pr_err("bad firmware length=%i for 82341d (expected %i).\n",
638			       config->init_data_length, hp_82341d_firmware_length);
639			return -EINVAL;
640		}
641		break;
642	default:
643		pr_err("bug! unknown hw_version\n");
644		break;
645	}
646	return hp_82341_load_firmware_array(hp_priv, config->init_data, config->init_data_length);
647}
648
649static void set_xilinx_not_prog(struct hp_82341_priv *hp_priv, int assert)
650{
651	switch (hp_priv->hw_version) {
652	case HW_VERSION_82341C:
653		if (assert)
654			hp_priv->config_control_bits |= DONE_PGL_BIT;
655		else
656			hp_priv->config_control_bits &= ~DONE_PGL_BIT;
657		outb(hp_priv->config_control_bits, hp_priv->iobase[0] + CONFIG_CONTROL_STATUS_REG);
658		break;
659	case HW_VERSION_82341D:
660		if (assert)
661			isapnp_write_byte(PIO_DATA_REG, HP_82341D_NOT_PROG_BIT);
662		else
663			isapnp_write_byte(PIO_DATA_REG, 0x0);
664		break;
665	default:
666		break;
667	}
668}
669
670// clear xilinx firmware
671static int clear_xilinx(struct hp_82341_priv *hp_priv)
672{
673	set_xilinx_not_prog(hp_priv, 1);
674	if (msleep_interruptible(1))
675		return -EINTR;
676	set_xilinx_not_prog(hp_priv, 0);
677	if (msleep_interruptible(1))
678		return -EINTR;
679	set_xilinx_not_prog(hp_priv, 1);
680	if (msleep_interruptible(1))
681		return -EINTR;
682	return 0;
683}
684
685static int hp_82341_attach(struct gpib_board *board, const struct gpib_board_config *config)
686{
687	struct hp_82341_priv *hp_priv;
688	struct tms9914_priv *tms_priv;
689	u32 start_addr;
690	u32 iobase;
691	int irq;
692	int i;
693	int retval;
694
695	board->status = 0;
696	if (hp_82341_allocate_private(board))
697		return -ENOMEM;
698	hp_priv = board->private_data;
699	tms_priv = &hp_priv->tms9914_priv;
700	tms_priv->read_byte = hp_82341_read_byte;
701	tms_priv->write_byte = hp_82341_write_byte;
702	tms_priv->offset = 1;
703
704	if (config->ibbase == 0) {
705		struct pnp_dev *dev;
706		int retval = hp_82341_find_isapnp_board(&dev);
707
708		if (retval < 0)
709			return retval;
710		hp_priv->pnp_dev = dev;
711		iobase = pnp_port_start(dev, 0);
712		irq = pnp_irq(dev, 0);
713		hp_priv->hw_version = HW_VERSION_82341D;
714		hp_priv->io_region_offset = 0x8;
715	} else {
716		iobase = config->ibbase;
717		irq = config->ibirq;
718		hp_priv->hw_version = HW_VERSION_82341C;
719		hp_priv->io_region_offset = 0x400;
720	}
721	for (i = 0; i < hp_82341_num_io_regions; ++i) {
722		start_addr = iobase + i * hp_priv->io_region_offset;
723		if (!request_region(start_addr, hp_82341_region_iosize, DRV_NAME)) {
724			dev_err(board->gpib_dev, "failed to allocate io ports 0x%x-0x%x\n",
725				start_addr,
726				start_addr + hp_82341_region_iosize - 1);
727			return -EIO;
728		}
729		hp_priv->iobase[i] = start_addr;
730	}
731	tms_priv->iobase = hp_priv->iobase[2];
732	if (hp_priv->hw_version == HW_VERSION_82341D) {
733		retval = isapnp_cfg_begin(hp_priv->pnp_dev->card->number,
734					  hp_priv->pnp_dev->number);
735		if (retval < 0)	{
736			dev_err(board->gpib_dev, "isapnp_cfg_begin returned error\n");
737			return retval;
738		}
739		isapnp_write_byte(PIO_DIRECTION_REG, HP_82341D_XILINX_READY_BIT |
740				  HP_82341D_XILINX_DONE_BIT);
741	}
742	retval = clear_xilinx(hp_priv);
743	if (retval < 0)
744		return retval;
745	retval = hp_82341_load_firmware(hp_priv, config);
746	if (hp_priv->hw_version == HW_VERSION_82341D)
747		isapnp_cfg_end();
748	if (retval < 0)
749		return retval;
750	if (irq_valid(hp_priv, irq) == 0)
751		return -EINVAL;
752	if (request_irq(irq, hp_82341_interrupt, 0, DRV_NAME, board))	{
753		dev_err(board->gpib_dev, "failed to allocate IRQ %d\n", irq);
754		return -EIO;
755	}
756	hp_priv->irq = irq;
757	hp_priv->config_control_bits &= ~IRQ_SELECT_MASK;
758	hp_priv->config_control_bits |= IRQ_SELECT_BITS(irq);
759	outb(hp_priv->config_control_bits, hp_priv->iobase[0] + CONFIG_CONTROL_STATUS_REG);
760	hp_priv->mode_control_bits |= ENABLE_IRQ_CONFIG_BIT;
761	outb(hp_priv->mode_control_bits, hp_priv->iobase[0] + MODE_CONTROL_STATUS_REG);
762	tms9914_board_reset(tms_priv);
763	outb(ENABLE_BUFFER_END_EVENT_BIT | ENABLE_TERMINAL_COUNT_EVENT_BIT |
764	     ENABLE_TI_INTERRUPT_EVENT_BIT, hp_priv->iobase[0] +  EVENT_ENABLE_REG);
765	outb(ENABLE_BUFFER_END_INTERRUPT_BIT | ENABLE_TERMINAL_COUNT_INTERRUPT_BIT |
766	     ENABLE_TI_INTERRUPT_BIT, hp_priv->iobase[0] + INTERRUPT_ENABLE_REG);
767	// write clear event register
768	outb((TI_INTERRUPT_EVENT_BIT | POINTERS_EQUAL_EVENT_BIT |
769	      BUFFER_END_EVENT_BIT | TERMINAL_COUNT_EVENT_BIT),
770	     hp_priv->iobase[0] + EVENT_STATUS_REG);
771
772	tms9914_online(board, tms_priv);
773
774	return 0;
775}
776
777static void hp_82341_detach(struct gpib_board *board)
778{
779	struct hp_82341_priv *hp_priv = board->private_data;
780	struct tms9914_priv *tms_priv;
781	int i;
782
783	if (hp_priv) {
784		tms_priv = &hp_priv->tms9914_priv;
785		if (hp_priv->iobase[0])	{
786			outb(0, hp_priv->iobase[0] + INTERRUPT_ENABLE_REG);
787			if (tms_priv->iobase)
788				tms9914_board_reset(tms_priv);
789			if (hp_priv->irq)
790				free_irq(hp_priv->irq, board);
791		}
792		for (i = 0; i < hp_82341_num_io_regions; ++i) {
793			if (hp_priv->iobase[i])
794				release_region(hp_priv->iobase[i], hp_82341_region_iosize);
795		}
796		if (hp_priv->pnp_dev)
797			pnp_device_detach(hp_priv->pnp_dev);
798	}
799	hp_82341_free_private(board);
800}
801
802#if 0
803/* unused, will be needed when the driver is turned into a pnp_driver */
804static const struct pnp_device_id hp_82341_pnp_table[] = {
805	{.id = "HWP1411"},
806	{.id = ""}
807};
808MODULE_DEVICE_TABLE(pnp, hp_82341_pnp_table);
809#endif
810
811static int __init hp_82341_init_module(void)
812{
813	int ret;
814
815	ret = gpib_register_driver(&hp_82341_unaccel_interface, THIS_MODULE);
816	if (ret) {
817		pr_err("gpib_register_driver failed: error = %d\n", ret);
818		return ret;
819	}
820
821	ret = gpib_register_driver(&hp_82341_interface, THIS_MODULE);
822	if (ret) {
823		pr_err("gpib_register_driver failed: error = %d\n", ret);
824		gpib_unregister_driver(&hp_82341_unaccel_interface);
825		return ret;
826	}
827
828	return 0;
829}
830
831static void __exit hp_82341_exit_module(void)
832{
833	gpib_unregister_driver(&hp_82341_interface);
834	gpib_unregister_driver(&hp_82341_unaccel_interface);
835}
836
837module_init(hp_82341_init_module);
838module_exit(hp_82341_exit_module);
839
840/*
841 * GPIB interrupt service routines
842 */
843static unsigned short read_and_clear_event_status(struct gpib_board *board)
844{
845	struct hp_82341_priv *hp_priv = board->private_data;
846	unsigned long flags;
847	unsigned short status;
848
849	spin_lock_irqsave(&board->spinlock, flags);
850	status = hp_priv->event_status_bits;
851	hp_priv->event_status_bits = 0;
852	spin_unlock_irqrestore(&board->spinlock, flags);
853	return status;
854}
855
856static irqreturn_t hp_82341_interrupt(int irq, void *arg)
857{
858	int status1, status2;
859	struct gpib_board *board = arg;
860	struct hp_82341_priv *hp_priv = board->private_data;
861	struct tms9914_priv *tms_priv = &hp_priv->tms9914_priv;
862	unsigned long flags;
863	irqreturn_t retval = IRQ_NONE;
864	int event_status;
865
866	spin_lock_irqsave(&board->spinlock, flags);
867	event_status = inb(hp_priv->iobase[0] + EVENT_STATUS_REG);
868	if (event_status & INTERRUPT_PENDING_EVENT_BIT)
869		retval = IRQ_HANDLED;
870	// write-clear status bits
871	if (event_status & (TI_INTERRUPT_EVENT_BIT | POINTERS_EQUAL_EVENT_BIT |
872			    BUFFER_END_EVENT_BIT | TERMINAL_COUNT_EVENT_BIT)) {
873		outb(event_status & (TI_INTERRUPT_EVENT_BIT | POINTERS_EQUAL_EVENT_BIT |
874				     BUFFER_END_EVENT_BIT | TERMINAL_COUNT_EVENT_BIT),
875		     hp_priv->iobase[0] + EVENT_STATUS_REG);
876		hp_priv->event_status_bits |= event_status;
877	}
878	if (event_status & TI_INTERRUPT_EVENT_BIT) {
879		status1 = read_byte(tms_priv, ISR0);
880		status2 = read_byte(tms_priv, ISR1);
881		tms9914_interrupt_have_status(board, tms_priv, status1, status2);
882	}
883	spin_unlock_irqrestore(&board->spinlock, flags);
884	return retval;
885}
886
887static int read_transfer_counter(struct hp_82341_priv *hp_priv)
888{
889	int lo, mid, value;
890
891	lo = inb(hp_priv->iobase[1] + TRANSFER_COUNT_LOW_REG);
892	mid = inb(hp_priv->iobase[1] + TRANSFER_COUNT_MID_REG);
893	value = (lo & 0xff) | ((mid << 8) & 0x7f00);
894	value = ~(value - 1) & 0x7fff;
895	return value;
896}
897
898static void set_transfer_counter(struct hp_82341_priv *hp_priv, int count)
899{
900	int complement = -count;
901
902	outb(complement & 0xff, hp_priv->iobase[1] + TRANSFER_COUNT_LOW_REG);
903	outb((complement >> 8) & 0xff, hp_priv->iobase[1] + TRANSFER_COUNT_MID_REG);
904	// I don't think the hi count reg is even used, but oh well
905	outb((complement >> 16) & 0xf, hp_priv->iobase[1] + TRANSFER_COUNT_HIGH_REG);
906}
907
~/ Read-only file preview.