Skip to contentSkip to conversation

PATA drivers queued for 2.6.19

DISCUSSION Jeff Garzik 12 participants 28 messages Sep 4, 2006 – May 29, 2007

Subsystems (2)
lore
Share & tools
lore
#0 lore raw

I just pulled the "pata-drivers" branch of libata-dev.git into the "upstream" branch, which means that Alan's libata PATA driver collection is now queued for 2.6.19.

Testing-wise, these PATA drivers have been Andrew Morton's -mm tree for many months. Community-wise, no one posted objections to the PATA driver merge plan, when Alan posted it on LKML and linux-ide.

The following must be in all caps, though:

drivers/ide IS STILL THE PATA DRIVER SET THAT USERS AND DISTROS SHOULD CHOOSE.

At this time, drivers/ide should not be added to Documentation/feature-removal-schedule.txt. The libata PATA driver set should be considered experimental still, and there remains a few user-visible differences between the two trees:

* Host-protected area (HPA) not ignored in libata, which means disk sizes differ between drivers/ide (whole disk) and libata (whole disk minus HPA).

* The obvious change between /dev/hdX to /dev/sdX

* /dev/sdX supports fewer partitions than /dev/hdX (16 versus 64, IIRC)

* /dev/sdX does not support all the HDIO_xxx ioctls that /dev/hdX does. In practice, the ioctls we ignored are ones that very few people care
about.

* ARM, PPC and other non-x86 platform drivers are severely under-represented.

As an aside, I would love to see paride updated to use libata, but we can probably count the number of paride users on one hand these days...

Jeff

Signature · 1 line
VGER BF report: U 0.499983
#1 lore raw

Ar Llu, 2006-09-04 am 07:01 -0400, ysgrifennodd Jeff Garzik:

Quoted 4 lines

The following must be in all caps, though:

drivers/ide IS STILL THE PATA DRIVER SET THAT USERS AND DISTROS SHOULD CHOOSE.

Except optionally for the following for chips not handled by or broken totally in drivers/ide:

pata_mpiix - some early pentium era laptops pata_oldpiix - original "PIIX" chipset pata_radisys - embedded chipset

The other apparently "libata only" chips are pata_jmicron and pata_optidma. There are patches to handle these as "generic" PCI IDE in the base 2.6.18 tree already so only features will be lost (eg mode switching). As Jeff implies distributions should be using drivers/ide for the Jmicron PATA and the Opti DMA PATA for now.

Quoted 5 lines

* /dev/sdX supports fewer partitions than /dev/hdX (16 versus 64, IIRC)

* /dev/sdX does not support all the HDIO_xxx ioctls that /dev/hdX does. In practice, the ioctls we ignored are ones that very few people care
about.

Add "/dev/sr*" does not support partitions. (That needs fixing anyway)

Quoted 2 lines

* ARM, PPC and other non-x86 platform drivers are severely under-represented.

libata needs changes for this too. I have some stuff saved from the older discussions to look at.

Quoted 2 lines

As an aside, I would love to see paride updated to use libata, but we can probably count the number of paride users on one hand these days...

and thats without using fingers or thumbs.

Signature · 1 line
VGER BF report: H 0.235691
#2 lore raw
Quoted 6 lines
Quoted 4 lines

* /dev/sdX does not support all the HDIO_xxx ioctls that /dev/hdX does. In practice, the ioctls we ignored are ones that very few people care
about.

Add "/dev/sr*" does not support partitions. (That needs fixing anyway)

scd*/sr* is usually CDROM, which in the rarest case have a partition table, don't they? (sd* stands for Scsi Disk, but what's the r in sr standing for?)

Quoted 4 lines
Quoted 2 lines

As an aside, I would love to see paride updated to use libata, but we can probably count the number of paride users on one hand these days...

and thats without using fingers or thumbs.

0? Could it be removed then? [I'm waiting for loud objection screams from paride users...]

Jan Engelhardt

Signature · 2 lines
-- 
VGER BF report: H 4.996e-16
#3 lore raw
Quoted 4 lines · Jan Engelhardt
Quoted 2 lines
Quoted 1 line

As an aside, I would love to see paride updated to use libata, but we can probably count the number of paride users on one hand these days...

and thats without using fingers or thumbs.

0? Could it be removed then? [I'm waiting for loud objection screams from paride users...]

I think Al Viro still uses paride ;-)

Jeff

Signature · 1 line
VGER BF report: H 0
#4 lore raw
In reply to Alan Cox
Quoted 1 line
Quoted 1 line
Quoted 1 line
Quoted 1 line
Quoted 1 line

"Alan" == Alan Cox <[email protected]> writes:

Alan> Ar Llu, 2006-09-04 am 07:01 -0400, ysgrifennodd Jeff Garzik:

Quoted 4 lines
Quoted 4 lines

The following must be in all caps, though:

drivers/ide IS STILL THE PATA DRIVER SET THAT USERS AND DISTROS SHOULD CHOOSE.

Alan> Except optionally for the following for chips not handled by or broken Alan> totally in drivers/ide:

Alan> pata_mpiix - some early pentium era laptops
Alan> pata_oldpiix - original "PIIX" chipset
Alan> pata_radisys - embedded chipset

What about pata_hpt37x and it's failure to work with my HPT302 Rev one controller? I admit it could be just an IRQ problem, but since 2.6.18-rc5-mm1 works with the old ide/pci/hpt366.c, but not with the new version? It's using the same interrupt each time too.

John

#5 lore raw
Quoted 13 lines · John Stoffel
Quoted 1 line
Quoted 1 line
Quoted 1 line
Quoted 1 line
Quoted 1 line

"Alan" == Alan Cox <[email protected]> writes:

Alan> Ar Llu, 2006-09-04 am 07:01 -0400, ysgrifennodd Jeff Garzik:

Quoted 3 lines
Quoted 3 lines

The following must be in all caps, though:

drivers/ide IS STILL THE PATA DRIVER SET THAT USERS AND DISTROS SHOULD CHOOSE.

Alan> Except optionally for the following for chips not handled by or broken Alan> totally in drivers/ide:

Quoted 7 lines

Alan> pata_mpiix - some early pentium era laptops
Alan> pata_oldpiix - original "PIIX" chipset
Alan> pata_radisys - embedded chipset

What about pata_hpt37x and it's failure to work with my HPT302 Rev one controller? I admit it could be just an IRQ problem, but since 2.6.18-rc5-mm1 works with the old ide/pci/hpt366.c, but not with the

Hm, I believe this driver hasn't been updated since 2.617-mm4 (I have one
patch pending still).

Quoted 1 line

new version? It's using the same interrupt each time too.

What's up with it?

#6 lore raw
Quoted 1 line
Quoted 1 line
Quoted 1 line
Quoted 1 line
Quoted 1 line

"Sergei" == Sergei Shtylyov <[email protected]> writes:

Quoted 3 lines · Sergei> John Stoffel wrote:
Quoted 3 lines
Quoted 1 line
Quoted 1 line
Quoted 1 line
Quoted 1 line
Quoted 1 line

"Alan" == Alan Cox <[email protected]> writes:

Alan> Ar Llu, 2006-09-04 am 07:01 -0400, ysgrifennodd Jeff Garzik:

Quoted 7 lines
Quoted 7 lines
Quoted 5 lines
Quoted 5 lines

The following must be in all caps, though:

drivers/ide IS STILL THE PATA DRIVER SET THAT USERS AND DISTROS SHOULD CHOOSE.

Alan> Except optionally for the following for chips not handled by or broken Alan> totally in drivers/ide:

Quoted 1 line
Quoted 1 line

Alan> pata_mpiix - some early pentium era laptops
Alan> pata_oldpiix - original "PIIX" chipset
Alan> pata_radisys - embedded chipset

Quoted 4 lines
Quoted 4 lines

What about pata_hpt37x and it's failure to work with my HPT302 Rev one controller? I admit it could be just an IRQ problem, but since 2.6.18-rc5-mm1 works with the old ide/pci/hpt366.c, but not with the

Sergei> Hm, I believe this driver hasn't been updated since
Sergei> 2.617-mm4 (I have one patch pending still).

Quoted 1 line
Quoted 1 line

new version? It's using the same interrupt each time too.

Sergei> What's up with it?

Look back in the archives for my messages on this. Basically, trying to use the pata_hpt37x driver on an Rocket133 card (HPT302 Rev 1 chip) fails with a bunch of errors shown below. This is a PCI add-on card with /home and /local filesystems on there, mirrored across a pair of 120gb WD drives. The system also has a pair of builtin SCSI controllers (AIC7xxx) which hold the OS filesystems, as well as a tape drive for backups. It's an SMP system. I guess I should try to boot it up UP and see how it goes then as well.

I've tried booting 2.6.18-rc4-mm3 with the irqpoll option, but it didn't make a difference.

Do you need more details?

irq 18: nobody cared (try booting with the "irqpoll" option)

   [<c0104061>] dump_trace+0x1e1/0x210
   [<c01040aa>] show_trace_log_lvl+0x1a/0x30
   [<c0104832>] show_trace+0x12/0x20
   [<c01049a9>] dump_stack+0x19/0x20
   [<c01406d7>] __report_bad_irq+0x27/0x90
   [<c0140966>] note_interrupt+0x226/0x260
   [<c0141221>] handle_fasteoi_irq+0xc1/0xd0
   [<c0105b38>] do_IRQ+0x88/0xf0
   [<c01039ee>] common_interrupt+0x1a/0x20
   [<c0101be4>] default_idle+0x34/0x70
   [<c0101c8c>] cpu_idle+0x6c/0x90
   [<c0100725>] rest_init+0x25/0x30
   [<c0565839>] start_kernel+0x2f9/0x400
   =======================
  handlers:
  [<c03004c0>] (ahc_linux_isr+0x0/0x60)
  [<c03004c0>] (ahc_linux_isr+0x0/0x60)
  [<c03155c0>] (ata_interrupt+0x0/0x1a0)
  Disabling IRQ #18
  ata2.00: exception Emask 0x0 SAct 0x0 SErr 0x0 action 0x2 frozen
  ata2.00: (BMDMA stat 0x4)
  ata2.00: tag 0 cmd 0xca Emask 0x4 stat 0x40 err 0x0 (timeout)
  ata2: soft resetting port
  ata2.00: qc timeout (cmd 0xec)
  ata2.00: failed to IDENTIFY (I/O error, err_mask=0x4)
  ata2.00: revalidation failed (errno=-5)
  ata2: failed to recover some devices, retrying in 5 secs
  ata2: soft resetting port
  ata2.00: qc timeout (cmd 0xec)
  ata2.00: failed to IDENTIFY (I/O error, err_mask=0x4)
  ata2.00: revalidation failed (errno=-5)
  ata2: failed to recover some devices, retrying in 5 secs
  ata2: soft resetting port
  ata2.00: qc timeout (cmd 0xec)
  ata2.00: failed to IDENTIFY (I/O error, err_mask=0x4)
  ata2.00: revalidation failed (errno=-5)
  ata2.00: disabled
  ata2: EH complete
  sd 3:0:0:0: SCSI error: return code = 0x00040000
  end_request: I/O error, dev sdd, sector 234436423
  raid1: Disk failure on sdd1, disabling device.
	  Operation continuing on 1 devices
  ata1.00: exception Emask 0x0 SAct 0x0 SErr 0x0 action 0x2 frozen
  ata1.00: tag 0 cmd 0xe7 Emask 0x4 stat 0x40 err 0x0 (timeout)
  ata1: soft resetting port
  ata1.00: qc timeout (cmd 0xec)
  ata1.00: failed to IDENTIFY (I/O error, err_mask=0x4)
  ata1.00: revalidation failed (errno=-5)
  ata1: failed to recover some devices, retrying in 5 secs
  ata1: soft resetting port
  ata1.00: qc timeout (cmd 0xec)
  ata1.00: failed to IDENTIFY (I/O error, err_mask=0x4)
  ata1.00: revalidation failed (errno=-5)
  ata1: failed to recover some devices, retrying in 5 secs
  ata1: soft resetting port
  ata1.00: qc timeout (cmd 0xec)
  ata1.00: failed to IDENTIFY (I/O error, err_mask=0x4)
  ata1.00: revalidation failed (errno=-5)
  ata1.00: disabled
  ata1: EH complete
  sd 2:0:0:0: SCSI error: return code = 0x00040000
  end_request: I/O error, dev sdc, sector 234436423
  sd 2:0:0:0: SCSI error: return code = 0x00040000
  end_request: I/O error, dev sdc, sector 234436415
  md: ... autorun DONE.
  RAID1 conf printout:
   --- wd:1 rd:2
   disk 0, wo:0, o:1, dev:sdc1
   disk 1, wo:1, o:0, dev:sdd1
  RAID1 conf printout:
   --- wd:1 rd:2
   disk 0, wo:0, o:1, dev:sdc1
#7 lore raw
In reply to Alan Cox
Quoted 26 lines · Alan Cox

Ar Llu, 2006-09-04 am 07:01 -0400, ysgrifennodd Jeff Garzik:

Quoted 3 lines

The following must be in all caps, though:

drivers/ide IS STILL THE PATA DRIVER SET THAT USERS AND DISTROS SHOULD CHOOSE.

Except optionally for the following for chips not handled by or broken totally in drivers/ide:

pata_mpiix - some early pentium era laptops pata_oldpiix - original "PIIX" chipset pata_radisys - embedded chipset

The other apparently "libata only" chips are pata_jmicron and pata_optidma. There are patches to handle these as "generic" PCI IDE in the base 2.6.18 tree already so only features will be lost (eg mode switching). As Jeff implies distributions should be using drivers/ide for the Jmicron PATA and the Opti DMA PATA for now.

Quoted 5 lines

* /dev/sdX supports fewer partitions than /dev/hdX (16 versus 64, IIRC)

* /dev/sdX does not support all the HDIO_xxx ioctls that /dev/hdX does. In practice, the ioctls we ignored are ones that very few people care
about.

Add "/dev/sr*" does not support partitions. (That needs fixing anyway)

Quoted 10 lines
Quoted 1 line

* ARM, PPC and other non-x86 platform drivers are severely under-represented.

libata needs changes for this too. I have some stuff saved from the older discussions to look at.

Quoted 1 line

As an aside, I would love to see paride updated to use libata, but we can probably count the number of paride users on one hand these days...

and thats without using fingers or thumbs.

I still use that interface, although I can't say it's critical if I can't upgrade at some point. There are some other users in the local UG, but they are probably not ever going to upgrade.

Signature · 5 lines
Bill Davidsen <[email protected]>
  Obscure bug of 2004: BASH BUFFER OVERFLOW - if bash is being run by a
normal user and is setuid root, with the "vi" line edit mode selected,
and the character set is "big5," an off-by-one errors occurs during
wildcard (glob) expansion.
#8 lore raw

Ar Maw, 2006-09-05 am 16:48 -0400, ysgrifennodd Bill Davidsen:

Quoted 3 lines

I still use that interface, although I can't say it's critical if I can't upgrade at some point. There are some other users in the local UG, but they are probably not ever going to upgrade.

Currently paride is stand alone so it would be pretty hard to break providing nothing else changes around it. I don't think its in danger of going away, just of not improving.

Alan

#9 lore raw
In reply to Jeff Garzik
Quoted 8 lines · Jeff Garzik

I just pulled the "pata-drivers" branch of libata-dev.git into the "upstream" branch, which means that Alan's libata PATA driver collection is now queued for 2.6.19.

Testing-wise, these PATA drivers have been Andrew Morton's -mm tree for many months. Community-wise, no one posted objections to the PATA driver merge plan, when Alan posted it on LKML and linux-ide.

Too friggin' hard to test Alan's stuff for older IDE here, therefore
ignored so far :( I have some old hardware that Alan is addressing,
even an old IBM 260MB PCMCIA HDD.

I can't see an easy way to arrange multi-boot with different /etc/fstab depending if I'm trying /dev/hdaX or /dev/sdaX. Parallel '/' partitions?

Plus, 2.6.18-rcX fails too early in boot on one machine (p100 IBM 365X) for any testing. Suggestions welcome...

Grant.

Signature · 1 line
VGER BF report: U 0.488991
#10 lore raw
Quoted 1 line · Grant Coady

I can't see an easy way to arrange multi-boot with different /etc/fstab depending if I'm trying /dev/hdaX or /dev/sdaX. Parallel '/' partitions?

That's actually pretty darn easy, with a modern distro. Use filesystem labels, and LABEL= in your /etc/fstab.

The LABEL= feature allowed me to bounce between drivers/ide and libata a dozen times a day, when I was doing the initial libata development.

Jeff

Signature · 1 line
VGER BF report: H 3.84798e-12
#11 lore raw
In reply to Grant Coady
Quoted 8 lines
Quoted 7 lines

I just pulled the "pata-drivers" branch of libata-dev.git into the "upstream" branch, which means that Alan's libata PATA driver collection is now queued for 2.6.19.

Testing-wise, these PATA drivers have been Andrew Morton's -mm tree for many months. Community-wise, no one posted objections to the PATA driver merge plan, when Alan posted it on LKML and linux-ide.

Quoted 6 lines

Too friggin' hard to test Alan's stuff for older IDE here, therefore
ignored so far :( I have some old hardware that Alan is addressing,
even an old IBM 260MB PCMCIA HDD.

I can't see an easy way to arrange multi-boot with different /etc/fstab depending if I'm trying /dev/hdaX or /dev/sdaX. Parallel '/' partitions?

Got udev?

/dev/disk/by-id/ata-ST3802110A_5LR13RN7-partX could be your friend.

Quoted 2 lines

Plus, 2.6.18-rcX fails too early in boot on one machine (p100 IBM 365X) for any testing. Suggestions welcome...

dmesg or any log.

Jan Engelhardt

Signature · 2 lines
-- 
VGER BF report: H 0
#12 lore raw
Quoted 12 lines · Jan Engelhardt
Quoted 12 lines
Quoted 7 lines

I just pulled the "pata-drivers" branch of libata-dev.git into the "upstream" branch, which means that Alan's libata PATA driver collection is now queued for 2.6.19.

Testing-wise, these PATA drivers have been Andrew Morton's -mm tree for many months. Community-wise, no one posted objections to the PATA driver merge plan, when Alan posted it on LKML and linux-ide.

Too friggin' hard to test Alan's stuff for older IDE here, therefore
ignored so far :( I have some old hardware that Alan is addressing,
even an old IBM 260MB PCMCIA HDD.

Quoted 6 lines
Quoted 2 lines

I can't see an easy way to arrange multi-boot with different /etc/fstab depending if I'm trying /dev/hdaX or /dev/sdaX. Parallel '/' partitions?

Got udev?

/dev/disk/by-id/ata-ST3802110A_5LR13RN7-partX could be your friend.

Almost. It would alternate between "ata-" and "scsi-".

Signature · 2 lines
Tomasz Torcz                Only gods can safely risk perfection,
[email protected]     it's a dangerous thing for a man.  -- Alia
#13 lore raw
Quoted 6 lines
Quoted 4 lines

Got udev?

/dev/disk/by-id/ata-ST3802110A_5LR13RN7-partX could be your friend.

Almost. It would alternate between "ata-" and "scsi-".

Well then label your partitions and use /dev/disk/by-label/ (harhar...)

You can also try by-uuid (FS UUID) (a214ecf5-6e06-47a8-bc6d-9cd9d6f10cd6) or by-path (pci-0000:00:1f.1-ide-0:0-part1).

Jan Engelhardt

#14 lore raw
In reply to Jan Engelhardt
Quoted 4 lines · Jan Engelhardt
Quoted 4 lines
Quoted 4 lines

I just pulled the "pata-drivers" branch of libata-dev.git into the "upstream" branch, which means that Alan's libata PATA driver collection is now queued for 2.6.19.

Testing-wise, these PATA drivers have been Andrew Morton's -mm tree for many months. Community-wise, no one posted objections to the PATA driver merge plan, when Alan posted it on LKML and linux-ide.

Quoted 9 lines
Quoted 4 lines

Too friggin' hard to test Alan's stuff for older IDE here, therefore ignored so far :( I have some old hardware that Alan is addressing, even an old IBM 260MB PCMCIA HDD.

I can't see an easy way to arrange multi-boot with different /etc/fstab depending if I'm trying /dev/hdaX or /dev/sdaX. Parallel '/' partitions?

Got udev?

/dev/disk/by-id/ata-ST3802110A_5LR13RN7-partX could be your friend.

Udev fixes this for most filesystems - except / which is cruical. With / on raid-1 this is not a problem, as md autodetect will assemble the arrays whether they are on ide or scsi. But anyone with / on a partition can't easily switch between sda/hda unless they also use an initrd. The kernel itself does not seem to support partition by label. :-(

Helge Hafting

#15 lore raw

Ar Maw, 2006-09-05 am 15:26 +0200, ysgrifennodd Helge Hafting:

Quoted 2 lines

between sda/hda unless they also use an initrd. The kernel itself does not seem to support partition by label. :-(

This is correct and one reason vendor kernels generally use an initrd. The kernel does however support "root=/dev/sda1"

Alan

#16 lore raw
Quoted 6 lines · Alan Cox

Ar Maw, 2006-09-05 am 15:26 +0200, ysgrifennodd Helge Hafting:

Quoted 2 lines

between sda/hda unless they also use an initrd. The kernel itself does not seem to support partition by label. :-(

This is correct and one reason vendor kernels generally use an initrd. The kernel does however support "root=/dev/sda1"

Which leads back to this slackware user, who's never used an initrd, thinking about dual root partitions just to get the name change from another /etc/fstab?

I dual boot 2.4 / 2.6 kernels, looking for a simple solution so I can test Alan's work.

No udev, no initrd, funny I see a second '/' partition as 'easy'? ;)

I'm missing something here? Generally /etc/lilo.conf looks like:
<http://bugsplatter.mine.nu/test/boxen/deltree/lilo.conf>

Grant.

#17 lore raw
Quoted 3 lines · Grant Coady

Which leads back to this slackware user, who's never used an initrd, thinking about dual root partitions just to get the name change from another /etc/fstab?

I think it's unnecessary, /etc/fstab is not used while mounting root fs, and both mount and fsck should understand labels (i.e., you can put labels there, even for root fs).

Signature · 1 line
Krzysztof Halasa
#18 lore raw
Quoted 9 lines · Krzysztof Halasa
Quoted 3 lines · Grant Coady

Which leads back to this slackware user, who's never used an initrd, thinking about dual root partitions just to get the name change from another /etc/fstab?

I think it's unnecessary, /etc/fstab is not used while mounting root fs, and both mount and fsck should understand labels (i.e., you can put labels there, even for root fs).

Thanks, Krzysztof, Alan and others, I can do labels now, avoiding them too long ;)

Grant.

#19 lore raw
In reply to Grant Coady

Ar Llu, 2006-09-04 am 22:02 +1000, ysgrifennodd Grant Coady:

Quoted 2 lines

I can't see an easy way to arrange multi-boot with different /etc/fstab depending if I'm trying /dev/hdaX or /dev/sdaX. Parallel '/' partitions?

Mount by label on modern distributions. You can also generally boot far enough to just test by booting a libata kernel with root=/dev/sdawhatever init=/bin/sh

Thats enough to get a test shell and poke around and check the boot messages

#20 lore raw
In reply to Jeff Garzik
Quoted 8 lines · Jeff Garzik

I just pulled the "pata-drivers" branch of libata-dev.git into the "upstream" branch, which means that Alan's libata PATA driver collection is now queued for 2.6.19.

Testing-wise, these PATA drivers have been Andrew Morton's -mm tree for many months. Community-wise, no one posted objections to the PATA driver merge plan, when Alan posted it on LKML and linux-ide.

Does this include the patch to support the PATA port on the promise controllers (described here
https://bugzilla.novell.com/show_bug.cgi?id=176249 ) ?

Andras

Signature · 2 lines
Quanta Plus developer - http://quanta.kdewebdev.org
K Desktop Environment - http://www.kde.org
#21 lore raw
Quoted 6 lines · Andras Mantia
Quoted 4 lines · Jeff Garzik

I just pulled the "pata-drivers" branch of libata-dev.git into the "upstream" branch, which means that Alan's libata PATA driver collection is now queued for 2.6.19.

Quoted 7 lines
Quoted 3 lines

Testing-wise, these PATA drivers have been Andrew Morton's -mm tree for many months. Community-wise, no one posted objections to the PATA driver merge plan, when Alan posted it on LKML and linux-ide.

Does this include the patch to support the PATA port on the promise controllers (described here
https://bugzilla.novell.com/show_bug.cgi?id=176249 ) ?

Unfortunately not. This patch still lives in -mm (and branch promise-sata-pata).

Hopefully this can be merged once the init code is cleaned up some more.

Jeff

#22 lore raw
In reply to Jeff Garzik
Quoted 2 lines · Jeff Garzik

* ARM, PPC and other non-x86 platform drivers are severely under-represented.

Allessandro Zummo sent the patch below to me a while ago, for support for the PATA controller (PIO only, although the hardware can also do UDMA) in the cirrus logic ep93xx ARM cpu.

The driver has bitrotted somewhat, and apart from that it never honored PIO timings properly and has some other issues, but Allessandro seems to have disappeared off the face of the planet. I'd still like to see support for this go in at some point, so I'll have a try at cleaning it up and updating it (and converting it to a platform driver, etc.)

cheers,
Lennert

drivers/scsi/Kconfig +4 -0
Index: linux-2.6.16-rc5/drivers/scsi/Kconfig
===================================================================
@@ -912,6 +912,10 @@ config SCSI_PATA_TS7200
 	tristate "TS7200 Compact Flash support"
 	depends on MACH_TS72XX
 
+config SCSI_PATA_EP93XX
+	tristate "Cirrus Logic EP93XX PATA support"
+	depends on ARCH_EP93XX
+
 config SCSI_BUSLOGIC
 	tristate "BusLogic SCSI support"
 	depends on (PCI || ISA || MCA) && SCSI && ISA_DMA_API
drivers/scsi/Makefile +1 -0
Index: linux-2.6.16-rc5/drivers/scsi/Makefile
===================================================================
@@ -175,6 +175,7 @@ obj-$(CONFIG_SCSI_PATA_WINBOND)	+= libat
 obj-$(CONFIG_SCSI_ATA_GENERIC)	+= libata.o ata_generic.o
 obj-$(CONFIG_SCSI_PATA_LEGACY)	+= libata.o pata_legacy.o
 obj-$(CONFIG_SCSI_PATA_TS7200)	+= libata.o pata_ts7200.o
+obj-$(CONFIG_SCSI_PATA_EP93XX)		+= libata.o pata_ep93xx.o
 
 obj-$(CONFIG_ARM)		+= arm/
 
drivers/scsi/pata_ep93xx.c new file +375 -0

375 lines not on this page · raw message

include/asm-arm/arch-ep93xx/ep93xx-regs.h +26 -0
Index: linux-2.6.16-rc5/include/asm-arm/arch-ep93xx/ep93xx-regs.h
===================================================================
@@ -42,6 +42,32 @@
 #define EP93XX_BOOT_ROM_BASE		(EP93XX_AHB_VIRT_BASE + 0x00090000)
 
 #define EP93XX_IDE_BASE			(EP93XX_AHB_VIRT_BASE + 0x000a0000)
+#define EP93XX_IDE_REG(x)		(EP93XX_IDE_BASE + (x))
+#define EP93XX_IDE_CTRL			EP93XX_IDE_REG(0x0000)
+#define EP93XX_IDE_CFG			EP93XX_IDE_REG(0x0004)
+#define EP93XX_IDE_DATAOUT		EP93XX_IDE_REG(0x0010)
+#define EP93XX_IDE_DATAIN		EP93XX_IDE_REG(0x0014)
+
+#define EP93XX_IDE_CTRL_CS0n		(1L << 0)
+#define EP93XX_IDE_CTRL_CS1n		(1L << 1)
+#define EP93XX_IDE_CTRL_DA_MASK		0x1C
+#define EP93XX_IDE_CTRL_DA(x)		((x << 2) & EP93XX_IDE_CTRL_DA_MASK)
+#define EP93XX_IDE_CTRL_DA_CS_MASK	(EP93XX_IDE_CTRL_DA_MASK | EP93XX_IDE_CTRL_CS0n | EP93XX_IDE_CTRL_CS1n)
+#define EP93XX_IDE_CTRL_DA_CS(x)	(((x)) & EP93XX_IDE_CTRL_DA_CS_MASK)
+#define EP93XX_IDE_CTRL_DIORn		(1L << 5)
+#define EP93XX_IDE_CTRL_DIOWn		(1L << 6)
+#define EP93XX_IDE_CTRL_DASPn		(1L << 7)
+#define EP93XX_IDE_CTRL_DMARQ		(1L << 8)
+#define EP93XX_IDE_CTRL_INTRQ		(1L << 9)
+#define EP93XX_IDE_CTRL_IORDY		(1L << 10)
+
+#define EP93XX_IDE_CFG_IDEEN		(1L << 0)
+#define EP93XX_IDE_CFG_PIO		(1L << 1)
+#define EP93XX_IDE_CFG_MDMA		(1L << 2)
+#define EP93XX_IDE_CFG_UDMA		(1L << 3)
+#define EP93XX_IDE_CFG_MODE(x)		((x & 0x0F) << 4)
+#define EP93XX_IDE_CFG_WST(x)		((x & 0x03) << 8)
+
 
 #define EP93XX_VIC1_BASE		(EP93XX_AHB_VIRT_BASE + 0x000b0000)
 
#23 lore raw
Quoted 8 lines · Lennert Buytenhek
Quoted 1 line · Jeff Garzik

* ARM, PPC and other non-x86 platform drivers are severely under-represented.

Allessandro Zummo sent the patch below to me a while ago, for support for the PATA controller (PIO only, although the hardware can also do UDMA) in the cirrus logic ep93xx ARM cpu.

Quoted 5 lines

The driver has bitrotted somewhat, and apart from that it never honored PIO timings properly and has some other issues, but Allessandro seems to have disappeared off the face of the planet. I'd still like to see support for this go in at some point, so I'll have a try at cleaning it up and updating it (and converting it to a platform driver, etc.)

Please do, I'm definitely interested in it.

If you can diff against jgarzik/libata-dev.git#upstream, that would be most helpful. That's where the other PATA drivers and API updates are, as well as a move of everything libata into drivers/ata.

I've included a few comments below, if they are of any help.

Quoted 20 lines

Index: linux-2.6.16-rc5/drivers/scsi/Kconfig
===================================================================

drivers/scsi/Kconfig +4 -0
@@ -912,6 +912,10 @@ config SCSI_PATA_TS7200
 	tristate "TS7200 Compact Flash support"
 	depends on MACH_TS72XX
 
+config SCSI_PATA_EP93XX
+	tristate "Cirrus Logic EP93XX PATA support"
+	depends on ARCH_EP93XX
+
 config SCSI_BUSLOGIC
 	tristate "BusLogic SCSI support"
 	depends on (PCI || ISA || MCA) && SCSI && ISA_DMA_API

Index: linux-2.6.16-rc5/drivers/scsi/Makefile
===================================================================

drivers/scsi/Makefile obj-$(CONFIG_SCSI_PATA_WINBOND) += libat · line 178

Quoted 4 lines
drivers/scsi/Makefile +1 -0
@@ -175,6 +175,7 @@ obj-$(CONFIG_SCSI_PATA_WINBOND)	+= libat
 obj-$(CONFIG_SCSI_ATA_GENERIC)	+= libata.o ata_generic.o
 obj-$(CONFIG_SCSI_PATA_LEGACY)	+= libata.o pata_legacy.o
 obj-$(CONFIG_SCSI_PATA_TS7200)	+= libata.o pata_ts7200.o
+obj-$(CONFIG_SCSI_PATA_EP93XX)		+= libata.o pata_ep93xx.o

this stuff moves to drivers/ata, and changes to CONFIG_PATA_xxx

Quoted 14 lines

Index: linux-2.6.16-rc5/drivers/scsi/pata_ep93xx.c
===================================================================

drivers/scsi/pata_ep93xx.c new file +9 -0
@@ -0,0 +1,375 @@
+/*
+ * EP93XX PATA controller driver.
+ * Copyright (c) 2006 Tower Technologies
+ * Author: Alessandro Zummo <[email protected]>
+ *
+ * An ATA driver to handle the embedded IDE controller
+ * of the Cirrus Logic EP93XX.
+ */
+

drivers/scsi/pata_ep93xx.c line 19

Quoted 10 lines
drivers/scsi/pata_ep93xx.c new file +10 -0
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/libata.h>
+#include <scsi/scsi_host.h>
+#include <linux/platform_device.h>
+
+#define DRV_NAME	"pata_ep93xx"
+#define DRV_VERSION	"0.1"
+
+struct ata_host_set *ep93xx_host;

this should be stored in the platform_driver's driver_data area.

The code should be pretty darn close to the current libata PCI code, which uses pci_set_drvdata().

drivers/scsi/pata_ep93xx.c line 21

Quoted 1 line
drivers/scsi/pata_ep93xx.c new file +1 -0
+static inline void ep93xx_toggle_wr(register u32 ctrl)

no 'register', please

drivers/scsi/pata_ep93xx.c line 30

Quoted 9 lines
drivers/scsi/pata_ep93xx.c new file +9 -0
+{
+	ctrl &= ~(EP93XX_IDE_CTRL_DIOWn);
+	__raw_writel(ctrl, EP93XX_IDE_CTRL);
+
+	ctrl |= EP93XX_IDE_CTRL_DIOWn;
+	__raw_writel(ctrl, EP93XX_IDE_CTRL);
+}
+
+static inline void ep93xx_toggle_rd(register u32 ctrl)

ditto

drivers/scsi/pata_ep93xx.c line 41

Quoted 11 lines
drivers/scsi/pata_ep93xx.c new file +11 -0
+{
+	ctrl &= ~(EP93XX_IDE_CTRL_DIORn);
+	__raw_writel(ctrl, EP93XX_IDE_CTRL);
+
+	ctrl |= EP93XX_IDE_CTRL_DIORn;
+	__raw_writel(ctrl, EP93XX_IDE_CTRL);
+}
+
+#define ep93xx_write_addr(ctrl,addr) { \
+	ctrl = (ctrl & ~(EP93XX_IDE_CTRL_DA_CS_MASK)) | EP93XX_IDE_CTRL_DA_CS(addr); \
+	__raw_writel(ctrl, EP93XX_IDE_CTRL); }

this could be static inline too, AFAICS?

drivers/scsi/pata_ep93xx.c line 43

Quoted 1 line
drivers/scsi/pata_ep93xx.c new file +1 -0
+static inline void ep93xx_writew(register u16 value, volatile void __iomem *p)

no 'volatile' or 'register', please

drivers/scsi/pata_ep93xx.c line 56

Quoted 13 lines
drivers/scsi/pata_ep93xx.c new file +13 -0
+{
+	register u32 ctrl = __raw_readl(EP93XX_IDE_CTRL);
+
+	ep93xx_write_addr(ctrl, (unsigned long) p);
+	__raw_writel(value, EP93XX_IDE_DATAOUT);
+	ep93xx_toggle_wr(ctrl);
+}
+
+#define ep93xx_writeb(value,addr) ep93xx_writew(value,addr)
+
+static inline unsigned short ep93xx_readw(volatile void __iomem *p)
+{
+	register u32 ctrl = __raw_readl(EP93XX_IDE_CTRL);

ditto

Quoted 87 lines
drivers/scsi/pata_ep93xx.c new file +87 -0
+	ep93xx_write_addr(ctrl, (unsigned long) p);
+	ep93xx_toggle_rd(ctrl);
+	return __raw_readl(EP93XX_IDE_DATAIN);
+}
+
+#define ep93xx_readb(addr) ep93xx_readw(addr)
+
+static unsigned int ep93xx_mode_filter(const struct ata_port *ap,
+	struct ata_device *adev, unsigned int mask, int shift)
+{
+	if (shift != ATA_SHIFT_PIO)
+		return 0;
+	return mask;
+}
+
+static void ep93xx_set_mode(struct ata_port *ap)
+{
+	int i;
+
+	for (i = 0; i < ATA_MAX_DEVICES; i++) {
+		struct ata_device *dev = &ap->device[i];
+		if (ata_dev_present(dev)) {
+			dev->pio_mode = XFER_PIO_0;
+			dev->xfer_mode = XFER_PIO_0;
+			dev->xfer_shift = ATA_SHIFT_PIO;
+			dev->flags |= ATA_DFLAG_PIO;
+		}
+	}
+}
+
+static void ep93xx_phy_reset(struct ata_port *ap)
+{
+	ap->cbl = ATA_CBL_PATA40;
+	ata_port_probe(ap);
+	ata_bus_reset(ap);
+}
+
+static void ep93xx_irq_clear(struct ata_port *ap)
+{
+}
+
+static void ep93xx_irq_on(struct ata_port *ap)
+{
+}
+
+static void ep93xx_tf_load(struct ata_port *ap, const struct ata_taskfile *tf)
+{
+	struct ata_ioports *ioaddr = &ap->ioaddr;
+	unsigned int is_addr = tf->flags & ATA_TFLAG_ISADDR;
+
+	if (tf->ctl != ap->last_ctl) {
+		ep93xx_writeb(tf->ctl, (void __iomem *) ap->ioaddr.ctl_addr);
+		ap->last_ctl = tf->ctl;
+		ata_wait_idle(ap);
+	}
+
+	if (is_addr && (tf->flags & ATA_TFLAG_LBA48)) {
+		ep93xx_writeb(tf->hob_feature, (void __iomem *) ioaddr->feature_addr);
+		ep93xx_writeb(tf->hob_nsect, (void __iomem *) ioaddr->nsect_addr);
+		ep93xx_writeb(tf->hob_lbal, (void __iomem *) ioaddr->lbal_addr);
+		ep93xx_writeb(tf->hob_lbam, (void __iomem *) ioaddr->lbam_addr);
+		ep93xx_writeb(tf->hob_lbah, (void __iomem *) ioaddr->lbah_addr);
+		VPRINTK("hob: feat 0x%X nsect 0x%X, lba 0x%X 0x%X 0x%X\n",
+			tf->hob_feature,
+			tf->hob_nsect,
+			tf->hob_lbal,
+			tf->hob_lbam,
+			tf->hob_lbah);
+	}
+
+	if (is_addr) {
+		ep93xx_writeb(tf->feature, (void __iomem *) ioaddr->feature_addr);
+		ep93xx_writeb(tf->nsect, (void __iomem *) ioaddr->nsect_addr);
+		ep93xx_writeb(tf->lbal, (void __iomem *) ioaddr->lbal_addr);
+		ep93xx_writeb(tf->lbam, (void __iomem *) ioaddr->lbam_addr);
+		ep93xx_writeb(tf->lbah, (void __iomem *) ioaddr->lbah_addr);
+		VPRINTK("feat 0x%X nsect 0x%X lba 0x%X 0x%X 0x%X\n",
+			tf->feature,
+			tf->nsect,
+			tf->lbal,
+			tf->lbam,
+			tf->lbah);
+	}
+
+	if (tf->flags & ATA_TFLAG_DEVICE) {
+		ep93xx_writeb(tf->device, (void __iomem *) ioaddr->device_addr);
+		VPRINTK("device 0x%X\n", tf->device);

drivers/scsi/pata_ep93xx.c line 154

Quoted 10 lines
drivers/scsi/pata_ep93xx.c new file +10 -0
+	}
+
+	ata_wait_idle(ap);
+}
+
+static void ep93xx_tf_read(struct ata_port *ap, struct ata_taskfile *tf)
+{
+	struct ata_ioports *ioaddr = &ap->ioaddr;
+
+	tf->command = ap->ops->check_status(ap);

remove indirection in the hot path, by directly calling ep93xx_check_status() here

Quoted 92 lines
drivers/scsi/pata_ep93xx.c new file +92 -0
+	tf->feature = ep93xx_readb((void __iomem *)ioaddr->error_addr);
+	tf->nsect = ep93xx_readb((void __iomem *)ioaddr->nsect_addr);
+	tf->lbal = ep93xx_readb((void __iomem *)ioaddr->lbal_addr);
+	tf->lbam = ep93xx_readb((void __iomem *)ioaddr->lbam_addr);
+	tf->lbah = ep93xx_readb((void __iomem *)ioaddr->lbah_addr);
+	tf->device = ep93xx_readb((void __iomem *)ioaddr->device_addr);
+
+	if (tf->flags & ATA_TFLAG_LBA48) {
+		ep93xx_writeb(tf->ctl | ATA_HOB, (void __iomem *) ap->ioaddr.ctl_addr);
+		tf->hob_feature = ep93xx_readb((void __iomem *)ioaddr->error_addr);
+		tf->hob_nsect = ep93xx_readb((void __iomem *)ioaddr->nsect_addr);
+		tf->hob_lbal = ep93xx_readb((void __iomem *)ioaddr->lbal_addr);
+		tf->hob_lbam = ep93xx_readb((void __iomem *)ioaddr->lbam_addr);
+		tf->hob_lbah = ep93xx_readb((void __iomem *)ioaddr->lbah_addr);
+	}
+}
+
+static u8 ep93xx_check_status(struct ata_port *ap)
+{
+	return ep93xx_readb((void __iomem *) ap->ioaddr.status_addr);
+}
+
+static u8 ep93xx_check_altstatus(struct ata_port *ap)
+{
+	return ep93xx_readb((void __iomem *)ap->ioaddr.altstatus_addr);
+}
+
+static void ep93xx_exec_command(struct ata_port *ap, const struct ata_taskfile *tf)
+{
+	DPRINTK("ata%u: cmd 0x%X\n", ap->id, tf->command);
+
+	ep93xx_writeb(tf->command, (void __iomem *) ap->ioaddr.command_addr);
+	ata_pause(ap);
+}
+
+static unsigned int ep93xx_dev_check(struct ata_port *ap, unsigned int device)
+{
+	struct ata_ioports *ioaddr = &ap->ioaddr;
+	u8 nsect, lbal;
+
+	ap->ops->dev_select(ap, device);
+
+	ep93xx_writeb(0x55, (void __iomem *) ioaddr->nsect_addr);
+	ep93xx_writeb(0xaa, (void __iomem *) ioaddr->lbal_addr);
+
+	ep93xx_writeb(0xaa, (void __iomem *) ioaddr->nsect_addr);
+	ep93xx_writeb(0x55, (void __iomem *) ioaddr->lbal_addr);
+
+	ep93xx_writeb(0x55, (void __iomem *) ioaddr->nsect_addr);
+	ep93xx_writeb(0xaa, (void __iomem *) ioaddr->lbal_addr);
+
+	nsect = ep93xx_readb((void __iomem *) ioaddr->nsect_addr);
+	lbal = ep93xx_readb((void __iomem *) ioaddr->lbal_addr);
+
+	if ((nsect == 0x55) && (lbal == 0xaa))
+		return 1;	/* we found a device */
+
+	return 0;		/* nothing found */
+}
+
+static void ep93xx_dev_select (struct ata_port *ap, unsigned int device)
+{
+	u8 tmp;
+
+	if (device == 0)
+		tmp = ATA_DEVICE_OBS;
+	else
+		tmp = ATA_DEVICE_OBS | ATA_DEV1;
+
+	ep93xx_writeb(tmp, (void __iomem *) ap->ioaddr.device_addr);
+
+	ata_pause(ap);	/* needed; also flushes, for mmio */
+}
+
+static void ep93xx_data_xfer(struct ata_port *ap, struct ata_device *adev,
+			unsigned char *buf, unsigned int buflen, int write_data)
+{
+	unsigned int i;
+	unsigned int words = buflen >> 1;
+	u16 *buf16 = (u16 *) buf;
+	void __iomem *mmio = (void __iomem *)ap->ioaddr.data_addr;
+
+	/* Transfer multiple of 2 bytes */
+	if (write_data) {
+		for (i = 0; i < words; i++)
+			ep93xx_writew(le16_to_cpu(buf16[i]), mmio);
+	} else {
+		for (i = 0; i < words; i++)
+			buf16[i] = cpu_to_le16(ep93xx_readw(mmio));
+	}
+
+	/* Transfer trailing 1 byte, if any. */

drivers/scsi/pata_ep93xx.c line 256

Quoted 10 lines
drivers/scsi/pata_ep93xx.c new file +10 -0
+	if (unlikely(buflen & 0x01)) {
+		u16 align_buf[1] = { 0 };
+		unsigned char *trailing_buf = buf + buflen - 1;
+
+		if (write_data) {
+			memcpy(align_buf, trailing_buf, 1);
+			ep93xx_writew(le16_to_cpu(align_buf[0]), mmio);
+		} else {
+			align_buf[0] = cpu_to_le16(ep93xx_readw(mmio));
+			memcpy(trailing_buf, align_buf, 1);

any chance your platform as string functions, a la insl() ?

Quoted 37 lines
drivers/scsi/pata_ep93xx.c new file +37 -0
+static struct scsi_host_template ep93xx_sht = {
+	.module			= THIS_MODULE,
+	.name			= DRV_NAME,
+	.ioctl			= ata_scsi_ioctl,
+	.queuecommand		= ata_scsi_queuecmd,
+	.eh_strategy_handler	= ata_scsi_error,
+	.can_queue		= ATA_DEF_QUEUE,
+	.this_id		= ATA_SHT_THIS_ID,
+	.sg_tablesize		= LIBATA_MAX_PRD,
+	.max_sectors		= ATA_MAX_SECTORS,
+	.cmd_per_lun		= ATA_SHT_CMD_PER_LUN,
+	.emulated		= ATA_SHT_EMULATED,
+	.use_clustering		= ATA_SHT_USE_CLUSTERING,
+	.proc_name		= DRV_NAME,
+	.dma_boundary		= ATA_DMA_BOUNDARY,
+	.slave_configure	= ata_scsi_slave_config,
+	.bios_param		= ata_std_bios_param,
+};
+
+static struct ata_port_operations ep93xx_port_ops = {
+	.set_mode		= ep93xx_set_mode,
+	.mode_filter		= ep93xx_mode_filter,
+
+	.port_disable		= ata_port_disable,
+	.tf_load		= ep93xx_tf_load,
+	.tf_read		= ep93xx_tf_read,
+	.check_status 		= ep93xx_check_status,
+	.check_altstatus	= ep93xx_check_altstatus,
+	.exec_command		= ep93xx_exec_command,
+	.data_xfer		= ep93xx_data_xfer,
+
+	.dev_select 		= ep93xx_dev_select,
+	.dev_check		= ep93xx_dev_check,
+
+	.qc_prep 		= ata_qc_prep,
+	.qc_issue		= ata_qc_issue_prot,
+	.eng_timeout		= ata_eng_timeout,

drivers/scsi/pata_ep93xx.c line 307

Quoted 10 lines
drivers/scsi/pata_ep93xx.c new file +10 -0
+
+	.irq_handler		= ata_interrupt,
+	.irq_clear		= ep93xx_irq_clear,
+	.irq_on			= ep93xx_irq_on,
+
+	.port_start		= ata_port_start,
+	.port_stop		= ata_port_stop,
+	.host_stop		= ata_host_stop,
+
+	.phy_reset		= ep93xx_phy_reset,

this driver will need updating for the new EH. Existing PATA drivers in drivers/ata/pata_* provide plenty of examples. It's mostly just deleting ->eng_timeout() hook and a couple others, and using the new reset driver.

Quoted 89 lines
drivers/scsi/pata_ep93xx.c new file +66 -0
+/* Setup the addresses and encode CSx within them */
+static void ep93xx_ports(struct ata_ioports *ioaddr)
+{
+	ioaddr->cmd_addr	= 0 + 2; /* CS1 */
+	ioaddr->altstatus_addr	= (0x06 << 2) + 1; /* CS0 */
+	ioaddr->ctl_addr	= (0x06 << 2) + 1; /* CS0 */
+
+	ioaddr->data_addr	= (ATA_REG_DATA << 2) + 2;
+	ioaddr->error_addr	= (ATA_REG_ERR << 2) + 2;
+	ioaddr->feature_addr	= (ATA_REG_FEATURE << 2) + 2;
+	ioaddr->nsect_addr	= (ATA_REG_NSECT << 2) + 2;
+	ioaddr->lbal_addr	= (ATA_REG_LBAL << 2) + 2;
+	ioaddr->lbam_addr	= (ATA_REG_LBAM << 2) + 2;
+	ioaddr->lbah_addr	= (ATA_REG_LBAH << 2) + 2;
+	ioaddr->device_addr	= (ATA_REG_DEVICE << 2) + 2;
+	ioaddr->status_addr	= (ATA_REG_STATUS << 2) + 2;
+	ioaddr->command_addr	= (ATA_REG_CMD << 2) + 2;
+}
+
+static int __init ep93xx_pata_init(void)
+{
+	int ret;
+	struct ata_probe_ent ae;
+
+	memset(&ae, 0, sizeof(struct ata_probe_ent));
+	INIT_LIST_HEAD(&ae.node);
+
+	ae.dev		= NULL;
+	ae.private_data = NULL;
+	ae.port_ops	= &ep93xx_port_ops;
+	ae.sht		= &ep93xx_sht;
+	ae.n_ports	= 1;
+	ae.pio_mask	= 0x1f; /* PIO4 */
+	ae.irq		= 0;
+	ae.irq_flags	= 0;
+	ae.host_flags	= ATA_FLAG_IRQ_MASK | ATA_FLAG_MMIO;
+
+	ep93xx_ports(&ae.port[0]);
+
+	/* enable ide and set pio mode 4 */
+	__raw_writel(EP93XX_IDE_CFG_IDEEN | EP93XX_IDE_CFG_PIO |
+			EP93XX_IDE_CFG_WST(0) | EP93XX_IDE_CFG_MODE(4),
+			EP93XX_IDE_CFG);
+
+	ret = ata_device_add(&ae);
+	if (ret == 0)
+		return -ENODEV;
+
+	ep93xx_host = ae.host_set;
+
+	return 0;
+}
+
+static void __exit ep93xx_pata_exit(void)
+{
+	if (ep93xx_host)
+		ata_host_set_remove(ep93xx_host);
+}
+
+MODULE_AUTHOR("Alessandro Zummo <[email protected]>");
+MODULE_DESCRIPTION("low-level driver for ep93xx ATA");
+MODULE_LICENSE("GPL");
+MODULE_VERSION(DRV_VERSION);
+
+module_init(ep93xx_pata_init);
+module_exit(ep93xx_pata_exit);

Index: linux-2.6.16-rc5/include/asm-arm/arch-ep93xx/ep93xx-regs.h
===================================================================

include/asm-arm/arch-ep93xx/ep93xx-regs.h +15 -0
@@ -42,6 +42,32 @@
 #define EP93XX_BOOT_ROM_BASE		(EP93XX_AHB_VIRT_BASE + 0x00090000)
 
 #define EP93XX_IDE_BASE			(EP93XX_AHB_VIRT_BASE + 0x000a0000)
+#define EP93XX_IDE_REG(x)		(EP93XX_IDE_BASE + (x))
+#define EP93XX_IDE_CTRL			EP93XX_IDE_REG(0x0000)
+#define EP93XX_IDE_CFG			EP93XX_IDE_REG(0x0004)
+#define EP93XX_IDE_DATAOUT		EP93XX_IDE_REG(0x0010)
+#define EP93XX_IDE_DATAIN		EP93XX_IDE_REG(0x0014)
+
+#define EP93XX_IDE_CTRL_CS0n		(1L << 0)
+#define EP93XX_IDE_CTRL_CS1n		(1L << 1)
+#define EP93XX_IDE_CTRL_DA_MASK		0x1C
+#define EP93XX_IDE_CTRL_DA(x)		((x << 2) & EP93XX_IDE_CTRL_DA_MASK)
+#define EP93XX_IDE_CTRL_DA_CS_MASK	(EP93XX_IDE_CTRL_DA_MASK | EP93XX_IDE_CTRL_CS0n | EP93XX_IDE_CTRL_CS1n)
+#define EP93XX_IDE_CTRL_DA_CS(x)	(((x)) & EP93XX_IDE_CTRL_DA_CS_MASK)
+#define EP93XX_IDE_CTRL_DIORn		(1L << 5)
+#define EP93XX_IDE_CTRL_DIOWn		(1L << 6)
+#define EP93XX_IDE_CTRL_DASPn		(1L << 7)

include/asm-arm/arch-ep93xx/ep93xx-regs.h line 69

Quoted 10 lines
include/asm-arm/arch-ep93xx/ep93xx-regs.h +10 -0
+#define EP93XX_IDE_CTRL_DMARQ		(1L << 8)
+#define EP93XX_IDE_CTRL_INTRQ		(1L << 9)
+#define EP93XX_IDE_CTRL_IORDY		(1L << 10)
+
+#define EP93XX_IDE_CFG_IDEEN		(1L << 0)
+#define EP93XX_IDE_CFG_PIO		(1L << 1)
+#define EP93XX_IDE_CFG_MDMA		(1L << 2)
+#define EP93XX_IDE_CFG_UDMA		(1L << 3)
+#define EP93XX_IDE_CFG_MODE(x)		((x & 0x0F) << 4)
+#define EP93XX_IDE_CFG_WST(x)		((x & 0x03) << 8)

would prefer that this stuff go into the pata_ep93xx.c file, if it's not used anywhere else

#24 lore raw

cirrus ep93xx pata driver (was: Re: PATA drivers queued for 2.6.19)

(please CC, not on the list)

Quoted 11 lines · Jeff Garzik
Quoted 9 lines

Allessandro Zummo sent the patch below to me a while ago, for support for the PATA controller (PIO only, although the hardware can also do UDMA) in the cirrus logic ep93xx ARM cpu.

The driver has bitrotted somewhat, and apart from that it never honored PIO timings properly and has some other issues, but Allessandro seems to have disappeared off the face of the planet. I'd still like to see support for this go in at some point, so I'll have a try at cleaning it up and updating it (and converting it to a platform driver, etc.)

Please do, I'm definitely interested in it.

Below is a mostly rewritten driver against 2.6.20-rcX for the ep93xx. Lightly tested, appears to work at least with CompactFlash cards.

There are still several issues with the current version that I am aware of, and so I'm not asking for a review of pata_ep93xx.c yet. I _would_ like to get some input on the libata-* changes in the patch.

The main problem with the ep93xx is that its "IDE controller" is really just a (somewhat) glorified GPIO controller. You can't trigger a PATA bus read or write by reading or writing some specified memory location, oh no, that would have been too easy. Instead, you have to set CS/DA manually, then assert DIORn/DIOWn manually, delay for the right number of nanoseconds corresponding to this PIO mode, and then deassert DIORn/DIOWn again by hand.

libata-{core,sff}.c assume that we can read from device registers using readb()/inb() and write to them via writeb()/outb(). While it is possible to avoid some of these codepaths by defining your own ata_port_operations, some codepaths that do direct accesses aren't override-able.

The approach taken below is to add ops for these, which isn't necessarily the best approach. (Another approach might be to define ATA_FLAG_FITH as a third access method alongside ATA_FLAG_MMIO and !ATA_FLAG_MMIO.)

The other thing is that it's not guaranteed that the INTRQ line is actually hooked up to something, while some libata code paths bail out if ent->irq is zero.

Comments?

drivers/ata/Kconfig +9 -0
Index: linux-2.6.19/drivers/ata/Kconfig
===================================================================
@@ -246,6 +246,15 @@ config ATA_GENERIC
 
 	  If unsure, say N.
 
+config PATA_EP93XX
+	tristate "Cirrus Logic EP93XX PATA support"
+	depends on ARCH_EP93XX
+	help
+	  This option enables support for the PATA controller in
+	  the Cirrus Logic ep93xx ARM CPU.
+
+	  If unsure, say N.
+
 config PATA_HPT366
 	tristate "HPT 366/368 PATA support (Very Experimental)"
 	depends on PCI && EXPERIMENTAL
drivers/ata/Makefile +1 -0
Index: linux-2.6.19/drivers/ata/Makefile
===================================================================
@@ -27,6 +27,7 @@ obj-$(CONFIG_PATA_CS5530)	+= pata_cs5530
 obj-$(CONFIG_PATA_CS5535)	+= pata_cs5535.o
 obj-$(CONFIG_PATA_CYPRESS)	+= pata_cypress.o
 obj-$(CONFIG_PATA_EFAR)		+= pata_efar.o
+obj-$(CONFIG_PATA_EP93XX)	+= pata_ep93xx.o
 obj-$(CONFIG_PATA_HPT366)	+= pata_hpt366.o
 obj-$(CONFIG_PATA_HPT37X)	+= pata_hpt37x.o
 obj-$(CONFIG_PATA_HPT3X2N)	+= pata_hpt3x2n.o
drivers/ata/libata-core.c +35 -11

102 lines not on this page · raw message

drivers/ata/libata-sff.c +14 -1
Index: linux-2.6.19/drivers/ata/libata-sff.c
===================================================================
@@ -38,6 +38,14 @@
 
 #include "libata.h"
 
+#ifdef CONFIG_ARCH_EP93XX
+#warning remove this
+#undef readb
+#undef writeb
+#define readb(x) printk(KERN_CRIT "readb() at sff line %d\n",  __LINE__)
+#define writeb(d,a) printk(KERN_CRIT "writeb() at sff line %d\n", __LINE__)
+#endif
+
 /**
  *	ata_irq_on - Enable interrupts on a port.
  *	@ap: Port on which interrupts are enabled.
@@ -56,7 +64,9 @@ u8 ata_irq_on(struct ata_port *ap)
 	ap->ctl &= ~ATA_NIEN;
 	ap->last_ctl = ap->ctl;
 
-	if (ap->flags & ATA_FLAG_MMIO)
+	if (ap->ops->irq_on != NULL)
+		ap->ops->irq_on(ap);
+	else if (ap->flags & ATA_FLAG_MMIO)
 		writeb(ap->ctl, (void __iomem *) ioaddr->ctl_addr);
 	else
 		outb(ap->ctl, ioaddr->ctl_addr);
@@ -417,6 +427,9 @@ static u8 ata_check_status_mmio(struct a
  */
 u8 ata_check_status(struct ata_port *ap)
 {
+	if (ap->ops->check_status)
+		return ap->ops->check_status(ap);
+
 	if (ap->flags & ATA_FLAG_MMIO)
 		return ata_check_status_mmio(ap);
 	return ata_check_status_pio(ap);
drivers/ata/pata_ep93xx.c new file +459 -0

459 lines not on this page · raw message

include/linux/libata.h +7 -1
Index: linux-2.6.19/include/linux/libata.h
===================================================================
@@ -610,8 +610,10 @@ struct ata_port_operations {
 	u8   (*check_status)(struct ata_port *ap);
 	u8   (*check_altstatus)(struct ata_port *ap);
 	void (*dev_select)(struct ata_port *ap, unsigned int device);
+	unsigned int (*dev_check)(struct ata_port *ap, unsigned int device);
 
 	void (*phy_reset) (struct ata_port *ap); /* obsolete */
+	void (*bus_softreset) (struct ata_port *ap);
 	void (*set_mode) (struct ata_port *ap);
 
 	void (*post_set_mode) (struct ata_port *ap);
@@ -637,7 +639,9 @@ struct ata_port_operations {
 	void (*post_internal_cmd) (struct ata_queued_cmd *qc);
 
 	irq_handler_t irq_handler;
+	u8 (*irq_ack) (struct ata_port *);
 	void (*irq_clear) (struct ata_port *);
+	void (*irq_on) (struct ata_port *);
 
 	u32 (*scr_read) (struct ata_port *ap, unsigned int sc_reg);
 	void (*scr_write) (struct ata_port *ap, unsigned int sc_reg,
@@ -1179,7 +1183,9 @@ static inline u8 ata_irq_ack(struct ata_
 			printk(KERN_ERR "abnormal status 0x%X\n", status);
 
 	/* get controller status; clear intr, err bits */
-	if (ap->flags & ATA_FLAG_MMIO) {
+	if (ap->ops->irq_ack) {
+		post_stat = ap->ops->irq_ack(ap);
+	} else if (ap->flags & ATA_FLAG_MMIO) {
 		void __iomem *mmio = (void __iomem *) ap->ioaddr.bmdma_addr;
 		host_stat = readb(mmio + ATA_DMA_STATUS);
 		writeb(host_stat | ATA_DMA_INTR | ATA_DMA_ERR,
#25 lore raw

Re: cirrus ep93xx pata driver

I know it's probably a low priority, but could you rediff this against the current libata?

I'm wondering where we are in terms of hooks that you need. Since you posted this we added some hooks for the pata_scc driver, most notably ->irq_on() hooks. And other code you modify, such as the ata_bus_reset() function, is slated for deletion once all drivers have been converted over to the new EH (done, in testing).

I'm betting libata-core only has a little way to go before pata_ep93xx will work.

Jeff

#26 lore raw

Re: cirrus ep93xx pata driver

Quoted 8 lines · Jeff Garzik

I know it's probably a low priority, but could you rediff this against the current libata?

I'm wondering where we are in terms of hooks that you need. Since you posted this we added some hooks for the pata_scc driver, most notably ->irq_on() hooks. And other code you modify, such as the ata_bus_reset() function, is slated for deletion once all drivers have been converted over to the new EH (done, in testing).

The main problem on ep93xx is that the IDE registers aren't accessible via memory space or I/O space reads/writes -- instead, you get to put the address/data on the bus by hand, twiddle the nRD/nWR lines by hand, enforcing PIO timings as you go along by manually delaying for the right number of nanoseconds, etc.

The libata methods I added hooks for were all methods that check ATA_FLAG_MMIO and do {read,write}[bwl] or {in,out}[bwl] accesses based on the state of that flag. What I did in those cases was to verbatim cut-'n-paste the libata code into pata_ep93xx, changing the {read,write,in,out}[bwl] calls into calls to pata_ep93xx's accessor functions. Of course, this is ugly, duplicates code, and will break whenever someone adds new code to libata that accesses the task file registers directly.

I did hack up the pata_ep93xx patch to add a third method, ATA_FLAG_FITH, and call the appropriate port-specific accessor functions via a pair of extra ops in ata_port_operations. However, I didn't really think that that was an upstream-mergeable solution.

(Although if we define ATA_FLAG_FITH to 0 so that all tests against it will fail at compile time if there are no FITH drivers compiled in or compiled as modules might make it not suck too hard.. but it's still ugly.)

#27 lore raw

Re: cirrus ep93xx pata driver

Quoted 8 lines · Lennert Buytenhek
Quoted 5 lines · Jeff Garzik

I know it's probably a low priority, but could you rediff this against the current libata?

I'm wondering where we are in terms of hooks that you need. Since you posted this we added some hooks for the pata_scc driver, most notably ->irq_on() hooks. And other code you modify, such as the
ata_bus_reset() function, is slated for deletion once all drivers have been converted over to the new EH (done, in testing).

Quoted 5 lines

The main problem on ep93xx is that the IDE registers aren't accessible via memory space or I/O space reads/writes -- instead, you get to put the address/data on the bus by hand, twiddle the nRD/nWR lines by hand, enforcing PIO timings as you go along by manually delaying for the right number of nanoseconds, etc.

Nod, your patch explained that :)

Quoted 8 lines

The libata methods I added hooks for were all methods that check ATA_FLAG_MMIO and do {read,write}[bwl] or {in,out}[bwl] accesses based on the state of that flag. What I did in those cases was to verbatim cut-'n-paste the libata code into pata_ep93xx, changing the {read,write,in,out}[bwl] calls into calls to pata_ep93xx's accessor functions. Of course, this is ugly, duplicates code, and will break whenever someone adds new code to libata that accesses the task file registers directly.

Well, judging solely from the patch you sent, it looks like we already have the necessary hooks for everything you need. After reviewing each modification, ata_devchk() appeared to be the only function that did not have a directly corresponding hook. Several of your modifications were to old-EH functions that your driver never calls, etc.

So if you could refresh the patch from Jan 28th, I bet recent API improvements can get it into upstream-mergeable shape, without having to create low-level IO accessor hooks.

Jeff