aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/ide
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/ide')
-rw-r--r--drivers/ide/sgiioc4.c119
1 files changed, 54 insertions, 65 deletions
diff --git a/drivers/ide/sgiioc4.c b/drivers/ide/sgiioc4.c
index 5f37f168f944..b7d61dc64096 100644
--- a/drivers/ide/sgiioc4.c
+++ b/drivers/ide/sgiioc4.c
@@ -1,6 +1,6 @@
1/* 1/*
2 * Copyright (c) 2003-2006 Silicon Graphics, Inc. All Rights Reserved. 2 * Copyright (c) 2003-2006 Silicon Graphics, Inc. All Rights Reserved.
3 * Copyright (C) 2008 MontaVista Software, Inc. 3 * Copyright (C) 2008-2009 MontaVista Software, Inc.
4 * 4 *
5 * This program is free software; you can redistribute it and/or modify it 5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License 6 * under the terms of version 2 of the GNU General Public License
@@ -29,8 +29,7 @@
29#include <linux/blkdev.h> 29#include <linux/blkdev.h>
30#include <linux/scatterlist.h> 30#include <linux/scatterlist.h>
31#include <linux/ioc4.h> 31#include <linux/ioc4.h>
32#include <asm/io.h> 32#include <linux/io.h>
33
34#include <linux/ide.h> 33#include <linux/ide.h>
35 34
36#define DRV_NAME "SGIIOC4" 35#define DRV_NAME "SGIIOC4"
@@ -72,7 +71,7 @@
72#define IOC4_CMD_CTL_BLK_SIZE 0x20 71#define IOC4_CMD_CTL_BLK_SIZE 0x20
73#define IOC4_SUPPORTED_FIRMWARE_REV 46 72#define IOC4_SUPPORTED_FIRMWARE_REV 46
74 73
75typedef struct { 74struct ioc4_dma_regs {
76 u32 timing_reg0; 75 u32 timing_reg0;
77 u32 timing_reg1; 76 u32 timing_reg1;
78 u32 low_mem_ptr; 77 u32 low_mem_ptr;
@@ -82,17 +81,18 @@ typedef struct {
82 u32 dev_byte_count; 81 u32 dev_byte_count;
83 u32 mem_byte_count; 82 u32 mem_byte_count;
84 u32 status; 83 u32 status;
85} ioc4_dma_regs_t; 84};
86 85
87/* Each Physical Region Descriptor Entry size is 16 bytes (2 * 64 bits) */ 86/* Each Physical Region Descriptor Entry size is 16 bytes (2 * 64 bits) */
88/* IOC4 has only 1 IDE channel */ 87/* IOC4 has only 1 IDE channel */
89#define IOC4_PRD_BYTES 16 88#define IOC4_PRD_BYTES 16
90#define IOC4_PRD_ENTRIES (PAGE_SIZE /(4*IOC4_PRD_BYTES)) 89#define IOC4_PRD_ENTRIES (PAGE_SIZE / (4 * IOC4_PRD_BYTES))
91 90
92 91
93static void 92static void sgiioc4_init_hwif_ports(struct ide_hw *hw,
94sgiioc4_init_hwif_ports(struct ide_hw *hw, unsigned long data_port, 93 unsigned long data_port,
95 unsigned long ctrl_port, unsigned long irq_port) 94 unsigned long ctrl_port,
95 unsigned long irq_port)
96{ 96{
97 unsigned long reg = data_port; 97 unsigned long reg = data_port;
98 int i; 98 int i;
@@ -105,13 +105,11 @@ sgiioc4_init_hwif_ports(struct ide_hw *hw, unsigned long data_port,
105 hw->io_ports.irq_addr = irq_port; 105 hw->io_ports.irq_addr = irq_port;
106} 106}
107 107
108static int 108static int sgiioc4_checkirq(ide_hwif_t *hwif)
109sgiioc4_checkirq(ide_hwif_t * hwif)
110{ 109{
111 unsigned long intr_addr = 110 unsigned long intr_addr = hwif->io_ports.irq_addr + IOC4_INTR_REG * 4;
112 hwif->io_ports.irq_addr + IOC4_INTR_REG * 4;
113 111
114 if ((u8)readl((void __iomem *)intr_addr) & 0x03) 112 if (readl((void __iomem *)intr_addr) & 0x03)
115 return 1; 113 return 1;
116 114
117 return 0; 115 return 0;
@@ -119,8 +117,7 @@ sgiioc4_checkirq(ide_hwif_t * hwif)
119 117
120static u8 sgiioc4_read_status(ide_hwif_t *); 118static u8 sgiioc4_read_status(ide_hwif_t *);
121 119
122static int 120static int sgiioc4_clearirq(ide_drive_t *drive)
123sgiioc4_clearirq(ide_drive_t * drive)
124{ 121{
125 u32 intr_reg; 122 u32 intr_reg;
126 ide_hwif_t *hwif = drive->hwif; 123 ide_hwif_t *hwif = drive->hwif;
@@ -158,12 +155,10 @@ sgiioc4_clearirq(ide_drive_t * drive)
158 readl((void __iomem *)(io_ports->irq_addr + 4)); 155 readl((void __iomem *)(io_ports->irq_addr + 4));
159 pci_read_config_dword(dev, PCI_COMMAND, 156 pci_read_config_dword(dev, PCI_COMMAND,
160 &pci_stat_cmd_reg); 157 &pci_stat_cmd_reg);
161 printk(KERN_ERR 158 printk(KERN_ERR "%s(%s): PCI Bus Error when doing DMA: "
162 "%s(%s) : PCI Bus Error when doing DMA:" 159 "status-cmd reg is 0x%x\n",
163 " status-cmd reg is 0x%x\n",
164 __func__, drive->name, pci_stat_cmd_reg); 160 __func__, drive->name, pci_stat_cmd_reg);
165 printk(KERN_ERR 161 printk(KERN_ERR "%s(%s): PCI Error Address is 0x%x%x\n",
166 "%s(%s) : PCI Error Address is 0x%x%x\n",
167 __func__, drive->name, 162 __func__, drive->name,
168 pci_err_addr_high, pci_err_addr_low); 163 pci_err_addr_high, pci_err_addr_low);
169 /* Clear the PCI Error indicator */ 164 /* Clear the PCI Error indicator */
@@ -189,8 +184,7 @@ static void sgiioc4_dma_start(ide_drive_t *drive)
189 writel(temp_reg, (void __iomem *)ioc4_dma_addr); 184 writel(temp_reg, (void __iomem *)ioc4_dma_addr);
190} 185}
191 186
192static u32 187static u32 sgiioc4_ide_dma_stop(ide_hwif_t *hwif, u64 dma_base)
193sgiioc4_ide_dma_stop(ide_hwif_t *hwif, u64 dma_base)
194{ 188{
195 unsigned long ioc4_dma_addr = dma_base + IOC4_DMA_CTRL * 4; 189 unsigned long ioc4_dma_addr = dma_base + IOC4_DMA_CTRL * 4;
196 u32 ioc4_dma; 190 u32 ioc4_dma;
@@ -227,7 +221,7 @@ static int sgiioc4_dma_end(ide_drive_t *drive)
227 } 221 }
228 222
229 /* 223 /*
230 * The IOC4 will DMA 1's to the ending dma area to indicate that 224 * The IOC4 will DMA 1's to the ending DMA area to indicate that
231 * previous data DMA is complete. This is necessary because of relaxed 225 * previous data DMA is complete. This is necessary because of relaxed
232 * ordering between register reads and DMA writes on the Altix. 226 * ordering between register reads and DMA writes on the Altix.
233 */ 227 */
@@ -265,7 +259,7 @@ static void sgiioc4_set_dma_mode(ide_drive_t *drive, const u8 speed)
265{ 259{
266} 260}
267 261
268/* returns 1 if dma irq issued, 0 otherwise */ 262/* Returns 1 if DMA IRQ issued, 0 otherwise */
269static int sgiioc4_dma_test_irq(ide_drive_t *drive) 263static int sgiioc4_dma_test_irq(ide_drive_t *drive)
270{ 264{
271 return sgiioc4_checkirq(drive->hwif); 265 return sgiioc4_checkirq(drive->hwif);
@@ -286,8 +280,7 @@ static void sgiioc4_resetproc(ide_drive_t *drive)
286 sgiioc4_clearirq(drive); 280 sgiioc4_clearirq(drive);
287} 281}
288 282
289static void 283static void sgiioc4_dma_lost_irq(ide_drive_t *drive)
290sgiioc4_dma_lost_irq(ide_drive_t * drive)
291{ 284{
292 sgiioc4_resetproc(drive); 285 sgiioc4_resetproc(drive);
293 286
@@ -313,13 +306,13 @@ static u8 sgiioc4_read_status(ide_hwif_t *hwif)
313 return reg; 306 return reg;
314} 307}
315 308
316/* Creates a dma map for the scatter-gather list entries */ 309/* Creates a DMA map for the scatter-gather list entries */
317static int __devinit 310static int __devinit ide_dma_sgiioc4(ide_hwif_t *hwif,
318ide_dma_sgiioc4(ide_hwif_t *hwif, const struct ide_port_info *d) 311 const struct ide_port_info *d)
319{ 312{
320 struct pci_dev *dev = to_pci_dev(hwif->dev); 313 struct pci_dev *dev = to_pci_dev(hwif->dev);
321 unsigned long dma_base = pci_resource_start(dev, 0) + IOC4_DMA_OFFSET; 314 unsigned long dma_base = pci_resource_start(dev, 0) + IOC4_DMA_OFFSET;
322 int num_ports = sizeof (ioc4_dma_regs_t); 315 int num_ports = sizeof(struct ioc4_dma_regs);
323 void *pad; 316 void *pad;
324 317
325 printk(KERN_INFO " %s: MMIO-DMA\n", hwif->name); 318 printk(KERN_INFO " %s: MMIO-DMA\n", hwif->name);
@@ -362,8 +355,7 @@ dma_pci_alloc_failure:
362} 355}
363 356
364/* Initializes the IOC4 DMA Engine */ 357/* Initializes the IOC4 DMA Engine */
365static void 358static void sgiioc4_configure_for_dma(int dma_direction, ide_drive_t *drive)
366sgiioc4_configure_for_dma(int dma_direction, ide_drive_t * drive)
367{ 359{
368 u32 ioc4_dma; 360 u32 ioc4_dma;
369 ide_hwif_t *hwif = drive->hwif; 361 ide_hwif_t *hwif = drive->hwif;
@@ -374,31 +366,27 @@ sgiioc4_configure_for_dma(int dma_direction, ide_drive_t * drive)
374 ioc4_dma = readl((void __iomem *)ioc4_dma_addr); 366 ioc4_dma = readl((void __iomem *)ioc4_dma_addr);
375 367
376 if (ioc4_dma & IOC4_S_DMA_ACTIVE) { 368 if (ioc4_dma & IOC4_S_DMA_ACTIVE) {
377 printk(KERN_WARNING 369 printk(KERN_WARNING "%s(%s): Warning!! DMA from previous "
378 "%s(%s):Warning!! DMA from previous transfer was still active\n", 370 "transfer was still active\n", __func__, drive->name);
379 __func__, drive->name);
380 writel(IOC4_S_DMA_STOP, (void __iomem *)ioc4_dma_addr); 371 writel(IOC4_S_DMA_STOP, (void __iomem *)ioc4_dma_addr);
381 ioc4_dma = sgiioc4_ide_dma_stop(hwif, dma_base); 372 ioc4_dma = sgiioc4_ide_dma_stop(hwif, dma_base);
382 373
383 if (ioc4_dma & IOC4_S_DMA_STOP) 374 if (ioc4_dma & IOC4_S_DMA_STOP)
384 printk(KERN_ERR 375 printk(KERN_ERR "%s(%s): IOC4 DMA STOP bit is "
385 "%s(%s) : IOC4 Dma STOP bit is still 1\n", 376 "still 1\n", __func__, drive->name);
386 __func__, drive->name);
387 } 377 }
388 378
389 ioc4_dma = readl((void __iomem *)ioc4_dma_addr); 379 ioc4_dma = readl((void __iomem *)ioc4_dma_addr);
390 if (ioc4_dma & IOC4_S_DMA_ERROR) { 380 if (ioc4_dma & IOC4_S_DMA_ERROR) {
391 printk(KERN_WARNING 381 printk(KERN_WARNING "%s(%s): Warning!! DMA Error during "
392 "%s(%s) : Warning!! - DMA Error during Previous" 382 "previous transfer, status 0x%x\n",
393 " transfer | status 0x%x\n",
394 __func__, drive->name, ioc4_dma); 383 __func__, drive->name, ioc4_dma);
395 writel(IOC4_S_DMA_STOP, (void __iomem *)ioc4_dma_addr); 384 writel(IOC4_S_DMA_STOP, (void __iomem *)ioc4_dma_addr);
396 ioc4_dma = sgiioc4_ide_dma_stop(hwif, dma_base); 385 ioc4_dma = sgiioc4_ide_dma_stop(hwif, dma_base);
397 386
398 if (ioc4_dma & IOC4_S_DMA_STOP) 387 if (ioc4_dma & IOC4_S_DMA_STOP)
399 printk(KERN_ERR 388 printk(KERN_ERR "%s(%s): IOC4 DMA STOP bit is "
400 "%s(%s) : IOC4 DMA STOP bit is still 1\n", 389 "still 1\n", __func__, drive->name);
401 __func__, drive->name);
402 } 390 }
403 391
404 /* Address of the Scatter Gather List */ 392 /* Address of the Scatter Gather List */
@@ -408,20 +396,22 @@ sgiioc4_configure_for_dma(int dma_direction, ide_drive_t * drive)
408 /* Address of the Ending DMA */ 396 /* Address of the Ending DMA */
409 memset(ide_get_hwifdata(hwif), 0, IOC4_IDE_CACHELINE_SIZE); 397 memset(ide_get_hwifdata(hwif), 0, IOC4_IDE_CACHELINE_SIZE);
410 ending_dma_addr = cpu_to_le32(hwif->extra_base); 398 ending_dma_addr = cpu_to_le32(hwif->extra_base);
411 writel(ending_dma_addr, (void __iomem *)(dma_base + IOC4_DMA_END_ADDR * 4)); 399 writel(ending_dma_addr, (void __iomem *)(dma_base +
400 IOC4_DMA_END_ADDR * 4));
412 401
413 writel(dma_direction, (void __iomem *)ioc4_dma_addr); 402 writel(dma_direction, (void __iomem *)ioc4_dma_addr);
414} 403}
415 404
416/* IOC4 Scatter Gather list Format */ 405/* IOC4 Scatter Gather list Format */
417/* 128 Bit entries to support 64 bit addresses in the future */ 406/* 128 Bit entries to support 64 bit addresses in the future */
418/* The Scatter Gather list Entry should be in the BIG-ENDIAN Format */ 407/* The Scatter Gather list Entry should be in the BIG-ENDIAN Format */
419/* --------------------------------------------------------------------- */ 408/* --------------------------------------------------------------------- */
420/* | Upper 32 bits - Zero | Lower 32 bits- address | */ 409/* | Upper 32 bits - Zero | Lower 32 bits- address | */
421/* --------------------------------------------------------------------- */ 410/* --------------------------------------------------------------------- */
422/* | Upper 32 bits - Zero |EOL| 15 unused | 16 Bit Length| */ 411/* | Upper 32 bits - Zero |EOL| 15 unused | 16 Bit Length| */
423/* --------------------------------------------------------------------- */ 412/* --------------------------------------------------------------------- */
424/* Creates the scatter gather list, DMA Table */ 413/* Creates the scatter gather list, DMA Table */
414
425static int sgiioc4_build_dmatable(ide_drive_t *drive, struct ide_cmd *cmd) 415static int sgiioc4_build_dmatable(ide_drive_t *drive, struct ide_cmd *cmd)
426{ 416{
427 ide_hwif_t *hwif = drive->hwif; 417 ide_hwif_t *hwif = drive->hwif;
@@ -448,8 +438,10 @@ static int sgiioc4_build_dmatable(ide_drive_t *drive, struct ide_cmd *cmd)
448 if (bcount > cur_len) 438 if (bcount > cur_len)
449 bcount = cur_len; 439 bcount = cur_len;
450 440
451 /* put the addr, length in 441 /*
452 * the IOC4 dma-table format */ 442 * Put the address, length in
443 * the IOC4 dma-table format
444 */
453 *table = 0x0; 445 *table = 0x0;
454 table++; 446 table++;
455 *table = cpu_to_be32(cur_addr); 447 *table = cpu_to_be32(cur_addr);
@@ -540,8 +532,7 @@ static const struct ide_port_info sgiioc4_port_info __devinitconst = {
540 .mwdma_mask = ATA_MWDMA2_ONLY, 532 .mwdma_mask = ATA_MWDMA2_ONLY,
541}; 533};
542 534
543static int __devinit 535static int __devinit sgiioc4_ide_setup_pci_device(struct pci_dev *dev)
544sgiioc4_ide_setup_pci_device(struct pci_dev *dev)
545{ 536{
546 unsigned long cmd_base, irqport; 537 unsigned long cmd_base, irqport;
547 unsigned long bar0, cmd_phys_base, ctl; 538 unsigned long bar0, cmd_phys_base, ctl;
@@ -549,7 +540,7 @@ sgiioc4_ide_setup_pci_device(struct pci_dev *dev)
549 struct ide_hw hw, *hws[] = { &hw }; 540 struct ide_hw hw, *hws[] = { &hw };
550 int rc; 541 int rc;
551 542
552 /* Get the CmdBlk and CtrlBlk Base Registers */ 543 /* Get the CmdBlk and CtrlBlk base registers */
553 bar0 = pci_resource_start(dev, 0); 544 bar0 = pci_resource_start(dev, 0);
554 virt_base = pci_ioremap_bar(dev, 0); 545 virt_base = pci_ioremap_bar(dev, 0);
555 if (virt_base == NULL) { 546 if (virt_base == NULL) {
@@ -557,9 +548,9 @@ sgiioc4_ide_setup_pci_device(struct pci_dev *dev)
557 DRV_NAME, bar0); 548 DRV_NAME, bar0);
558 return -ENOMEM; 549 return -ENOMEM;
559 } 550 }
560 cmd_base = (unsigned long) virt_base + IOC4_CMD_OFFSET; 551 cmd_base = (unsigned long)virt_base + IOC4_CMD_OFFSET;
561 ctl = (unsigned long) virt_base + IOC4_CTRL_OFFSET; 552 ctl = (unsigned long)virt_base + IOC4_CTRL_OFFSET;
562 irqport = (unsigned long) virt_base + IOC4_INTR_OFFSET; 553 irqport = (unsigned long)virt_base + IOC4_INTR_OFFSET;
563 554
564 cmd_phys_base = bar0 + IOC4_CMD_OFFSET; 555 cmd_phys_base = bar0 + IOC4_CMD_OFFSET;
565 if (request_mem_region(cmd_phys_base, IOC4_CMD_CTL_BLK_SIZE, 556 if (request_mem_region(cmd_phys_base, IOC4_CMD_CTL_BLK_SIZE,
@@ -577,7 +568,7 @@ sgiioc4_ide_setup_pci_device(struct pci_dev *dev)
577 hw.irq = dev->irq; 568 hw.irq = dev->irq;
578 hw.dev = &dev->dev; 569 hw.dev = &dev->dev;
579 570
580 /* Initializing chipset IRQ Registers */ 571 /* Initialize chipset IRQ registers */
581 writel(0x03, (void __iomem *)(irqport + IOC4_INTR_SET * 4)); 572 writel(0x03, (void __iomem *)(irqport + IOC4_INTR_SET * 4));
582 573
583 rc = ide_host_add(&sgiioc4_port_info, hws, 1, NULL); 574 rc = ide_host_add(&sgiioc4_port_info, hws, 1, NULL);
@@ -590,8 +581,7 @@ req_mem_rgn_err:
590 return rc; 581 return rc;
591} 582}
592 583
593static unsigned int __devinit 584static unsigned int __devinit pci_init_sgiioc4(struct pci_dev *dev)
594pci_init_sgiioc4(struct pci_dev *dev)
595{ 585{
596 int ret; 586 int ret;
597 587
@@ -611,10 +601,10 @@ out:
611 return ret; 601 return ret;
612} 602}
613 603
614int __devinit 604int __devinit ioc4_ide_attach_one(struct ioc4_driver_data *idd)
615ioc4_ide_attach_one(struct ioc4_driver_data *idd)
616{ 605{
617 /* PCI-RT does not bring out IDE connection. 606 /*
607 * PCI-RT does not bring out IDE connection.
618 * Do not attach to this particular IOC4. 608 * Do not attach to this particular IOC4.
619 */ 609 */
620 if (idd->idd_variant == IOC4_VARIANT_PCI_RT) 610 if (idd->idd_variant == IOC4_VARIANT_PCI_RT)
@@ -627,7 +617,6 @@ static struct ioc4_submodule __devinitdata ioc4_ide_submodule = {
627 .is_name = "IOC4_ide", 617 .is_name = "IOC4_ide",
628 .is_owner = THIS_MODULE, 618 .is_owner = THIS_MODULE,
629 .is_probe = ioc4_ide_attach_one, 619 .is_probe = ioc4_ide_attach_one,
630/* .is_remove = ioc4_ide_remove_one, */
631}; 620};
632 621
633static int __init ioc4_ide_init(void) 622static int __init ioc4_ide_init(void)