Skip to content

Commit

Permalink
Merge tag 'scsi-misc' of git://git.kernel.org/pub/scm/linux/kernel/gi…
Browse files Browse the repository at this point in the history
…t/jejb/scsi

Pull more SCSI updates from James Bottomley:
 "This is the final round of mostly small fixes and performance
  improvements to our initial submit.

  The main regression fix is the ia64 simscsi build failure which was
  missed in the serial number elimination conversion"

* tag 'scsi-misc' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi: (24 commits)
  scsi: ia64: simscsi: use request tag instead of serial_number
  scsi: aacraid: Fix performance issue on logical drives
  scsi: lpfc: Fix error codes in lpfc_sli4_pci_mem_setup()
  scsi: libiscsi: Hold back_lock when calling iscsi_complete_task
  scsi: hisi_sas: Change SERDES_CFG init value to increase reliability of HiLink
  scsi: hisi_sas: Send HARD RESET to clear the previous affiliation of STP target port
  scsi: hisi_sas: Set PHY linkrate when disconnected
  scsi: hisi_sas: print PHY RX errors count for later revision of v3 hw
  scsi: hisi_sas: Fix a timeout race of driver internal and SMP IO
  scsi: hisi_sas: Change return variable type in phy_up_v3_hw()
  scsi: qla2xxx: check for kstrtol() failure
  scsi: lpfc: fix 32-bit format string warning
  scsi: lpfc: fix unused variable warning
  scsi: target: tcmu: Switch to bitmap_zalloc()
  scsi: libiscsi: fall back to sendmsg for slab pages
  scsi: qla2xxx: avoid printf format warning
  scsi: lpfc: resolve static checker warning in lpfc_sli4_hba_unset
  scsi: lpfc: Correct __lpfc_sli_issue_iocb_s4 lockdep check
  scsi: ufs: hisi: fix ufs_hba_variant_ops passing
  scsi: qla2xxx: Fix panic in qla_dfs_tgt_counters_show
  ...
  • Loading branch information
torvalds committed Mar 16, 2019
2 parents 11efae3 + 52eaa79 commit 477558d
Show file tree
Hide file tree
Showing 22 changed files with 210 additions and 80 deletions.
7 changes: 4 additions & 3 deletions arch/ia64/hp/sim/simscsi.c
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,8 @@ simscsi_interrupt (unsigned long val)
atomic_dec(&num_reqs);
queue[rd].sc = NULL;
if (DBG)
printk("simscsi_interrupt: done with %ld\n", sc->serial_number);
printk("simscsi_interrupt: done with %u\n",
sc->request->tag);
(*sc->scsi_done)(sc);
rd = (rd + 1) % SIMSCSI_REQ_QUEUE_LEN;
}
Expand Down Expand Up @@ -214,8 +215,8 @@ simscsi_queuecommand_lck (struct scsi_cmnd *sc, void (*done)(struct scsi_cmnd *)
register long sp asm ("sp");

if (DBG)
printk("simscsi_queuecommand: target=%d,cmnd=%u,sc=%lu,sp=%lx,done=%p\n",
target_id, sc->cmnd[0], sc->serial_number, sp, done);
printk("simscsi_queuecommand: target=%d,cmnd=%u,sc=%u,sp=%lx,done=%p\n",
target_id, sc->cmnd[0], sc->request->tag, sp, done);
#endif

sc->result = DID_BAD_TARGET << 16;
Expand Down
13 changes: 8 additions & 5 deletions drivers/scsi/aacraid/linit.c
Original file line number Diff line number Diff line change
Expand Up @@ -413,13 +413,16 @@ static int aac_slave_configure(struct scsi_device *sdev)
if (chn < AAC_MAX_BUSES && tid < AAC_MAX_TARGETS && aac->sa_firmware) {
devtype = aac->hba_map[chn][tid].devtype;

if (devtype == AAC_DEVTYPE_NATIVE_RAW)
if (devtype == AAC_DEVTYPE_NATIVE_RAW) {
depth = aac->hba_map[chn][tid].qd_limit;
else if (devtype == AAC_DEVTYPE_ARC_RAW)
set_timeout = 1;
goto common_config;
}
if (devtype == AAC_DEVTYPE_ARC_RAW) {
set_qd_dev_type = true;

set_timeout = 1;
goto common_config;
set_timeout = 1;
goto common_config;
}
}

if (aac->jbod && (sdev->type == TYPE_DISK))
Expand Down
8 changes: 8 additions & 0 deletions drivers/scsi/hisi_sas/hisi_sas.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
#include <linux/dmapool.h>
#include <linux/iopoll.h>
#include <linux/lcm.h>
#include <linux/libata.h>
#include <linux/mfd/syscon.h>
#include <linux/module.h>
#include <linux/of_address.h>
Expand Down Expand Up @@ -94,6 +95,11 @@ enum {
PORT_TYPE_SATA = (1U << 0),
};

enum dev_status {
HISI_SAS_DEV_INIT,
HISI_SAS_DEV_NORMAL,
};

enum {
HISI_SAS_INT_ABT_CMD = 0,
HISI_SAS_INT_ABT_DEV = 1,
Expand Down Expand Up @@ -161,6 +167,7 @@ struct hisi_sas_phy {
u8 in_reset;
u8 reserved[2];
u32 phy_type;
u32 code_violation_err_count;
enum sas_linkrate minimum_linkrate;
enum sas_linkrate maximum_linkrate;
};
Expand Down Expand Up @@ -194,6 +201,7 @@ struct hisi_sas_device {
struct hisi_sas_dq *dq;
struct list_head list;
enum sas_device_type dev_type;
enum dev_status dev_status;
int device_id;
int sata_idx;
spinlock_t lock; /* For protecting slots */
Expand Down
57 changes: 53 additions & 4 deletions drivers/scsi/hisi_sas/hisi_sas_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
*/

#include "hisi_sas.h"
#include "../libsas/sas_internal.h"
#define DRV_NAME "hisi_sas"

#define DEV_IS_GONE(dev) \
Expand Down Expand Up @@ -707,6 +708,7 @@ static struct hisi_sas_device *hisi_sas_alloc_dev(struct domain_device *device)

hisi_hba->devices[i].device_id = i;
sas_dev = &hisi_hba->devices[i];
sas_dev->dev_status = HISI_SAS_DEV_INIT;
sas_dev->dev_type = device->dev_type;
sas_dev->hisi_hba = hisi_hba;
sas_dev->sas_device = device;
Expand All @@ -731,6 +733,8 @@ static int hisi_sas_init_device(struct domain_device *device)
struct hisi_sas_tmf_task tmf_task;
int retry = HISI_SAS_SRST_ATA_DISK_CNT;
struct hisi_hba *hisi_hba = dev_to_hisi_hba(device);
struct device *dev = hisi_hba->dev;
struct sas_phy *local_phy;

switch (device->dev_type) {
case SAS_END_DEVICE:
Expand All @@ -746,6 +750,31 @@ static int hisi_sas_init_device(struct domain_device *device)
case SAS_SATA_PM:
case SAS_SATA_PM_PORT:
case SAS_SATA_PENDING:
/*
* send HARD RESET to clear previous affiliation of
* STP target port
*/
local_phy = sas_get_local_phy(device);
if (!scsi_is_sas_phy_local(local_phy)) {
unsigned long deadline = ata_deadline(jiffies, 20000);
struct sata_device *sata_dev = &device->sata_dev;
struct ata_host *ata_host = sata_dev->ata_host;
struct ata_port_operations *ops = ata_host->ops;
struct ata_port *ap = sata_dev->ap;
struct ata_link *link;
unsigned int classes;

ata_for_each_link(link, ap, EDGE)
rc = ops->hardreset(link, &classes,
deadline);
}
sas_put_local_phy(local_phy);
if (rc) {
dev_warn(dev, "SATA disk hardreset fail: 0x%x\n",
rc);
return rc;
}

while (retry-- > 0) {
rc = hisi_sas_softreset_ata_disk(device);
if (!rc)
Expand Down Expand Up @@ -808,6 +837,7 @@ static int hisi_sas_dev_found(struct domain_device *device)
rc = hisi_sas_init_device(device);
if (rc)
goto err_out;
sas_dev->dev_status = HISI_SAS_DEV_NORMAL;
return 0;

err_out:
Expand Down Expand Up @@ -980,7 +1010,8 @@ static void hisi_sas_do_release_task(struct hisi_hba *hisi_hba, struct sas_task
spin_lock_irqsave(&task->task_state_lock, flags);
task->task_state_flags &=
~(SAS_TASK_STATE_PENDING | SAS_TASK_AT_INITIATOR);
task->task_state_flags |= SAS_TASK_STATE_DONE;
if (!slot->is_internal && task->task_proto != SAS_PROTOCOL_SMP)
task->task_state_flags |= SAS_TASK_STATE_DONE;
spin_unlock_irqrestore(&task->task_state_lock, flags);
}

Expand Down Expand Up @@ -1713,20 +1744,23 @@ static int hisi_sas_clear_aca(struct domain_device *device, u8 *lun)
static int hisi_sas_debug_I_T_nexus_reset(struct domain_device *device)
{
struct sas_phy *local_phy = sas_get_local_phy(device);
int rc, reset_type = (device->dev_type == SAS_SATA_DEV ||
(device->tproto & SAS_PROTOCOL_STP)) ? 0 : 1;
struct hisi_sas_device *sas_dev = device->lldd_dev;
struct hisi_hba *hisi_hba = dev_to_hisi_hba(device);
struct sas_ha_struct *sas_ha = &hisi_hba->sha;
struct asd_sas_phy *sas_phy = sas_ha->sas_phy[local_phy->number];
struct hisi_sas_phy *phy = container_of(sas_phy,
struct hisi_sas_phy, sas_phy);
DECLARE_COMPLETION_ONSTACK(phyreset);
int rc, reset_type;

if (scsi_is_sas_phy_local(local_phy)) {
phy->in_reset = 1;
phy->reset_completion = &phyreset;
}

reset_type = (sas_dev->dev_status == HISI_SAS_DEV_INIT ||
!dev_is_sata(device)) ? 1 : 0;

rc = sas_phy_reset(local_phy, reset_type);
sas_put_local_phy(local_phy);

Expand All @@ -1742,8 +1776,13 @@ static int hisi_sas_debug_I_T_nexus_reset(struct domain_device *device)
/* report PHY down if timed out */
if (!ret)
hisi_sas_phy_down(hisi_hba, sas_phy->id, 0);
} else
} else if (sas_dev->dev_status != HISI_SAS_DEV_INIT) {
/*
* If in init state, we rely on caller to wait for link to be
* ready; otherwise, delay.
*/
msleep(2000);
}

return rc;
}
Expand Down Expand Up @@ -2125,9 +2164,18 @@ static int hisi_sas_write_gpio(struct sas_ha_struct *sha, u8 reg_type,

static void hisi_sas_phy_disconnected(struct hisi_sas_phy *phy)
{
struct asd_sas_phy *sas_phy = &phy->sas_phy;
struct sas_phy *sphy = sas_phy->phy;
struct sas_phy_data *d = sphy->hostdata;

phy->phy_attached = 0;
phy->phy_type = 0;
phy->port = NULL;

if (d->enable)
sphy->negotiated_linkrate = SAS_LINK_RATE_UNKNOWN;
else
sphy->negotiated_linkrate = SAS_PHY_DISABLED;
}

void hisi_sas_phy_down(struct hisi_hba *hisi_hba, int phy_no, int rdy)
Expand Down Expand Up @@ -2253,6 +2301,7 @@ int hisi_sas_alloc(struct hisi_hba *hisi_hba)
for (i = 0; i < HISI_SAS_MAX_DEVICES; i++) {
hisi_hba->devices[i].dev_type = SAS_PHY_UNUSED;
hisi_hba->devices[i].device_id = i;
hisi_hba->devices[i].dev_status = HISI_SAS_DEV_INIT;
}

for (i = 0; i < hisi_hba->queue_count; i++) {
Expand Down
1 change: 1 addition & 0 deletions drivers/scsi/hisi_sas/hisi_sas_v2_hw.c
Original file line number Diff line number Diff line change
Expand Up @@ -868,6 +868,7 @@ hisi_sas_device *alloc_dev_quirk_v2_hw(struct domain_device *device)

hisi_hba->devices[i].device_id = i;
sas_dev = &hisi_hba->devices[i];
sas_dev->dev_status = HISI_SAS_DEV_INIT;
sas_dev->dev_type = device->dev_type;
sas_dev->hisi_hba = hisi_hba;
sas_dev->sas_device = device;
Expand Down
89 changes: 63 additions & 26 deletions drivers/scsi/hisi_sas/hisi_sas_v3_hw.c
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,7 @@
#define PHY_CTRL_RESET_MSK (0x1 << PHY_CTRL_RESET_OFF)
#define CMD_HDR_PIR_OFF 8
#define CMD_HDR_PIR_MSK (0x1 << CMD_HDR_PIR_OFF)
#define SERDES_CFG (PORT_BASE + 0x1c)
#define SL_CFG (PORT_BASE + 0x84)
#define AIP_LIMIT (PORT_BASE + 0x90)
#define SL_CONTROL (PORT_BASE + 0x94)
Expand Down Expand Up @@ -181,6 +182,8 @@
#define CHL_INT1_DMAC_RX_AXI_RD_ERR_OFF 22
#define CHL_INT2 (PORT_BASE + 0x1bc)
#define CHL_INT2_SL_IDAF_TOUT_CONF_OFF 0
#define CHL_INT2_RX_DISP_ERR_OFF 28
#define CHL_INT2_RX_CODE_ERR_OFF 29
#define CHL_INT2_RX_INVLD_DW_OFF 30
#define CHL_INT2_STP_LINK_TIMEOUT_OFF 31
#define CHL_INT0_MSK (PORT_BASE + 0x1c0)
Expand Down Expand Up @@ -523,6 +526,7 @@ static void init_reg_v3_hw(struct hisi_hba *hisi_hba)
}
hisi_sas_phy_write32(hisi_hba, i, PROG_PHY_LINK_RATE,
prog_phy_link_rate);
hisi_sas_phy_write32(hisi_hba, i, SERDES_CFG, 0xffc00);
hisi_sas_phy_write32(hisi_hba, i, SAS_RX_TRAIN_TIMER, 0x13e80);
hisi_sas_phy_write32(hisi_hba, i, CHL_INT0, 0xffffffff);
hisi_sas_phy_write32(hisi_hba, i, CHL_INT1, 0xffffffff);
Expand All @@ -544,6 +548,8 @@ static void init_reg_v3_hw(struct hisi_hba *hisi_hba)
hisi_sas_phy_write32(hisi_hba, i, STP_LINK_TIMER, 0x7f7a120);
hisi_sas_phy_write32(hisi_hba, i, CON_CFG_DRIVER, 0x2a0a01);
hisi_sas_phy_write32(hisi_hba, i, SAS_SSP_CON_TIMER_CFG, 0x32);
hisi_sas_phy_write32(hisi_hba, i, SAS_EC_INT_COAL_TIME,
0x30f4240);
/* used for 12G negotiate */
hisi_sas_phy_write32(hisi_hba, i, COARSETUNE_TIME, 0x1e);
hisi_sas_phy_write32(hisi_hba, i, AIP_LIMIT, 0x2ffff);
Expand Down Expand Up @@ -1344,7 +1350,8 @@ static void prep_abort_v3_hw(struct hisi_hba *hisi_hba,

static irqreturn_t phy_up_v3_hw(int phy_no, struct hisi_hba *hisi_hba)
{
int i, res;
int i;
irqreturn_t res;
u32 context, port_id, link_rate;
struct hisi_sas_phy *phy = &hisi_hba->phy[phy_no];
struct asd_sas_phy *sas_phy = &phy->sas_phy;
Expand Down Expand Up @@ -1575,13 +1582,49 @@ static void handle_chl_int1_v3_hw(struct hisi_hba *hisi_hba, int phy_no)
hisi_sas_phy_write32(hisi_hba, phy_no, CHL_INT1, irq_value);
}

static void phy_get_events_v3_hw(struct hisi_hba *hisi_hba, int phy_no)
{
struct hisi_sas_phy *phy = &hisi_hba->phy[phy_no];
struct asd_sas_phy *sas_phy = &phy->sas_phy;
struct sas_phy *sphy = sas_phy->phy;
unsigned long flags;
u32 reg_value;

spin_lock_irqsave(&phy->lock, flags);

/* loss dword sync */
reg_value = hisi_sas_phy_read32(hisi_hba, phy_no, ERR_CNT_DWS_LOST);
sphy->loss_of_dword_sync_count += reg_value;

/* phy reset problem */
reg_value = hisi_sas_phy_read32(hisi_hba, phy_no, ERR_CNT_RESET_PROB);
sphy->phy_reset_problem_count += reg_value;

/* invalid dword */
reg_value = hisi_sas_phy_read32(hisi_hba, phy_no, ERR_CNT_INVLD_DW);
sphy->invalid_dword_count += reg_value;

/* disparity err */
reg_value = hisi_sas_phy_read32(hisi_hba, phy_no, ERR_CNT_DISP_ERR);
sphy->running_disparity_error_count += reg_value;

/* code violation error */
reg_value = hisi_sas_phy_read32(hisi_hba, phy_no, ERR_CNT_CODE_ERR);
phy->code_violation_err_count += reg_value;

spin_unlock_irqrestore(&phy->lock, flags);
}

static void handle_chl_int2_v3_hw(struct hisi_hba *hisi_hba, int phy_no)
{
u32 irq_msk = hisi_sas_phy_read32(hisi_hba, phy_no, CHL_INT2_MSK);
u32 irq_value = hisi_sas_phy_read32(hisi_hba, phy_no, CHL_INT2);
struct hisi_sas_phy *phy = &hisi_hba->phy[phy_no];
struct pci_dev *pci_dev = hisi_hba->pci_dev;
struct device *dev = hisi_hba->dev;
static const u32 msk = BIT(CHL_INT2_RX_DISP_ERR_OFF) |
BIT(CHL_INT2_RX_CODE_ERR_OFF) |
BIT(CHL_INT2_RX_INVLD_DW_OFF);

irq_value &= ~irq_msk;
if (!irq_value)
Expand All @@ -1602,6 +1645,25 @@ static void handle_chl_int2_v3_hw(struct hisi_hba *hisi_hba, int phy_no)
hisi_sas_notify_phy_event(phy, HISI_PHYE_LINK_RESET);
}

if (pci_dev->revision > 0x20 && (irq_value & msk)) {
struct asd_sas_phy *sas_phy = &phy->sas_phy;
struct sas_phy *sphy = sas_phy->phy;

phy_get_events_v3_hw(hisi_hba, phy_no);

if (irq_value & BIT(CHL_INT2_RX_INVLD_DW_OFF))
dev_info(dev, "phy%d invalid dword cnt: %u\n", phy_no,
sphy->invalid_dword_count);

if (irq_value & BIT(CHL_INT2_RX_CODE_ERR_OFF))
dev_info(dev, "phy%d code violation cnt: %u\n", phy_no,
phy->code_violation_err_count);

if (irq_value & BIT(CHL_INT2_RX_DISP_ERR_OFF))
dev_info(dev, "phy%d disparity error cnt: %u\n", phy_no,
sphy->running_disparity_error_count);
}

if ((irq_value & BIT(CHL_INT2_RX_INVLD_DW_OFF)) &&
(pci_dev->revision == 0x20)) {
u32 reg_value;
Expand Down Expand Up @@ -2230,31 +2292,6 @@ static u32 get_phys_state_v3_hw(struct hisi_hba *hisi_hba)
return hisi_sas_read32(hisi_hba, PHY_STATE);
}

static void phy_get_events_v3_hw(struct hisi_hba *hisi_hba, int phy_no)
{
struct hisi_sas_phy *phy = &hisi_hba->phy[phy_no];
struct asd_sas_phy *sas_phy = &phy->sas_phy;
struct sas_phy *sphy = sas_phy->phy;
u32 reg_value;

/* loss dword sync */
reg_value = hisi_sas_phy_read32(hisi_hba, phy_no, ERR_CNT_DWS_LOST);
sphy->loss_of_dword_sync_count += reg_value;

/* phy reset problem */
reg_value = hisi_sas_phy_read32(hisi_hba, phy_no, ERR_CNT_RESET_PROB);
sphy->phy_reset_problem_count += reg_value;

/* invalid dword */
reg_value = hisi_sas_phy_read32(hisi_hba, phy_no, ERR_CNT_INVLD_DW);
sphy->invalid_dword_count += reg_value;

/* disparity err */
reg_value = hisi_sas_phy_read32(hisi_hba, phy_no, ERR_CNT_DISP_ERR);
sphy->running_disparity_error_count += reg_value;

}

static int disable_host_v3_hw(struct hisi_hba *hisi_hba)
{
struct device *dev = hisi_hba->dev;
Expand Down
Loading

0 comments on commit 477558d

Please sign in to comment.