1/* ps2esdi driver based on assembler code by Arindam Banerji,
2   written by Peter De Schrijver */
3/* Reassuring note to IBM : This driver was NOT developed by vice-versa
4   engineering the PS/2's BIOS */
5/* Dedicated to Wannes, Tofke, Ykke, Godot, Killroy and all those
6   other lovely fish out there... */
7/* This code was written during the long and boring WINA
8   elections 1994 */
9/* Thanks to Arindam Banerij for giving me the source of his driver */
10/* This code may be freely distributed and modified in any way,
11   as long as these notes remain intact */
12
13/*  Revised: 05/07/94 by Arindam Banerji (axb@cse.nd.edu) */
14/*  Revised: 09/08/94 by Peter De Schrijver (stud11@cc4.kuleuven.ac.be)
15   Thanks to Arindam Banerij for sending me the docs of the adapter */
16
17/* BA Modified for ThinkPad 720 by Boris Ashkinazi */
18/*                    (bash@vnet.ibm.com) 08/08/95 */
19
20/* Modified further for ThinkPad-720C by Uri Blumenthal */
21/*                    (uri@watson.ibm.com) Sep 11, 1995 */
22
23/* TODO :
24   + Timeouts
25   + Get disk parameters
26   + DMA above 16MB
27   + reset after read/write error
28 */
29
30#define DEVICE_NAME "PS/2 ESDI"
31
32#include <linux/major.h>
33#include <linux/errno.h>
34#include <linux/wait.h>
35#include <linux/interrupt.h>
36#include <linux/fs.h>
37#include <linux/kernel.h>
38#include <linux/genhd.h>
39#include <linux/ps2esdi.h>
40#include <linux/blkdev.h>
41#include <linux/mca-legacy.h>
42#include <linux/init.h>
43#include <linux/ioport.h>
44#include <linux/module.h>
45#include <linux/hdreg.h>
46
47#include <asm/system.h>
48#include <asm/io.h>
49#include <asm/dma.h>
50#include <asm/mca_dma.h>
51#include <asm/uaccess.h>
52
53#define PS2ESDI_IRQ 14
54#define MAX_HD 2
55#define MAX_RETRIES 5
56#define MAX_16BIT 65536
57#define ESDI_TIMEOUT   0xf000
58#define ESDI_STAT_TIMEOUT 4
59
60#define TYPE_0_CMD_BLK_LENGTH 2
61#define TYPE_1_CMD_BLK_LENGTH 4
62
63static void reset_ctrl(void);
64
65static int ps2esdi_geninit(void);
66
67static void do_ps2esdi_request(request_queue_t * q);
68
69static void ps2esdi_readwrite(int cmd, struct request *req);
70
71static void ps2esdi_fill_cmd_block(u_short * cmd_blk, u_short cmd,
72u_short cyl, u_short head, u_short sector, u_short length, u_char drive);
73
74static int ps2esdi_out_cmd_blk(u_short * cmd_blk);
75
76static void ps2esdi_prep_dma(char *buffer, u_short length, u_char dma_xmode);
77
78static irqreturn_t ps2esdi_interrupt_handler(int irq, void *dev_id);
79static void (*current_int_handler) (u_int) = NULL;
80static void ps2esdi_normal_interrupt_handler(u_int);
81static void ps2esdi_initial_reset_int_handler(u_int);
82static void ps2esdi_geometry_int_handler(u_int);
83static int ps2esdi_getgeo(struct block_device *bdev, struct hd_geometry *geo);
84
85static int ps2esdi_read_status_words(int num_words, int max_words, u_short * buffer);
86
87static void dump_cmd_complete_status(u_int int_ret_code);
88
89static void ps2esdi_get_device_cfg(void);
90
91static void ps2esdi_reset_timer(unsigned long unused);
92
93static u_int dma_arb_level;		/* DMA arbitration level */
94
95static DECLARE_WAIT_QUEUE_HEAD(ps2esdi_int);
96
97static int no_int_yet;
98static int ps2esdi_drives;
99static u_short io_base;
100static DEFINE_TIMER(esdi_timer, ps2esdi_reset_timer, 0, 0);
101static int reset_status;
102static int ps2esdi_slot = -1;
103static int tp720esdi = 0;	/* Is it Integrated ESDI of ThinkPad-720? */
104static int intg_esdi = 0;       /* If integrated adapter */
105struct ps2esdi_i_struct {
106	unsigned int head, sect, cyl, wpcom, lzone, ctl;
107};
108static DEFINE_SPINLOCK(ps2esdi_lock);
109static struct request_queue *ps2esdi_queue;
110static struct request *current_req;
111
112static struct ps2esdi_i_struct ps2esdi_info[MAX_HD] =
113{
114	{0, 0, 0, 0, 0, 0},
115	{0, 0, 0, 0, 0, 0}};
116
117static struct block_device_operations ps2esdi_fops =
118{
119	.owner		= THIS_MODULE,
120	.getgeo		= ps2esdi_getgeo,
121};
122
123static struct gendisk *ps2esdi_gendisk[2];
124
125/* initialization routine called by ll_rw_blk.c   */
126static int __init ps2esdi_init(void)
127{
128
129	int error = 0;
130
131	/* register the device - pass the name and major number */
132	if (register_blkdev(PS2ESDI_MAJOR, "ed"))
133		return -EBUSY;
134
135	/* set up some global information - indicating device specific info */
136	ps2esdi_queue = blk_init_queue(do_ps2esdi_request, &ps2esdi_lock);
137	if (!ps2esdi_queue) {
138		unregister_blkdev(PS2ESDI_MAJOR, "ed");
139		return -ENOMEM;
140	}
141
142	/* some minor housekeeping - setup the global gendisk structure */
143	error = ps2esdi_geninit();
144	if (error) {
145		printk(KERN_WARNING "PS2ESDI: error initialising"
146			" device, releasing resources\n");
147		unregister_blkdev(PS2ESDI_MAJOR, "ed");
148		blk_cleanup_queue(ps2esdi_queue);
149		return error;
150	}
151	return 0;
152}				/* ps2esdi_init */
153
154#ifndef MODULE
155
156module_init(ps2esdi_init);
157
158#else
159
160static int cyl[MAX_HD] = {-1,-1};
161static int head[MAX_HD] = {-1, -1};
162static int sect[MAX_HD] = {-1, -1};
163
164module_param(tp720esdi, bool, 0);
165module_param_array(cyl, int, NULL, 0);
166module_param_array(head, int, NULL, 0);
167module_param_array(sect, int, NULL, 0);
168MODULE_LICENSE("GPL");
169
170int init_module(void) {
171	int drive;
172
173	for(drive = 0; drive < MAX_HD; drive++) {
174	        struct ps2esdi_i_struct *info = &ps2esdi_info[drive];
175
176        	if (cyl[drive] != -1) {
177		  	info->cyl = info->lzone = cyl[drive];
178			info->wpcom = 0;
179		}
180        	if (head[drive] != -1) {
181			info->head = head[drive];
182			info->ctl = (head[drive] > 8 ? 8 : 0);
183		}
184        	if (sect[drive] != -1) info->sect = sect[drive];
185	}
186	return ps2esdi_init();
187}
188
189void
190cleanup_module(void) {
191	int i;
192	if(ps2esdi_slot) {
193		mca_mark_as_unused(ps2esdi_slot);
194		mca_set_adapter_procfn(ps2esdi_slot, NULL, NULL);
195	}
196	release_region(io_base, 4);
197	free_dma(dma_arb_level);
198	free_irq(PS2ESDI_IRQ, &ps2esdi_gendisk);
199	unregister_blkdev(PS2ESDI_MAJOR, "ed");
200	blk_cleanup_queue(ps2esdi_queue);
201	for (i = 0; i < ps2esdi_drives; i++) {
202		del_gendisk(ps2esdi_gendisk[i]);
203		put_disk(ps2esdi_gendisk[i]);
204	}
205}
206#endif /* MODULE */
207
208/* handles boot time command line parameters */
209void __init tp720_setup(char *str, int *ints)
210{
211	/* no params, just sets the tp720esdi flag if it exists */
212
213	printk("%s: TP 720 ESDI flag set\n", DEVICE_NAME);
214	tp720esdi = 1;
215}
216
217void __init ed_setup(char *str, int *ints)
218{
219	int hdind = 0;
220
221	/* handles 3 parameters only - corresponding to
222	   1. Number of cylinders
223	   2. Number of heads
224	   3. Sectors/track
225	 */
226
227	if (ints[0] != 3)
228		return;
229
230	/* print out the information - seen at boot time */
231	printk("%s: ints[0]=%d ints[1]=%d ints[2]=%d ints[3]=%d\n",
232	       DEVICE_NAME, ints[0], ints[1], ints[2], ints[3]);
233
234	/* set the index into device specific information table */
235	if (ps2esdi_info[0].head != 0)
236		hdind = 1;
237
238	/* set up all the device information */
239	ps2esdi_info[hdind].head = ints[2];
240	ps2esdi_info[hdind].sect = ints[3];
241	ps2esdi_info[hdind].cyl = ints[1];
242	ps2esdi_info[hdind].wpcom = 0;
243	ps2esdi_info[hdind].lzone = ints[1];
244	ps2esdi_info[hdind].ctl = (ints[2] > 8 ? 8 : 0);
245}				/* ed_setup */
246
247static int ps2esdi_getinfo(char *buf, int slot, void *d)
248{
249	int len = 0;
250
251	len += sprintf(buf + len, "DMA Arbitration Level: %d\n",
252		       dma_arb_level);
253	len += sprintf(buf + len, "IO Port: %x\n", io_base);
254	len += sprintf(buf + len, "IRQ: 14\n");
255	len += sprintf(buf + len, "Drives: %d\n", ps2esdi_drives);
256
257	return len;
258}
259
260/* ps2 esdi specific initialization - called thru the gendisk chain */
261static int __init ps2esdi_geninit(void)
262{
263	/*
264	   The first part contains the initialization code
265	   for the ESDI disk subsystem.  All we really do
266	   is search for the POS registers of the controller
267	   to do some simple setup operations.  First, we
268	   must ensure that the controller is installed,
269	   enabled, and configured as PRIMARY.  Then we must
270	   determine the DMA arbitration level being used by
271	   the controller so we can handle data transfer
272	   operations properly.  If all of this works, then
273	   we will set the INIT_FLAG to a non-zero value.
274	 */
275
276	int slot = 0, i, reset_start, reset_end;
277	u_char status;
278	unsigned short adapterID;
279	int error = 0;
280
281	if ((slot = mca_find_adapter(INTG_ESDI_ID, 0)) != MCA_NOTFOUND) {
282		adapterID = INTG_ESDI_ID;
283		printk("%s: integrated ESDI adapter found in slot %d\n",
284		       DEVICE_NAME, slot+1);
285#ifndef MODULE
286		mca_set_adapter_name(slot, "PS/2 Integrated ESDI");
287#endif
288	} else if ((slot = mca_find_adapter(NRML_ESDI_ID, 0)) != -1) {
289		adapterID = NRML_ESDI_ID;
290		printk("%s: normal ESDI adapter found in slot %d\n",
291		       DEVICE_NAME, slot+1);
292		mca_set_adapter_name(slot, "PS/2 ESDI");
293	} else {
294		return -ENODEV;
295	}
296
297	ps2esdi_slot = slot;
298	mca_mark_as_used(slot);
299	mca_set_adapter_procfn(slot, (MCA_ProcFn) ps2esdi_getinfo, NULL);
300
301	/* Found the slot - read the POS register 2 to get the necessary
302	   configuration and status information.  POS register 2 has the
303	   following information :
304	   Bit           Function
305	   7             reserved = 0
306	   6             arbitration method
307	   0 - fairness enabled
308	   1 - fairness disabled, linear priority assignment
309	   5-2           arbitration level
310	   1             alternate address
311	   1              alternate address
312	   0 - use addresses 0x3510 - 0x3517
313	   0             adapter enable
314	 */
315
316	status = mca_read_stored_pos(slot, 2);
317	/* is it enabled ? */
318	if (!(status & STATUS_ENABLED)) {
319		printk("%s: ESDI adapter disabled\n", DEVICE_NAME);
320		error = -ENODEV;
321		goto err_out1;
322	}
323	/* try to grab IRQ, and try to grab a slow IRQ if it fails, so we can
324	   share with the SCSI driver */
325	if (request_irq(PS2ESDI_IRQ, ps2esdi_interrupt_handler,
326		  IRQF_DISABLED | IRQF_SHARED, "PS/2 ESDI", &ps2esdi_gendisk)
327	    && request_irq(PS2ESDI_IRQ, ps2esdi_interrupt_handler,
328			   IRQF_SHARED, "PS/2 ESDI", &ps2esdi_gendisk)
329	    ) {
330		printk("%s: Unable to get IRQ %d\n", DEVICE_NAME, PS2ESDI_IRQ);
331		error = -EBUSY;
332		goto err_out1;
333	}
334	if (status & STATUS_ALTERNATE)
335		io_base = ALT_IO_BASE;
336	else
337		io_base = PRIMARY_IO_BASE;
338
339	if (!request_region(io_base, 4, "ed")) {
340		printk(KERN_WARNING"Unable to request region 0x%x\n", io_base);
341		error = -EBUSY;
342		goto err_out2;
343	}
344	/* get the dma arbitration level */
345	dma_arb_level = (status >> 2) & 0xf;
346
347	/* BA */
348	printk("%s: DMA arbitration level : %d\n",
349	       DEVICE_NAME, dma_arb_level);
350
351	LITE_ON;
352	current_int_handler = ps2esdi_initial_reset_int_handler;
353	reset_ctrl();
354	reset_status = 0;
355	reset_start = jiffies;
356	while (!reset_status) {
357		init_timer(&esdi_timer);
358		esdi_timer.expires = jiffies + HZ;
359		esdi_timer.data = 0;
360		add_timer(&esdi_timer);
361		sleep_on(&ps2esdi_int);
362	}
363	reset_end = jiffies;
364	LITE_OFF;
365	printk("%s: reset interrupt after %d jiffies,  %u.%02u secs\n",
366	       DEVICE_NAME, reset_end - reset_start, (reset_end - reset_start) / HZ,
367	       (reset_end - reset_start) % HZ);
368
369
370	/* Integrated ESDI Disk and Controller has only one drive! */
371	if (adapterID == INTG_ESDI_ID) {/* if not "normal" PS2 ESDI adapter */
372		ps2esdi_drives = 1;	/* then we have only one physical disk! */		intg_esdi = 1;
373	}
374
375
376
377	/* finally this part sets up some global data structures etc. */
378
379	ps2esdi_get_device_cfg();
380
381	/* some annoyance in the above routine returns TWO drives?
382	 Is something else happining in the background?
383	 Regaurdless we fix the # of drives again. AJK */
384	/* Integrated ESDI Disk and Controller has only one drive! */
385	if (adapterID == INTG_ESDI_ID)	/* if not "normal" PS2 ESDI adapter */
386		ps2esdi_drives = 1;	/* Not three or two, ONE DAMNIT! */
387
388	current_int_handler = ps2esdi_normal_interrupt_handler;
389
390	if (request_dma(dma_arb_level, "ed") !=0) {
391		printk(KERN_WARNING "PS2ESDI: Can't request dma-channel %d\n"
392			,(int) dma_arb_level);
393		error = -EBUSY;
394		goto err_out3;
395	}
396	blk_queue_max_sectors(ps2esdi_queue, 128);
397
398	error = -ENOMEM;
399	for (i = 0; i < ps2esdi_drives; i++) {
400		struct gendisk *disk = alloc_disk(64);
401		if (!disk)
402			goto err_out4;
403		disk->major = PS2ESDI_MAJOR;
404		disk->first_minor = i<<6;
405		sprintf(disk->disk_name, "ed%c", 'a'+i);
406		disk->fops = &ps2esdi_fops;
407		ps2esdi_gendisk[i] = disk;
408	}
409
410	for (i = 0; i < ps2esdi_drives; i++) {
411		struct gendisk *disk = ps2esdi_gendisk[i];
412		set_capacity(disk, ps2esdi_info[i].head * ps2esdi_info[i].sect *
413				ps2esdi_info[i].cyl);
414		disk->queue = ps2esdi_queue;
415		disk->private_data = &ps2esdi_info[i];
416		add_disk(disk);
417	}
418	return 0;
419err_out4:
420	while (i--)
421		put_disk(ps2esdi_gendisk[i]);
422err_out3:
423	release_region(io_base, 4);
424err_out2:
425	free_irq(PS2ESDI_IRQ, &ps2esdi_gendisk);
426err_out1:
427	if(ps2esdi_slot) {
428		mca_mark_as_unused(ps2esdi_slot);
429		mca_set_adapter_procfn(ps2esdi_slot, NULL, NULL);
430	}
431	return error;
432}
433
434static void __init ps2esdi_get_device_cfg(void)
435{
436	u_short cmd_blk[TYPE_0_CMD_BLK_LENGTH];
437
438	/*BA */ printk("%s: Drive 0\n", DEVICE_NAME);
439	current_int_handler = ps2esdi_geometry_int_handler;
440	cmd_blk[0] = CMD_GET_DEV_CONFIG | 0x600;
441	cmd_blk[1] = 0;
442	no_int_yet = TRUE;
443	ps2esdi_out_cmd_blk(cmd_blk);
444	if (no_int_yet)
445		sleep_on(&ps2esdi_int);
446
447	if (ps2esdi_drives > 1) {
448		printk("%s: Drive 1\n", DEVICE_NAME);	/*BA */
449		cmd_blk[0] = CMD_GET_DEV_CONFIG | (1 << 5) | 0x600;
450		cmd_blk[1] = 0;
451		no_int_yet = TRUE;
452		ps2esdi_out_cmd_blk(cmd_blk);
453		if (no_int_yet)
454			sleep_on(&ps2esdi_int);
455	}			/* if second physical drive is present */
456	return;
457}
458
459/* strategy routine that handles most of the IO requests */
460static void do_ps2esdi_request(request_queue_t * q)
461{
462	struct request *req;
463	/* since, this routine is called with interrupts cleared - they
464	   must be before it finishes  */
465
466	req = elv_next_request(q);
467	if (!req)
468		return;
469
470
471	/* check for above 16Mb dmas */
472	if (isa_virt_to_bus(req->buffer + req->current_nr_sectors * 512) > 16 * MB) {
473		printk("%s: DMA above 16MB not supported\n", DEVICE_NAME);
474		end_request(req, FAIL);
475		return;
476	}
477
478	if (req->sector+req->current_nr_sectors > get_capacity(req->rq_disk)) {
479		printk("Grrr. error. ps2esdi_drives: %d, %llu %llu\n",
480		    ps2esdi_drives, req->sector,
481		    (unsigned long long)get_capacity(req->rq_disk));
482		end_request(req, FAIL);
483		return;
484	}
485
486	switch (rq_data_dir(req)) {
487	case READ:
488		ps2esdi_readwrite(READ, req);
489		break;
490	case WRITE:
491		ps2esdi_readwrite(WRITE, req);
492		break;
493	default:
494		printk("%s: Unknown command\n", req->rq_disk->disk_name);
495		end_request(req, FAIL);
496		break;
497	}		/* handle different commands */
498}				/* main strategy routine */
499
500/* resets the ESDI adapter */
501static void reset_ctrl(void)
502{
503
504	u_long expire;
505	u_short status;
506
507	/* enable interrupts on the controller */
508	status = inb(ESDI_INTRPT);
509	outb((status & 0xe0) | ATT_EOI, ESDI_ATTN);	/* to be sure we don't have
510							   any interrupt pending... */
511	outb_p(CTRL_ENABLE_INTR, ESDI_CONTROL);
512
513	/* read the ESDI status port - if the controller is not busy,
514	   simply do a soft reset (fast) - otherwise we'll have to do a
515	   hard (slow) reset.  */
516	if (!(inb_p(ESDI_STATUS) & STATUS_BUSY)) {
517		/*BA */ printk("%s: soft reset...\n", DEVICE_NAME);
518		outb_p(CTRL_SOFT_RESET, ESDI_ATTN);
519	}
520	/* soft reset */
521	else {
522		/*BA */
523		printk("%s: hard reset...\n", DEVICE_NAME);
524		outb_p(CTRL_HARD_RESET, ESDI_CONTROL);
525		expire = jiffies + 2*HZ;
526		while (time_before(jiffies, expire));
527		outb_p(1, ESDI_CONTROL);
528	}			/* hard reset */
529
530
531}				/* reset the controller */
532
533/* called by the strategy routine to handle read and write requests */
534static void ps2esdi_readwrite(int cmd, struct request *req)
535{
536	struct ps2esdi_i_struct *p = req->rq_disk->private_data;
537	unsigned block = req->sector;
538	unsigned count = req->current_nr_sectors;
539	int drive = p - ps2esdi_info;
540	u_short track, head, cylinder, sector;
541	u_short cmd_blk[TYPE_1_CMD_BLK_LENGTH];
542
543	/* do some relevant arithmatic */
544	track = block / p->sect;
545	head = track % p->head;
546	cylinder = track / p->head;
547	sector = block % p->sect;
548
549	/* call the routine that actually fills out a command block */
550	ps2esdi_fill_cmd_block
551	    (cmd_blk,
552	     (cmd == READ) ? CMD_READ : CMD_WRITE,
553	     cylinder, head, sector, count, drive);
554
555	/* send the command block to the controller */
556	current_req = req;
557	spin_unlock_irq(&ps2esdi_lock);
558	if (ps2esdi_out_cmd_blk(cmd_blk)) {
559		spin_lock_irq(&ps2esdi_lock);
560		printk("%s: Controller failed\n", DEVICE_NAME);
561		if ((++req->errors) >= MAX_RETRIES)
562			end_request(req, FAIL);
563	}
564	/* check for failure to put out the command block */
565	else {
566		spin_lock_irq(&ps2esdi_lock);
567		/* turn disk lights on */
568		LITE_ON;
569	}
570
571}				/* ps2esdi_readwrite */
572
573/* fill out the command block */
574static void ps2esdi_fill_cmd_block(u_short * cmd_blk, u_short cmd,
575 u_short cyl, u_short head, u_short sector, u_short length, u_char drive)
576{
577
578	cmd_blk[0] = (drive << 5) | cmd;
579	cmd_blk[1] = length;
580	cmd_blk[2] = ((cyl & 0x1f) << 11) | (head << 5) | sector;
581	cmd_blk[3] = (cyl & 0x3E0) >> 5;
582
583}				/* fill out the command block */
584
585/* write a command block to the controller */
586static int ps2esdi_out_cmd_blk(u_short * cmd_blk)
587{
588
589	int i;
590	unsigned long jif;
591	u_char status;
592
593	/* enable interrupts */
594	outb(CTRL_ENABLE_INTR, ESDI_CONTROL);
595
596	/* do not write to the controller, if it is busy */
597	for (jif = jiffies + ESDI_STAT_TIMEOUT;
598		time_after(jif, jiffies) &&
599			(inb(ESDI_STATUS) & STATUS_BUSY); )
600		;
601
602
603	/* if device is still busy - then just time out */
604	if (inb(ESDI_STATUS) & STATUS_BUSY) {
605		printk("%s: ps2esdi_out_cmd timed out (1)\n", DEVICE_NAME);
606		return ERROR;
607	}			/* timeout ??? */
608	/* Set up the attention register in the controller */
609	outb(((*cmd_blk) & 0xE0) | 1, ESDI_ATTN);
610
611
612	/* one by one send each word out */
613	for (i = (((*cmd_blk) >> 14) + 1) << 1; i; i--) {
614		status = inb(ESDI_STATUS);
615		for (jif = jiffies + ESDI_STAT_TIMEOUT;
616		     time_after(jif, jiffies) && (status & STATUS_BUSY) &&
617		   (status & STATUS_CMD_INF); status = inb(ESDI_STATUS));
618		if ((status & (STATUS_BUSY | STATUS_CMD_INF)) == STATUS_BUSY) {
619			outw(*cmd_blk++, ESDI_CMD_INT);
620		} else {
621			printk("%s: ps2esdi_out_cmd timed out while sending command (status=%02X)\n",
622			       DEVICE_NAME, status);
623			return ERROR;
624		}
625	}			/* send all words out */
626	return OK;
627}				/* send out the commands */
628
629
630/* prepare for dma - do all the necessary setup */
631static void ps2esdi_prep_dma(char *buffer, u_short length, u_char dma_xmode)
632{
633	unsigned long flags = claim_dma_lock();
634
635	mca_disable_dma(dma_arb_level);
636
637	mca_set_dma_addr(dma_arb_level, isa_virt_to_bus(buffer));
638
639	mca_set_dma_count(dma_arb_level, length * 512 / 2);
640
641	mca_set_dma_mode(dma_arb_level, dma_xmode);
642
643	mca_enable_dma(dma_arb_level);
644
645	release_dma_lock(flags);
646
647}				/* prepare for dma */
648
649
650
651static irqreturn_t ps2esdi_interrupt_handler(int irq, void *dev_id)
652{
653	u_int int_ret_code;
654
655	if (inb(ESDI_STATUS) & STATUS_INTR) {
656		int_ret_code = inb(ESDI_INTRPT);
657		if (current_int_handler) {
658			/* Disable adapter interrupts till processing is finished */
659			outb(CTRL_DISABLE_INTR, ESDI_CONTROL);
660			current_int_handler(int_ret_code);
661		} else
662			printk("%s: help ! No interrupt handler.\n", DEVICE_NAME);
663	} else {
664		return IRQ_NONE;
665	}
666	return IRQ_HANDLED;
667}
668
669static void ps2esdi_initial_reset_int_handler(u_int int_ret_code)
670{
671
672	switch (int_ret_code & 0xf) {
673	case INT_RESET:
674		/*BA */
675		printk("%s: initial reset completed.\n", DEVICE_NAME);
676		outb((int_ret_code & 0xe0) | ATT_EOI, ESDI_ATTN);
677		wake_up(&ps2esdi_int);
678		break;
679	case INT_ATTN_ERROR:
680		printk("%s: Attention error. interrupt status : %02X\n", DEVICE_NAME,
681		       int_ret_code);
682		printk("%s: status: %02x\n", DEVICE_NAME, inb(ESDI_STATUS));
683		break;
684	default:
685		printk("%s: initial reset handler received interrupt: %02X\n",
686		       DEVICE_NAME, int_ret_code);
687		outb((int_ret_code & 0xe0) | ATT_EOI, ESDI_ATTN);
688		break;
689	}
690	outb(CTRL_ENABLE_INTR, ESDI_CONTROL);
691}
692
693
694static void ps2esdi_geometry_int_handler(u_int int_ret_code)
695{
696	u_int status, drive_num;
697	unsigned long rba;
698	int i;
699
700	drive_num = int_ret_code >> 5;
701	switch (int_ret_code & 0xf) {
702	case INT_CMD_COMPLETE:
703		for (i = ESDI_TIMEOUT; i && !(inb(ESDI_STATUS) & STATUS_STAT_AVAIL); i--);
704		if (!(inb(ESDI_STATUS) & STATUS_STAT_AVAIL)) {
705			printk("%s: timeout reading status word\n", DEVICE_NAME);
706			outb((int_ret_code & 0xe0) | ATT_EOI, ESDI_ATTN);
707			break;
708		}
709		status = inw(ESDI_STT_INT);
710		if ((status & 0x1F) == CMD_GET_DEV_CONFIG) {
711#define REPLY_WORDS 5		/* we already read word 0 */
712			u_short reply[REPLY_WORDS];
713
714			if (ps2esdi_read_status_words((status >> 8) - 1, REPLY_WORDS, reply)) {
715				/*BA */
716				printk("%s: Device Configuration Status for drive %u\n",
717				       DEVICE_NAME, drive_num);
718
719				printk("%s: Spares/cyls: %u", DEVICE_NAME, reply[0] >> 8);
720
721				printk
722				    ("Config bits: %s%s%s%s%s\n",
723				     (reply[0] & CONFIG_IS) ? "Invalid Secondary, " : "",
724				     ((reply[0] & CONFIG_ZD) && !(reply[0] & CONFIG_IS))
725				 ? "Zero Defect, " : "Defects Present, ",
726				     (reply[0] & CONFIG_SF) ? "Skewed Format, " : "",
727				     (reply[0] & CONFIG_FR) ? "Removable, " : "Non-Removable, ",
728				     (reply[0] & CONFIG_RT) ? "No Retries" : "Retries");
729
730				rba = reply[1] | ((unsigned long) reply[2] << 16);
731				printk("%s: Number of RBA's: %lu\n", DEVICE_NAME, rba);
732
733				printk("%s: Physical number of cylinders: %u, Sectors/Track: %u, Heads: %u\n",
734				       DEVICE_NAME, reply[3], reply[4] >> 8, reply[4] & 0xff);
735
736				if (!ps2esdi_info[drive_num].head) {
737					ps2esdi_info[drive_num].head = 64;
738					ps2esdi_info[drive_num].sect = 32;
739					ps2esdi_info[drive_num].cyl = rba / (64 * 32);
740					ps2esdi_info[drive_num].wpcom = 0;
741					ps2esdi_info[drive_num].lzone = ps2esdi_info[drive_num].cyl;
742					ps2esdi_info[drive_num].ctl = 8;
743					if (tp720esdi) {	/* store the retrieved parameters */
744						ps2esdi_info[0].head = reply[4] & 0Xff;
745						ps2esdi_info[0].sect = reply[4] >> 8;
746						ps2esdi_info[0].cyl = reply[3];
747						ps2esdi_info[0].wpcom = 0;
748						ps2esdi_info[0].lzone = reply[3];
749					} else {
750						if (!intg_esdi)
751							ps2esdi_drives++;
752					}
753				}
754#ifdef OBSOLETE
755				if (!ps2esdi_info[drive_num].head) {
756					ps2esdi_info[drive_num].head = reply[4] & 0Xff;
757					ps2esdi_info[drive_num].sect = reply[4] >> 8;
758					ps2esdi_info[drive_num].cyl = reply[3];
759					ps2esdi_info[drive_num].wpcom = 0;
760					ps2esdi_info[drive_num].lzone = reply[3];
761					if (tp720esdi) {	/* store the retrieved parameters */
762						ps2esdi_info[0].head = reply[4] & 0Xff;
763						ps2esdi_info[0].sect = reply[4] >> 8;
764						ps2esdi_info[0].cyl = reply[3];
765						ps2esdi_info[0].wpcom = 0;
766						ps2esdi_info[0].lzone = reply[3];
767					} else {
768						ps2esdi_drives++;
769					}
770				}
771#endif
772
773			} else
774				printk("%s: failed while getting device config\n", DEVICE_NAME);
775#undef REPLY_WORDS
776		} else
777			printk("%s: command %02X unknown by geometry handler\n",
778			       DEVICE_NAME, status & 0x1f);
779
780		outb((int_ret_code & 0xe0) | ATT_EOI, ESDI_ATTN);
781		break;
782
783	case INT_ATTN_ERROR:
784		printk("%s: Attention error. interrupt status : %02X\n", DEVICE_NAME,
785		       int_ret_code);
786		printk("%s: Device not available\n", DEVICE_NAME);
787		break;
788	case INT_CMD_ECC:
789	case INT_CMD_RETRY:
790	case INT_CMD_ECC_RETRY:
791	case INT_CMD_WARNING:
792	case INT_CMD_ABORT:
793	case INT_CMD_FAILED:
794	case INT_DMA_ERR:
795	case INT_CMD_BLK_ERR:
796		/*BA */ printk("%s: Whaa. Error occurred...\n", DEVICE_NAME);
797		dump_cmd_complete_status(int_ret_code);
798		outb((int_ret_code & 0xe0) | ATT_EOI, ESDI_ATTN);
799		break;
800	default:
801		printk("%s: Unknown interrupt reason: %02X\n",
802		       DEVICE_NAME, int_ret_code & 0xf);
803		outb((int_ret_code & 0xe0) | ATT_EOI, ESDI_ATTN);
804		break;
805	}
806
807	wake_up(&ps2esdi_int);
808	no_int_yet = FALSE;
809	outb(CTRL_ENABLE_INTR, ESDI_CONTROL);
810
811}
812
813static void ps2esdi_normal_interrupt_handler(u_int int_ret_code)
814{
815	unsigned long flags;
816	u_int status;
817	u_int ending;
818	int i;
819
820	switch (int_ret_code & 0x0f) {
821	case INT_TRANSFER_REQ:
822		ps2esdi_prep_dma(current_req->buffer,
823				 current_req->current_nr_sectors,
824		    (rq_data_dir(current_req) == READ)
825		    ? MCA_DMA_MODE_16 | MCA_DMA_MODE_WRITE | MCA_DMA_MODE_XFER
826		    : MCA_DMA_MODE_16 | MCA_DMA_MODE_READ);
827		outb(CTRL_ENABLE_DMA | CTRL_ENABLE_INTR, ESDI_CONTROL);
828		ending = -1;
829		break;
830
831	case INT_ATTN_ERROR:
832		printk("%s: Attention error. interrupt status : %02X\n", DEVICE_NAME,
833		       int_ret_code);
834		outb(CTRL_ENABLE_INTR, ESDI_CONTROL);
835		ending = FAIL;
836		break;
837
838	case INT_CMD_COMPLETE:
839		for (i = ESDI_TIMEOUT; i && !(inb(ESDI_STATUS) & STATUS_STAT_AVAIL); i--);
840		if (!(inb(ESDI_STATUS) & STATUS_STAT_AVAIL)) {
841			printk("%s: timeout reading status word\n", DEVICE_NAME);
842			outb((int_ret_code & 0xe0) | ATT_EOI, ESDI_ATTN);
843			outb(CTRL_ENABLE_INTR, ESDI_CONTROL);
844			if ((++current_req->errors) >= MAX_RETRIES)
845				ending = FAIL;
846			else
847				ending = -1;
848			break;
849		}
850		status = inw(ESDI_STT_INT);
851		switch (status & 0x1F) {
852		case (CMD_READ & 0xff):
853		case (CMD_WRITE & 0xff):
854			LITE_OFF;
855			outb((int_ret_code & 0xe0) | ATT_EOI, ESDI_ATTN);
856			outb(CTRL_ENABLE_INTR, ESDI_CONTROL);
857			ending = SUCCES;
858			break;
859		default:
860			printk("%s: interrupt for unknown command %02X\n",
861			       DEVICE_NAME, status & 0x1f);
862			outb((int_ret_code & 0xe0) | ATT_EOI, ESDI_ATTN);
863			outb(CTRL_ENABLE_INTR, ESDI_CONTROL);
864			ending = -1;
865			break;
866		}
867		break;
868	case INT_CMD_ECC:
869	case INT_CMD_RETRY:
870	case INT_CMD_ECC_RETRY:
871		LITE_OFF;
872		dump_cmd_complete_status(int_ret_code);
873		outb((int_ret_code & 0xe0) | ATT_EOI, ESDI_ATTN);
874		outb(CTRL_ENABLE_INTR, ESDI_CONTROL);
875		ending = SUCCES;
876		break;
877	case INT_CMD_WARNING:
878	case INT_CMD_ABORT:
879	case INT_CMD_FAILED:
880	case INT_DMA_ERR:
881		LITE_OFF;
882		dump_cmd_complete_status(int_ret_code);
883		outb((int_ret_code & 0xe0) | ATT_EOI, ESDI_ATTN);
884		outb(CTRL_ENABLE_INTR, ESDI_CONTROL);
885		if ((++current_req->errors) >= MAX_RETRIES)
886			ending = FAIL;
887		else
888			ending = -1;
889		break;
890
891	case INT_CMD_BLK_ERR:
892		dump_cmd_complete_status(int_ret_code);
893		outb((int_ret_code & 0xe0) | ATT_EOI, ESDI_ATTN);
894		outb(CTRL_ENABLE_INTR, ESDI_CONTROL);
895		ending = FAIL;
896		break;
897
898	case INT_CMD_FORMAT:
899		printk("%s: huh ? Who issued this format command ?\n"
900		       ,DEVICE_NAME);
901		outb((int_ret_code & 0xe0) | ATT_EOI, ESDI_ATTN);
902		outb(CTRL_ENABLE_INTR, ESDI_CONTROL);
903		ending = -1;
904		break;
905
906	case INT_RESET:
907		/* BA printk("%s: reset completed.\n", DEVICE_NAME) */ ;
908		outb((int_ret_code & 0xe0) | ATT_EOI, ESDI_ATTN);
909		outb(CTRL_ENABLE_INTR, ESDI_CONTROL);
910		ending = -1;
911		break;
912
913	default:
914		printk("%s: Unknown interrupt reason: %02X\n",
915		       DEVICE_NAME, int_ret_code & 0xf);
916		outb((int_ret_code & 0xe0) | ATT_EOI, ESDI_ATTN);
917		outb(CTRL_ENABLE_INTR, ESDI_CONTROL);
918		ending = -1;
919		break;
920	}
921	if(ending != -1) {
922		spin_lock_irqsave(&ps2esdi_lock, flags);
923		end_request(current_req, ending);
924		current_req = NULL;
925		do_ps2esdi_request(ps2esdi_queue);
926		spin_unlock_irqrestore(&ps2esdi_lock, flags);
927	}
928}				/* handle interrupts */
929
930
931
932static int ps2esdi_read_status_words(int num_words,
933				     int max_words,
934				     u_short * buffer)
935{
936	int i;
937
938	for (; max_words && num_words; max_words--, num_words--, buffer++) {
939		for (i = ESDI_TIMEOUT; i && !(inb(ESDI_STATUS) & STATUS_STAT_AVAIL); i--);
940		if (!(inb(ESDI_STATUS) & STATUS_STAT_AVAIL)) {
941			printk("%s: timeout reading status word\n", DEVICE_NAME);
942			return FAIL;
943		}
944		*buffer = inw(ESDI_STT_INT);
945	}
946	return SUCCES;
947}
948
949
950
951
952static void dump_cmd_complete_status(u_int int_ret_code)
953{
954#define WAIT_FOR_STATUS \
955  for(i=ESDI_TIMEOUT;i && !(inb(ESDI_STATUS) & STATUS_STAT_AVAIL);i--); \
956    if(!(inb(ESDI_STATUS) & STATUS_STAT_AVAIL)) { \
957    printk("%s: timeout reading status word\n",DEVICE_NAME); \
958    return; \
959    }
960
961	int i, word_count;
962	u_short stat_word;
963	u_long rba;
964
965	printk("%s: Device: %u, interrupt ID: %02X\n",
966	       DEVICE_NAME, int_ret_code >> 5,
967	       int_ret_code & 0xf);
968
969	WAIT_FOR_STATUS;
970	stat_word = inw(ESDI_STT_INT);
971	word_count = (stat_word >> 8) - 1;
972	printk("%s: %u status words, command: %02X\n", DEVICE_NAME, word_count,
973	       stat_word & 0xff);
974
975	if (word_count--) {
976		WAIT_FOR_STATUS;
977		stat_word = inw(ESDI_STT_INT);
978		printk("%s: command status code: %02X, command error code: %02X\n",
979		       DEVICE_NAME, stat_word >> 8, stat_word & 0xff);
980	}
981	if (word_count--) {
982		WAIT_FOR_STATUS;
983		stat_word = inw(ESDI_STT_INT);
984		printk("%s: device error code: %s%s%s%s%s,%02X\n", DEVICE_NAME,
985		       (stat_word & 0x1000) ? "Ready, " : "Not Ready, ",
986		  (stat_word & 0x0800) ? "Selected, " : "Not Selected, ",
987		       (stat_word & 0x0400) ? "Write Fault, " : "",
988		       (stat_word & 0x0200) ? "Track 0, " : "",
989		(stat_word & 0x0100) ? "Seek or command complete, " : "",
990		       stat_word >> 8);
991	}
992	if (word_count--) {
993		WAIT_FOR_STATUS;
994		stat_word = inw(ESDI_STT_INT);
995		printk("%s: Blocks to do: %u", DEVICE_NAME, stat_word);
996	}
997	if (word_count -= 2) {
998		WAIT_FOR_STATUS;
999		rba = inw(ESDI_STT_INT);
1000		WAIT_FOR_STATUS;
1001		rba |= inw(ESDI_STT_INT) << 16;
1002		printk(", Last Cyl: %u Head: %u Sector: %u\n",
1003		       (u_short) ((rba & 0x1ff80000) >> 11),
1004		 (u_short) ((rba & 0x7E0) >> 5), (u_short) (rba & 0x1f));
1005	} else
1006		printk("\n");
1007
1008	if (word_count--) {
1009		WAIT_FOR_STATUS;
1010		stat_word = inw(ESDI_STT_INT);
1011		printk("%s: Blocks required ECC: %u", DEVICE_NAME, stat_word);
1012	}
1013	printk("\n");
1014
1015#undef WAIT_FOR_STATUS
1016
1017}
1018
1019static int ps2esdi_getgeo(struct block_device *bdev, struct hd_geometry *geo)
1020{
1021	struct ps2esdi_i_struct *p = bdev->bd_disk->private_data;
1022
1023	geo->heads = p->head;
1024	geo->sectors = p->sect;
1025	geo->cylinders = p->cyl;
1026	return 0;
1027}
1028
1029static void ps2esdi_reset_timer(unsigned long unused)
1030{
1031
1032	int status;
1033
1034	status = inb(ESDI_INTRPT);
1035	if ((status & 0xf) == INT_RESET) {
1036		outb((status & 0xe0) | ATT_EOI, ESDI_ATTN);
1037		outb(CTRL_ENABLE_INTR, ESDI_CONTROL);
1038		reset_status = 1;
1039	}
1040	wake_up(&ps2esdi_int);
1041}
1042