aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/sata_sil24.c
diff options
context:
space:
mode:
authorTejun Heo <htejun@gmail.com>2005-11-18 00:14:01 -0500
committerJeff Garzik <jgarzik@pobox.com>2005-11-18 13:11:39 -0500
commitca45160db70661a006d884df07f82c9b51d27a52 (patch)
treedd039aa865552c935004c6792a7a82e988607a5e /drivers/scsi/sata_sil24.c
parent7d1ce682d08625258524d23ef5eb9e7ae261c1d0 (diff)
[PATCH] sil24: use SRST for phy_reset
There seems to be no way to obtain device signature from sil24 after SATA phy reset and SRST is needed anyway for later port multiplier suppport. This patch converts sil24_phy_reset to use SRST instaed. Signed-off-by: Tejun Heo <htejun@gmail.com> -- Jeff, I didn't remove the 10ms sleep just to be on the safe side. I think we can live with 10ms sleep on SRST. Signed-off-by: Jeff Garzik <jgarzik@pobox.com>
Diffstat (limited to 'drivers/scsi/sata_sil24.c')
-rw-r--r--drivers/scsi/sata_sil24.c76
1 files changed, 66 insertions, 10 deletions
diff --git a/drivers/scsi/sata_sil24.c b/drivers/scsi/sata_sil24.c
index a6836a07a9e..59aab163bcd 100644
--- a/drivers/scsi/sata_sil24.c
+++ b/drivers/scsi/sata_sil24.c
@@ -333,7 +333,7 @@ static struct ata_port_info sil24_port_info[] = {
333 { 333 {
334 .sht = &sil24_sht, 334 .sht = &sil24_sht,
335 .host_flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY | 335 .host_flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
336 ATA_FLAG_SATA_RESET | ATA_FLAG_MMIO | 336 ATA_FLAG_SRST | ATA_FLAG_MMIO |
337 ATA_FLAG_PIO_DMA | SIL24_NPORTS2FLAG(4), 337 ATA_FLAG_PIO_DMA | SIL24_NPORTS2FLAG(4),
338 .pio_mask = 0x1f, /* pio0-4 */ 338 .pio_mask = 0x1f, /* pio0-4 */
339 .mwdma_mask = 0x07, /* mwdma0-2 */ 339 .mwdma_mask = 0x07, /* mwdma0-2 */
@@ -344,7 +344,7 @@ static struct ata_port_info sil24_port_info[] = {
344 { 344 {
345 .sht = &sil24_sht, 345 .sht = &sil24_sht,
346 .host_flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY | 346 .host_flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
347 ATA_FLAG_SATA_RESET | ATA_FLAG_MMIO | 347 ATA_FLAG_SRST | ATA_FLAG_MMIO |
348 ATA_FLAG_PIO_DMA | SIL24_NPORTS2FLAG(2), 348 ATA_FLAG_PIO_DMA | SIL24_NPORTS2FLAG(2),
349 .pio_mask = 0x1f, /* pio0-4 */ 349 .pio_mask = 0x1f, /* pio0-4 */
350 .mwdma_mask = 0x07, /* mwdma0-2 */ 350 .mwdma_mask = 0x07, /* mwdma0-2 */
@@ -355,7 +355,7 @@ static struct ata_port_info sil24_port_info[] = {
355 { 355 {
356 .sht = &sil24_sht, 356 .sht = &sil24_sht,
357 .host_flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY | 357 .host_flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
358 ATA_FLAG_SATA_RESET | ATA_FLAG_MMIO | 358 ATA_FLAG_SRST | ATA_FLAG_MMIO |
359 ATA_FLAG_PIO_DMA | SIL24_NPORTS2FLAG(1), 359 ATA_FLAG_PIO_DMA | SIL24_NPORTS2FLAG(1),
360 .pio_mask = 0x1f, /* pio0-4 */ 360 .pio_mask = 0x1f, /* pio0-4 */
361 .mwdma_mask = 0x07, /* mwdma0-2 */ 361 .mwdma_mask = 0x07, /* mwdma0-2 */
@@ -415,16 +415,72 @@ static void sil24_tf_read(struct ata_port *ap, struct ata_taskfile *tf)
415 *tf = pp->tf; 415 *tf = pp->tf;
416} 416}
417 417
418static void sil24_phy_reset(struct ata_port *ap) 418static int sil24_issue_SRST(struct ata_port *ap)
419{ 419{
420 __sata_phy_reset(ap); 420 void __iomem *port = (void __iomem *)ap->ioaddr.cmd_addr;
421 struct sil24_port_priv *pp = ap->private_data;
422 struct sil24_prb *prb = &pp->cmd_block[0].prb;
423 dma_addr_t paddr = pp->cmd_block_dma;
424 u32 irq_enable, irq_stat;
425 int cnt;
426
427 /* temporarily turn off IRQs during SRST */
428 irq_enable = readl(port + PORT_IRQ_ENABLE_SET);
429 writel(irq_enable, port + PORT_IRQ_ENABLE_CLR);
430
421 /* 431 /*
422 * No ATAPI yet. Just unconditionally indicate ATA device. 432 * XXX: Not sure whether the following sleep is needed or not.
423 * If ATAPI device is attached, it will fail ATA_CMD_ID_ATA 433 * The original driver had it. So....
424 * and libata core will ignore the device.
425 */ 434 */
426 if (!(ap->flags & ATA_FLAG_PORT_DISABLED)) 435 msleep(10);
427 ap->device[0].class = ATA_DEV_ATA; 436
437 prb->ctrl = PRB_CTRL_SRST;
438 prb->fis[1] = 0; /* no PM yet */
439
440 writel((u32)paddr, port + PORT_CMD_ACTIVATE);
441
442 for (cnt = 0; cnt < 100; cnt++) {
443 irq_stat = readl(port + PORT_IRQ_STAT);
444 writel(irq_stat, port + PORT_IRQ_STAT); /* clear irq */
445
446 irq_stat >>= PORT_IRQ_RAW_SHIFT;
447 if (irq_stat & (PORT_IRQ_COMPLETE | PORT_IRQ_ERROR))
448 break;
449
450 msleep(1);
451 }
452
453 /* restore IRQs */
454 writel(irq_enable, port + PORT_IRQ_ENABLE_SET);
455
456 if (!(irq_stat & PORT_IRQ_COMPLETE))
457 return -1;
458
459 /* update TF */
460 sil24_update_tf(ap);
461 return 0;
462}
463
464static void sil24_phy_reset(struct ata_port *ap)
465{
466 struct sil24_port_priv *pp = ap->private_data;
467
468 __sata_phy_reset(ap);
469 if (ap->flags & ATA_FLAG_PORT_DISABLED)
470 return;
471
472 if (sil24_issue_SRST(ap) < 0) {
473 printk(KERN_ERR DRV_NAME
474 " ata%u: SRST failed, disabling port\n", ap->id);
475 ap->ops->port_disable(ap);
476 return;
477 }
478
479 ap->device->class = ata_dev_classify(&pp->tf);
480
481 /* No ATAPI yet */
482 if (ap->device->class == ATA_DEV_ATAPI)
483 ap->ops->port_disable(ap);
428} 484}
429 485
430static inline void sil24_fill_sg(struct ata_queued_cmd *qc, 486static inline void sil24_fill_sg(struct ata_queued_cmd *qc,