Patch to add support for SGI's IOC4 chipset
Hi
This patch adds support for the ATAPI part of SGI's IOC4 chipset.
A version of this patch for the 2.4 series has been accepted and is present in the tree. This patch is a slight modification of the earlier patch for the 2.4 series.
Please merge this patch if there are no outstanding issues.
Thanks
Aniket
# This is a BitKeeper generated patch for the following project:
# Project Name: Linux kernel tree
# This patch format is intended for GNU patch command version 2.5 or higher. # This patch includes the following deltas:
# ChangeSet 1.1418 -> 1.1419
# drivers/ide/pci/Makefile 1.8 -> 1.9
# include/linux/pci_ids.h 1.123 -> 1.124
# drivers/ide/Kconfig 1.29 -> 1.30 # (new) -> 1.1 drivers/ide/pci/sgiioc4.c # (new) -> 1.1 drivers/ide/pci/sgiioc4.h
#
# The following is the BitKeeper ChangeSet Log # --------------------------------------------
# 03/10/02 [email protected] 1.1419
# Adds support for the ATAPI part of the IOC4 chipset. # -------------------------------------------- #
drivers/ide/Kconfig +7 -0
@@ -740,6 +740,13 @@ This driver adds PIO/(U)DMA support for the ServerWorks OSB4/CSB5 chipsets. +config BLK_DEV_SGIIOC4 + tristate "Silicon Graphics IOC4 chipset support" + help + This driver adds PIO & MultiMode DMA-2 support for the SGI IOC4 + chipset. Please say Y here, if you have an Altix System from + Silicon Graphics Inc. + config BLK_DEV_SIIMAGE tristate "Silicon Image chipset support" help
drivers/ide/pci/Makefile +1 -0
@@ -22,6 +22,7 @@ obj-$(CONFIG_BLK_DEV_PIIX) += piix.o obj-$(CONFIG_BLK_DEV_RZ1000) += rz1000.o obj-$(CONFIG_BLK_DEV_SVWKS) += serverworks.o +obj-$(CONFIG_BLK_DEV_SGIIOC4) += sgiioc4.o obj-$(CONFIG_BLK_DEV_SIIMAGE) += siimage.o obj-$(CONFIG_BLK_DEV_SIS5513) += sis5513.o obj-$(CONFIG_BLK_DEV_SL82C105) += sl82c105.o
drivers/ide/pci/sgiioc4.c new file +855 -0
855 lines not on this page · raw message
drivers/ide/pci/sgiioc4.h new file +170 -0
170 lines not on this page · raw message
include/linux/pci_ids.h +1 -0
@@ -896,6 +896,7 @@#define PCI_VENDOR_ID_SGI 0x10a9#define PCI_DEVICE_ID_SGI_IOC3 0x0003 +#define PCI_DEVICE_ID_SGI_IOC4 0x100a#define PCI_VENDOR_ID_SGI_LITHIUM 0x1002#define PCI_VENDOR_ID_ACC 0x10aa
Quoted 7 lines · Aniket Malatpure
Hi
This patch adds support for the ATAPI part of SGI's IOC4 chipset.
A version of this patch for the 2.4 series has been accepted and is present in the tree. This patch is a slight modification of the earlier patch for the 2.4 series.
Perhaps Bart could take a look over this sometime please?
Review
Quoted 3 lines
+++
b/drivers/ide/pci/sgiioc4.cThu Oct 2 16:53:34 2003(quoted diff) +2
-0+ +extern int dma_timer_expiry(ide_drive_t * drive);
This is unused. Just as well, as it is static to a different file.
Quoted 1 line
+static struct
pci_device_idsgiioc4_pci_tbl[]__devinitdata= {
This cannot be __devinitdata because the PCI table walking will look at it even after __init code has been dropped. We've had oopses from this.
drivers/ide/pci/sgiioc4.h
Quoted 2 lines
drivers/ide/pci/sgiioc4.h new file +0
-0
hrm, why does this file exist? It has only one include site, and should not be included by other .c files anyway because it defines static storage.
It looks like the whole file should just be pasted into sgiioc4.c?
drivers/ide/pci/sgiioc4.h line 104
Quoted 11 lines
drivers/ide/pci/sgiioc4.h new file +11
-0+typedef volatile struct { +u32 timing_reg0; +u32 timing_reg1; +u32 low_mem_ptr; +u32 high_mem_ptr; +u32 low_mem_addr; +u32 high_mem_addr; +u32 dev_byte_count; +u32 mem_byte_count; +u32 status; +}ioc4_dma_regs_t ;
Does this actually need to be volatile?
Quoted 8 lines · Aniket Malatpure
Hi
This patch adds support for the ATAPI part of SGI's IOC4 chipset. A version of this patch for the 2.4 series has been accepted and is present in the tree. This patch is a slight modification of the earlier patch for the 2.4 series.
Please merge this patch if there are no outstanding issues.
Please follow Documentation/CodingStyle and respect 80-columns limit.
+/**
+ * "Copied from drivers/ide/ide-dma.c"
+ * sgiioc4_ide_build_sglist - map IDE scatter gather for DMA I/O
+ * @hwif: the interface to build the DMA table for
+ * @rq: the request holding the sg list
+ * @ddir: data direction
+ *
+ * Perform the PCI mapping magic neccessary to access the source
+ * or target buffers of a request via PCI DMA. The lower layers
+ * of the kernel provide the neccessary cache management so that
+ * we can operate in a portable fashion.
+ *
+ * This code is identical to ide_build_sglist in ide-dma.c
+ * however that it not exported and even if it were would create
+ * dependancy problems for modular drivers.
+ */
+/**
+ * Copied from drivers/ide/ide-dma.c
+ * sgiioc4_ide_raw_build_sglist - map IDE scatter gather for DMA
+ * @hwif: the interface to build the DMA table for
+ * @rq: the request holding the sg list
+ *
+ * Perform the PCI mapping magic neccessary to access the source or
+ * target buffers of a taskfile request via PCI DMA. The lower layers
+ * of the kernel provide the neccessary cache management so that we can
+ * operate in a portable fashion
+ *
+ * This code is identical to ide_raw_build_sglist in ide-dma.c
+ * however that it not exported and even if it were would create
+ * dependancy problems for modular drivers.
+ */
What problems?
BTW during coping tabs were replaced by spaces in these functions.
+static int
+sgiioc4_get_info(char *buffer, char **addr, off_t offset, int count) +{
+ char *p = buffer;
+ unsigned int class_rev;
+ int i = 0;
+
+ while (i < n_sgiioc4_devs) {
+ pci_read_config_dword(sgiioc4_devs[i], PCI_CLASS_REVISION,
+ &class_rev);
+ class_rev &= 0xff;
+
+ if (sgiioc4_devs[i]->device == PCI_DEVICE_ID_SGI_IOC4) {
+ p += sprintf(p, "\n SGI IOC4 Chipset rev %d. ", class_rev);
+ p += sprintf(p, "\n Chipset has 1 IDE channel and supports 2 devices on that channel.");
+ p += sprintf(p, "\n Chipset supports DMA in MultiMode-2 data transfer protocol.\n");
+ /* Do we need more info. here? */
+ }
+ i++;
+ }
+
+ return p - buffer;
+}
Do you really need /proc/ide/sgiioc4?
You can print revision number during init.
Quoted 1 line
From
sgiioc4.h:
+static void sgiioc4_init_hwif_ports(hw_regs_t * hw, unsigned long data_port,
+ unsigned long ctrl_port, unsigned long irq_port);
+static void sgiioc4_ide_setup_pci_device(struct pci_dev *dev, ide_pci_device_t *d); +static void sgiioc4_resetproc(ide_drive_t * drive);
+static void sgiioc4_maskproc(ide_drive_t * drive, int mask);
+static void sgiioc4_configure_for_dma(int dma_direction, ide_drive_t * drive); +static void __init ide_init_sgiioc4(ide_hwif_t * hwif);
+static void __init ide_dma_sgiioc4(ide_hwif_t * hwif, unsigned long dma_base); +static int sgiioc4_checkirq(ide_hwif_t * hwif);
+static int sgiioc4_clearirq(ide_drive_t * drive);
+static int sgiioc4_get_info(char *buffer, char **addr, off_t offset, int count); +static int sgiioc4_ide_dma_read(ide_drive_t * drive);
+static int sgiioc4_ide_dma_write(ide_drive_t * drive);
+static int sgiioc4_ide_dma_begin(ide_drive_t * drive);
+static int sgiioc4_ide_dma_end(ide_drive_t * drive);
+static int sgiioc4_ide_dma_check(ide_drive_t * drive);
+static int sgiioc4_ide_dma_on(ide_drive_t * drive);
+static int sgiioc4_ide_dma_off(ide_drive_t * drive);
+static int sgiioc4_ide_dma_off_quietly(ide_drive_t * drive);
+static int sgiioc4_ide_dma_test_irq(ide_drive_t * drive);
+static int sgiioc4_ide_dma_host_on(ide_drive_t * drive);
+static int sgiioc4_ide_dma_host_off(ide_drive_t * drive);
+static int sgiioc4_ide_dma_count(ide_drive_t * drive);
+static int sgiioc4_ide_dma_verbose(ide_drive_t * drive);
+static int sgiioc4_ide_dma_lostirq(ide_drive_t * drive);
+static int sgiioc4_ide_dma_timeout(ide_drive_t * drive);
+static int sgiioc4_ide_build_sglist(ide_drive_t *drive, struct request *rq); +static int sgiioc4_ide_raw_build_sglist(ide_drive_t *drive, struct request *rq); +
+static u8 sgiioc4_INB(unsigned long port);
+static inline void xide_delay(long ticks);
+extern int (*sgiioc4_display_info) (char *, char **, off_t, int); /* ide-proc.c */
+static unsigned int sgiioc4_build_dma_table(ide_drive_t * drive, struct request *rq,
+ int ddir);
+static unsigned int __init pci_init_sgiioc4(struct pci_dev *dev,ide_pci_device_t *d);
Most of this declarations are not needed as sgiioc4.h is only included from shiioc4.c.
Otherwise it looks okay.
Thanks.
--bartlomiej
Quoted 1 line · Bartlomiej Zolnierkiewicz
Most of this declarations are not needed as
sgiioc4.his only included fromshiioc4.c.
I agree... but if you look at other PCI IDE drivers like piix.c,
you see the same thing. Maybe we should blame Alan... ;-)
Jeff
Quoted 6 lines · Jeff Garzik
Quoted 2 lines · Bartlomiej Zolnierkiewicz
Most of this declarations are not needed as
sgiioc4.his only included fromshiioc4.c.I agree... but if you look at other PCI IDE drivers like
piix.c,
you see the same thing. Maybe we should blame Alan... ;-)
Not exactly...
in piix.h you have only declarations which are later used in piix.h.
Maybe all these PCI IDE *.h files should die, I find them really annoying while going through PCI IDE *.c files.
--bartlomiej
Hi
Attached is a new patch which takes into account the comments on the earlier patch.
I have changed the patch as per the comments below :
--------------------------------------------------------------------------------------------------
a) Comments from Andrew Morton :
Quoted 5 lines
Review
Quoted 3 lines
+++
b/drivers/ide/pci/sgiioc4.cThu Oct 2 16:53:34 2003(quoted diff) +2
-0+ +extern int dma_timer_expiry(ide_drive_t * drive);This is unused. Just as well, as it is static to a different file.
This line has been removed.
Quoted 4 lines
Quoted 1 line
+static struct
pci_device_idsgiioc4_pci_tbl[]__devinitdata= {This cannot be
__devinitdatabecause the PCI table walking will look at it even after__initcode has been dropped. We've had oopses from this.
The __devinitdata attribute has been removed from this declaration.
Quoted 7 lines
drivers/ide/pci/sgiioc4.h Thu Oct 2 16:53:34 2003
Quoted 2 lines
drivers/ide/pci/sgiioc4.h Thu Oct 2 16:53:34 2003 renamed from dev/null Wed Dec 31 16:00:00 1969 +0
-0hrm, why does this file exist? It has only one include site, and should not be included by other .c files anyway because it defines static storage.
It looks like the whole file should just be pasted into
sgiioc4.c?
This file has been merged with sgiioc4.c as was suggested.
Quoted 5 lines
Quoted 5 lines
drivers/ide/pci/sgiioc4.h Thu Oct 2 16:53:34 2003 renamed from dev/null Wed Dec 31 16:00:00 1969 +5
-0+typedef volatile struct { + u32 timing_reg0; + u32 timing_reg1; + u32 low_mem_ptr; + u32 high_mem_ptr;
Quoted 8 lines
drivers/ide/pci/sgiioc4.h Thu Oct 2 16:53:34 2003
Quoted 6 lines
drivers/ide/pci/sgiioc4.h Thu Oct 2 16:53:34 2003 renamed from dev/null Wed Dec 31 16:00:00 1969 +6
-0+ u32 low_mem_addr; + u32 high_mem_addr; + u32 dev_byte_count; + u32 mem_byte_count; + u32 status; +} ioc4_dma_regs_t;Does this actually need to be volatile?
This structure is no longer volatile in the new patch.
--------------------------------------------------------------------------------------------------
b) Comments from Bartlomiej Zolnierkiewicz
Quoted 1 line
Please follow
Documentation/CodingStyleand respect 80-columns limit.
Lindent has been used to format the original file. Some parts have been reformatted by hand.
The 80 column limit is respected for a majority of the patch.
+ *
+ * This code is identical to ide_raw_build_sglist in ide-dma.c + * however that it not exported and even if it were would create + * dependancy problems for modular drivers.
+ */
Quoted 2 lines
What problems?
BTW during coping tabs were replaced by spaces in these functions.
Actually what I meant by problems was that, when this driver is compiled as a module and the earlier functions are not exported, the driver fails to find them. I have removed the earlier line from the new patch.
+ return p - buffer;
+}
Quoted 2 lines
Do you really need
/proc/ide/sgiioc4?
You can print revision number during init.
It has been helpful to be able to see the firmware revision num anytime during system operation.
So the new patch still creates the above entry.
+ int ddir);
+static unsigned int __init pci_init_sgiioc4(struct pci_dev *dev,ide_pci_device_t *d);
Quoted 1 line
Most of this declarations are not needed as
sgiioc4.his only included fromshiioc4.c.
The sgiioc4.h file has been removed in the new patch.
--------------------------------------------------------------------------------------------------
Please merge this patch if there are no other issues.
Thanks
Aniket
# This is a BitKeeper generated patch for the following project:
# Project Name: Linux kernel tree
# This patch format is intended for GNU patch command version 2.5 or higher. # This patch includes the following deltas:
# ChangeSet 1.1433 -> 1.1434
# drivers/ide/pci/Makefile 1.8 -> 1.9
# include/linux/pci_ids.h 1.123 -> 1.124
# drivers/ide/Kconfig 1.29 -> 1.30
# (new) -> 1.1 drivers/ide/pci/sgiioc4.c
#
# The following is the BitKeeper ChangeSet Log
# --------------------------------------------
# 03/10/03 [email protected] 1.1434
# Adds support for the IOC4 IDE part.
# --------------------------------------------
#
drivers/ide/Kconfig +7 -0
@@ -740,6 +740,13 @@ This driver adds PIO/(U)DMA support for the ServerWorks OSB4/CSB5 chipsets. +config BLK_DEV_SGIIOC4 + tristate "Silicon Graphics IOC4 chipset support" + help + This driver adds PIO & MultiMode DMA-2 support for the SGI IOC4 + chipset. Please say Y here, if you have an Altix System from + Silicon Graphics Inc. + config BLK_DEV_SIIMAGE tristate "Silicon Image chipset support" help
drivers/ide/pci/Makefile +1 -0
@@ -22,6 +22,7 @@ obj-$(CONFIG_BLK_DEV_PIIX) += piix.o obj-$(CONFIG_BLK_DEV_RZ1000) += rz1000.o obj-$(CONFIG_BLK_DEV_SVWKS) += serverworks.o +obj-$(CONFIG_BLK_DEV_SGIIOC4) += sgiioc4.o obj-$(CONFIG_BLK_DEV_SIIMAGE) += siimage.o obj-$(CONFIG_BLK_DEV_SIS5513) += sis5513.o obj-$(CONFIG_BLK_DEV_SL82C105) += sl82c105.o
drivers/ide/pci/sgiioc4.c new file +1044 -0
1,044 lines not on this page · raw message
include/linux/pci_ids.h +1 -0
@@ -896,6 +896,7 @@#define PCI_VENDOR_ID_SGI 0x10a9#define PCI_DEVICE_ID_SGI_IOC3 0x0003 +#define PCI_DEVICE_ID_SGI_IOC4 0x100a#define PCI_VENDOR_ID_SGI_LITHIUM 0x1002#define PCI_VENDOR_ID_ACC 0x10aa
Hi
Please find attached a newer version of the patch I sent out earlier today. This patch has exactly the same code as earlier, it is just formatted in a neater way.
(We realized this after an internal review of my code).
Please merge this patch if there are no other issues.
Thanks
Aniket
# This is a BitKeeper generated patch for the following project:
# Project Name: Linux kernel tree
# This patch format is intended for GNU patch command version 2.5 or higher. # This patch includes the following deltas:
# ChangeSet 1.1433 -> 1.1435
# drivers/ide/pci/Makefile 1.8 -> 1.9
# include/linux/pci_ids.h 1.123 -> 1.124
# drivers/ide/Kconfig 1.29 -> 1.30
# (new) -> 1.2 drivers/ide/pci/sgiioc4.c
#
# The following is the BitKeeper ChangeSet Log
# --------------------------------------------
# 03/10/03 [email protected] 1.1434
# Adds support for the IOC4 IDE part.
# --------------------------------------------
# 03/10/03 [email protected] 1.1435
# Formatted the driver to make it neat
# --------------------------------------------
#
drivers/ide/Kconfig +7 -0
@@ -740,6 +740,13 @@ This driver adds PIO/(U)DMA support for the ServerWorks OSB4/CSB5 chipsets. +config BLK_DEV_SGIIOC4 + tristate "Silicon Graphics IOC4 chipset support" + help + This driver adds PIO & MultiMode DMA-2 support for the SGI IOC4 + chipset. Please say Y here, if you have an Altix System from + Silicon Graphics Inc. + config BLK_DEV_SIIMAGE tristate "Silicon Image chipset support" help
drivers/ide/pci/Makefile +1 -0
@@ -22,6 +22,7 @@ obj-$(CONFIG_BLK_DEV_PIIX) += piix.o obj-$(CONFIG_BLK_DEV_RZ1000) += rz1000.o obj-$(CONFIG_BLK_DEV_SVWKS) += serverworks.o +obj-$(CONFIG_BLK_DEV_SGIIOC4) += sgiioc4.o obj-$(CONFIG_BLK_DEV_SIIMAGE) += siimage.o obj-$(CONFIG_BLK_DEV_SIS5513) += sis5513.o obj-$(CONFIG_BLK_DEV_SL82C105) += sl82c105.o
drivers/ide/pci/sgiioc4.c new file +1053 -0
1,053 lines not on this page · raw message
include/linux/pci_ids.h +1 -0
@@ -896,6 +896,7 @@#define PCI_VENDOR_ID_SGI 0x10a9#define PCI_DEVICE_ID_SGI_IOC3 0x0003 +#define PCI_DEVICE_ID_SGI_IOC4 0x100a#define PCI_VENDOR_ID_SGI_LITHIUM 0x1002#define PCI_VENDOR_ID_ACC 0x10aa
Hi,
Patch looks better, but there are still some issues to be resolved.
Quoted 4 lines
+ *
+ * This code is identical to ide_raw_build_sglist in ide-dma.c + * however that it not exported and even if it were would create + * dependancy problems for modular drivers.
Quoted 8 lines
+ */
Quoted 2 lines
What problems?
BTW during coping tabs were replaced by spaces in these functions.Actually what I meant by problems was that, when this driver is compiled as a module and the earlier functions are not exported, the driver fails to find them. I have removed the earlier line from the new patch.
Okay, please apply attached patch first.
It exports ide_build_sglist() and ide_raw_build_sglist().
I've noticed that descriptions of these functions are slightly incorrect in your patch, there is no hwif argument etc.
Quoted 9 lines
(quoted diff) +2
-0+ return p - buffer; +}Quoted 3 lines
Do you really need
/proc/ide/sgiioc4?
You can print revision number during init.It has been helpful to be able to see the firmware revision num anytime during system operation.
So the new patch still creates the above entry.
I don't buy this, lspci can be used :-).
Quoted 8 lines
(quoted diff) +2
-0+ int ddir); +static unsigned int __init pci_init_sgiioc4(struct pci_dev*dev,ide_pci_device_t *d);
Quoted 2 lines
Most of this declarations are not needed as
sgiioc4.his only included fromshiioc4.c.The
sgiioc4.hfile has been removed in the new patch.
sgiioc4.h was removed, but declarations weren't.
You can shuffle code around to get rid of them.
Quoted 1 line
Please merge this patch if there are no other issues.
ide_dma_sgiioc4():
+ if (!request_region(dma_base, num_ports, hwif->name)) {
+ printk(KERN_ERR
+ "%s(%s) -- WARNING, Addresses 0x%p to 0x%p ALREADY in use\n", + __FUNCTION__, hwif->name, (void *) dma_base, + (void *) dma_base + num_ports - 1);
+ }
+
Driver can't just warn if addresses are already in use, it should fail. There is one more request_region() with this problem in the driver.
+ hwif->sg_table =
+ kmalloc(sizeof (struct scatterlist) * IOC4_PRD_ENTRIES, GFP_KERNEL);
+
+ if (!hwif->sg_table) {
+ pci_free_consistent(hwif->pci_dev,
+ IOC4_PRD_ENTRIES * IOC4_PRD_BYTES,
+ hwif->dmatable_cpu, hwif->dmatable_dma);
+ goto dma_alloc_failure;
+ }
+
+ hwif->dma_base2 =
+ (unsigned long) pci_alloc_consistent(hwif->pci_dev,
+ IOC4_IDE_CACHELINE_SIZE,
+ (dma_addr_t *) &(hwif->dma_status));
+
+ if (!hwif->dma_base2) {
+ pci_free_consistent(hwif->pci_dev,
+ IOC4_PRD_ENTRIES * IOC4_PRD_BYTES,
+ hwif->dmatable_cpu, hwif->dmatable_dma);
+ kfree(hwif->sg_table);
+ goto dma_alloc_failure;
+ }
+
+ return;
+
+ dma_alloc_failure:
Minor issue: you can move pci_free_consisten() after dma_alloc_failure label.
+static ide_pci_device_t sgiioc4_chipsets[] __devinitdata = {
+ {
+ /* Channel 0 */
+ .vendor = PCI_VENDOR_ID_SGI,
+ .device = PCI_DEVICE_ID_SGI_IOC4,
+ .name = "SGIIOC4",
+ .init_chipset = NULL,
+ .init_iops = NULL,
+ .init_hwif = ide_init_sgiioc4,
+ .init_dma = ide_dma_sgiioc4,
+ .channels = 1,
+ .autodma = AUTODMA,
+ .enablebits = {{0x00, 0x00, 0x00}, {0x00, 0x00, 0x00}},
+ .bootable = ON_BOARD,
+ .extra = 0,
+ }
+};
Minor issue: static variables are initialized to 0 by kernel, so .init_{chipset, iops}, .enablebits and .extra lines should go away.
There are no .enablebits on SGI IOC4? Please add a comment about it.
sgiioc4_init_one():
+ pci_read_config_dword(dev, PCI_CLASS_REVISION, &class_rev);
+ class_rev &= 0xff;
Access to PCI devices before pci_enable_device()
(it is called later in pci_init_sgiioc4).
+static int
+sgiioc4_ide_dma_count(ide_drive_t * drive)
+{
+ return HWIF(drive)->ide_dma_begin(drive);
+}
This is identical to __ide_dma_count().
+static int
+sgiioc4_ide_dma_timeout(ide_drive_t * drive)
+{
+ printk(KERN_ERR "%s: timeout waiting for DMA\n", drive->name);
+ if (HWIF(drive)->ide_dma_test_irq(drive))
+ return 0;
+
+ return HWIF(drive)->ide_dma_end(drive);
+}
This is identical to __ide_dma_timeout().
+ hwif->OUTL(IOC4_S_DMA_STOP, dma_base + IOC4_DMA_CTRL * 4);
+ count = 0;
+ do {
+ xide_delay(count);
+ ioc4_dma = hwif->INL(dma_base + IOC4_DMA_CTRL * 4);
+ count += 10;
+ } while ((ioc4_dma & IOC4_S_DMA_STOP) && (count < 100));
This is duplicated 3x (one time with "xide_delay()" and "hwif->INL()" lines interchanged, maybe by a mistake?).
Can you make it a helper function, i.e. sgiioc4_ide_dma_stop_engine() ?
Thanks,
--bartlomiej
drivers/ide/arm/icside.c | 4 ++-- drivers/ide/ide-dma.c | 12 ++++++++---- include/linux/ide.h | 2 ++ 3 files changed, 12 insertions(+), 6 deletions(-)
drivers/ide/arm/icside.c renamed from drivers/ide/arm/icside.c~ide-dma-sgiioc4-exports +2 -2
@@ -214,7 +214,7 @@ static void icside_maskproc(ide_drive_t#define NR_ENTRIES 256#define TABLE_SIZE (NR_ENTRIES * 8) -static void ide_build_sglist (ide_drive_t *drive,struct request *rq) +static void icside_build_sglist (ide_drive_t *drive,struct request *rq) {ide_hwif_t *hwif = drive->hwif;struct icside_state *state = hwif->hwif_data;
@@ -543,7 +543,7 @@ icside_dma_common(ide_drive_t *drive, stBUG_ON (hwif->sg_dma_active);BUG_ON (dma_channel_active (hwif->hw.dma)); -ide_build_sglist (drive, rq); +icside_build_sglist (drive, rq);/* * Ensure that we have the right interrupt routed.
drivers/ide/ide-dma.c renamed from drivers/ide/ide-dma.c~ide-dma-sgiioc4-exports +8 -4
@@ -200,8 +200,8 @@ EXPORT_SYMBOL_GPL(ide_dma_intr);* kernel provide the necessary cache management so that we can * operate in a portable fashion */ - -static int ide_build_sglist (ide_drive_t *drive,struct request *rq) + +int ide_build_sglist (ide_drive_t *drive,struct request *rq) {ide_hwif_t *hwif =HWIF (drive);struct scatterlist *sg = hwif->sg_table;
@@ -220,6 +220,8 @@ static int ide_build_sglist (ide_drive_treturn pci_map_sg (hwif->pci_dev, sg, nents, hwif->sg_dma_direction); } +EXPORT_SYMBOL_GPL (ide_build_sglist); +/** * ide_raw_build_sglist - map IDE scatter gather for DMA * @drive: the drive to build the DMA table for
@@ -230,8 +232,8 @@ static int ide_build_sglist (ide_drive_t* of the kernel provide the necessary cache management so that we can * operate in a portable fashion */ - -static int ide_raw_build_sglist (ide_drive_t *drive,struct request *rq) + +int ide_raw_build_sglist (ide_drive_t *drive,struct request *rq) {ide_hwif_t *hwif =HWIF (drive);struct scatterlist *sg = hwif->sg_table;
@@ -270,6 +272,8 @@ static int ide_raw_build_sglist (ide_drireturn pci_map_sg (hwif->pci_dev, sg, nents, hwif->sg_dma_direction); } +EXPORT_SYMBOL_GPL (ide_raw_build_sglist); +/** * ide_build_dmatable - build IDE DMA table *
include/linux/ide.h renamed from include/linux/ide.h~ide-dma-sgiioc4-exports +2 -0
@@ -1695,6 +1695,8 @@ extern void ide_setup_pci_devices(struct#define GOOD_DMA_DRIVE 1#ifdef CONFIG_BLK_DEV_IDEDMA_PCI +extern int ide_build_sglist (ide_drive_t *,struct request *); +extern int ide_raw_build_sglist (ide_drive_t *,struct request *);extern int ide_build_dmatable (ide_drive_t *,struct request *);extern void ide_destroy_dmatable (ide_drive_t *);extern ide_startstop_t ide_dma_intr (ide_drive_t *);
_
Hello Bartlomiej,
I have a few questions. I'm going to be submitting the rest of the patches that Aniket was working on, as he started at a new company today (he was attempting to finish the submission before he left). Please forgive a lack of expertise on my part.
Quoted 4 lines · Bartlomiej Zolnierkiewicz
Quoted 4 lines
(quoted diff) +2
-0+ return p - buffer; +}
Quoted 8 lines
Quoted 6 lines
Quoted 2 lines
Do you really need
/proc/ide/sgiioc4?
You can print revision number during init.It has been helpful to be able to see the firmware revision num anytime during system operation.
So the new patch still creates the above entry.I don't buy this, lspci can be used :-).
lspci gives the version number./proc/ide/sgiioc4 gives you:
SGI IOC4 Chipset rev 79.
Chipset has 1 IDE channel and supports 2 devices on that channel. Chipset supports DMA in MultiMode-2 data transfer protocol.
Is the # of IDE channels/devices and the DMA mode also available elsewhere?
Quoted 11 lines
Quoted 8 lines
(quoted diff) +2
-0+ int ddir); +static unsigned int __init pci_init_sgiioc4(struct pci_dev*dev,ide_pci_device_t *d);
Quoted 2 lines
Most of this declarations are not needed as
sgiioc4.his only included fromshiioc4.c.The
sgiioc4.hfile has been removed in the new patch.
sgiioc4.hwas removed, but declarations weren't.
You can shuffle code around to get rid of them.
How important is this to you? It seems more a style issue. I agree with you, by the way. When I write code, I try to minimize forward declarations. If I can get rid of some easily, will that be good enough?
Quoted 1 line
There are no .enablebits on SGI IOC4? Please add a comment about it.
What are they used for (i.e. what are you looking for in the comment)?
Quoted 6 lines
sgiioc4_init_one():(quoted diff) +2
-0+ pci_read_config_dword(dev, PCI_CLASS_REVISION, &class_rev); + class_rev &= 0xff;Access to PCI devices before
pci_enable_device()
(it is called later inpci_init_sgiioc4).
Is pci_enable_device required before a config space access?
I will make changes in accordance with the other comments and based on your responses to this.
Thanks
jeremy
Quoted 1 line · Jeremy Higdon
Hello Bartlomiej,
Hi,
Quoted 4 lines
I have a few questions. I'm going to be submitting the rest of the patches that Aniket was working on, as he started at a new company today (he was attempting to finish the submission before he left). Please forgive a lack of expertise on my part.
Okay.
Quoted 13 lines · Bartlomiej Zolnierkiewicz
Quoted 11 lines
Quoted 9 lines
(quoted diff) +2
-0+ return p - buffer; +}Quoted 3 lines
Do you really need
/proc/ide/sgiioc4?
You can print revision number during init.It has been helpful to be able to see the firmware revision num anytime during system operation.
So the new patch still creates the above entry.I don't buy this, lspci can be used :-).
Quoted 8 lines
lspci gives the version number.
/proc/ide/sgiioc4gives you:SGI IOC4 Chipset rev 79.
Chipset has 1 IDE channel and supports 2 devices on that channel. Chipset supports DMA in MultiMode-2 data transfer protocol.Is the # of IDE channels/devices and the DMA mode also available elsewhere?
Channels/devices is only available indirectly by /proc/ide/ device symlinks and mate entry in (ie.) ide0 proc directory. Controller DMA mode info is not available. However /proc/ide/sgiioc4 is useless for programs (parsing it to obtain needed info is a really bad idea) and info for users should be provided by drivers/ide/Kconfig (and optionally by init time message).
Quoted 7 lines
Quoted 7 lines
Quoted 7 lines
(quoted diff) +2
-0+ int ddir); +static unsigned int __init pci_init_sgiioc4(struct pci_dev*dev,ide_pci_device_t *d);
Quoted 2 lines
Most of this declarations are not needed as
sgiioc4.his only included fromshiioc4.c.
Quoted 8 lines
Quoted 4 lines
Quoted 1 line
The
sgiioc4.hfile has been removed in the new patch.
sgiioc4.hwas removed, but declarations weren't.
You can shuffle code around to get rid of them.How important is this to you? It seems more a style issue. I agree with you, by the way. When I write code, I try to minimize forward declarations. If I can get rid of some easily, will that be good enough?
Okay, I can clear the rest.
It is good for simplicity (people reading this code) and maintainability (you don't have to update declaration if you change corresponding function).
Quoted 3 lines
Quoted 1 line
There are no .enablebits on SGI IOC4? Please add a comment about it.
What are they used for (i.e. what are you looking for in the comment)?
It is mainly x86 thing (if channel is disabled in BIOS we don't probe it). You can just put "/* SGI IOC4 doesn't have enablebits. */ somewhere.
Quoted 8 lines
Quoted 6 lines
sgiioc4_init_one():(quoted diff) +2
-0+ pci_read_config_dword(dev, PCI_CLASS_REVISION, &class_rev); + class_rev &= 0xff;Access to PCI devices before
pci_enable_device()
(it is called later inpci_init_sgiioc4).Is
pci_enable_devicerequired before a config space access?
Yes, please read Documentation/pci.txt chapter 3.
Quoted 2 lines
I will make changes in accordance with the other comments and based on your responses to this.
Thanks,
--bartlomiej
Quoted 8 lines · Bartlomiej Zolnierkiewicz
Quoted 7 lines · Jeremy Higdon
lspci gives the version number.
/proc/ide/sgiioc4gives you:SGI IOC4 Chipset rev 79.
Chipset has 1 IDE channel and supports 2 devices on that channel. Chipset supports DMA in MultiMode-2 data transfer protocol.
Quoted 7 lines
Quoted 1 line
Is the # of IDE channels/devices and the DMA mode also available elsewhere?
Channels/devices is only available indirectly by
/proc/ide/device symlinks and mate entry in (ie.) ide0 proc directory. Controller DMA mode info is not available. However/proc/ide/sgiioc4is useless for programs (parsing it to obtain needed info is a really bad idea) and info for users should be provided bydrivers/ide/Kconfig(and optionally by init time message).
Okay, I've removed this /proc entry (which was the only /proc entry in the driver).
Quoted 8 lines
Quoted 3 lines
How important is this to you? It seems more a style issue. I agree with you, by the way. When I write code, I try to minimize forward declarations. If I can get rid of some easily, will that be good enough?
Okay, I can clear the rest.
It is good for simplicity (people reading this code) and maintainability (you don't have to update declaration if you change corresponding function).
Once I got started, I found that I was able to get rid of all of them.
Quoted 4 lines
Quoted 1 line
What are they used for (i.e. what are you looking for in the comment)?
It is mainly x86 thing (if channel is disabled in BIOS we don't probe it). You can just put "/* SGI IOC4 doesn't have enablebits. */ somewhere.
done
Quoted 10 lines
Quoted 8 lines
Quoted 6 lines
sgiioc4_init_one():(quoted diff) +2
-0+ pci_read_config_dword(dev, PCI_CLASS_REVISION, &class_rev); + class_rev &= 0xff;Access to PCI devices before
pci_enable_device()
(it is called later inpci_init_sgiioc4).Is
pci_enable_devicerequired before a config space access?Yes, please read
Documentation/pci.txtchapter 3.
Fixed.
Attached is the latest patch, which also includes your patch sent previously. Thanks for your review and assistance.
I will be on a vacation starting tomorrow, so I won't be able to reply until Oct 19th or 20th, in case there are any more issues. Hopefully this one will be okay :-)
thanks
jeremy
# This is a BitKeeper generated patch for the following project:
# Project Name: Linux kernel tree
# This patch format is intended for GNU patch command version 2.5 or higher. # This patch includes the following deltas:
# ChangeSet 1.1490 -> 1.1492
# drivers/ide/pci/Makefile 1.9 -> 1.10
# include/linux/ide.h 1.75 -> 1.76
# include/linux/pci_ids.h 1.123 -> 1.124
# drivers/ide/Kconfig 1.30 -> 1.32
# drivers/ide/arm/icside.c 1.10 -> 1.11
# drivers/ide/ide-dma.c 1.21 -> 1.22
# (new) -> 1.2 drivers/ide/pci/sgiioc4.c
#
# The following is the BitKeeper ChangeSet Log
# --------------------------------------------
# 03/10/07 [email protected] 1.1491
# Add SGI IOC4.
# --------------------------------------------
# 03/10/07 [email protected] 1.1492
# Changes based on comments from Bartlomiej.
# --------------------------------------------
#
drivers/ide/Kconfig +7 -0
@@ -740,6 +740,13 @@ This driver adds PIO/(U)DMA support for the ServerWorks OSB4/CSB5 chipsets. +config BLK_DEV_SGIIOC4 + tristate "Silicon Graphics IOC4 chipset support" + help + This driver adds PIO & MultiMode DMA-2 support for the SGI IOC4 + chipset, which has one channel and can support two devices. + Please say Y here if you have an Altix System from SGI. + config BLK_DEV_SIIMAGE tristate "Silicon Image chipset support" help
drivers/ide/arm/icside.c +2 -2
@@ -214,7 +214,7 @@#define NR_ENTRIES 256#define TABLE_SIZE (NR_ENTRIES * 8) -static void ide_build_sglist (ide_drive_t *drive,struct request *rq) +static void icside_build_sglist (ide_drive_t *drive,struct request *rq) {ide_hwif_t *hwif = drive->hwif;struct icside_state *state = hwif->hwif_data;
@@ -543,7 +543,7 @@BUG_ON (hwif->sg_dma_active);BUG_ON (dma_channel_active (hwif->hw.dma)); -ide_build_sglist (drive, rq); +icside_build_sglist (drive, rq);/* * Ensure that we have the right interrupt routed.
drivers/ide/ide-dma.c +8 -4
@@ -200,8 +200,8 @@* kernel provide the necessary cache management so that we can * operate in a portable fashion */ - -static int ide_build_sglist (ide_drive_t *drive,struct request *rq) + +int ide_build_sglist (ide_drive_t *drive,struct request *rq) {ide_hwif_t *hwif =HWIF (drive);struct scatterlist *sg = hwif->sg_table;
@@ -220,6 +220,8 @@return pci_map_sg (hwif->pci_dev, sg, nents, hwif->sg_dma_direction); } +EXPORT_SYMBOL_GPL (ide_build_sglist); +/** * ide_raw_build_sglist - map IDE scatter gather for DMA * @drive: the drive to build the DMA table for
@@ -230,8 +232,8 @@* of the kernel provide the necessary cache management so that we can * operate in a portable fashion */ - -static int ide_raw_build_sglist (ide_drive_t *drive,struct request *rq) + +int ide_raw_build_sglist (ide_drive_t *drive,struct request *rq) {ide_hwif_t *hwif =HWIF (drive);struct scatterlist *sg = hwif->sg_table;
@@ -269,6 +271,8 @@return pci_map_sg (hwif->pci_dev, sg, nents, hwif->sg_dma_direction); } + +EXPORT_SYMBOL_GPL (ide_raw_build_sglist);/** * ide_build_dmatable - build IDE DMA table
drivers/ide/pci/Makefile +1 -0
@@ -21,6 +21,7 @@ obj-$(CONFIG_BLK_DEV_PIIX) += piix.o obj-$(CONFIG_BLK_DEV_RZ1000) += rz1000.o obj-$(CONFIG_BLK_DEV_SVWKS) += serverworks.o +obj-$(CONFIG_BLK_DEV_SGIIOC4) += sgiioc4.o obj-$(CONFIG_BLK_DEV_SIIMAGE) += siimage.o obj-$(CONFIG_BLK_DEV_SIS5513) += sis5513.o obj-$(CONFIG_BLK_DEV_SL82C105) += sl82c105.o
drivers/ide/pci/sgiioc4.c new file +844 -0
844 lines not on this page · raw message
include/linux/ide.h +2 -0
@@ -1695,6 +1695,8 @@#define GOOD_DMA_DRIVE 1#ifdef CONFIG_BLK_DEV_IDEDMA_PCI +extern int ide_build_sglist (ide_drive_t *,struct request *); +extern int ide_raw_build_sglist (ide_drive_t *,struct request *);extern int ide_build_dmatable (ide_drive_t *,struct request *);extern void ide_destroy_dmatable (ide_drive_t *);extern ide_startstop_t ide_dma_intr (ide_drive_t *);
include/linux/pci_ids.h +1 -0
@@ -896,6 +896,7 @@#define PCI_VENDOR_ID_SGI 0x10a9#define PCI_DEVICE_ID_SGI_IOC3 0x0003 +#define PCI_DEVICE_ID_SGI_IOC4 0x100a#define PCI_VENDOR_ID_SGI_LITHIUM 0x1002#define PCI_VENDOR_ID_ACC 0x10aa
Quoted 2 lines · Jeremy Higdon
Attached is the latest patch, which also includes your patch sent previously. Thanks for your review and assistance.
Thanks.
Quoted 3 lines
I will be on a vacation starting tomorrow, so I won't be able to reply until Oct 19th or 20th, in case there are any more issues. Hopefully this one will be okay :-)
I think that after applying attached incremental patch it can go in.
- defining IDE_ARCH_ACK_INTR and ide_ack_intr() in sgiioc4.c is a no-op, it should be done <asm/ide.h> to make it work
(I think the same problem is present in 2.4.x)
- fix NULL pointer dereference (accessing hwif->name while hwif is NULL) in sgiioc4_ide_setup_pci_device() (was this driver ever tested?)
- make config option SN2 specific
- replace uint{8,32,64}_t by u{8,32,64}
--bartlomiej
drivers/ide/Kconfig | 3 ++- drivers/ide/pci/sgiioc4.c | 44 ++++++++++++++++---------------------------- include/asm-ia64/ide.h | 6 ++++++ 3 files changed, 24 insertions(+), 29 deletions(-)
drivers/ide/Kconfig renamed from drivers/ide/Kconfig~ide-sgiioc4-fixes +2 -1
@@ -742,11 +742,12 @@ config BLK_DEV_SVWKS config BLK_DEV_SGIIOC4 tristate "Silicon Graphics IOC4 chipset support" + depends on IA64_SGI_SN2 help This driver adds PIO & MultiMode DMA-2 support for the SGI IOC4 chipset, which has one channel and can support two devices. Please say Y here if you have an Altix System from SGI. - + config BLK_DEV_SIIMAGE tristate "Silicon Image chipset support" help
include/asm-ia64/ide.h renamed from include/asm-ia64/ide.h~ide-sgiioc4-fixes +6 -0
@@ -91,6 +91,12 @@ ide_init_default_hwifs (void) #endif } +#ifdef CONFIG_BLK_DEV_SGIIOC4 +#define IDE_ARCH_ACK_INTR +/* Weeds out non-IDE interrupts to the IOC4 */ +#define ide_ack_intr (hwif) ((hwif)->hw.ack_intr ? (hwif)->hw.ack_intr(hwif) : 1) +#endif +#include <asm-generic/ide_iops.h> #endif /* __KERNEL__ */
drivers/ide/pci/sgiioc4.c renamed from drivers/ide/pci/sgiioc4.c~ide-sgiioc4-fixes +16 -28
128 lines not on this page · raw message
_
Quoted 6 lines · Bartlomiej Zolnierkiewicz
Quoted 4 lines
I will be on a vacation starting tomorrow, so I won't be able to reply until Oct 19th or 20th, in case there are any more issues. Hopefully this one will be okay :-)
I think that after applying attached incremental patch it can go in.
Thanks. I'll test this and reply with the results.
Quoted 3 lines
- defining
IDE_ARCH_ACK_INTRandide_ack_intr()insgiioc4.cis a no-op, it should be done <asm/ide.h> to make it work
(I think the same problem is present in 2.4.x)
The definition in <include/linux/ide.h> is only used if IDE_ARCH_ACK_INTR is not defined. sgiioc4.c defines IDE_ARCH_ACK_INTR before including that file, so I believe we get the definition we want without touching ide.h, don't we?
Quoted 2 lines
- fix NULL pointer dereference (accessing
hwif->namewhile hwif is NULL) insgiioc4_ide_setup_pci_device()(was this driver ever tested?)
Yes. It may be that since name is an array, the value passed to request_region was the offset of name in the structure. Since that was never dereferenced, things worked okay. In any case, the code was obviously incorrect.
Quoted 2 lines
- make config option SN2 specific
- replace uint{8,32,64}_t by u{8,32,64}
These look fine.
I'll await a response on the IDE_ARCH_ACK_INTR issue. Do you want me to send another patch, or is the previous with your update sufficient?
thanks
jeremy
Quoted 8 lines · Jeremy Higdon
Quoted 3 lines
- defining
IDE_ARCH_ACK_INTRandide_ack_intr()insgiioc4.cis a no-op, it should be done <asm/ide.h> to make it work
(I think the same problem is present in 2.4.x)The definition in <
include/linux/ide.h> is only used ifIDE_ARCH_ACK_INTRis not defined.sgiioc4.cdefinesIDE_ARCH_ACK_INTRbefore including that file, so I believe we get the definition we want without touchingide.h, don't we?
ide_ack_intr() is used by ide-io.c. If IDE_ARCH_ACK_INTR is not defined in ide.h (and it won't be cause you are doing this only in sgiioc4.c /sgiioc4.h in 2.4.x case/ about which ide-io.c has abolutely no idea) ide_ack_intr() will turn into no-op and hwif->ack_intr() won't be called.
Quoted 2 lines
I'll await a response on the
IDE_ARCH_ACK_INTRissue. Do you want me to send another patch, or is the previous with your update sufficient?
It is sufficient.
thanks,
--bartlomiej
Quoted 10 lines · Bartlomiej Zolnierkiewicz
Quoted 8 lines · Jeremy Higdon
Quoted 3 lines
- defining
IDE_ARCH_ACK_INTRandide_ack_intr()insgiioc4.cis a no-op, it should be done <asm/ide.h> to make it work
(I think the same problem is present in 2.4.x)The definition in <
include/linux/ide.h> is only used ifIDE_ARCH_ACK_INTRis not defined.sgiioc4.cdefinesIDE_ARCH_ACK_INTRbefore including that file, so I believe we get the definition we want without touchingide.h, don't we?
Quoted 4 lines
ide_ack_intr()is used byide-io.c. IfIDE_ARCH_ACK_INTRis not defined inide.h(and it won't be cause you are doing this only insgiioc4.c/sgiioc4.h in 2.4.x case/ about whichide-io.chas abolutely no idea)ide_ack_intr()will turn into no-op andhwif->ack_intr()won't be called.
I see what you mean. Thanks for spotting and fixing this.
I've run into a problem in testing. For some reason, I've started to get ide timeouts, and the error recovery is not working correctly, due to a problem in the driver.
In sgiioc4_ide_dma_stop(), sgiioc4_ide_dma_end(), and sgiioc4_clearirq(), there are calls to xide_delay(), which uses schedule_timeout() to sleep. Since all of these sgiioc4_ functions can be called from interrupt context, that's an obvious problem.
In sgiioc4_clearirq(), the delay function is while we're waiting for the interrupt to clear.
In sgiioc4_ide_dma_stop(), we're waiting for the DMA bit to clear.
In sgiioc4_ide_dma_end(), we're waiting for another DMA to finish.
I believe that the right answer is to use udelay() and give up after a short period of time. My question is what does the ide layer expect? That is, if you call the dma_end function and the hardware driver can't succeed, what would you like us to do? Is there a way to return error, or should we just fail and the ide infrastructure will pick it up later and reset things?
I am new to Linux IDE, so forgive these questions if the answers should be obvious.
thanks
jeremy
Quoted 11 lines · Jeremy Higdon
Quoted 10 lines · Bartlomiej Zolnierkiewicz
Quoted 8 lines · Jeremy Higdon
Quoted 3 lines
- defining
IDE_ARCH_ACK_INTRandide_ack_intr()insgiioc4.cis a no-op, it should be done <asm/ide.h> to make it work
(I think the same problem is present in 2.4.x)The definition in <
include/linux/ide.h> is only used ifIDE_ARCH_ACK_INTRis not defined.sgiioc4.cdefinesIDE_ARCH_ACK_INTRbefore including that file, so I believe we get the definition we want without touchingide.h, don't we?
Quoted 6 lines
Quoted 4 lines
ide_ack_intr()is used byide-io.c. IfIDE_ARCH_ACK_INTRis not defined inide.h(and it won't be cause you are doing this only insgiioc4.c/sgiioc4.h in 2.4.x case/ about whichide-io.chas abolutely no idea)ide_ack_intr()will turn into no-op andhwif->ack_intr()won't be called.I see what you mean. Thanks for spotting and fixing this.
I think there is another bug:
...
hwif->hw.ack_intr = &sgiioc4_checkirq; /* MultiFunction Chip */
...
sgiioc4_clearirq() should be used instead of sgiioc4_checkirq() here, because otherwise IRQ won't be cleared.
In order to do this you must modify sgiioc4_clearirq() slightly, just change "return intr_reg;" to "return intr_reg & 0x03;".
If you wonder why, please look at ide_ack_intr() use in ide-io.c:ide_intr().
Quoted 12 lines
I've run into a problem in testing. For some reason, I've started to get ide timeouts, and the error recovery is not working correctly, due to a problem in the driver.
In
sgiioc4_ide_dma_stop(),sgiioc4_ide_dma_end(), andsgiioc4_clearirq(), there are calls toxide_delay(), which usesschedule_timeout()to sleep. Since all of thesesgiioc4_functions can be called from interrupt context, that's an obvious problem.In
sgiioc4_clearirq(), the delay function is while we're waiting for the interrupt to clear.
Quoted 6 lines
In
sgiioc4_ide_dma_stop(), we're waiting for the DMA bit to clear.In
sgiioc4_ide_dma_end(), we're waiting for another DMA to finish.I believe that the right answer is to use
udelay()and give up after a short period of time. My question is what does the ide layer
Yes, just use udelay().
Quoted 4 lines
expect? That is, if you call the
dma_endfunction and the hardware driver can't succeed, what would you like us to do? Is there a way to return error, or should we just fail and the ide infrastructure will pick it up later and reset things?
The latter, sgiioc4_ide_dma_end() already returns error value to higher layer. dma_intr() checks it and handle errors (at least in theory).
Quoted 2 lines
I am new to Linux IDE, so forgive these questions if the answers should be obvious.
No problem.
thanks,
--bartlomiej
Quoted 7 lines · Bartlomiej Zolnierkiewicz
I think there is another bug:
...
hwif->hw.ack_intr = &sgiioc4_checkirq; /* MultiFunction Chip */...
Quoted 7 lines
sgiioc4_clearirq()should be used instead ofsgiioc4_checkirq()here, because otherwise IRQ won't be cleared.In order to do this you must modify
sgiioc4_clearirq()slightly, just change "returnintr_reg;" to "returnintr_reg&0x03;".If you wonder why, please look at
ide_ack_intr()use in ide-io.c:ide_intr().
Thanks. I've taken a look at it and have become puzzled.
It looks as though ide_ack_intr normally just "returns" 1 and has no other effect. But then I see some ide drivers that also have an ack_intr routine. On some (most?) architechtures, it would appear that the ack_intr routine is not used, since the ide_ack_intr macro will not call it.
In gayle_ack_intr_a4000(), it looks as though all it does is read a register and return something. Is that register read supposed to clear interrupt as a side effect.
So maybe an explicit clear is not needed on most implementations?
jeremy
Bartlomiej and Andrew,
Here is the new IOC4 patch relative to Linus's BK tree.
Bartlomiej, can you review and give your comment? I took out the ack_intr code, since it seems to be redundant, because the IOC4 is a PCI device and the interrupt is cleared in sgiioc4_INB().
thanks
jeremy
drivers/ide/Kconfig | 8 drivers/ide/arm/icside.c | 4 drivers/ide/ide-dma.c | 12 drivers/ide/pci/Makefile | 1 drivers/ide/pci/sgiioc4.c | 833 ++++++++++++++++++++++++++++++++++++++++++++++ include/linux/ide.h | 2 include/linux/pci_ids.h | 1 7 files changed, 855 insertions(+), 6 deletions(-)
drivers/ide/Kconfig +8 -0
@@ -740,6 +740,14 @@ This driver adds PIO/(U)DMA support for the ServerWorks OSB4/CSB5 chipsets. +config BLK_DEV_SGIIOC4 + tristate "Silicon Graphics IOC4 chipset support" + depends on IA64_SGI_SN2 + help + This driver adds PIO & MultiMode DMA-2 support for the SGI IOC4 + chipset, which has one channel and can support two devices. + Please say Y here if you have an Altix System from SGI. + config BLK_DEV_SIIMAGE tristate "Silicon Image chipset support" help
drivers/ide/arm/icside.c +2 -2
@@ -214,7 +214,7 @@#define NR_ENTRIES 256#define TABLE_SIZE (NR_ENTRIES * 8) -static void ide_build_sglist (ide_drive_t *drive,struct request *rq) +static void icside_build_sglist (ide_drive_t *drive,struct request *rq) {ide_hwif_t *hwif = drive->hwif;struct icside_state *state = hwif->hwif_data;
@@ -543,7 +543,7 @@BUG_ON (hwif->sg_dma_active);BUG_ON (dma_channel_active (hwif->hw.dma)); -ide_build_sglist (drive, rq); +icside_build_sglist (drive, rq);/* * Ensure that we have the right interrupt routed.
drivers/ide/ide-dma.c +8 -4
@@ -200,8 +200,8 @@* kernel provide the necessary cache management so that we can * operate in a portable fashion */ - -static int ide_build_sglist (ide_drive_t *drive,struct request *rq) + +int ide_build_sglist (ide_drive_t *drive,struct request *rq) {ide_hwif_t *hwif =HWIF (drive);struct scatterlist *sg = hwif->sg_table;
@@ -220,6 +220,8 @@return pci_map_sg (hwif->pci_dev, sg, nents, hwif->sg_dma_direction); } +EXPORT_SYMBOL_GPL (ide_build_sglist); +/** * ide_raw_build_sglist - map IDE scatter gather for DMA * @drive: the drive to build the DMA table for
@@ -230,8 +232,8 @@* of the kernel provide the necessary cache management so that we can * operate in a portable fashion */ - -static int ide_raw_build_sglist (ide_drive_t *drive,struct request *rq) + +int ide_raw_build_sglist (ide_drive_t *drive,struct request *rq) {ide_hwif_t *hwif =HWIF (drive);struct scatterlist *sg = hwif->sg_table;
@@ -269,6 +271,8 @@return pci_map_sg (hwif->pci_dev, sg, nents, hwif->sg_dma_direction); } + +EXPORT_SYMBOL_GPL (ide_raw_build_sglist);/** * ide_build_dmatable - build IDE DMA table
drivers/ide/pci/Makefile +1 -0
@@ -21,6 +21,7 @@ obj-$(CONFIG_BLK_DEV_PIIX) += piix.o obj-$(CONFIG_BLK_DEV_RZ1000) += rz1000.o obj-$(CONFIG_BLK_DEV_SVWKS) += serverworks.o +obj-$(CONFIG_BLK_DEV_SGIIOC4) += sgiioc4.o obj-$(CONFIG_BLK_DEV_SIIMAGE) += siimage.o obj-$(CONFIG_BLK_DEV_SIS5513) += sis5513.o obj-$(CONFIG_BLK_DEV_SL82C105) += sl82c105.o
drivers/ide/pci/sgiioc4.c new file +833 -0
833 lines not on this page · raw message
include/linux/ide.h +2 -0
@@ -1693,6 +1693,8 @@#define GOOD_DMA_DRIVE 1#ifdef CONFIG_BLK_DEV_IDEDMA_PCI +extern int ide_build_sglist (ide_drive_t *,struct request *); +extern int ide_raw_build_sglist (ide_drive_t *,struct request *);extern int ide_build_dmatable (ide_drive_t *,struct request *);extern void ide_destroy_dmatable (ide_drive_t *);extern ide_startstop_t ide_dma_intr (ide_drive_t *);
include/linux/pci_ids.h +1 -0
@@ -896,6 +896,7 @@#define PCI_VENDOR_ID_SGI 0x10a9#define PCI_DEVICE_ID_SGI_IOC3 0x0003 +#define PCI_DEVICE_ID_SGI_IOC4 0x100a#define PCI_VENDOR_ID_SGI_LITHIUM 0x1002#define PCI_VENDOR_ID_ACC 0x10aa