Merge branch 'master' into for-next
Fast-forward merge with Linus to be able to merge patches based on more recent version of the tree.
Esse commit está contido em:
@@ -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);
|
||||
@@ -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);
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -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)
|
||||
|
@@ -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)
|
||||
{
|
||||
|
@@ -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) = {
|
||||
@@ -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,
|
||||
@@ -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 = {
|
||||
@@ -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;
|
||||
@@ -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);
|
||||
|
||||
@@ -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:
|
||||
@@ -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)
|
||||
|
@@ -104,6 +104,7 @@ sci_phy_link_layer_initialization(struct isci_phy *iphy,
|
||||
u32 parity_count = 0;
|
||||
u32 llctl, link_rate;
|
||||
u32 clksm_value = 0;
|
||||
u32 sp_timeouts = 0;
|
||||
|
||||
iphy->link_layer_registers = reg;
|
||||
|
||||
@@ -211,6 +212,18 @@ sci_phy_link_layer_initialization(struct isci_phy *iphy,
|
||||
llctl |= SCU_SAS_LLCTL_GEN_VAL(MAX_LINK_RATE, link_rate);
|
||||
writel(llctl, &iphy->link_layer_registers->link_layer_control);
|
||||
|
||||
sp_timeouts = readl(&iphy->link_layer_registers->sas_phy_timeouts);
|
||||
|
||||
/* Clear the default 0x36 (54us) RATE_CHANGE timeout value. */
|
||||
sp_timeouts &= ~SCU_SAS_PHYTOV_GEN_VAL(RATE_CHANGE, 0xFF);
|
||||
|
||||
/* Set RATE_CHANGE timeout value to 0x3B (59us). This ensures SCU can
|
||||
* lock with 3Gb drive when SCU max rate is set to 1.5Gb.
|
||||
*/
|
||||
sp_timeouts |= SCU_SAS_PHYTOV_GEN_VAL(RATE_CHANGE, 0x3B);
|
||||
|
||||
writel(sp_timeouts, &iphy->link_layer_registers->sas_phy_timeouts);
|
||||
|
||||
if (is_a2(ihost->pdev)) {
|
||||
/* Program the max ARB time for the PHY to 700us so we inter-operate with
|
||||
* the PMC expander which shuts down PHYs if the expander PHY generates too
|
||||
|
@@ -1299,6 +1299,18 @@ struct scu_transport_layer_registers {
|
||||
#define SCU_AFE_XCVRCR_OFFSET 0x00DC
|
||||
#define SCU_AFE_LUTCR_OFFSET 0x00E0
|
||||
|
||||
#define SCU_SAS_PHY_TIMER_TIMEOUT_VALUES_ALIGN_DETECTION_SHIFT (0UL)
|
||||
#define SCU_SAS_PHY_TIMER_TIMEOUT_VALUES_ALIGN_DETECTION_MASK (0x000000FFUL)
|
||||
#define SCU_SAS_PHY_TIMER_TIMEOUT_VALUES_HOT_PLUG_SHIFT (8UL)
|
||||
#define SCU_SAS_PHY_TIMER_TIMEOUT_VALUES_HOT_PLUG_MASK (0x0000FF00UL)
|
||||
#define SCU_SAS_PHY_TIMER_TIMEOUT_VALUES_COMSAS_DETECTION_SHIFT (16UL)
|
||||
#define SCU_SAS_PHY_TIMER_TIMEOUT_VALUES_COMSAS_DETECTION_MASK (0x00FF0000UL)
|
||||
#define SCU_SAS_PHY_TIMER_TIMEOUT_VALUES_RATE_CHANGE_SHIFT (24UL)
|
||||
#define SCU_SAS_PHY_TIMER_TIMEOUT_VALUES_RATE_CHANGE_MASK (0xFF000000UL)
|
||||
|
||||
#define SCU_SAS_PHYTOV_GEN_VAL(name, value) \
|
||||
SCU_GEN_VALUE(SCU_SAS_PHY_TIMER_TIMEOUT_VALUES_##name, value)
|
||||
|
||||
#define SCU_SAS_LINK_LAYER_CONTROL_MAX_LINK_RATE_SHIFT (0)
|
||||
#define SCU_SAS_LINK_LAYER_CONTROL_MAX_LINK_RATE_MASK (0x00000003)
|
||||
#define SCU_SAS_LINK_LAYER_CONTROL_MAX_LINK_RATE_GEN1 (0)
|
||||
|
@@ -732,12 +732,20 @@ sci_io_request_terminate(struct isci_request *ireq)
|
||||
sci_change_state(&ireq->sm, SCI_REQ_ABORTING);
|
||||
return SCI_SUCCESS;
|
||||
case SCI_REQ_TASK_WAIT_TC_RESP:
|
||||
/* The task frame was already confirmed to have been
|
||||
* sent by the SCU HW. Since the state machine is
|
||||
* now only waiting for the task response itself,
|
||||
* abort the request and complete it immediately
|
||||
* and don't wait for the task response.
|
||||
*/
|
||||
sci_change_state(&ireq->sm, SCI_REQ_ABORTING);
|
||||
sci_change_state(&ireq->sm, SCI_REQ_COMPLETED);
|
||||
return SCI_SUCCESS;
|
||||
case SCI_REQ_ABORTING:
|
||||
sci_change_state(&ireq->sm, SCI_REQ_COMPLETED);
|
||||
return SCI_SUCCESS;
|
||||
/* If a request has a termination requested twice, return
|
||||
* a failure indication, since HW confirmation of the first
|
||||
* abort is still outstanding.
|
||||
*/
|
||||
case SCI_REQ_COMPLETED:
|
||||
default:
|
||||
dev_warn(&ireq->owning_controller->pdev->dev,
|
||||
@@ -2399,22 +2407,19 @@ static void isci_task_save_for_upper_layer_completion(
|
||||
}
|
||||
}
|
||||
|
||||
static void isci_request_process_stp_response(struct sas_task *task,
|
||||
void *response_buffer)
|
||||
static void isci_process_stp_response(struct sas_task *task, struct dev_to_host_fis *fis)
|
||||
{
|
||||
struct dev_to_host_fis *d2h_reg_fis = response_buffer;
|
||||
struct task_status_struct *ts = &task->task_status;
|
||||
struct ata_task_resp *resp = (void *)&ts->buf[0];
|
||||
|
||||
resp->frame_len = le16_to_cpu(*(__le16 *)(response_buffer + 6));
|
||||
memcpy(&resp->ending_fis[0], response_buffer + 16, 24);
|
||||
resp->frame_len = sizeof(*fis);
|
||||
memcpy(resp->ending_fis, fis, sizeof(*fis));
|
||||
ts->buf_valid_size = sizeof(*resp);
|
||||
|
||||
/**
|
||||
* If the device fault bit is set in the status register, then
|
||||
/* If the device fault bit is set in the status register, then
|
||||
* set the sense data and return.
|
||||
*/
|
||||
if (d2h_reg_fis->status & ATA_DF)
|
||||
if (fis->status & ATA_DF)
|
||||
ts->stat = SAS_PROTO_RESPONSE;
|
||||
else
|
||||
ts->stat = SAM_STAT_GOOD;
|
||||
@@ -2428,7 +2433,6 @@ static void isci_request_io_request_complete(struct isci_host *ihost,
|
||||
{
|
||||
struct sas_task *task = isci_request_access_task(request);
|
||||
struct ssp_response_iu *resp_iu;
|
||||
void *resp_buf;
|
||||
unsigned long task_flags;
|
||||
struct isci_remote_device *idev = isci_lookup_device(task->dev);
|
||||
enum service_response response = SAS_TASK_UNDELIVERED;
|
||||
@@ -2565,9 +2569,7 @@ static void isci_request_io_request_complete(struct isci_host *ihost,
|
||||
task);
|
||||
|
||||
if (sas_protocol_ata(task->task_proto)) {
|
||||
resp_buf = &request->stp.rsp;
|
||||
isci_request_process_stp_response(task,
|
||||
resp_buf);
|
||||
isci_process_stp_response(task, &request->stp.rsp);
|
||||
} else if (SAS_PROTOCOL_SSP == task->task_proto) {
|
||||
|
||||
/* crack the iu response buffer. */
|
||||
|
@@ -72,7 +72,7 @@ int sci_unsolicited_frame_control_construct(struct isci_host *ihost)
|
||||
*/
|
||||
buf_len = SCU_MAX_UNSOLICITED_FRAMES * SCU_UNSOLICITED_FRAME_BUFFER_SIZE;
|
||||
header_len = SCU_MAX_UNSOLICITED_FRAMES * sizeof(struct scu_unsolicited_frame_header);
|
||||
size = buf_len + header_len + SCU_MAX_UNSOLICITED_FRAMES * sizeof(dma_addr_t);
|
||||
size = buf_len + header_len + SCU_MAX_UNSOLICITED_FRAMES * sizeof(uf_control->address_table.array[0]);
|
||||
|
||||
/*
|
||||
* The Unsolicited Frame buffers are set at the start of the UF
|
||||
|
@@ -214,7 +214,7 @@ struct sci_uf_address_table_array {
|
||||
* starting address of the UF address table.
|
||||
* 64-bit pointers are required by the hardware.
|
||||
*/
|
||||
dma_addr_t *array;
|
||||
u64 *array;
|
||||
|
||||
/**
|
||||
* This field specifies the physical address location for the UF
|
||||
|
Referência em uma nova issue
Block a user