aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/scsi/mvsas.c123
1 files changed, 87 insertions, 36 deletions
diff --git a/drivers/scsi/mvsas.c b/drivers/scsi/mvsas.c
index 5ec0665b3a3d..3a447fea0b1f 100644
--- a/drivers/scsi/mvsas.c
+++ b/drivers/scsi/mvsas.c
@@ -37,11 +37,13 @@
37#include <linux/dma-mapping.h> 37#include <linux/dma-mapping.h>
38#include <linux/ctype.h> 38#include <linux/ctype.h>
39#include <scsi/libsas.h> 39#include <scsi/libsas.h>
40#include <scsi/scsi_tcq.h>
41#include <scsi/sas_ata.h>
40#include <asm/io.h> 42#include <asm/io.h>
41 43
42#define DRV_NAME "mvsas" 44#define DRV_NAME "mvsas"
43#define DRV_VERSION "0.5.1" 45#define DRV_VERSION "0.5.2"
44#define _MV_DUMP 0 46#define _MV_DUMP 0
45#define MVS_DISABLE_NVRAM 47#define MVS_DISABLE_NVRAM
46#define MVS_DISABLE_MSI 48#define MVS_DISABLE_MSI
47 49
@@ -52,7 +54,7 @@
52 readl(regs + MVS_##reg); \ 54 readl(regs + MVS_##reg); \
53 } while (0) 55 } while (0)
54 56
55#define MVS_ID_NOT_MAPPED 0xff 57#define MVS_ID_NOT_MAPPED 0x7f
56#define MVS_CHIP_SLOT_SZ (1U << mvi->chip->slot_width) 58#define MVS_CHIP_SLOT_SZ (1U << mvi->chip->slot_width)
57 59
58/* offset for D2H FIS in the Received FIS List Structure */ 60/* offset for D2H FIS in the Received FIS List Structure */
@@ -84,6 +86,7 @@ enum driver_configuration {
84 MVS_RX_FIS_COUNT = 17, /* Optional rx'd FISs (max 17) */ 86 MVS_RX_FIS_COUNT = 17, /* Optional rx'd FISs (max 17) */
85 87
86 MVS_QUEUE_SIZE = 30, /* Support Queue depth */ 88 MVS_QUEUE_SIZE = 30, /* Support Queue depth */
89 MVS_CAN_QUEUE = MVS_SLOTS - 1, /* SCSI Queue depth */
87}; 90};
88 91
89/* unchangeable hardware details */ 92/* unchangeable hardware details */
@@ -358,7 +361,20 @@ enum hw_register_bits {
358 361
359 /* VSR */ 362 /* VSR */
360 /* PHYMODE 6 (CDB) */ 363 /* PHYMODE 6 (CDB) */
361 PHY_MODE6_DTL_SPEED = (1U << 27), 364 PHY_MODE6_LATECLK = (1U << 29), /* Lock Clock */
365 PHY_MODE6_DTL_SPEED = (1U << 27), /* Digital Loop Speed */
366 PHY_MODE6_FC_ORDER = (1U << 26), /* Fibre Channel Mode Order*/
367 PHY_MODE6_MUCNT_EN = (1U << 24), /* u Count Enable */
368 PHY_MODE6_SEL_MUCNT_LEN = (1U << 22), /* Training Length Select */
369 PHY_MODE6_SELMUPI = (1U << 20), /* Phase Multi Select (init) */
370 PHY_MODE6_SELMUPF = (1U << 18), /* Phase Multi Select (final) */
371 PHY_MODE6_SELMUFF = (1U << 16), /* Freq Loop Multi Sel(final) */
372 PHY_MODE6_SELMUFI = (1U << 14), /* Freq Loop Multi Sel(init) */
373 PHY_MODE6_FREEZE_LOOP = (1U << 12), /* Freeze Rx CDR Loop */
374 PHY_MODE6_INT_RXFOFFS = (1U << 3), /* Rx CDR Freq Loop Enable */
375 PHY_MODE6_FRC_RXFOFFS = (1U << 2), /* Initial Rx CDR Offset */
376 PHY_MODE6_STAU_0D8 = (1U << 1), /* Rx CDR Freq Loop Saturate */
377 PHY_MODE6_RXSAT_DIS = (1U << 0), /* Saturate Ctl */
362}; 378};
363 379
364enum mvs_info_flags { 380enum mvs_info_flags {
@@ -511,7 +527,43 @@ enum status_buffer {
511}; 527};
512 528
513enum error_info_rec { 529enum error_info_rec {
514 CMD_ISS_STPD = (1U << 31), /* Cmd Issue Stopped */ 530 CMD_ISS_STPD = (1U << 31), /* Cmd Issue Stopped */
531 CMD_PI_ERR = (1U << 30), /* Protection info error. see flags2 */
532 RSP_OVER = (1U << 29), /* rsp buffer overflow */
533 RETRY_LIM = (1U << 28), /* FIS/frame retry limit exceeded */
534 UNK_FIS = (1U << 27), /* unknown FIS */
535 DMA_TERM = (1U << 26), /* DMA terminate primitive rx'd */
536 SYNC_ERR = (1U << 25), /* SYNC rx'd during frame xmit */
537 TFILE_ERR = (1U << 24), /* SATA taskfile Error bit set */
538 R_ERR = (1U << 23), /* SATA returned R_ERR prim */
539 RD_OFS = (1U << 20), /* Read DATA frame invalid offset */
540 XFER_RDY_OFS = (1U << 19), /* XFER_RDY offset error */
541 UNEXP_XFER_RDY = (1U << 18), /* unexpected XFER_RDY error */
542 DATA_OVER_UNDER = (1U << 16), /* data overflow/underflow */
543 INTERLOCK = (1U << 15), /* interlock error */
544 NAK = (1U << 14), /* NAK rx'd */
545 ACK_NAK_TO = (1U << 13), /* ACK/NAK timeout */
546 CXN_CLOSED = (1U << 12), /* cxn closed w/out ack/nak */
547 OPEN_TO = (1U << 11), /* I_T nexus lost, open cxn timeout */
548 PATH_BLOCKED = (1U << 10), /* I_T nexus lost, pathway blocked */
549 NO_DEST = (1U << 9), /* I_T nexus lost, no destination */
550 STP_RES_BSY = (1U << 8), /* STP resources busy */
551 BREAK = (1U << 7), /* break received */
552 BAD_DEST = (1U << 6), /* bad destination */
553 BAD_PROTO = (1U << 5), /* protocol not supported */
554 BAD_RATE = (1U << 4), /* cxn rate not supported */
555 WRONG_DEST = (1U << 3), /* wrong destination error */
556 CREDIT_TO = (1U << 2), /* credit timeout */
557 WDOG_TO = (1U << 1), /* watchdog timeout */
558 BUF_PAR = (1U << 0), /* buffer parity error */
559};
560
561enum error_info_rec_2 {
562 SLOT_BSY_ERR = (1U << 31), /* Slot Busy Error */
563 GRD_CHK_ERR = (1U << 14), /* Guard Check Error */
564 APP_CHK_ERR = (1U << 13), /* Application Check error */
565 REF_CHK_ERR = (1U << 12), /* Reference Check Error */
566 USR_BLK_NM = (1U << 0), /* User Block Number */
515}; 567};
516 568
517struct mvs_chip_info { 569struct mvs_chip_info {
@@ -543,28 +595,12 @@ struct mvs_cmd_hdr {
543 __le32 reserved[4]; 595 __le32 reserved[4];
544}; 596};
545 597
546struct mvs_slot_info {
547 struct sas_task *task;
548 u32 n_elem;
549 u32 tx;
550
551 /* DMA buffer for storing cmd tbl, open addr frame, status buffer,
552 * and PRD table
553 */
554 void *buf;
555 dma_addr_t buf_dma;
556#if _MV_DUMP
557 u32 cmd_size;
558#endif
559
560 void *response;
561};
562
563struct mvs_port { 598struct mvs_port {
564 struct asd_sas_port sas_port; 599 struct asd_sas_port sas_port;
565 u8 port_attached; 600 u8 port_attached;
566 u8 taskfileset; 601 u8 taskfileset;
567 u8 wide_port_phymap; 602 u8 wide_port_phymap;
603 struct list_head list;
568}; 604};
569 605
570struct mvs_phy { 606struct mvs_phy {
@@ -582,6 +618,27 @@ struct mvs_phy {
582 u32 frame_rcvd_size; 618 u32 frame_rcvd_size;
583 u8 frame_rcvd[32]; 619 u8 frame_rcvd[32];
584 u8 phy_attached; 620 u8 phy_attached;
621 enum sas_linkrate minimum_linkrate;
622 enum sas_linkrate maximum_linkrate;
623};
624
625struct mvs_slot_info {
626 struct list_head list;
627 struct sas_task *task;
628 u32 n_elem;
629 u32 tx;
630
631 /* DMA buffer for storing cmd tbl, open addr frame, status buffer,
632 * and PRD table
633 */
634 void *buf;
635 dma_addr_t buf_dma;
636#if _MV_DUMP
637 u32 cmd_size;
638#endif
639
640 void *response;
641 struct mvs_port *port;
585}; 642};
586 643
587struct mvs_info { 644struct mvs_info {
@@ -612,21 +669,14 @@ struct mvs_info {
612 669
613 const struct mvs_chip_info *chip; 670 const struct mvs_chip_info *chip;
614 671
615 unsigned long tags[MVS_SLOTS]; 672 u8 tags[MVS_SLOTS];
616 struct mvs_slot_info slot_info[MVS_SLOTS]; 673 struct mvs_slot_info slot_info[MVS_SLOTS];
617 /* further per-slot information */ 674 /* further per-slot information */
618 struct mvs_phy phy[MVS_MAX_PHYS]; 675 struct mvs_phy phy[MVS_MAX_PHYS];
619 struct mvs_port port[MVS_MAX_PHYS]; 676 struct mvs_port port[MVS_MAX_PHYS];
620 677#ifdef MVS_USE_TASKLET
621 u32 can_queue; /* per adapter */ 678 struct tasklet_struct tasklet;
622 u32 tag_out; /*Get*/ 679#endif
623 u32 tag_in; /*Give*/
624};
625
626struct mvs_queue_task {
627 struct list_head list;
628
629 void *uldd_task;
630}; 680};
631 681
632static int mvs_phy_control(struct asd_sas_phy *sas_phy, enum phy_func func, 682static int mvs_phy_control(struct asd_sas_phy *sas_phy, enum phy_func func,
@@ -641,10 +691,11 @@ static u32 mvs_read_port_irq_mask(struct mvs_info *mvi, u32 port);
641static u32 mvs_is_phy_ready(struct mvs_info *mvi, int i); 691static u32 mvs_is_phy_ready(struct mvs_info *mvi, int i);
642static void mvs_detect_porttype(struct mvs_info *mvi, int i); 692static void mvs_detect_porttype(struct mvs_info *mvi, int i);
643static void mvs_update_phyinfo(struct mvs_info *mvi, int i, int get_st); 693static void mvs_update_phyinfo(struct mvs_info *mvi, int i, int get_st);
694static void mvs_release_task(struct mvs_info *mvi, int phy_no);
644 695
645static int mvs_scan_finished(struct Scsi_Host *, unsigned long); 696static int mvs_scan_finished(struct Scsi_Host *, unsigned long);
646static void mvs_scan_start(struct Scsi_Host *); 697static void mvs_scan_start(struct Scsi_Host *);
647static int mvs_sas_slave_alloc(struct scsi_device *scsi_dev); 698static int mvs_slave_configure(struct scsi_device *sdev);
648 699
649static struct scsi_transport_template *mvs_stt; 700static struct scsi_transport_template *mvs_stt;
650 701
@@ -659,7 +710,7 @@ static struct scsi_host_template mvs_sht = {
659 .name = DRV_NAME, 710 .name = DRV_NAME,
660 .queuecommand = sas_queuecommand, 711 .queuecommand = sas_queuecommand,
661 .target_alloc = sas_target_alloc, 712 .target_alloc = sas_target_alloc,
662 .slave_configure = sas_slave_configure, 713 .slave_configure = mvs_slave_configure,
663 .slave_destroy = sas_slave_destroy, 714 .slave_destroy = sas_slave_destroy,
664 .scan_finished = mvs_scan_finished, 715 .scan_finished = mvs_scan_finished,
665 .scan_start = mvs_scan_start, 716 .scan_start = mvs_scan_start,
@@ -674,7 +725,7 @@ static struct scsi_host_template mvs_sht = {
674 .use_clustering = ENABLE_CLUSTERING, 725 .use_clustering = ENABLE_CLUSTERING,
675 .eh_device_reset_handler = sas_eh_device_reset_handler, 726 .eh_device_reset_handler = sas_eh_device_reset_handler,
676 .eh_bus_reset_handler = sas_eh_bus_reset_handler, 727 .eh_bus_reset_handler = sas_eh_bus_reset_handler,
677 .slave_alloc = mvs_sas_slave_alloc, 728 .slave_alloc = sas_slave_alloc,
678 .target_destroy = sas_target_destroy, 729 .target_destroy = sas_target_destroy,
679 .ioctl = sas_ioctl, 730 .ioctl = sas_ioctl,
680}; 731};