Skip to contentSkip to conversation

IDE 1Gig Microdrive (Working!!)

DISCUSSION Ira Weiny 2 participants 3 messages Sep 19, 2001

lore
Share & tools
lore

Ira Weiny

author
#0 lore raw

I have Ben H's 2.4.9 kernel and I have hacked up something which allows the 1Gig Microdrive PCCard to work.

What I am wondering is, does my patch stand a chance of making it into the tree?

Quoted 1 line

From what I can tell there is already some code to disable the IRQ on

the Card but I guess the 1Gig drive does not honor this. So I am disabling the IRQ at the processor. It is my understanding that the IDE maintainer will not accept this. Of course I would put this flag into the hwif or drive structure and not use a global like this but if I am going to have to apply this patch for every kernel upgrade I will leave it this way.

These are against Ben's latest rsync. Any thoughts, would be appreciated.

And Thanks so much for all your help again,
Ira Weiny
[email protected]

*** ./ide-cs.c Sun Sep 9 17:35:01 2001
--- /usr/src/linux/drivers/ide/ide-cs.c Sun Sep 16 08:15:36 2001
*************** int idecs_register (int arg1, int arg2, *** 233,238 ****
--- 233,245 ----

          return ide_register_hw(&hw, NULL);

}

+
+ extern int ide_disable_irq_on_probe;
+
void ide_config(dev_link_t *link)

  {
      client_handle_t handle = link->handle;
*************** void ide_config(dev_link_t *link)
*** 334,339 ****
--- 341,351 ----
      if (link->io.NumPorts2)

release_region(link->io.BasePort2, link->io.NumPorts2);

+ ide_disable_irq_on_probe = 1;
+

      outb(0x02, ctl_base); // Set nIEN = disable device interrupts

      /* retry registration in case device is still spinning up */
*************** void ide_config(dev_link_t *link)
*** 352,357 ****
--- 364,375 ----
  	schedule_timeout(HZ/10);
      }

+ ide_disable_irq_on_probe = 0;
+

      if (hd < 0) {

printk(KERN_NOTICE "ide_cs: ide_register() at 0x%03x & 0x%03x"
", irq %u failed\n", io_base, ctl_base,

*** ./ide-probe.c Sun Sep 9 17:35:01 2001
--- /usr/src/linux/drivers/ide/ide-probe.c Tue Sep 18 20:48:25 2001
*************** static inline void do_identify (ide_driv *** 176,181 ****
--- 176,183 ----
return;
}

+ int ide_disable_irq_on_probe = 0;
+
/*
* try_to_identify() sends an ATA(PI) IDENTIFY request to a drive
* and waits for a response. It also monitors irqs while this is
*************** static int actual_try_to_identify (ide_d *** 213,223 ****
--- 215,234 ----
if ((cmd == WIN_PIDENTIFY))
OUT_BYTE(0,IDE_FEATURE_REG); /* disable dma & overlap */

+ if (ide_disable_irq_on_probe == 1)
+ {
+ disable_irq(HWIF(drive)->irq);
+ }
+
#if CONFIG_BLK_DEV_PDC4030
if (HWIF(drive)->chipset == ide_pdc4030) {
/* DC4030 hosted drives need their own identify... */ extern int pdc4030_identify(ide_drive_t *); if (pdc4030_identify(drive)) {
+ if (ide_disable_irq_on_probe == 1)
+ {
+ enable_irq(HWIF(drive)->irq);
+ }
return 1;
}
} else
*************** static int actual_try_to_identify (ide_d *** 227,238 ****
--- 238,254 ----
timeout += jiffies;
do {
if (0 < (signed long)(jiffies - timeout)) {
+ if (ide_disable_irq_on_probe == 1)
+ {
+ enable_irq(HWIF(drive)->irq);
+ }
return 1; /* drive timed-out */
}
ide_delay_50ms(); /* give drive a breather */
} while (IN_BYTE(hd_status) & BUSY_STAT);

ide_delay_50ms(); /* wait for IRQ and DRQ_STAT */
+
if (OK_STAT(GET_STAT(),DRQ_STAT,BAD_R_STAT)) {
unsigned long flags;
__save_flags(flags); /* local CPU only */
*************** static int actual_try_to_identify (ide_d *** 242,248 ****
--- 258,272 ----
(void) GET_STAT(); /* clear drive IRQ */
__restore_flags(flags); /* local CPU only */
} else
+ {
rc = 2; /* drive refused ID */
+ }
+
+ if (ide_disable_irq_on_probe == 1)
+ {
+ enable_irq(HWIF(drive)->irq);
+ }
+
return rc;
}

#1 lore raw
Quoted 15 lines

I have Ben H's 2.4.9 kernel and I have hacked up something which allows the 1Gig Microdrive PCCard to work.

What I am wondering is, does my patch stand a chance of making it into the tree?

From what I can tell there is already some code to disable the IRQ on the Card but I guess the 1Gig drive does not honor this. So I am disabling the IRQ at the processor. It is my understanding that the IDE maintainer will not accept this. Of course I would put this flag into the hwif or drive structure and not use a global like this but if I am going to have to apply this patch for every kernel upgrade I will leave it this way.

Quoted 2 lines

These are against Ben's latest rsync. Any thoughts, would be appreciated.

Well, it's a problem of both broken devices (shame on those drive manufacturers that don't honor specs), and the linux IDE driver which isn't prepared to deal with such situations (well, I wouldn't blame it, but I beleive it might be possible to just clear the interrupt condition by reading the status register when no handler is installed, issuing a warning printk). Eventually, moving the request_irq in the driver to after the probe may work as well...

The code you see in my tree that already sets nIEN is not in the main Linus tree. It's a workaround for other broken PCCard IDE devices that was adapted by Paul Mackerras. It's a hack, I hope a solution can be found that fixes cleanly the problem for all cases.

In theory, the interrupt is masked until request_irq() is called. So if the linux IDE code was ready to accept and clear interrupt conditions when it calls request_irq, things would work... But... in pratice that is not the case.

The problem is when your interrupt is shared with another device, this is rarely the case on macs, more frequent on x86 hardware, but in our case, it does happen as the PCCard controller shares his interrupt with the PCCard device interrupt. It _might_ be possible to mask the PCCard interrupt at the controller level, but that would be a mess and add some more special cases to the already complex IDE layer.

Andre, what do you think would be a good solution ?

Temporarily masking out the interrupt with disable_irq(), even if it's shared, would be acceptable ? (Provided that it's only masked for a short period of time obviously). Can the problem be worked around by doing the request_irq earlier, and making sure the IDE handler always clear the interrupt condition even when no handler is attached when it's doing the probe ?

Regards,
Ben.

** Sent via the linuxppc-dev mail list. See http://lists.linuxppc.org/

author
#2 lore raw
Quoted 10 lines · Benjamin Herrenschmidt

Andre, what do you think would be a good solution ?

Temporarily masking out the interrupt with disable_irq(), even if it's shared, would be acceptable ? (Provided that it's only masked for a short period of time obviously). Can the problem be worked around by doing the request_irq earlier, and making sure the IDE handler always clear the interrupt condition even when no handler is attached when it's doing the probe ?

Well I am slowly getting my head around the IDE layer so I know what I did is a hack. Moving the request_irq() around seemed like a daunting task which I probably could not do without messing something up, sorry.

However, my solution relys on the fact that the probe, as far as I could tell, does not need the irq, as it polls. So I just disabled it until something happens, timeout or success. I would think this would solve the problem for all drives but I don't have a lot of test cases. I have tried all my CF cards and my Microdrive. One thing I have not tried is to simply disable the irq all the time in the probe to see what happens on boot with my normal internal drive. If this were to work for all probes then I could get rid of the flag.

However, I do realize the error of my ways. If there is something else on this line which is important... Anyway, I would think this is something others would want to have working. So if I can help with testing or a solution, I would be happy to.

Thanks,
Ira Weiny
[email protected]

** Sent via the linuxppc-dev mail list. See http://lists.linuxppc.org/