aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/scsi/sata_mv.c3
-rw-r--r--drivers/scsi/sata_sil24.c197
2 files changed, 162 insertions, 38 deletions
diff --git a/drivers/scsi/sata_mv.c b/drivers/scsi/sata_mv.c
index ac184e60797e..ab7432a5778e 100644
--- a/drivers/scsi/sata_mv.c
+++ b/drivers/scsi/sata_mv.c
@@ -2,6 +2,7 @@
2 * sata_mv.c - Marvell SATA support 2 * sata_mv.c - Marvell SATA support
3 * 3 *
4 * Copyright 2005: EMC Corporation, all rights reserved. 4 * Copyright 2005: EMC Corporation, all rights reserved.
5 * Copyright 2005 Red Hat, Inc. All rights reserved.
5 * 6 *
6 * Please ALWAYS copy linux-ide@vger.kernel.org on emails. 7 * Please ALWAYS copy linux-ide@vger.kernel.org on emails.
7 * 8 *
@@ -36,7 +37,7 @@
36#include <asm/io.h> 37#include <asm/io.h>
37 38
38#define DRV_NAME "sata_mv" 39#define DRV_NAME "sata_mv"
39#define DRV_VERSION "0.25" 40#define DRV_VERSION "0.5"
40 41
41enum { 42enum {
42 /* BAR's are enumerated in terms of pci_resource_start() terms */ 43 /* BAR's are enumerated in terms of pci_resource_start() terms */
diff --git a/drivers/scsi/sata_sil24.c b/drivers/scsi/sata_sil24.c
index cb1933a3bd55..e0d6f194f54f 100644
--- a/drivers/scsi/sata_sil24.c
+++ b/drivers/scsi/sata_sil24.c
@@ -5,17 +5,6 @@
5 * 5 *
6 * Based on preview driver from Silicon Image. 6 * Based on preview driver from Silicon Image.
7 * 7 *
8 * NOTE: No NCQ/ATAPI support yet. The preview driver didn't support
9 * NCQ nor ATAPI, and, unfortunately, I couldn't find out how to make
10 * those work. Enabling those shouldn't be difficult. Basic
11 * structure is all there (in libata-dev tree). If you have any
12 * information about this hardware, please contact me or linux-ide.
13 * Info is needed on...
14 *
15 * - How to issue tagged commands and turn on sactive on issue accordingly.
16 * - Where to put an ATAPI command and how to tell the device to send it.
17 * - How to enable/use 64bit.
18 *
19 * This program is free software; you can redistribute it and/or modify it 8 * This program is free software; you can redistribute it and/or modify it
20 * under the terms of the GNU General Public License as published by the 9 * under the terms of the GNU General Public License as published by the
21 * Free Software Foundation; either version 2, or (at your option) any 10 * Free Software Foundation; either version 2, or (at your option) any
@@ -42,7 +31,7 @@
42#include <asm/io.h> 31#include <asm/io.h>
43 32
44#define DRV_NAME "sata_sil24" 33#define DRV_NAME "sata_sil24"
45#define DRV_VERSION "0.22" /* Silicon Image's preview driver was 0.10 */ 34#define DRV_VERSION "0.23"
46 35
47/* 36/*
48 * Port request block (PRB) 32 bytes 37 * Port request block (PRB) 32 bytes
@@ -221,11 +210,22 @@ enum {
221 IRQ_STAT_4PORTS = 0xf, 210 IRQ_STAT_4PORTS = 0xf,
222}; 211};
223 212
224struct sil24_cmd_block { 213struct sil24_ata_block {
225 struct sil24_prb prb; 214 struct sil24_prb prb;
226 struct sil24_sge sge[LIBATA_MAX_PRD]; 215 struct sil24_sge sge[LIBATA_MAX_PRD];
227}; 216};
228 217
218struct sil24_atapi_block {
219 struct sil24_prb prb;
220 u8 cdb[16];
221 struct sil24_sge sge[LIBATA_MAX_PRD - 1];
222};
223
224union sil24_cmd_block {
225 struct sil24_ata_block ata;
226 struct sil24_atapi_block atapi;
227};
228
229/* 229/*
230 * ap->private_data 230 * ap->private_data
231 * 231 *
@@ -233,7 +233,7 @@ struct sil24_cmd_block {
233 * here from the previous interrupt. 233 * here from the previous interrupt.
234 */ 234 */
235struct sil24_port_priv { 235struct sil24_port_priv {
236 struct sil24_cmd_block *cmd_block; /* 32 cmd blocks */ 236 union sil24_cmd_block *cmd_block; /* 32 cmd blocks */
237 dma_addr_t cmd_block_dma; /* DMA base addr for them */ 237 dma_addr_t cmd_block_dma; /* DMA base addr for them */
238 struct ata_taskfile tf; /* Cached taskfile registers */ 238 struct ata_taskfile tf; /* Cached taskfile registers */
239}; 239};
@@ -244,6 +244,7 @@ struct sil24_host_priv {
244 void __iomem *port_base; /* port registers (4 * 8192 bytes @BAR2) */ 244 void __iomem *port_base; /* port registers (4 * 8192 bytes @BAR2) */
245}; 245};
246 246
247static void sil24_dev_config(struct ata_port *ap, struct ata_device *dev);
247static u8 sil24_check_status(struct ata_port *ap); 248static u8 sil24_check_status(struct ata_port *ap);
248static u32 sil24_scr_read(struct ata_port *ap, unsigned sc_reg); 249static u32 sil24_scr_read(struct ata_port *ap, unsigned sc_reg);
249static void sil24_scr_write(struct ata_port *ap, unsigned sc_reg, u32 val); 250static void sil24_scr_write(struct ata_port *ap, unsigned sc_reg, u32 val);
@@ -297,6 +298,8 @@ static struct scsi_host_template sil24_sht = {
297static const struct ata_port_operations sil24_ops = { 298static const struct ata_port_operations sil24_ops = {
298 .port_disable = ata_port_disable, 299 .port_disable = ata_port_disable,
299 300
301 .dev_config = sil24_dev_config,
302
300 .check_status = sil24_check_status, 303 .check_status = sil24_check_status,
301 .check_altstatus = sil24_check_status, 304 .check_altstatus = sil24_check_status,
302 .dev_select = ata_noop_dev_select, 305 .dev_select = ata_noop_dev_select,
@@ -333,7 +336,7 @@ static struct ata_port_info sil24_port_info[] = {
333 { 336 {
334 .sht = &sil24_sht, 337 .sht = &sil24_sht,
335 .host_flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY | 338 .host_flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
336 ATA_FLAG_SATA_RESET | ATA_FLAG_MMIO | 339 ATA_FLAG_SRST | ATA_FLAG_MMIO |
337 ATA_FLAG_PIO_DMA | SIL24_NPORTS2FLAG(4), 340 ATA_FLAG_PIO_DMA | SIL24_NPORTS2FLAG(4),
338 .pio_mask = 0x1f, /* pio0-4 */ 341 .pio_mask = 0x1f, /* pio0-4 */
339 .mwdma_mask = 0x07, /* mwdma0-2 */ 342 .mwdma_mask = 0x07, /* mwdma0-2 */
@@ -344,7 +347,7 @@ static struct ata_port_info sil24_port_info[] = {
344 { 347 {
345 .sht = &sil24_sht, 348 .sht = &sil24_sht,
346 .host_flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY | 349 .host_flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
347 ATA_FLAG_SATA_RESET | ATA_FLAG_MMIO | 350 ATA_FLAG_SRST | ATA_FLAG_MMIO |
348 ATA_FLAG_PIO_DMA | SIL24_NPORTS2FLAG(2), 351 ATA_FLAG_PIO_DMA | SIL24_NPORTS2FLAG(2),
349 .pio_mask = 0x1f, /* pio0-4 */ 352 .pio_mask = 0x1f, /* pio0-4 */
350 .mwdma_mask = 0x07, /* mwdma0-2 */ 353 .mwdma_mask = 0x07, /* mwdma0-2 */
@@ -355,7 +358,7 @@ static struct ata_port_info sil24_port_info[] = {
355 { 358 {
356 .sht = &sil24_sht, 359 .sht = &sil24_sht,
357 .host_flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY | 360 .host_flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
358 ATA_FLAG_SATA_RESET | ATA_FLAG_MMIO | 361 ATA_FLAG_SRST | ATA_FLAG_MMIO |
359 ATA_FLAG_PIO_DMA | SIL24_NPORTS2FLAG(1), 362 ATA_FLAG_PIO_DMA | SIL24_NPORTS2FLAG(1),
360 .pio_mask = 0x1f, /* pio0-4 */ 363 .pio_mask = 0x1f, /* pio0-4 */
361 .mwdma_mask = 0x07, /* mwdma0-2 */ 364 .mwdma_mask = 0x07, /* mwdma0-2 */
@@ -364,6 +367,16 @@ static struct ata_port_info sil24_port_info[] = {
364 }, 367 },
365}; 368};
366 369
370static void sil24_dev_config(struct ata_port *ap, struct ata_device *dev)
371{
372 void __iomem *port = (void __iomem *)ap->ioaddr.cmd_addr;
373
374 if (ap->cdb_len == 16)
375 writel(PORT_CS_CDB16, port + PORT_CTRL_STAT);
376 else
377 writel(PORT_CS_CDB16, port + PORT_CTRL_CLR);
378}
379
367static inline void sil24_update_tf(struct ata_port *ap) 380static inline void sil24_update_tf(struct ata_port *ap)
368{ 381{
369 struct sil24_port_priv *pp = ap->private_data; 382 struct sil24_port_priv *pp = ap->private_data;
@@ -415,22 +428,73 @@ static void sil24_tf_read(struct ata_port *ap, struct ata_taskfile *tf)
415 *tf = pp->tf; 428 *tf = pp->tf;
416} 429}
417 430
418static void sil24_phy_reset(struct ata_port *ap) 431static int sil24_issue_SRST(struct ata_port *ap)
419{ 432{
420 __sata_phy_reset(ap); 433 void __iomem *port = (void __iomem *)ap->ioaddr.cmd_addr;
434 struct sil24_port_priv *pp = ap->private_data;
435 struct sil24_prb *prb = &pp->cmd_block[0].ata.prb;
436 dma_addr_t paddr = pp->cmd_block_dma;
437 u32 irq_enable, irq_stat;
438 int cnt;
439
440 /* temporarily turn off IRQs during SRST */
441 irq_enable = readl(port + PORT_IRQ_ENABLE_SET);
442 writel(irq_enable, port + PORT_IRQ_ENABLE_CLR);
443
421 /* 444 /*
422 * No ATAPI yet. Just unconditionally indicate ATA device. 445 * XXX: Not sure whether the following sleep is needed or not.
423 * If ATAPI device is attached, it will fail ATA_CMD_ID_ATA 446 * The original driver had it. So....
424 * and libata core will ignore the device.
425 */ 447 */
426 if (!(ap->flags & ATA_FLAG_PORT_DISABLED)) 448 msleep(10);
427 ap->device[0].class = ATA_DEV_ATA; 449
450 prb->ctrl = PRB_CTRL_SRST;
451 prb->fis[1] = 0; /* no PM yet */
452
453 writel((u32)paddr, port + PORT_CMD_ACTIVATE);
454
455 for (cnt = 0; cnt < 100; cnt++) {
456 irq_stat = readl(port + PORT_IRQ_STAT);
457 writel(irq_stat, port + PORT_IRQ_STAT); /* clear irq */
458
459 irq_stat >>= PORT_IRQ_RAW_SHIFT;
460 if (irq_stat & (PORT_IRQ_COMPLETE | PORT_IRQ_ERROR))
461 break;
462
463 msleep(1);
464 }
465
466 /* restore IRQs */
467 writel(irq_enable, port + PORT_IRQ_ENABLE_SET);
468
469 if (!(irq_stat & PORT_IRQ_COMPLETE))
470 return -1;
471
472 /* update TF */
473 sil24_update_tf(ap);
474 return 0;
475}
476
477static void sil24_phy_reset(struct ata_port *ap)
478{
479 struct sil24_port_priv *pp = ap->private_data;
480
481 __sata_phy_reset(ap);
482 if (ap->flags & ATA_FLAG_PORT_DISABLED)
483 return;
484
485 if (sil24_issue_SRST(ap) < 0) {
486 printk(KERN_ERR DRV_NAME
487 " ata%u: SRST failed, disabling port\n", ap->id);
488 ap->ops->port_disable(ap);
489 return;
490 }
491
492 ap->device->class = ata_dev_classify(&pp->tf);
428} 493}
429 494
430static inline void sil24_fill_sg(struct ata_queued_cmd *qc, 495static inline void sil24_fill_sg(struct ata_queued_cmd *qc,
431 struct sil24_cmd_block *cb) 496 struct sil24_sge *sge)
432{ 497{
433 struct sil24_sge *sge = cb->sge;
434 struct scatterlist *sg; 498 struct scatterlist *sg;
435 unsigned int idx = 0; 499 unsigned int idx = 0;
436 500
@@ -451,23 +515,47 @@ static void sil24_qc_prep(struct ata_queued_cmd *qc)
451{ 515{
452 struct ata_port *ap = qc->ap; 516 struct ata_port *ap = qc->ap;
453 struct sil24_port_priv *pp = ap->private_data; 517 struct sil24_port_priv *pp = ap->private_data;
454 struct sil24_cmd_block *cb = pp->cmd_block + qc->tag; 518 union sil24_cmd_block *cb = pp->cmd_block + qc->tag;
455 struct sil24_prb *prb = &cb->prb; 519 struct sil24_prb *prb;
520 struct sil24_sge *sge;
456 521
457 switch (qc->tf.protocol) { 522 switch (qc->tf.protocol) {
458 case ATA_PROT_PIO: 523 case ATA_PROT_PIO:
459 case ATA_PROT_DMA: 524 case ATA_PROT_DMA:
460 case ATA_PROT_NODATA: 525 case ATA_PROT_NODATA:
526 prb = &cb->ata.prb;
527 sge = cb->ata.sge;
528 prb->ctrl = 0;
529 break;
530
531 case ATA_PROT_ATAPI:
532 case ATA_PROT_ATAPI_DMA:
533 case ATA_PROT_ATAPI_NODATA:
534 prb = &cb->atapi.prb;
535 sge = cb->atapi.sge;
536 memset(cb->atapi.cdb, 0, 32);
537 memcpy(cb->atapi.cdb, qc->cdb, ap->cdb_len);
538
539 if (qc->tf.protocol != ATA_PROT_ATAPI_NODATA) {
540 if (qc->tf.flags & ATA_TFLAG_WRITE)
541 prb->ctrl = PRB_CTRL_PACKET_WRITE;
542 else
543 prb->ctrl = PRB_CTRL_PACKET_READ;
544 } else
545 prb->ctrl = 0;
546
461 break; 547 break;
548
462 default: 549 default:
463 /* ATAPI isn't supported yet */ 550 prb = NULL; /* shut up, gcc */
551 sge = NULL;
464 BUG(); 552 BUG();
465 } 553 }
466 554
467 ata_tf_to_fis(&qc->tf, prb->fis, 0); 555 ata_tf_to_fis(&qc->tf, prb->fis, 0);
468 556
469 if (qc->flags & ATA_QCFLAG_DMAMAP) 557 if (qc->flags & ATA_QCFLAG_DMAMAP)
470 sil24_fill_sg(qc, cb); 558 sil24_fill_sg(qc, sge);
471} 559}
472 560
473static int sil24_qc_issue(struct ata_queued_cmd *qc) 561static int sil24_qc_issue(struct ata_queued_cmd *qc)
@@ -486,6 +574,31 @@ static void sil24_irq_clear(struct ata_port *ap)
486 /* unused */ 574 /* unused */
487} 575}
488 576
577static int __sil24_restart_controller(void __iomem *port)
578{
579 u32 tmp;
580 int cnt;
581
582 writel(PORT_CS_INIT, port + PORT_CTRL_STAT);
583
584 /* Max ~10ms */
585 for (cnt = 0; cnt < 10000; cnt++) {
586 tmp = readl(port + PORT_CTRL_STAT);
587 if (tmp & PORT_CS_RDY)
588 return 0;
589 udelay(1);
590 }
591
592 return -1;
593}
594
595static void sil24_restart_controller(struct ata_port *ap)
596{
597 if (__sil24_restart_controller((void __iomem *)ap->ioaddr.cmd_addr))
598 printk(KERN_ERR DRV_NAME
599 " ata%u: failed to restart controller\n", ap->id);
600}
601
489static int __sil24_reset_controller(void __iomem *port) 602static int __sil24_reset_controller(void __iomem *port)
490{ 603{
491 int cnt; 604 int cnt;
@@ -505,7 +618,11 @@ static int __sil24_reset_controller(void __iomem *port)
505 618
506 if (tmp & PORT_CS_DEV_RST) 619 if (tmp & PORT_CS_DEV_RST)
507 return -1; 620 return -1;
508 return 0; 621
622 if (tmp & PORT_CS_RDY)
623 return 0;
624
625 return __sil24_restart_controller(port);
509} 626}
510 627
511static void sil24_reset_controller(struct ata_port *ap) 628static void sil24_reset_controller(struct ata_port *ap)
@@ -567,9 +684,15 @@ static void sil24_error_intr(struct ata_port *ap, u32 slot_stat)
567 if (serror) 684 if (serror)
568 writel(serror, port + PORT_SERROR); 685 writel(serror, port + PORT_SERROR);
569 686
570 printk(KERN_ERR DRV_NAME " ata%u: error interrupt on port%d\n" 687 /*
571 " stat=0x%x irq=0x%x cmd_err=%d sstatus=0x%x serror=0x%x\n", 688 * Don't log ATAPI device errors. They're supposed to happen
572 ap->id, ap->port_no, slot_stat, irq_stat, cmd_err, sstatus, serror); 689 * and any serious errors will be logged using sense data by
690 * the SCSI layer.
691 */
692 if (ap->device[0].class != ATA_DEV_ATAPI || cmd_err > PORT_CERR_SDB)
693 printk("ata%u: error interrupt on port%d\n"
694 " stat=0x%x irq=0x%x cmd_err=%d sstatus=0x%x serror=0x%x\n",
695 ap->id, ap->port_no, slot_stat, irq_stat, cmd_err, sstatus, serror);
573 696
574 if (cmd_err == PORT_CERR_DEV || cmd_err == PORT_CERR_SDB) { 697 if (cmd_err == PORT_CERR_DEV || cmd_err == PORT_CERR_SDB) {
575 /* 698 /*
@@ -577,6 +700,7 @@ static void sil24_error_intr(struct ata_port *ap, u32 slot_stat)
577 */ 700 */
578 sil24_update_tf(ap); 701 sil24_update_tf(ap);
579 err_mask = ac_err_mask(pp->tf.command); 702 err_mask = ac_err_mask(pp->tf.command);
703 sil24_restart_controller(ap);
580 } else { 704 } else {
581 /* 705 /*
582 * Other errors. libata currently doesn't have any 706 * Other errors. libata currently doesn't have any
@@ -584,12 +708,11 @@ static void sil24_error_intr(struct ata_port *ap, u32 slot_stat)
584 * ATA_ERR. 708 * ATA_ERR.
585 */ 709 */
586 err_mask = AC_ERR_OTHER; 710 err_mask = AC_ERR_OTHER;
711 sil24_reset_controller(ap);
587 } 712 }
588 713
589 if (qc) 714 if (qc)
590 ata_qc_complete(qc, err_mask); 715 ata_qc_complete(qc, err_mask);
591
592 sil24_reset_controller(ap);
593} 716}
594 717
595static inline void sil24_host_intr(struct ata_port *ap) 718static inline void sil24_host_intr(struct ata_port *ap)
@@ -665,7 +788,7 @@ static int sil24_port_start(struct ata_port *ap)
665{ 788{
666 struct device *dev = ap->host_set->dev; 789 struct device *dev = ap->host_set->dev;
667 struct sil24_port_priv *pp; 790 struct sil24_port_priv *pp;
668 struct sil24_cmd_block *cb; 791 union sil24_cmd_block *cb;
669 size_t cb_size = sizeof(*cb); 792 size_t cb_size = sizeof(*cb);
670 dma_addr_t cb_dma; 793 dma_addr_t cb_dma;
671 int rc = -ENOMEM; 794 int rc = -ENOMEM;