Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 271049
b: refs/heads/master
c: ad4f4c1
h: refs/heads/master
i:
  271047: a6a21dc
v: v3
  • Loading branch information
Dan Williams authored and James Bottomley committed Sep 22, 2011
1 parent 09b1261 commit 31647ba
Show file tree
Hide file tree
Showing 4 changed files with 88 additions and 1 deletion.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 13257cfbc57e9cf84fd9fe0cb7a909b3fb4f7482
refs/heads/master: ad4f4c1de80abdda5d55315289505598aa78e355
69 changes: 69 additions & 0 deletions trunk/drivers/scsi/isci/host.c
Original file line number Diff line number Diff line change
Expand Up @@ -1263,6 +1263,10 @@ void isci_host_deinit(struct isci_host *ihost)
{
int i;

/* disable output data selects */
for (i = 0; i < isci_gpio_count(ihost); i++)
writel(SGPIO_HW_CONTROL, &ihost->scu_registers->peg0.sgpio.output_data_select[i]);

isci_host_change_state(ihost, isci_stopping);
for (i = 0; i < SCI_MAX_PORTS; i++) {
struct isci_port *iport = &ihost->ports[i];
Expand All @@ -1281,6 +1285,12 @@ void isci_host_deinit(struct isci_host *ihost)
spin_unlock_irq(&ihost->scic_lock);

wait_for_stop(ihost);

/* disable sgpio: where the above wait should give time for the
* enclosure to sample the gpios going inactive
*/
writel(0, &ihost->scu_registers->peg0.sgpio.interface_control);

sci_controller_reset(ihost);

/* Cancel any/all outstanding port timers */
Expand Down Expand Up @@ -2365,6 +2375,12 @@ int isci_host_init(struct isci_host *ihost)
for (i = 0; i < SCI_MAX_PHYS; i++)
isci_phy_init(&ihost->phys[i], ihost, i);

/* enable sgpio */
writel(1, &ihost->scu_registers->peg0.sgpio.interface_control);
for (i = 0; i < isci_gpio_count(ihost); i++)
writel(SGPIO_HW_CONTROL, &ihost->scu_registers->peg0.sgpio.output_data_select[i]);
writel(0, &ihost->scu_registers->peg0.sgpio.vendor_specific_code);

for (i = 0; i < SCI_MAX_REMOTE_DEVICES; i++) {
struct isci_remote_device *idev = &ihost->devices[i];

Expand Down Expand Up @@ -2760,3 +2776,56 @@ enum sci_task_status sci_controller_start_task(struct isci_host *ihost,

return status;
}

static int sci_write_gpio_tx_gp(struct isci_host *ihost, u8 reg_index, u8 reg_count, u8 *write_data)
{
int d;

/* no support for TX_GP_CFG */
if (reg_index == 0)
return -EINVAL;

for (d = 0; d < isci_gpio_count(ihost); d++) {
u32 val = 0x444; /* all ODx.n clear */
int i;

for (i = 0; i < 3; i++) {
int bit = (i << 2) + 2;

bit = try_test_sas_gpio_gp_bit(to_sas_gpio_od(d, i),
write_data, reg_index,
reg_count);
if (bit < 0)
break;

/* if od is set, clear the 'invert' bit */
val &= ~(bit << ((i << 2) + 2));
}

if (i < 3)
break;
writel(val, &ihost->scu_registers->peg0.sgpio.output_data_select[d]);
}

/* unless reg_index is > 1, we should always be able to write at
* least one register
*/
return d > 0;
}

int isci_gpio_write(struct sas_ha_struct *sas_ha, u8 reg_type, u8 reg_index,
u8 reg_count, u8 *write_data)
{
struct isci_host *ihost = sas_ha->lldd_ha;
int written;

switch (reg_type) {
case SAS_GPIO_REG_TX_GP:
written = sci_write_gpio_tx_gp(ihost, reg_index, reg_count, write_data);
break;
default:
written = -EINVAL;
}

return written;
}
15 changes: 15 additions & 0 deletions trunk/drivers/scsi/isci/host.h
Original file line number Diff line number Diff line change
Expand Up @@ -440,6 +440,18 @@ static inline bool is_c0(struct pci_dev *pdev)
return false;
}

/* set hw control for 'activity', even though active enclosures seem to drive
* the activity led on their own. Skip setting FSENG control on 'status' due
* to unexpected operation and 'error' due to not being a supported automatic
* FSENG output
*/
#define SGPIO_HW_CONTROL 0x00000443

static inline int isci_gpio_count(struct isci_host *ihost)
{
return ARRAY_SIZE(ihost->scu_registers->peg0.sgpio.output_data_select);
}

void sci_controller_post_request(struct isci_host *ihost,
u32 request);
void sci_controller_release_frame(struct isci_host *ihost,
Expand Down Expand Up @@ -542,4 +554,7 @@ void sci_port_configuration_agent_construct(
enum sci_status sci_port_configuration_agent_initialize(
struct isci_host *ihost,
struct sci_port_configuration_agent *port_agent);

int isci_gpio_write(struct sas_ha_struct *, u8 reg_type, u8 reg_index,
u8 reg_count, u8 *write_data);
#endif
3 changes: 3 additions & 0 deletions trunk/drivers/scsi/isci/init.c
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,9 @@ static struct sas_domain_function_template isci_transport_ops = {

/* Phy management */
.lldd_control_phy = isci_phy_control,

/* GPIO support */
.lldd_write_gpio = isci_gpio_write,
};


Expand Down

0 comments on commit 31647ba

Please sign in to comment.