Skip to content

Commit

Permalink
Merge git://bedivere.hansenpartnership.com/git/scsi-rc-fixes-2.6
Browse files Browse the repository at this point in the history
* git://bedivere.hansenpartnership.com/git/scsi-rc-fixes-2.6: (25 commits)
  [SCSI] bnx2i: Fixed the endian on TTT for NOP out transmission
  [SCSI] libfc: fix referencing to fc_fcp_pkt from the frame pointer via fr_fsp()
  [SCSI] libfc: block SCSI eh thread for blocked rports
  [SCSI] libfc: fix fc_eh_host_reset
  [SCSI] fcoe: Fix deadlock between fip's recv_work and rtnl
  [SCSI] qla2xxx: Update version number to 8.03.07.07-k.
  [SCSI] qla2xxx: Set the task attributes after memsetting fcp cmnd.
  [SCSI] qla2xxx: Correct inadvertent loop state transitions during port-update handling.
  [SCSI] qla2xxx: Save and restore irq in the response queue interrupt handler.
  [SCSI] qla2xxx: Double check for command completion if abort mailbox command fails.
  [SCSI] qla2xxx: Acquire hardware lock while manipulating dsd list.
  [SCSI] qla2xxx: Fix qla24xx revision check while enabling interrupts.
  [SCSI] qla2xxx: T10 DIF - Fix incorrect error reporting.
  [SCSI] qla2xxx: T10 DIF - Handle uninitalized sectors.
  [SCSI] hpsa: fix physical device lun and target numbering problem
  [SCSI] hpsa: fix problem that OBDR devices are not detected
  [SCSI] isci: add version number
  [SCSI] isci: fix event-get pointer increment
  [SCSI] isci: dynamic interrupt coalescing
  [SCSI] isci: Leave requests alone if already terminating.
  ...
  • Loading branch information
torvalds committed Sep 14, 2011
2 parents 53d872e + 610602f commit bcd438b
Show file tree
Hide file tree
Showing 28 changed files with 631 additions and 200 deletions.
13 changes: 13 additions & 0 deletions Documentation/ABI/testing/sysfs-class-scsi_host
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
What: /sys/class/scsi_host/hostX/isci_id
Date: June 2011
Contact: Dave Jiang <[email protected]>
Description:
This file contains the enumerated host ID for the Intel
SCU controller. The Intel(R) C600 Series Chipset SATA/SAS
Storage Control Unit embeds up to two 4-port controllers in
a single PCI device. The controllers are enumerated in order
which usually means the lowest number scsi_host corresponds
with the first controller, but this association is not
guaranteed. The 'isci_id' attribute unambiguously identifies
the controller index: '0' for the first controller,
'1' for the second.
11 changes: 11 additions & 0 deletions MAINTAINERS
Original file line number Diff line number Diff line change
Expand Up @@ -3262,6 +3262,17 @@ F: Documentation/input/multi-touch-protocol.txt
F: drivers/input/input-mt.c
K: \b(ABS|SYN)_MT_

INTEL C600 SERIES SAS CONTROLLER DRIVER
M: Intel SCU Linux support <[email protected]>
M: Dan Williams <[email protected]>
M: Dave Jiang <[email protected]>
M: Ed Nadolski <[email protected]>
L: [email protected]
T: git git://git.kernel.org/pub/scm/linux/kernel/git/djbw/isci.git
S: Maintained
F: drivers/scsi/isci/
F: firmware/isci/

INTEL IDLE DRIVER
M: Len Brown <[email protected]>
L: [email protected]
Expand Down
2 changes: 1 addition & 1 deletion drivers/scsi/bnx2i/bnx2i_hwi.c
Original file line number Diff line number Diff line change
Expand Up @@ -563,7 +563,7 @@ int bnx2i_send_iscsi_nopout(struct bnx2i_conn *bnx2i_conn,
nopout_wqe->itt = ((u16)task->itt |
(ISCSI_TASK_TYPE_MPATH <<
ISCSI_TMF_REQUEST_TYPE_SHIFT));
nopout_wqe->ttt = nopout_hdr->ttt;
nopout_wqe->ttt = be32_to_cpu(nopout_hdr->ttt);
nopout_wqe->flags = 0;
if (!unsol)
nopout_wqe->flags = ISCSI_NOP_OUT_REQUEST_LOCAL_COMPLETION;
Expand Down
13 changes: 8 additions & 5 deletions drivers/scsi/fcoe/fcoe.c
Original file line number Diff line number Diff line change
Expand Up @@ -432,6 +432,8 @@ void fcoe_interface_cleanup(struct fcoe_interface *fcoe)
u8 flogi_maddr[ETH_ALEN];
const struct net_device_ops *ops;

rtnl_lock();

/*
* Don't listen for Ethernet packets anymore.
* synchronize_net() ensures that the packet handlers are not running
Expand Down Expand Up @@ -461,6 +463,8 @@ void fcoe_interface_cleanup(struct fcoe_interface *fcoe)
" specific feature for LLD.\n");
}

rtnl_unlock();

/* Release the self-reference taken during fcoe_interface_create() */
fcoe_interface_put(fcoe);
}
Expand Down Expand Up @@ -1951,11 +1955,8 @@ static void fcoe_destroy_work(struct work_struct *work)
fcoe_if_destroy(port->lport);

/* Do not tear down the fcoe interface for NPIV port */
if (!npiv) {
rtnl_lock();
if (!npiv)
fcoe_interface_cleanup(fcoe);
rtnl_unlock();
}

mutex_unlock(&fcoe_config_mutex);
}
Expand Down Expand Up @@ -2009,8 +2010,9 @@ static int fcoe_create(struct net_device *netdev, enum fip_state fip_mode)
printk(KERN_ERR "fcoe: Failed to create interface (%s)\n",
netdev->name);
rc = -EIO;
rtnl_unlock();
fcoe_interface_cleanup(fcoe);
goto out_nodev;
goto out_nortnl;
}

/* Make this the "master" N_Port */
Expand All @@ -2027,6 +2029,7 @@ static int fcoe_create(struct net_device *netdev, enum fip_state fip_mode)

out_nodev:
rtnl_unlock();
out_nortnl:
mutex_unlock(&fcoe_config_mutex);
return rc;
}
Expand Down
57 changes: 37 additions & 20 deletions drivers/scsi/hpsa.c
Original file line number Diff line number Diff line change
Expand Up @@ -676,6 +676,16 @@ static void hpsa_scsi_replace_entry(struct ctlr_info *h, int hostno,
BUG_ON(entry < 0 || entry >= HPSA_MAX_SCSI_DEVS_PER_HBA);
removed[*nremoved] = h->dev[entry];
(*nremoved)++;

/*
* New physical devices won't have target/lun assigned yet
* so we need to preserve the values in the slot we are replacing.
*/
if (new_entry->target == -1) {
new_entry->target = h->dev[entry]->target;
new_entry->lun = h->dev[entry]->lun;
}

h->dev[entry] = new_entry;
added[*nadded] = new_entry;
(*nadded)++;
Expand Down Expand Up @@ -1548,10 +1558,17 @@ static inline void hpsa_set_bus_target_lun(struct hpsa_scsi_dev_t *device,
}

static int hpsa_update_device_info(struct ctlr_info *h,
unsigned char scsi3addr[], struct hpsa_scsi_dev_t *this_device)
unsigned char scsi3addr[], struct hpsa_scsi_dev_t *this_device,
unsigned char *is_OBDR_device)
{
#define OBDR_TAPE_INQ_SIZE 49

#define OBDR_SIG_OFFSET 43
#define OBDR_TAPE_SIG "$DR-10"
#define OBDR_SIG_LEN (sizeof(OBDR_TAPE_SIG) - 1)
#define OBDR_TAPE_INQ_SIZE (OBDR_SIG_OFFSET + OBDR_SIG_LEN)

unsigned char *inq_buff;
unsigned char *obdr_sig;

inq_buff = kzalloc(OBDR_TAPE_INQ_SIZE, GFP_KERNEL);
if (!inq_buff)
Expand Down Expand Up @@ -1583,6 +1600,16 @@ static int hpsa_update_device_info(struct ctlr_info *h,
else
this_device->raid_level = RAID_UNKNOWN;

if (is_OBDR_device) {
/* See if this is a One-Button-Disaster-Recovery device
* by looking for "$DR-10" at offset 43 in inquiry data.
*/
obdr_sig = &inq_buff[OBDR_SIG_OFFSET];
*is_OBDR_device = (this_device->devtype == TYPE_ROM &&
strncmp(obdr_sig, OBDR_TAPE_SIG,
OBDR_SIG_LEN) == 0);
}

kfree(inq_buff);
return 0;

Expand Down Expand Up @@ -1716,7 +1743,7 @@ static int add_msa2xxx_enclosure_device(struct ctlr_info *h,
return 0;
}

if (hpsa_update_device_info(h, scsi3addr, this_device))
if (hpsa_update_device_info(h, scsi3addr, this_device, NULL))
return 0;
(*nmsa2xxx_enclosures)++;
hpsa_set_bus_target_lun(this_device, bus, target, 0);
Expand Down Expand Up @@ -1808,7 +1835,6 @@ static void hpsa_update_scsi_devices(struct ctlr_info *h, int hostno)
*/
struct ReportLUNdata *physdev_list = NULL;
struct ReportLUNdata *logdev_list = NULL;
unsigned char *inq_buff = NULL;
u32 nphysicals = 0;
u32 nlogicals = 0;
u32 ndev_allocated = 0;
Expand All @@ -1824,11 +1850,9 @@ static void hpsa_update_scsi_devices(struct ctlr_info *h, int hostno)
GFP_KERNEL);
physdev_list = kzalloc(reportlunsize, GFP_KERNEL);
logdev_list = kzalloc(reportlunsize, GFP_KERNEL);
inq_buff = kmalloc(OBDR_TAPE_INQ_SIZE, GFP_KERNEL);
tmpdevice = kzalloc(sizeof(*tmpdevice), GFP_KERNEL);

if (!currentsd || !physdev_list || !logdev_list ||
!inq_buff || !tmpdevice) {
if (!currentsd || !physdev_list || !logdev_list || !tmpdevice) {
dev_err(&h->pdev->dev, "out of memory\n");
goto out;
}
Expand Down Expand Up @@ -1863,7 +1887,7 @@ static void hpsa_update_scsi_devices(struct ctlr_info *h, int hostno)
/* adjust our table of devices */
nmsa2xxx_enclosures = 0;
for (i = 0; i < nphysicals + nlogicals + 1; i++) {
u8 *lunaddrbytes;
u8 *lunaddrbytes, is_OBDR = 0;

/* Figure out where the LUN ID info is coming from */
lunaddrbytes = figure_lunaddrbytes(h, raid_ctlr_position,
Expand All @@ -1874,7 +1898,8 @@ static void hpsa_update_scsi_devices(struct ctlr_info *h, int hostno)
continue;

/* Get device type, vendor, model, device id */
if (hpsa_update_device_info(h, lunaddrbytes, tmpdevice))
if (hpsa_update_device_info(h, lunaddrbytes, tmpdevice,
&is_OBDR))
continue; /* skip it if we can't talk to it. */
figure_bus_target_lun(h, lunaddrbytes, &bus, &target, &lun,
tmpdevice);
Expand All @@ -1898,23 +1923,16 @@ static void hpsa_update_scsi_devices(struct ctlr_info *h, int hostno)
hpsa_set_bus_target_lun(this_device, bus, target, lun);

switch (this_device->devtype) {
case TYPE_ROM: {
case TYPE_ROM:
/* We don't *really* support actual CD-ROM devices,
* just "One Button Disaster Recovery" tape drive
* which temporarily pretends to be a CD-ROM drive.
* So we check that the device is really an OBDR tape
* device by checking for "$DR-10" in bytes 43-48 of
* the inquiry data.
*/
char obdr_sig[7];
#define OBDR_TAPE_SIG "$DR-10"
strncpy(obdr_sig, &inq_buff[43], 6);
obdr_sig[6] = '\0';
if (strncmp(obdr_sig, OBDR_TAPE_SIG, 6) != 0)
/* Not OBDR device, ignore it. */
break;
}
ncurrent++;
if (is_OBDR)
ncurrent++;
break;
case TYPE_DISK:
if (i < nphysicals)
Expand Down Expand Up @@ -1947,7 +1965,6 @@ static void hpsa_update_scsi_devices(struct ctlr_info *h, int hostno)
for (i = 0; i < ndev_allocated; i++)
kfree(currentsd[i]);
kfree(currentsd);
kfree(inq_buff);
kfree(physdev_list);
kfree(logdev_list);
}
Expand Down
13 changes: 12 additions & 1 deletion drivers/scsi/isci/host.c
Original file line number Diff line number Diff line change
Expand Up @@ -531,6 +531,9 @@ static void sci_controller_process_completions(struct isci_host *ihost)
break;

case SCU_COMPLETION_TYPE_EVENT:
sci_controller_event_completion(ihost, ent);
break;

case SCU_COMPLETION_TYPE_NOTIFY: {
event_cycle ^= ((event_get+1) & SCU_MAX_EVENTS) <<
(SMU_COMPLETION_QUEUE_GET_EVENT_CYCLE_BIT_SHIFT - SCU_MAX_EVENTS_SHIFT);
Expand Down Expand Up @@ -1091,6 +1094,7 @@ static void isci_host_completion_routine(unsigned long data)
struct isci_request *request;
struct isci_request *next_request;
struct sas_task *task;
u16 active;

INIT_LIST_HEAD(&completed_request_list);
INIT_LIST_HEAD(&errored_request_list);
Expand Down Expand Up @@ -1181,6 +1185,13 @@ static void isci_host_completion_routine(unsigned long data)
}
}

/* the coalesence timeout doubles at each encoding step, so
* update it based on the ilog2 value of the outstanding requests
*/
active = isci_tci_active(ihost);
writel(SMU_ICC_GEN_VAL(NUMBER, active) |
SMU_ICC_GEN_VAL(TIMER, ISCI_COALESCE_BASE + ilog2(active)),
&ihost->smu_registers->interrupt_coalesce_control);
}

/**
Expand Down Expand Up @@ -1471,7 +1482,7 @@ static void sci_controller_ready_state_enter(struct sci_base_state_machine *sm)
struct isci_host *ihost = container_of(sm, typeof(*ihost), sm);

/* set the default interrupt coalescence number and timeout value. */
sci_controller_set_interrupt_coalescence(ihost, 0x10, 250);
sci_controller_set_interrupt_coalescence(ihost, 0, 0);
}

static void sci_controller_ready_state_exit(struct sci_base_state_machine *sm)
Expand Down
3 changes: 3 additions & 0 deletions drivers/scsi/isci/host.h
Original file line number Diff line number Diff line change
Expand Up @@ -369,6 +369,9 @@ static inline struct isci_host *dev_to_ihost(struct domain_device *dev)
#define ISCI_TAG_SEQ(tag) (((tag) >> 12) & (SCI_MAX_SEQ-1))
#define ISCI_TAG_TCI(tag) ((tag) & (SCI_MAX_IO_REQUESTS-1))

/* interrupt coalescing baseline: 9 == 3 to 5us interrupt delay per command */
#define ISCI_COALESCE_BASE 9

/* expander attached sata devices require 3 rnc slots */
static inline int sci_remote_device_node_count(struct isci_remote_device *idev)
{
Expand Down
47 changes: 28 additions & 19 deletions drivers/scsi/isci/init.c
Original file line number Diff line number Diff line change
Expand Up @@ -59,10 +59,19 @@
#include <linux/firmware.h>
#include <linux/efi.h>
#include <asm/string.h>
#include <scsi/scsi_host.h>
#include "isci.h"
#include "task.h"
#include "probe_roms.h"

#define MAJ 1
#define MIN 0
#define BUILD 0
#define DRV_VERSION __stringify(MAJ) "." __stringify(MIN) "." \
__stringify(BUILD)

MODULE_VERSION(DRV_VERSION);

static struct scsi_transport_template *isci_transport_template;

static DEFINE_PCI_DEVICE_TABLE(isci_id_table) = {
Expand Down Expand Up @@ -113,6 +122,22 @@ unsigned char max_concurr_spinup = 1;
module_param(max_concurr_spinup, byte, 0);
MODULE_PARM_DESC(max_concurr_spinup, "Max concurrent device spinup");

static ssize_t isci_show_id(struct device *dev, struct device_attribute *attr, char *buf)
{
struct Scsi_Host *shost = container_of(dev, typeof(*shost), shost_dev);
struct sas_ha_struct *sas_ha = SHOST_TO_SAS_HA(shost);
struct isci_host *ihost = container_of(sas_ha, typeof(*ihost), sas_ha);

return snprintf(buf, PAGE_SIZE, "%d\n", ihost->id);
}

static DEVICE_ATTR(isci_id, S_IRUGO, isci_show_id, NULL);

struct device_attribute *isci_host_attrs[] = {
&dev_attr_isci_id,
NULL
};

static struct scsi_host_template isci_sht = {

.module = THIS_MODULE,
Expand All @@ -138,6 +163,7 @@ static struct scsi_host_template isci_sht = {
.slave_alloc = sas_slave_alloc,
.target_destroy = sas_target_destroy,
.ioctl = sas_ioctl,
.shost_attrs = isci_host_attrs,
};

static struct sas_domain_function_template isci_transport_ops = {
Expand Down Expand Up @@ -232,17 +258,6 @@ static int isci_register_sas_ha(struct isci_host *isci_host)
return 0;
}

static ssize_t isci_show_id(struct device *dev, struct device_attribute *attr, char *buf)
{
struct Scsi_Host *shost = container_of(dev, typeof(*shost), shost_dev);
struct sas_ha_struct *sas_ha = SHOST_TO_SAS_HA(shost);
struct isci_host *ihost = container_of(sas_ha, typeof(*ihost), sas_ha);

return snprintf(buf, PAGE_SIZE, "%d\n", ihost->id);
}

static DEVICE_ATTR(isci_id, S_IRUGO, isci_show_id, NULL);

static void isci_unregister(struct isci_host *isci_host)
{
struct Scsi_Host *shost;
Expand All @@ -251,7 +266,6 @@ static void isci_unregister(struct isci_host *isci_host)
return;

shost = isci_host->shost;
device_remove_file(&shost->shost_dev, &dev_attr_isci_id);

sas_unregister_ha(&isci_host->sas_ha);

Expand Down Expand Up @@ -415,14 +429,8 @@ static struct isci_host *isci_host_alloc(struct pci_dev *pdev, int id)
if (err)
goto err_shost_remove;

err = device_create_file(&shost->shost_dev, &dev_attr_isci_id);
if (err)
goto err_unregister_ha;

return isci_host;

err_unregister_ha:
sas_unregister_ha(&(isci_host->sas_ha));
err_shost_remove:
scsi_remove_host(shost);
err_shost:
Expand Down Expand Up @@ -540,7 +548,8 @@ static __init int isci_init(void)
{
int err;

pr_info("%s: Intel(R) C600 SAS Controller Driver\n", DRV_NAME);
pr_info("%s: Intel(R) C600 SAS Controller Driver - version %s\n",
DRV_NAME, DRV_VERSION);

isci_transport_template = sas_domain_attach_transport(&isci_transport_ops);
if (!isci_transport_template)
Expand Down
Loading

0 comments on commit bcd438b

Please sign in to comment.