1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30#include <linux/config.h>
31#include <linux/major.h>
32
33#ifdef CONFIG_BLK_DEV_PS2
34
35#define MAJOR_NR PS2ESDI_MAJOR
36
37#include <linux/errno.h>
38#include <linux/sched.h>
39#include <linux/mm.h>
40#include <linux/fs.h>
41#include <linux/kernel.h>
42#include <linux/genhd.h>
43#include <linux/ps2esdi.h>
44#include <linux/devfs_fs_kernel.h>
45#include <linux/blk.h>
46#include <linux/blkpg.h>
47#include <linux/mca.h>
48#include <linux/init.h>
49#include <linux/ioport.h>
50#include <linux/module.h>
51
52#include <asm/system.h>
53#include <asm/io.h>
54#include <asm/segment.h>
55#include <asm/dma.h>
56#include <asm/mca_dma.h>
57#include <asm/uaccess.h>
58
59#define PS2ESDI_IRQ 14
60#define MAX_HD 2
61#define MAX_RETRIES 5
62#define MAX_16BIT 65536
63#define ESDI_TIMEOUT 0xf000
64#define ESDI_STAT_TIMEOUT 4
65
66#define TYPE_0_CMD_BLK_LENGTH 2
67#define TYPE_1_CMD_BLK_LENGTH 4
68
69
70static void reset_ctrl(void);
71
72int ps2esdi_init(void);
73
74static void ps2esdi_geninit(void);
75
76static void do_ps2esdi_request(request_queue_t * q);
77
78static void ps2esdi_readwrite(int cmd, u_char drive, u_int block, u_int count);
79
80static void ps2esdi_fill_cmd_block(u_short * cmd_blk, u_short cmd,
81u_short cyl, u_short head, u_short sector, u_short length, u_char drive);
82
83static int ps2esdi_out_cmd_blk(u_short * cmd_blk);
84
85static void ps2esdi_prep_dma(char *buffer, u_short length, u_char dma_xmode);
86
87static void ps2esdi_interrupt_handler(int irq, void *dev_id,
88 struct pt_regs *regs);
89static void (*current_int_handler) (u_int) = NULL;
90static void ps2esdi_normal_interrupt_handler(u_int);
91static void ps2esdi_initial_reset_int_handler(u_int);
92static void ps2esdi_geometry_int_handler(u_int);
93
94static int ps2esdi_open(struct inode *inode, struct file *file);
95
96static int ps2esdi_release(struct inode *inode, struct file *file);
97
98static int ps2esdi_ioctl(struct inode *inode, struct file *file,
99 u_int cmd, u_long arg);
100
101static int ps2esdi_reread_partitions(kdev_t dev);
102
103static int ps2esdi_read_status_words(int num_words, int max_words, u_short * buffer);
104
105static void dump_cmd_complete_status(u_int int_ret_code);
106
107static void ps2esdi_get_device_cfg(void);
108
109static void ps2esdi_reset_timer(unsigned long unused);
110
111static u_int dma_arb_level;
112
113static DECLARE_WAIT_QUEUE_HEAD(ps2esdi_int);
114static DECLARE_WAIT_QUEUE_HEAD(ps2esdi_wait_open);
115
116static int no_int_yet;
117static int access_count[MAX_HD];
118static char ps2esdi_valid[MAX_HD];
119static int ps2esdi_sizes[MAX_HD << 6];
120static int ps2esdi_blocksizes[MAX_HD << 6];
121static int ps2esdi_maxsect[MAX_HD << 6];
122static int ps2esdi_drives;
123static struct hd_struct ps2esdi[MAX_HD << 6];
124static u_short io_base;
125static struct timer_list esdi_timer = { function: ps2esdi_reset_timer };
126static int reset_status;
127static int ps2esdi_slot = -1;
128static int tp720esdi = 0;
129static int intg_esdi = 0;
130struct ps2esdi_i_struct {
131 unsigned int head, sect, cyl, wpcom, lzone, ctl;
132};
133
134#if 0
135#if 0
136static struct ps2esdi_i_struct ps2esdi_info[MAX_HD] =
137{
138 {4, 48, 1553, 0, 0, 0},
139 {0, 0, 0, 0, 0, 0}};
140#else
141static struct ps2esdi_i_struct ps2esdi_info[MAX_HD] =
142{
143 {64, 32, 161, 0, 0, 0},
144 {0, 0, 0, 0, 0, 0}};
145#endif
146#endif
147static struct ps2esdi_i_struct ps2esdi_info[MAX_HD] =
148{
149 {0, 0, 0, 0, 0, 0},
150 {0, 0, 0, 0, 0, 0}};
151
152static struct block_device_operations ps2esdi_fops =
153{
154 owner: THIS_MODULE,
155 open: ps2esdi_open,
156 release: ps2esdi_release,
157 ioctl: ps2esdi_ioctl,
158};
159
160static struct gendisk ps2esdi_gendisk =
161{
162 major: MAJOR_NR,
163 major_name: "ed",
164 minor_shift: 6,
165 max_p: 1 << 6,
166 part: ps2esdi,
167 sizes: ps2esdi_sizes,
168 real_devices: (void *)ps2esdi_info,
169 fops: &ps2esdi_fops,
170};
171
172
173int __init ps2esdi_init(void)
174{
175
176
177
178 if (devfs_register_blkdev(MAJOR_NR, "ed", &ps2esdi_fops)) {
179 printk("%s: Unable to get major number %d\n", DEVICE_NAME, MAJOR_NR);
180 return -1;
181 }
182
183 blk_init_queue(BLK_DEFAULT_QUEUE(MAJOR_NR), DEVICE_REQUEST);
184 read_ahead[MAJOR_NR] = 8;
185
186
187 add_gendisk(&ps2esdi_gendisk);
188 ps2esdi_geninit();
189 return 0;
190}
191
192#ifdef MODULE
193
194static int cyl[MAX_HD] = {-1,-1};
195static int head[MAX_HD] = {-1, -1};
196static int sect[MAX_HD] = {-1, -1};
197
198MODULE_PARM(tp720esdi, "i");
199MODULE_PARM(cyl, "i");
200MODULE_PARM(head, "i");
201MODULE_PARM(track, "i");
202MODULE_LICENSE("GPL");
203
204int init_module(void) {
205 int drive;
206
207 for(drive = 0; drive < MAX_HD; drive++) {
208 struct ps2_esdi_i_struct *info = &ps2esdi_info[drive];
209
210 if (cyl[drive] != -1) {
211 info->cyl = info->lzone = cyl[drive];
212 info->wpcom = 0;
213 }
214 if (head[drive] != -1) {
215 info->head = head[drive];
216 info->ctl = (head[drive] > 8 ? 8 : 0);
217 }
218 if (sect[drive] != -1) info->sect = sect[drive];
219 }
220 return ps2esdi_init();
221}
222
223void
224cleanup_module(void)
225{
226 if(ps2esdi_slot) {
227 mca_mark_as_unused(ps2esdi_slot);
228 mca_set_adapter_procfn(ps2esdi_slot, NULL, NULL);
229 }
230 release_region(io_base, 4);
231 free_dma(dma_arb_level);
232 free_irq(PS2ESDI_IRQ, NULL);
233 devfs_unregister_blkdev(MAJOR_NR, "ed");
234 del_gendisk(&ps2esdi_gendisk);
235 blk_cleanup_queue(BLK_DEFAULT_QUEUE(MAJOR_NR));
236}
237#endif
238
239
240void __init tp720_setup(char *str, int *ints)
241{
242
243
244 printk("%s: TP 720 ESDI flag set\n", DEVICE_NAME);
245 tp720esdi = 1;
246}
247
248void __init ed_setup(char *str, int *ints)
249{
250 int hdind = 0;
251
252
253
254
255
256
257
258 if (ints[0] != 3)
259 return;
260
261
262 printk("%s: ints[0]=%d ints[1]=%d ints[2]=%d ints[3]=%d\n",
263 DEVICE_NAME, ints[0], ints[1], ints[2], ints[3]);
264
265
266 if (ps2esdi_info[0].head != 0)
267 hdind = 1;
268
269
270 ps2esdi_info[hdind].head = ints[2];
271 ps2esdi_info[hdind].sect = ints[3];
272 ps2esdi_info[hdind].cyl = ints[1];
273 ps2esdi_info[hdind].wpcom = 0;
274 ps2esdi_info[hdind].lzone = ints[1];
275 ps2esdi_info[hdind].ctl = (ints[2] > 8 ? 8 : 0);
276#if 0
277 ps2esdi_drives = hdind + 1;
278#endif
279}
280
281static int ps2esdi_getinfo(char *buf, int slot, void *d)
282{
283 int len = 0;
284
285 len += sprintf(buf + len, "DMA Arbitration Level: %d\n",
286 dma_arb_level);
287 len += sprintf(buf + len, "IO Port: %x\n", io_base);
288 len += sprintf(buf + len, "IRQ: 14\n");
289 len += sprintf(buf + len, "Drives: %d\n", ps2esdi_drives);
290
291 return len;
292}
293
294
295static void __init ps2esdi_geninit(void)
296{
297
298
299
300
301
302
303
304
305
306
307
308
309
310 int slot = 0, i, reset_start, reset_end;
311 u_char status;
312 unsigned short adapterID;
313
314 if ((slot = mca_find_adapter(INTG_ESDI_ID, 0)) != MCA_NOTFOUND) {
315 adapterID = INTG_ESDI_ID;
316 printk("%s: integrated ESDI adapter found in slot %d\n",
317 DEVICE_NAME, slot+1);
318#ifndef MODULE
319 mca_set_adapter_name(slot, "PS/2 Integrated ESDI");
320#endif
321 } else if ((slot = mca_find_adapter(NRML_ESDI_ID, 0)) != -1) {
322 adapterID = NRML_ESDI_ID;
323 printk("%s: normal ESDI adapter found in slot %d\n",
324 DEVICE_NAME, slot+1);
325 mca_set_adapter_name(slot, "PS/2 ESDI");
326 } else {
327 return;
328 }
329
330 ps2esdi_slot = slot;
331 mca_mark_as_used(slot);
332 mca_set_adapter_procfn(slot, (MCA_ProcFn) ps2esdi_getinfo, NULL);
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349 status = mca_read_stored_pos(slot, 2);
350
351 if (!(status & STATUS_ENABLED)) {
352 printk("%s: ESDI adapter disabled\n", DEVICE_NAME);
353 return;
354 }
355
356
357 if (request_irq(PS2ESDI_IRQ, ps2esdi_interrupt_handler,
358 SA_INTERRUPT | SA_SHIRQ, "PS/2 ESDI", &ps2esdi_gendisk)
359 && request_irq(PS2ESDI_IRQ, ps2esdi_interrupt_handler,
360 SA_SHIRQ, "PS/2 ESDI", &ps2esdi_gendisk)
361 ) {
362 printk("%s: Unable to get IRQ %d\n", DEVICE_NAME, PS2ESDI_IRQ);
363 return;
364 }
365 if (status & STATUS_ALTERNATE)
366 io_base = ALT_IO_BASE;
367 else
368 io_base = PRIMARY_IO_BASE;
369
370
371 dma_arb_level = (status >> 2) & 0xf;
372
373
374 printk("%s: DMA arbitration level : %d\n",
375 DEVICE_NAME, dma_arb_level);
376
377 LITE_ON;
378 current_int_handler = ps2esdi_initial_reset_int_handler;
379 reset_ctrl();
380 reset_status = 0;
381 reset_start = jiffies;
382 while (!reset_status) {
383 init_timer(&esdi_timer);
384 esdi_timer.expires = jiffies + HZ;
385 esdi_timer.data = 0;
386 add_timer(&esdi_timer);
387 sleep_on(&ps2esdi_int);
388 }
389 reset_end = jiffies;
390 LITE_OFF;
391 printk("%s: reset interrupt after %d jiffies, %u.%02u secs\n",
392 DEVICE_NAME, reset_end - reset_start, (reset_end - reset_start) / HZ,
393 (reset_end - reset_start) % HZ);
394
395
396
397 if (adapterID == INTG_ESDI_ID) {
398 ps2esdi_drives = 1; intg_esdi = 1;
399 }
400
401
402
403
404
405 ps2esdi_get_device_cfg();
406
407
408
409
410
411 if (adapterID == INTG_ESDI_ID)
412 ps2esdi_drives = 1;
413
414 current_int_handler = ps2esdi_normal_interrupt_handler;
415
416 ps2esdi_gendisk.nr_real = ps2esdi_drives;
417
418
419 for (i = 0; i < (MAX_HD << 6); i++) {
420 ps2esdi_maxsect[i] = 128;
421 ps2esdi_blocksizes[i] = 1024;
422 }
423
424 request_dma(dma_arb_level, "ed");
425 request_region(io_base, 4, "ed");
426 blksize_size[MAJOR_NR] = ps2esdi_blocksizes;
427 max_sectors[MAJOR_NR] = ps2esdi_maxsect;
428
429 for (i = 0; i < ps2esdi_drives; i++) {
430 register_disk(&ps2esdi_gendisk,MKDEV(MAJOR_NR,i<<6),1<<6,
431 &ps2esdi_fops,
432 ps2esdi_info[i].head * ps2esdi_info[i].sect *
433 ps2esdi_info[i].cyl);
434 ps2esdi_valid[i] = 1;
435 }
436}
437
438static void __init ps2esdi_get_device_cfg(void)
439{
440 u_short cmd_blk[TYPE_0_CMD_BLK_LENGTH];
441
442 printk("%s: Drive 0\n", DEVICE_NAME);
443 current_int_handler = ps2esdi_geometry_int_handler;
444 cmd_blk[0] = CMD_GET_DEV_CONFIG | 0x600;
445 cmd_blk[1] = 0;
446 no_int_yet = TRUE;
447 ps2esdi_out_cmd_blk(cmd_blk);
448 if (no_int_yet)
449 sleep_on(&ps2esdi_int);
450
451 if (ps2esdi_drives > 1) {
452 printk("%s: Drive 1\n", DEVICE_NAME);
453 cmd_blk[0] = CMD_GET_DEV_CONFIG | (1 << 5) | 0x600;
454 cmd_blk[1] = 0;
455 no_int_yet = TRUE;
456 ps2esdi_out_cmd_blk(cmd_blk);
457 if (no_int_yet)
458 sleep_on(&ps2esdi_int);
459 }
460 return;
461}
462
463
464static void do_ps2esdi_request(request_queue_t * q)
465{
466 u_int block, count;
467
468
469
470#if 0
471 printk("%s:got request. device : %d minor : %d command : %d sector : %ld count : %ld, buffer: %p\n",
472 DEVICE_NAME,
473 CURRENT_DEV, MINOR(CURRENT->rq_dev),
474 CURRENT->cmd, CURRENT->sector,
475 CURRENT->current_nr_sectors, CURRENT->buffer);
476#endif
477
478
479
480 INIT_REQUEST;
481
482 if (virt_to_bus(CURRENT->buffer + CURRENT->current_nr_sectors * 512) > 16 * MB) {
483 printk("%s: DMA above 16MB not supported\n", DEVICE_NAME);
484 end_request(FAIL);
485 }
486 else if ((CURRENT_DEV < ps2esdi_drives) &&
487 (CURRENT->sector + CURRENT->current_nr_sectors <=
488 ps2esdi[MINOR(CURRENT->rq_dev)].nr_sects)) {
489#if 0
490 printk("%s:got request. device : %d minor : %d command : %d sector : %ld count : %ld\n",
491 DEVICE_NAME,
492 CURRENT_DEV, MINOR(CURRENT->rq_dev),
493 CURRENT->cmd, CURRENT->sector,
494 CURRENT->current_nr_sectors);
495#endif
496
497
498 block = CURRENT->sector + ps2esdi[MINOR(CURRENT->rq_dev)].start_sect;
499
500#if 0
501 printk("%s: blocknumber : %d\n", DEVICE_NAME, block);
502#endif
503 count = CURRENT->current_nr_sectors;
504 switch (CURRENT->cmd) {
505 case READ:
506 ps2esdi_readwrite(READ, CURRENT_DEV, block, count);
507 break;
508 case WRITE:
509 ps2esdi_readwrite(WRITE, CURRENT_DEV, block, count);
510 break;
511 default:
512 printk("%s: Unknown command\n", DEVICE_NAME);
513 end_request(FAIL);
514 break;
515 }
516 }
517
518 else {
519 printk("Grrr. error. ps2esdi_drives: %d, %lu %lu\n", ps2esdi_drives,
520 CURRENT->sector, ps2esdi[MINOR(CURRENT->rq_dev)].nr_sects);
521 end_request(FAIL);
522 }
523
524}
525
526
527static void reset_ctrl(void)
528{
529
530 u_long expire;
531 u_short status;
532
533
534 status = inb(ESDI_INTRPT);
535 outb((status & 0xe0) | ATT_EOI, ESDI_ATTN);
536
537 outb_p(CTRL_ENABLE_INTR, ESDI_CONTROL);
538
539
540
541
542 if (!(inb_p(ESDI_STATUS) & STATUS_BUSY)) {
543 printk("%s: soft reset...\n", DEVICE_NAME);
544 outb_p(CTRL_SOFT_RESET, ESDI_ATTN);
545 }
546
547 else {
548
549 printk("%s: hard reset...\n", DEVICE_NAME);
550 outb_p(CTRL_HARD_RESET, ESDI_CONTROL);
551 expire = jiffies + 2*HZ;
552 while (time_before(jiffies, expire));
553 outb_p(1, ESDI_CONTROL);
554 }
555
556
557}
558
559
560static void ps2esdi_readwrite(int cmd, u_char drive, u_int block, u_int count)
561{
562
563 u_short track, head, cylinder, sector;
564 u_short cmd_blk[TYPE_1_CMD_BLK_LENGTH];
565 int err;
566
567
568 track = block / ps2esdi_info[drive].sect;
569 head = track % ps2esdi_info[drive].head;
570 cylinder = track / ps2esdi_info[drive].head;
571 sector = block % ps2esdi_info[drive].sect;
572
573#if 0
574 printk("%s: cyl=%d head=%d sect=%d\n", DEVICE_NAME, cylinder, head, sector);
575#endif
576
577 ps2esdi_fill_cmd_block
578 (cmd_blk,
579 (cmd == READ) ? CMD_READ : CMD_WRITE,
580 cylinder, head, sector,
581 CURRENT->current_nr_sectors, drive);
582
583 spin_unlock_irq(&io_request_lock);
584
585 err = ps2esdi_out_cmd_blk(cmd_blk);
586 spin_lock_irq(&io_request_lock);
587
588 if (err) {
589 printk(KERN_ERR "%s: Controller failed\n", DEVICE_NAME);
590 if ((++CURRENT->errors) >= MAX_RETRIES)
591 end_request(FAIL);
592 }
593
594 else {
595#if 0
596 printk("%s: waiting for xfer\n", DEVICE_NAME);
597#endif
598
599 LITE_ON;
600 }
601
602}
603
604
605static void ps2esdi_fill_cmd_block(u_short * cmd_blk, u_short cmd,
606 u_short cyl, u_short head, u_short sector, u_short length, u_char drive)
607{
608
609 cmd_blk[0] = (drive << 5) | cmd;
610 cmd_blk[1] = length;
611 cmd_blk[2] = ((cyl & 0x1f) << 11) | (head << 5) | sector;
612 cmd_blk[3] = (cyl & 0x3E0) >> 5;
613
614}
615
616
617static int ps2esdi_out_cmd_blk(u_short * cmd_blk)
618{
619
620 int i, j;
621 u_char status;
622
623
624 outb(CTRL_ENABLE_INTR, ESDI_CONTROL);
625
626
627 for (i = jiffies + ESDI_STAT_TIMEOUT; time_after(i, jiffies) && (inb(ESDI_STATUS) &
628 STATUS_BUSY););
629
630#if 0
631 printk("%s: i(1)=%d\n", DEVICE_NAME, i);
632#endif
633
634
635 if (inb(ESDI_STATUS) & STATUS_BUSY) {
636 printk("%s: ps2esdi_out_cmd timed out (1)\n", DEVICE_NAME);
637 return ERROR;
638 }
639
640 outb(((*cmd_blk) & 0xE0) | 1, ESDI_ATTN);
641
642#if 0
643 printk("%s: sending %d words to controller\n", DEVICE_NAME, (((*cmd_blk) >> 14) + 1) << 1);
644#endif
645
646
647 for (i = (((*cmd_blk) >> 14) + 1) << 1; i; i--) {
648 status = inb(ESDI_STATUS);
649 for (j = jiffies + ESDI_STAT_TIMEOUT;
650 time_after(j, jiffies) && (status & STATUS_BUSY) &&
651 (status & STATUS_CMD_INF); status = inb(ESDI_STATUS));
652 if ((status & (STATUS_BUSY | STATUS_CMD_INF)) == STATUS_BUSY) {
653#if 0
654 printk("%s: sending %04X\n", DEVICE_NAME, *cmd_blk);
655#endif
656 outw(*cmd_blk++, ESDI_CMD_INT);
657 } else {
658 printk("%s: ps2esdi_out_cmd timed out while sending command (status=%02X)\n",
659 DEVICE_NAME, status);
660 return ERROR;
661 }
662 }
663 return OK;
664}
665
666
667
668static void ps2esdi_prep_dma(char *buffer, u_short length, u_char dma_xmode)
669{
670 unsigned long flags;
671#if 0
672 printk("ps2esdi: b_wait: %p\n", &CURRENT->bh->b_wait);
673#endif
674 flags = claim_dma_lock();
675
676 mca_disable_dma(dma_arb_level);
677
678 mca_set_dma_addr(dma_arb_level, virt_to_bus(buffer));
679
680 mca_set_dma_count(dma_arb_level, length * 512 / 2);
681
682 mca_set_dma_mode(dma_arb_level, dma_xmode);
683
684 mca_enable_dma(dma_arb_level);
685
686 release_dma_lock(flags);
687
688}
689
690
691
692static void ps2esdi_interrupt_handler(int irq, void *dev_id,
693 struct pt_regs *regs)
694{
695 u_int int_ret_code;
696
697 if (inb(ESDI_STATUS) & STATUS_INTR) {
698 int_ret_code = inb(ESDI_INTRPT);
699 if (current_int_handler) {
700
701 outb(CTRL_DISABLE_INTR, ESDI_CONTROL);
702 current_int_handler(int_ret_code);
703 } else
704 printk("%s: help ! No interrupt handler.\n", DEVICE_NAME);
705 } else {
706 return;
707 }
708}
709
710static void ps2esdi_initial_reset_int_handler(u_int int_ret_code)
711{
712
713 switch (int_ret_code & 0xf) {
714 case INT_RESET:
715
716 printk("%s: initial reset completed.\n", DEVICE_NAME);
717 outb((int_ret_code & 0xe0) | ATT_EOI, ESDI_ATTN);
718 wake_up(&ps2esdi_int);
719 break;
720 case INT_ATTN_ERROR:
721 printk("%s: Attention error. interrupt status : %02X\n", DEVICE_NAME,
722 int_ret_code);
723 printk("%s: status: %02x\n", DEVICE_NAME, inb(ESDI_STATUS));
724 break;
725 default:
726 printk("%s: initial reset handler received interrupt: %02X\n",
727 DEVICE_NAME, int_ret_code);
728 outb((int_ret_code & 0xe0) | ATT_EOI, ESDI_ATTN);
729 break;
730 }
731 outb(CTRL_ENABLE_INTR, ESDI_CONTROL);
732}
733
734
735static void ps2esdi_geometry_int_handler(u_int int_ret_code)
736{
737 u_int status, drive_num;
738 unsigned long rba;
739 int i;
740
741 drive_num = int_ret_code >> 5;
742 switch (int_ret_code & 0xf) {
743 case INT_CMD_COMPLETE:
744 for (i = ESDI_TIMEOUT; i & !(inb(ESDI_STATUS) & STATUS_STAT_AVAIL); i--);
745 if (!(inb(ESDI_STATUS) & STATUS_STAT_AVAIL)) {
746 printk("%s: timeout reading status word\n", DEVICE_NAME);
747 outb((int_ret_code & 0xe0) | ATT_EOI, ESDI_ATTN);
748 break;
749 }
750 status = inw(ESDI_STT_INT);
751 if ((status & 0x1F) == CMD_GET_DEV_CONFIG) {
752#define REPLY_WORDS 5
753 u_short reply[REPLY_WORDS];
754
755 if (ps2esdi_read_status_words((status >> 8) - 1, REPLY_WORDS, reply)) {
756
757 printk("%s: Device Configuration Status for drive %u\n",
758 DEVICE_NAME, drive_num);
759
760 printk("%s: Spares/cyls: %u", DEVICE_NAME, reply[0] >> 8);
761
762 printk
763 ("Config bits: %s%s%s%s%s\n",
764 (reply[0] & CONFIG_IS) ? "Invalid Secondary, " : "",
765 ((reply[0] & CONFIG_ZD) && !(reply[0] & CONFIG_IS))
766 ? "Zero Defect, " : "Defects Present, ",
767 (reply[0] & CONFIG_SF) ? "Skewed Format, " : "",
768 (reply[0] & CONFIG_FR) ? "Removable, " : "Non-Removable, ",
769 (reply[0] & CONFIG_RT) ? "No Retries" : "Retries");
770
771 rba = reply[1] | ((unsigned long) reply[2] << 16);
772 printk("%s: Number of RBA's: %lu\n", DEVICE_NAME, rba);
773
774 printk("%s: Physical number of cylinders: %u, Sectors/Track: %u, Heads: %u\n",
775 DEVICE_NAME, reply[3], reply[4] >> 8, reply[4] & 0xff);
776
777 if (!ps2esdi_info[drive_num].head) {
778 ps2esdi_info[drive_num].head = 64;
779 ps2esdi_info[drive_num].sect = 32;
780 ps2esdi_info[drive_num].cyl = rba / (64 * 32);
781 ps2esdi_info[drive_num].wpcom = 0;
782 ps2esdi_info[drive_num].lzone = ps2esdi_info[drive_num].cyl;
783 ps2esdi_info[drive_num].ctl = 8;
784 if (tp720esdi) {
785 ps2esdi_info[0].head = reply[4] & 0Xff;
786 ps2esdi_info[0].sect = reply[4] >> 8;
787 ps2esdi_info[0].cyl = reply[3];
788 ps2esdi_info[0].wpcom = 0;
789 ps2esdi_info[0].lzone = reply[3];
790 } else {
791 if (!intg_esdi)
792 ps2esdi_drives++;
793 }
794 }
795#ifdef OBSOLETE
796 if (!ps2esdi_info[drive_num].head) {
797 ps2esdi_info[drive_num].head = reply[4] & 0Xff;
798 ps2esdi_info[drive_num].sect = reply[4] >> 8;
799 ps2esdi_info[drive_num].cyl = reply[3];
800 ps2esdi_info[drive_num].wpcom = 0;
801 ps2esdi_info[drive_num].lzone = reply[3];
802 if (tp720esdi) {
803 ps2esdi_info[0].head = reply[4] & 0Xff;
804 ps2esdi_info[0].sect = reply[4] >> 8;
805 ps2esdi_info[0].cyl = reply[3];
806 ps2esdi_info[0].wpcom = 0;
807 ps2esdi_info[0].lzone = reply[3];
808 } else {
809 ps2esdi_drives++;
810 }
811 }
812#endif
813
814 } else
815 printk("%s: failed while getting device config\n", DEVICE_NAME);
816#undef REPLY_WORDS
817 } else
818 printk("%s: command %02X unknown by geometry handler\n",
819 DEVICE_NAME, status & 0x1f);
820
821 outb((int_ret_code & 0xe0) | ATT_EOI, ESDI_ATTN);
822 break;
823
824 case INT_ATTN_ERROR:
825 printk("%s: Attention error. interrupt status : %02X\n", DEVICE_NAME,
826 int_ret_code);
827 printk("%s: Device not available\n", DEVICE_NAME);
828 break;
829 case INT_CMD_ECC:
830 case INT_CMD_RETRY:
831 case INT_CMD_ECC_RETRY:
832 case INT_CMD_WARNING:
833 case INT_CMD_ABORT:
834 case INT_CMD_FAILED:
835 case INT_DMA_ERR:
836 case INT_CMD_BLK_ERR:
837 printk("%s: Whaa. Error occurred...\n", DEVICE_NAME);
838 dump_cmd_complete_status(int_ret_code);
839 outb((int_ret_code & 0xe0) | ATT_EOI, ESDI_ATTN);
840 break;
841 default:
842 printk("%s: Unknown interrupt reason: %02X\n",
843 DEVICE_NAME, int_ret_code & 0xf);
844 outb((int_ret_code & 0xe0) | ATT_EOI, ESDI_ATTN);
845 break;
846 }
847
848 wake_up(&ps2esdi_int);
849 no_int_yet = FALSE;
850 outb(CTRL_ENABLE_INTR, ESDI_CONTROL);
851
852}
853
854static void ps2esdi_normal_interrupt_handler(u_int int_ret_code)
855{
856 unsigned long flags;
857 u_int status;
858 u_int ending;
859 int i;
860
861 switch (int_ret_code & 0x0f) {
862 case INT_TRANSFER_REQ:
863 ps2esdi_prep_dma(CURRENT->buffer, CURRENT->current_nr_sectors,
864 (CURRENT->cmd == READ)
865 ? MCA_DMA_MODE_16 | MCA_DMA_MODE_WRITE | MCA_DMA_MODE_XFER
866 : MCA_DMA_MODE_16 | MCA_DMA_MODE_READ);
867 outb(CTRL_ENABLE_DMA | CTRL_ENABLE_INTR, ESDI_CONTROL);
868 ending = -1;
869 break;
870
871 case INT_ATTN_ERROR:
872 printk("%s: Attention error. interrupt status : %02X\n", DEVICE_NAME,
873 int_ret_code);
874 outb(CTRL_ENABLE_INTR, ESDI_CONTROL);
875 ending = FAIL;
876 break;
877
878 case INT_CMD_COMPLETE:
879 for (i = ESDI_TIMEOUT; i & !(inb(ESDI_STATUS) & STATUS_STAT_AVAIL); i--);
880 if (!(inb(ESDI_STATUS) & STATUS_STAT_AVAIL)) {
881 printk("%s: timeout reading status word\n", DEVICE_NAME);
882 outb((int_ret_code & 0xe0) | ATT_EOI, ESDI_ATTN);
883 outb(CTRL_ENABLE_INTR, ESDI_CONTROL);
884 if ((++CURRENT->errors) >= MAX_RETRIES)
885 ending = FAIL;
886 else
887 ending = -1;
888 break;
889 }
890 status = inw(ESDI_STT_INT);
891 switch (status & 0x1F) {
892 case (CMD_READ & 0xff):
893 case (CMD_WRITE & 0xff):
894 LITE_OFF;
895 outb((int_ret_code & 0xe0) | ATT_EOI, ESDI_ATTN);
896 outb(CTRL_ENABLE_INTR, ESDI_CONTROL);
897#if 0
898 printk("ps2esdi: cmd_complete b_wait: %p\n", &CURRENT->bh->b_wait);
899#endif
900 ending = SUCCES;
901 break;
902 default:
903 printk("%s: interrupt for unknown command %02X\n",
904 DEVICE_NAME, status & 0x1f);
905 outb((int_ret_code & 0xe0) | ATT_EOI, ESDI_ATTN);
906 outb(CTRL_ENABLE_INTR, ESDI_CONTROL);
907 ending = -1;
908 break;
909 }
910 break;
911 case INT_CMD_ECC:
912 case INT_CMD_RETRY:
913 case INT_CMD_ECC_RETRY:
914 LITE_OFF;
915 dump_cmd_complete_status(int_ret_code);
916 outb((int_ret_code & 0xe0) | ATT_EOI, ESDI_ATTN);
917 outb(CTRL_ENABLE_INTR, ESDI_CONTROL);
918 ending = SUCCES;
919 break;
920 case INT_CMD_WARNING:
921 case INT_CMD_ABORT:
922 case INT_CMD_FAILED:
923 case INT_DMA_ERR:
924 LITE_OFF;
925 dump_cmd_complete_status(int_ret_code);
926 outb((int_ret_code & 0xe0) | ATT_EOI, ESDI_ATTN);
927 outb(CTRL_ENABLE_INTR, ESDI_CONTROL);
928 if ((++CURRENT->errors) >= MAX_RETRIES)
929 ending = FAIL;
930 else
931 ending = -1;
932 break;
933
934 case INT_CMD_BLK_ERR:
935 dump_cmd_complete_status(int_ret_code);
936 outb((int_ret_code & 0xe0) | ATT_EOI, ESDI_ATTN);
937 outb(CTRL_ENABLE_INTR, ESDI_CONTROL);
938 ending = FAIL;
939 break;
940
941 case INT_CMD_FORMAT:
942 printk("%s: huh ? Who issued this format command ?\n"
943 ,DEVICE_NAME);
944 outb((int_ret_code & 0xe0) | ATT_EOI, ESDI_ATTN);
945 outb(CTRL_ENABLE_INTR, ESDI_CONTROL);
946 ending = -1;
947 break;
948
949 case INT_RESET:
950 ;
951 outb((int_ret_code & 0xe0) | ATT_EOI, ESDI_ATTN);
952 outb(CTRL_ENABLE_INTR, ESDI_CONTROL);
953 ending = -1;
954 break;
955
956 default:
957 printk("%s: Unknown interrupt reason: %02X\n",
958 DEVICE_NAME, int_ret_code & 0xf);
959 outb((int_ret_code & 0xe0) | ATT_EOI, ESDI_ATTN);
960 outb(CTRL_ENABLE_INTR, ESDI_CONTROL);
961 ending = -1;
962 break;
963 }
964 if(ending != -1) {
965 spin_lock_irqsave(&io_request_lock, flags);
966 end_request(ending);
967 do_ps2esdi_request(BLK_DEFAULT_QUEUE(MAJOR_NR));
968 spin_unlock_irqrestore(&io_request_lock, flags);
969 }
970}
971
972
973
974static int ps2esdi_read_status_words(int num_words,
975 int max_words,
976 u_short * buffer)
977{
978 int i;
979
980 for (; max_words && num_words; max_words--, num_words--, buffer++) {
981 for (i = ESDI_TIMEOUT; i && !(inb(ESDI_STATUS) & STATUS_STAT_AVAIL); i--);
982 if (!(inb(ESDI_STATUS) & STATUS_STAT_AVAIL)) {
983 printk("%s: timeout reading status word\n", DEVICE_NAME);
984 return FAIL;
985 }
986 *buffer = inw(ESDI_STT_INT);
987 }
988 return SUCCES;
989}
990
991
992
993
994static void dump_cmd_complete_status(u_int int_ret_code)
995{
996#define WAIT_FOR_STATUS \
997 for(i=ESDI_TIMEOUT;i && !(inb(ESDI_STATUS) & STATUS_STAT_AVAIL);i--); \
998 if(!(inb(ESDI_STATUS) & STATUS_STAT_AVAIL)) { \
999 printk("%s: timeout reading status word\n",DEVICE_NAME); \
1000 return; \
1001 }
1002
1003 int i, word_count;
1004 u_short stat_word;
1005 u_long rba;
1006
1007 printk("%s: Device: %u, interrupt ID: %02X\n",
1008 DEVICE_NAME, int_ret_code >> 5,
1009 int_ret_code & 0xf);
1010
1011 WAIT_FOR_STATUS;
1012 stat_word = inw(ESDI_STT_INT);
1013 word_count = (stat_word >> 8) - 1;
1014 printk("%s: %u status words, command: %02X\n", DEVICE_NAME, word_count,
1015 stat_word & 0xff);
1016
1017 if (word_count--) {
1018 WAIT_FOR_STATUS;
1019 stat_word = inw(ESDI_STT_INT);
1020 printk("%s: command status code: %02X, command error code: %02X\n",
1021 DEVICE_NAME, stat_word >> 8, stat_word & 0xff);
1022 }
1023 if (word_count--) {
1024 WAIT_FOR_STATUS;
1025 stat_word = inw(ESDI_STT_INT);
1026 printk("%s: device error code: %s%s%s%s%s,%02X\n", DEVICE_NAME,
1027 (stat_word & 0x1000) ? "Ready, " : "Not Ready, ",
1028 (stat_word & 0x0800) ? "Selected, " : "Not Selected, ",
1029 (stat_word & 0x0400) ? "Write Fault, " : "",
1030 (stat_word & 0x0200) ? "Track 0, " : "",
1031 (stat_word & 0x0100) ? "Seek or command complete, " : "",
1032 stat_word >> 8);
1033 }
1034 if (word_count--) {
1035 WAIT_FOR_STATUS;
1036 stat_word = inw(ESDI_STT_INT);
1037 printk("%s: Blocks to do: %u", DEVICE_NAME, stat_word);
1038 }
1039 if (word_count -= 2) {
1040 WAIT_FOR_STATUS;
1041 rba = inw(ESDI_STT_INT);
1042 WAIT_FOR_STATUS;
1043 rba |= inw(ESDI_STT_INT) << 16;
1044 printk(", Last Cyl: %u Head: %u Sector: %u\n",
1045 (u_short) ((rba & 0x1ff80000) >> 11),
1046 (u_short) ((rba & 0x7E0) >> 5), (u_short) (rba & 0x1f));
1047 } else
1048 printk("\n");
1049
1050 if (word_count--) {
1051 WAIT_FOR_STATUS;
1052 stat_word = inw(ESDI_STT_INT);
1053 printk("%s: Blocks required ECC: %u", DEVICE_NAME, stat_word);
1054 }
1055 printk("\n");
1056
1057#undef WAIT_FOR_STATUS
1058
1059}
1060
1061
1062static int ps2esdi_open(struct inode *inode, struct file *file)
1063{
1064 int dev = DEVICE_NR(inode->i_rdev);
1065
1066 if (dev < ps2esdi_drives) {
1067 while (!ps2esdi_valid[dev])
1068 sleep_on(&ps2esdi_wait_open);
1069
1070 access_count[dev]++;
1071
1072 return (0);
1073 } else
1074 return (-ENODEV);
1075}
1076
1077
1078
1079static int ps2esdi_release(struct inode *inode, struct file *file)
1080{
1081 int dev = DEVICE_NR(inode->i_rdev);
1082
1083 if (dev < ps2esdi_drives) {
1084 access_count[dev]--;
1085 }
1086 return 0;
1087}
1088
1089
1090
1091static int ps2esdi_ioctl(struct inode *inode,
1092 struct file *file, u_int cmd, u_long arg)
1093{
1094
1095 struct ps2esdi_geometry *geometry = (struct ps2esdi_geometry *) arg;
1096 int dev = DEVICE_NR(inode->i_rdev), err;
1097
1098 if (inode && (dev < ps2esdi_drives))
1099 switch (cmd) {
1100 case HDIO_GETGEO:
1101 if (arg) {
1102 if ((err = verify_area(VERIFY_WRITE, geometry, sizeof(*geometry))))
1103 return (err);
1104 put_user(ps2esdi_info[dev].head, (char *) &geometry->heads);
1105 put_user(ps2esdi_info[dev].sect, (char *) &geometry->sectors);
1106 put_user(ps2esdi_info[dev].cyl, (short *) &geometry->cylinders);
1107 put_user(ps2esdi[MINOR(inode->i_rdev)].start_sect,
1108 (long *) &geometry->start);
1109
1110 return (0);
1111 }
1112 break;
1113
1114 case BLKRRPART:
1115 if (!capable(CAP_SYS_ADMIN))
1116 return -EACCES;
1117 return (ps2esdi_reread_partitions(inode->i_rdev));
1118
1119 case BLKGETSIZE:
1120 case BLKGETSIZE64:
1121 case BLKROSET:
1122 case BLKROGET:
1123 case BLKRASET:
1124 case BLKRAGET:
1125 case BLKFLSBUF:
1126 case BLKBSZGET:
1127 case BLKBSZSET:
1128 case BLKPG:
1129 return blk_ioctl(inode->i_rdev, cmd, arg);
1130 }
1131 return (-EINVAL);
1132}
1133
1134
1135
1136static int ps2esdi_reread_partitions(kdev_t dev)
1137{
1138 int target = DEVICE_NR(dev);
1139 int start = target << ps2esdi_gendisk.minor_shift;
1140 int partition;
1141
1142 ps2esdi_valid[target] = (access_count[target] != 1);
1143 if (ps2esdi_valid[target])
1144 return (-EBUSY);
1145
1146 for (partition = ps2esdi_gendisk.max_p - 1;
1147 partition >= 0; partition--) {
1148 int minor = (start | partition);
1149 invalidate_device(MKDEV(MAJOR_NR, minor), 1);
1150 ps2esdi_gendisk.part[minor].start_sect = 0;
1151 ps2esdi_gendisk.part[minor].nr_sects = 0;
1152 }
1153
1154 grok_partitions(&ps2esdi_gendisk, target, 1<<6,
1155 ps2esdi_info[target].head * ps2esdi_info[target].cyl * ps2esdi_info[target].sect);
1156
1157 ps2esdi_valid[target] = 1;
1158 wake_up(&ps2esdi_wait_open);
1159
1160 return (0);
1161}
1162
1163static void ps2esdi_reset_timer(unsigned long unused)
1164{
1165
1166 int status;
1167
1168 status = inb(ESDI_INTRPT);
1169 if ((status & 0xf) == INT_RESET) {
1170 outb((status & 0xe0) | ATT_EOI, ESDI_ATTN);
1171 outb(CTRL_ENABLE_INTR, ESDI_CONTROL);
1172 reset_status = 1;
1173 }
1174 wake_up(&ps2esdi_int);
1175}
1176
1177#endif
1178