mtip32xx: ensure that all local functions are static
Kill the declarations in the header file and mark them as static. Reshuffle a few functions to ensure that everything is properly declared before being used. Signed-off-by: Jens Axboe <axboe@kernel.dk>
This commit is contained in:
parent
ef0f158734
commit
6316668fbc
@ -107,6 +107,72 @@ static int mtip_exec_internal_command(struct mtip_port *port,
|
|||||||
gfp_t atomic,
|
gfp_t atomic,
|
||||||
unsigned long timeout);
|
unsigned long timeout);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This function check_for_surprise_removal is called
|
||||||
|
* while card is removed from the system and it will
|
||||||
|
* read the vendor id from the configration space
|
||||||
|
*
|
||||||
|
* @pdev Pointer to the pci_dev structure.
|
||||||
|
*
|
||||||
|
* return value
|
||||||
|
* true if device removed, else false
|
||||||
|
*/
|
||||||
|
static bool mtip_check_surprise_removal(struct pci_dev *pdev)
|
||||||
|
{
|
||||||
|
u16 vendor_id = 0;
|
||||||
|
|
||||||
|
/* Read the vendorID from the configuration space */
|
||||||
|
pci_read_config_word(pdev, 0x00, &vendor_id);
|
||||||
|
if (vendor_id == 0xFFFF)
|
||||||
|
return true; /* device removed */
|
||||||
|
|
||||||
|
return false; /* device present */
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This function is called for clean the pending command in the
|
||||||
|
* command slot during the surprise removal of device and return
|
||||||
|
* error to the upper layer.
|
||||||
|
*
|
||||||
|
* @dd Pointer to the DRIVER_DATA structure.
|
||||||
|
*
|
||||||
|
* return value
|
||||||
|
* None
|
||||||
|
*/
|
||||||
|
static void mtip_command_cleanup(struct driver_data *dd)
|
||||||
|
{
|
||||||
|
int group = 0, commandslot = 0, commandindex = 0;
|
||||||
|
struct mtip_cmd *command;
|
||||||
|
struct mtip_port *port = dd->port;
|
||||||
|
|
||||||
|
for (group = 0; group < 4; group++) {
|
||||||
|
for (commandslot = 0; commandslot < 32; commandslot++) {
|
||||||
|
if (!(port->allocated[group] & (1 << commandslot)))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
commandindex = group << 5 | commandslot;
|
||||||
|
command = &port->commands[commandindex];
|
||||||
|
|
||||||
|
if (atomic_read(&command->active)
|
||||||
|
&& (command->async_callback)) {
|
||||||
|
command->async_callback(command->async_data,
|
||||||
|
-ENODEV);
|
||||||
|
command->async_callback = NULL;
|
||||||
|
command->async_data = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
dma_unmap_sg(&port->dd->pdev->dev,
|
||||||
|
command->sg,
|
||||||
|
command->scatter_ents,
|
||||||
|
command->direction);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
up(&port->cmd_slot);
|
||||||
|
|
||||||
|
atomic_set(&dd->drv_cleanup_done, true);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Obtain an empty command slot.
|
* Obtain an empty command slot.
|
||||||
*
|
*
|
||||||
@ -166,6 +232,47 @@ static inline void release_slot(struct mtip_port *port, int tag)
|
|||||||
smp_mb__after_clear_bit();
|
smp_mb__after_clear_bit();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Reset the HBA (without sleeping)
|
||||||
|
*
|
||||||
|
* Just like hba_reset, except does not call sleep, so can be
|
||||||
|
* run from interrupt/tasklet context.
|
||||||
|
*
|
||||||
|
* @dd Pointer to the driver data structure.
|
||||||
|
*
|
||||||
|
* return value
|
||||||
|
* 0 The reset was successful.
|
||||||
|
* -1 The HBA Reset bit did not clear.
|
||||||
|
*/
|
||||||
|
static int hba_reset_nosleep(struct driver_data *dd)
|
||||||
|
{
|
||||||
|
unsigned long timeout;
|
||||||
|
|
||||||
|
/* Chip quirk: quiesce any chip function */
|
||||||
|
mdelay(10);
|
||||||
|
|
||||||
|
/* Set the reset bit */
|
||||||
|
writel(HOST_RESET, dd->mmio + HOST_CTL);
|
||||||
|
|
||||||
|
/* Flush */
|
||||||
|
readl(dd->mmio + HOST_CTL);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Wait 10ms then spin for up to 1 second
|
||||||
|
* waiting for reset acknowledgement
|
||||||
|
*/
|
||||||
|
timeout = jiffies + msecs_to_jiffies(1000);
|
||||||
|
mdelay(10);
|
||||||
|
while ((readl(dd->mmio + HOST_CTL) & HOST_RESET)
|
||||||
|
&& time_before(jiffies, timeout))
|
||||||
|
mdelay(1);
|
||||||
|
|
||||||
|
if (readl(dd->mmio + HOST_CTL) & HOST_RESET)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Issue a command to the hardware.
|
* Issue a command to the hardware.
|
||||||
*
|
*
|
||||||
@ -194,6 +301,207 @@ static inline void mtip_issue_ncq_command(struct mtip_port *port, int tag)
|
|||||||
spin_unlock_irqrestore(&port->cmd_issue_lock, flags);
|
spin_unlock_irqrestore(&port->cmd_issue_lock, flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Enable/disable the reception of FIS
|
||||||
|
*
|
||||||
|
* @port Pointer to the port data structure
|
||||||
|
* @enable 1 to enable, 0 to disable
|
||||||
|
*
|
||||||
|
* return value
|
||||||
|
* Previous state: 1 enabled, 0 disabled
|
||||||
|
*/
|
||||||
|
static int mtip_enable_fis(struct mtip_port *port, int enable)
|
||||||
|
{
|
||||||
|
u32 tmp;
|
||||||
|
|
||||||
|
/* enable FIS reception */
|
||||||
|
tmp = readl(port->mmio + PORT_CMD);
|
||||||
|
if (enable)
|
||||||
|
writel(tmp | PORT_CMD_FIS_RX, port->mmio + PORT_CMD);
|
||||||
|
else
|
||||||
|
writel(tmp & ~PORT_CMD_FIS_RX, port->mmio + PORT_CMD);
|
||||||
|
|
||||||
|
/* Flush */
|
||||||
|
readl(port->mmio + PORT_CMD);
|
||||||
|
|
||||||
|
return (((tmp & PORT_CMD_FIS_RX) == PORT_CMD_FIS_RX));
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Enable/disable the DMA engine
|
||||||
|
*
|
||||||
|
* @port Pointer to the port data structure
|
||||||
|
* @enable 1 to enable, 0 to disable
|
||||||
|
*
|
||||||
|
* return value
|
||||||
|
* Previous state: 1 enabled, 0 disabled.
|
||||||
|
*/
|
||||||
|
static int mtip_enable_engine(struct mtip_port *port, int enable)
|
||||||
|
{
|
||||||
|
u32 tmp;
|
||||||
|
|
||||||
|
/* enable FIS reception */
|
||||||
|
tmp = readl(port->mmio + PORT_CMD);
|
||||||
|
if (enable)
|
||||||
|
writel(tmp | PORT_CMD_START, port->mmio + PORT_CMD);
|
||||||
|
else
|
||||||
|
writel(tmp & ~PORT_CMD_START, port->mmio + PORT_CMD);
|
||||||
|
|
||||||
|
readl(port->mmio + PORT_CMD);
|
||||||
|
return (((tmp & PORT_CMD_START) == PORT_CMD_START));
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Enables the port DMA engine and FIS reception.
|
||||||
|
*
|
||||||
|
* return value
|
||||||
|
* None
|
||||||
|
*/
|
||||||
|
static inline void mtip_start_port(struct mtip_port *port)
|
||||||
|
{
|
||||||
|
/* Enable FIS reception */
|
||||||
|
mtip_enable_fis(port, 1);
|
||||||
|
|
||||||
|
/* Enable the DMA engine */
|
||||||
|
mtip_enable_engine(port, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Deinitialize a port by disabling port interrupts, the DMA engine,
|
||||||
|
* and FIS reception.
|
||||||
|
*
|
||||||
|
* @port Pointer to the port structure
|
||||||
|
*
|
||||||
|
* return value
|
||||||
|
* None
|
||||||
|
*/
|
||||||
|
static inline void mtip_deinit_port(struct mtip_port *port)
|
||||||
|
{
|
||||||
|
/* Disable interrupts on this port */
|
||||||
|
writel(0, port->mmio + PORT_IRQ_MASK);
|
||||||
|
|
||||||
|
/* Disable the DMA engine */
|
||||||
|
mtip_enable_engine(port, 0);
|
||||||
|
|
||||||
|
/* Disable FIS reception */
|
||||||
|
mtip_enable_fis(port, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Initialize a port.
|
||||||
|
*
|
||||||
|
* This function deinitializes the port by calling mtip_deinit_port() and
|
||||||
|
* then initializes it by setting the command header and RX FIS addresses,
|
||||||
|
* clearing the SError register and any pending port interrupts before
|
||||||
|
* re-enabling the default set of port interrupts.
|
||||||
|
*
|
||||||
|
* @port Pointer to the port structure.
|
||||||
|
*
|
||||||
|
* return value
|
||||||
|
* None
|
||||||
|
*/
|
||||||
|
static void mtip_init_port(struct mtip_port *port)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
mtip_deinit_port(port);
|
||||||
|
|
||||||
|
/* Program the command list base and FIS base addresses */
|
||||||
|
if (readl(port->dd->mmio + HOST_CAP) & HOST_CAP_64) {
|
||||||
|
writel((port->command_list_dma >> 16) >> 16,
|
||||||
|
port->mmio + PORT_LST_ADDR_HI);
|
||||||
|
writel((port->rxfis_dma >> 16) >> 16,
|
||||||
|
port->mmio + PORT_FIS_ADDR_HI);
|
||||||
|
}
|
||||||
|
|
||||||
|
writel(port->command_list_dma & 0xffffffff,
|
||||||
|
port->mmio + PORT_LST_ADDR);
|
||||||
|
writel(port->rxfis_dma & 0xffffffff, port->mmio + PORT_FIS_ADDR);
|
||||||
|
|
||||||
|
/* Clear SError */
|
||||||
|
writel(readl(port->mmio + PORT_SCR_ERR), port->mmio + PORT_SCR_ERR);
|
||||||
|
|
||||||
|
/* reset the completed registers.*/
|
||||||
|
for (i = 0; i < port->dd->slot_groups; i++)
|
||||||
|
writel(0xFFFFFFFF, port->completed[i]);
|
||||||
|
|
||||||
|
/* Clear any pending interrupts for this port */
|
||||||
|
writel(readl(port->mmio + PORT_IRQ_STAT), port->mmio + PORT_IRQ_STAT);
|
||||||
|
|
||||||
|
/* Enable port interrupts */
|
||||||
|
writel(DEF_PORT_IRQ, port->mmio + PORT_IRQ_MASK);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Restart a port
|
||||||
|
*
|
||||||
|
* @port Pointer to the port data structure.
|
||||||
|
*
|
||||||
|
* return value
|
||||||
|
* None
|
||||||
|
*/
|
||||||
|
static void mtip_restart_port(struct mtip_port *port)
|
||||||
|
{
|
||||||
|
unsigned long timeout;
|
||||||
|
|
||||||
|
/* Disable the DMA engine */
|
||||||
|
mtip_enable_engine(port, 0);
|
||||||
|
|
||||||
|
/* Chip quirk: wait up to 500ms for PxCMD.CR == 0 */
|
||||||
|
timeout = jiffies + msecs_to_jiffies(500);
|
||||||
|
while ((readl(port->mmio + PORT_CMD) & PORT_CMD_LIST_ON)
|
||||||
|
&& time_before(jiffies, timeout))
|
||||||
|
;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Chip quirk: escalate to hba reset if
|
||||||
|
* PxCMD.CR not clear after 500 ms
|
||||||
|
*/
|
||||||
|
if (readl(port->mmio + PORT_CMD) & PORT_CMD_LIST_ON) {
|
||||||
|
dev_warn(&port->dd->pdev->dev,
|
||||||
|
"PxCMD.CR not clear, escalating reset\n");
|
||||||
|
|
||||||
|
if (hba_reset_nosleep(port->dd))
|
||||||
|
dev_err(&port->dd->pdev->dev,
|
||||||
|
"HBA reset escalation failed.\n");
|
||||||
|
|
||||||
|
/* 30 ms delay before com reset to quiesce chip */
|
||||||
|
mdelay(30);
|
||||||
|
}
|
||||||
|
|
||||||
|
dev_warn(&port->dd->pdev->dev, "Issuing COM reset\n");
|
||||||
|
|
||||||
|
/* Set PxSCTL.DET */
|
||||||
|
writel(readl(port->mmio + PORT_SCR_CTL) |
|
||||||
|
1, port->mmio + PORT_SCR_CTL);
|
||||||
|
readl(port->mmio + PORT_SCR_CTL);
|
||||||
|
|
||||||
|
/* Wait 1 ms to quiesce chip function */
|
||||||
|
timeout = jiffies + msecs_to_jiffies(1);
|
||||||
|
while (time_before(jiffies, timeout))
|
||||||
|
;
|
||||||
|
|
||||||
|
/* Clear PxSCTL.DET */
|
||||||
|
writel(readl(port->mmio + PORT_SCR_CTL) & ~1,
|
||||||
|
port->mmio + PORT_SCR_CTL);
|
||||||
|
readl(port->mmio + PORT_SCR_CTL);
|
||||||
|
|
||||||
|
/* Wait 500 ms for bit 0 of PORT_SCR_STS to be set */
|
||||||
|
timeout = jiffies + msecs_to_jiffies(500);
|
||||||
|
while (((readl(port->mmio + PORT_SCR_STAT) & 0x01) == 0)
|
||||||
|
&& time_before(jiffies, timeout))
|
||||||
|
;
|
||||||
|
|
||||||
|
if ((readl(port->mmio + PORT_SCR_STAT) & 0x01) == 0)
|
||||||
|
dev_warn(&port->dd->pdev->dev,
|
||||||
|
"COM reset failed\n");
|
||||||
|
|
||||||
|
/* Clear SError, the PxSERR.DIAG.x should be set so clear it */
|
||||||
|
writel(readl(port->mmio + PORT_SCR_ERR), port->mmio + PORT_SCR_ERR);
|
||||||
|
|
||||||
|
/* Enable the DMA engine */
|
||||||
|
mtip_enable_engine(port, 1);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Called periodically to see if any read/write commands are
|
* Called periodically to see if any read/write commands are
|
||||||
* taking too long to complete.
|
* taking too long to complete.
|
||||||
@ -203,7 +511,7 @@ static inline void mtip_issue_ncq_command(struct mtip_port *port, int tag)
|
|||||||
* return value
|
* return value
|
||||||
* None
|
* None
|
||||||
*/
|
*/
|
||||||
void mtip_timeout_function(unsigned long int data)
|
static void mtip_timeout_function(unsigned long int data)
|
||||||
{
|
{
|
||||||
struct mtip_port *port = (struct mtip_port *) data;
|
struct mtip_port *port = (struct mtip_port *) data;
|
||||||
struct host_to_dev_fis *fis;
|
struct host_to_dev_fis *fis;
|
||||||
@ -377,248 +685,6 @@ static void mtip_completion(struct mtip_port *port,
|
|||||||
complete(waiting);
|
complete(waiting);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* Enable/disable the reception of FIS
|
|
||||||
*
|
|
||||||
* @port Pointer to the port data structure
|
|
||||||
* @enable 1 to enable, 0 to disable
|
|
||||||
*
|
|
||||||
* return value
|
|
||||||
* Previous state: 1 enabled, 0 disabled
|
|
||||||
*/
|
|
||||||
static int mtip_enable_fis(struct mtip_port *port, int enable)
|
|
||||||
{
|
|
||||||
u32 tmp;
|
|
||||||
|
|
||||||
/* enable FIS reception */
|
|
||||||
tmp = readl(port->mmio + PORT_CMD);
|
|
||||||
if (enable)
|
|
||||||
writel(tmp | PORT_CMD_FIS_RX, port->mmio + PORT_CMD);
|
|
||||||
else
|
|
||||||
writel(tmp & ~PORT_CMD_FIS_RX, port->mmio + PORT_CMD);
|
|
||||||
|
|
||||||
/* Flush */
|
|
||||||
readl(port->mmio + PORT_CMD);
|
|
||||||
|
|
||||||
return (((tmp & PORT_CMD_FIS_RX) == PORT_CMD_FIS_RX));
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Enable/disable the DMA engine
|
|
||||||
*
|
|
||||||
* @port Pointer to the port data structure
|
|
||||||
* @enable 1 to enable, 0 to disable
|
|
||||||
*
|
|
||||||
* return value
|
|
||||||
* Previous state: 1 enabled, 0 disabled.
|
|
||||||
*/
|
|
||||||
static int mtip_enable_engine(struct mtip_port *port, int enable)
|
|
||||||
{
|
|
||||||
u32 tmp;
|
|
||||||
|
|
||||||
/* enable FIS reception */
|
|
||||||
tmp = readl(port->mmio + PORT_CMD);
|
|
||||||
if (enable)
|
|
||||||
writel(tmp | PORT_CMD_START, port->mmio + PORT_CMD);
|
|
||||||
else
|
|
||||||
writel(tmp & ~PORT_CMD_START, port->mmio + PORT_CMD);
|
|
||||||
|
|
||||||
readl(port->mmio + PORT_CMD);
|
|
||||||
return (((tmp & PORT_CMD_START) == PORT_CMD_START));
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Enables the port DMA engine and FIS reception.
|
|
||||||
*
|
|
||||||
* return value
|
|
||||||
* None
|
|
||||||
*/
|
|
||||||
static inline void mtip_start_port(struct mtip_port *port)
|
|
||||||
{
|
|
||||||
/* Enable FIS reception */
|
|
||||||
mtip_enable_fis(port, 1);
|
|
||||||
|
|
||||||
/* Enable the DMA engine */
|
|
||||||
mtip_enable_engine(port, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Deinitialize a port by disabling port interrupts, the DMA engine,
|
|
||||||
* and FIS reception.
|
|
||||||
*
|
|
||||||
* @port Pointer to the port structure
|
|
||||||
*
|
|
||||||
* return value
|
|
||||||
* None
|
|
||||||
*/
|
|
||||||
static inline void mtip_deinit_port(struct mtip_port *port)
|
|
||||||
{
|
|
||||||
/* Disable interrupts on this port */
|
|
||||||
writel(0, port->mmio + PORT_IRQ_MASK);
|
|
||||||
|
|
||||||
/* Disable the DMA engine */
|
|
||||||
mtip_enable_engine(port, 0);
|
|
||||||
|
|
||||||
/* Disable FIS reception */
|
|
||||||
mtip_enable_fis(port, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Initialize a port.
|
|
||||||
*
|
|
||||||
* This function deinitializes the port by calling mtip_deinit_port() and
|
|
||||||
* then initializes it by setting the command header and RX FIS addresses,
|
|
||||||
* clearing the SError register and any pending port interrupts before
|
|
||||||
* re-enabling the default set of port interrupts.
|
|
||||||
*
|
|
||||||
* @port Pointer to the port structure.
|
|
||||||
*
|
|
||||||
* return value
|
|
||||||
* None
|
|
||||||
*/
|
|
||||||
static void mtip_init_port(struct mtip_port *port)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
mtip_deinit_port(port);
|
|
||||||
|
|
||||||
/* Program the command list base and FIS base addresses */
|
|
||||||
if (readl(port->dd->mmio + HOST_CAP) & HOST_CAP_64) {
|
|
||||||
writel((port->command_list_dma >> 16) >> 16,
|
|
||||||
port->mmio + PORT_LST_ADDR_HI);
|
|
||||||
writel((port->rxfis_dma >> 16) >> 16,
|
|
||||||
port->mmio + PORT_FIS_ADDR_HI);
|
|
||||||
}
|
|
||||||
|
|
||||||
writel(port->command_list_dma & 0xffffffff,
|
|
||||||
port->mmio + PORT_LST_ADDR);
|
|
||||||
writel(port->rxfis_dma & 0xffffffff, port->mmio + PORT_FIS_ADDR);
|
|
||||||
|
|
||||||
/* Clear SError */
|
|
||||||
writel(readl(port->mmio + PORT_SCR_ERR), port->mmio + PORT_SCR_ERR);
|
|
||||||
|
|
||||||
/* reset the completed registers.*/
|
|
||||||
for (i = 0; i < port->dd->slot_groups; i++)
|
|
||||||
writel(0xFFFFFFFF, port->completed[i]);
|
|
||||||
|
|
||||||
/* Clear any pending interrupts for this port */
|
|
||||||
writel(readl(port->mmio + PORT_IRQ_STAT), port->mmio + PORT_IRQ_STAT);
|
|
||||||
|
|
||||||
/* Enable port interrupts */
|
|
||||||
writel(DEF_PORT_IRQ, port->mmio + PORT_IRQ_MASK);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Reset the HBA (without sleeping)
|
|
||||||
*
|
|
||||||
* Just like hba_reset, except does not call sleep, so can be
|
|
||||||
* run from interrupt/tasklet context.
|
|
||||||
*
|
|
||||||
* @dd Pointer to the driver data structure.
|
|
||||||
*
|
|
||||||
* return value
|
|
||||||
* 0 The reset was successful.
|
|
||||||
* -1 The HBA Reset bit did not clear.
|
|
||||||
*/
|
|
||||||
int hba_reset_nosleep(struct driver_data *dd)
|
|
||||||
{
|
|
||||||
unsigned long timeout;
|
|
||||||
|
|
||||||
/* Chip quirk: quiesce any chip function */
|
|
||||||
mdelay(10);
|
|
||||||
|
|
||||||
/* Set the reset bit */
|
|
||||||
writel(HOST_RESET, dd->mmio + HOST_CTL);
|
|
||||||
|
|
||||||
/* Flush */
|
|
||||||
readl(dd->mmio + HOST_CTL);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Wait 10ms then spin for up to 1 second
|
|
||||||
* waiting for reset acknowledgement
|
|
||||||
*/
|
|
||||||
timeout = jiffies + msecs_to_jiffies(1000);
|
|
||||||
mdelay(10);
|
|
||||||
while ((readl(dd->mmio + HOST_CTL) & HOST_RESET)
|
|
||||||
&& time_before(jiffies, timeout))
|
|
||||||
mdelay(1);
|
|
||||||
|
|
||||||
if (readl(dd->mmio + HOST_CTL) & HOST_RESET)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Restart a port
|
|
||||||
*
|
|
||||||
* @port Pointer to the port data structure.
|
|
||||||
*
|
|
||||||
* return value
|
|
||||||
* None
|
|
||||||
*/
|
|
||||||
void mtip_restart_port(struct mtip_port *port)
|
|
||||||
{
|
|
||||||
unsigned long timeout;
|
|
||||||
|
|
||||||
/* Disable the DMA engine */
|
|
||||||
mtip_enable_engine(port, 0);
|
|
||||||
|
|
||||||
/* Chip quirk: wait up to 500ms for PxCMD.CR == 0 */
|
|
||||||
timeout = jiffies + msecs_to_jiffies(500);
|
|
||||||
while ((readl(port->mmio + PORT_CMD) & PORT_CMD_LIST_ON)
|
|
||||||
&& time_before(jiffies, timeout))
|
|
||||||
;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Chip quirk: escalate to hba reset if
|
|
||||||
* PxCMD.CR not clear after 500 ms
|
|
||||||
*/
|
|
||||||
if (readl(port->mmio + PORT_CMD) & PORT_CMD_LIST_ON) {
|
|
||||||
dev_warn(&port->dd->pdev->dev,
|
|
||||||
"PxCMD.CR not clear, escalating reset\n");
|
|
||||||
|
|
||||||
if (hba_reset_nosleep(port->dd))
|
|
||||||
dev_err(&port->dd->pdev->dev,
|
|
||||||
"HBA reset escalation failed.\n");
|
|
||||||
|
|
||||||
/* 30 ms delay before com reset to quiesce chip */
|
|
||||||
mdelay(30);
|
|
||||||
}
|
|
||||||
|
|
||||||
dev_warn(&port->dd->pdev->dev, "Issuing COM reset\n");
|
|
||||||
|
|
||||||
/* Set PxSCTL.DET */
|
|
||||||
writel(readl(port->mmio + PORT_SCR_CTL) |
|
|
||||||
1, port->mmio + PORT_SCR_CTL);
|
|
||||||
readl(port->mmio + PORT_SCR_CTL);
|
|
||||||
|
|
||||||
/* Wait 1 ms to quiesce chip function */
|
|
||||||
timeout = jiffies + msecs_to_jiffies(1);
|
|
||||||
while (time_before(jiffies, timeout))
|
|
||||||
;
|
|
||||||
|
|
||||||
/* Clear PxSCTL.DET */
|
|
||||||
writel(readl(port->mmio + PORT_SCR_CTL) & ~1,
|
|
||||||
port->mmio + PORT_SCR_CTL);
|
|
||||||
readl(port->mmio + PORT_SCR_CTL);
|
|
||||||
|
|
||||||
/* Wait 500 ms for bit 0 of PORT_SCR_STS to be set */
|
|
||||||
timeout = jiffies + msecs_to_jiffies(500);
|
|
||||||
while (((readl(port->mmio + PORT_SCR_STAT) & 0x01) == 0)
|
|
||||||
&& time_before(jiffies, timeout))
|
|
||||||
;
|
|
||||||
|
|
||||||
if ((readl(port->mmio + PORT_SCR_STAT) & 0x01) == 0)
|
|
||||||
dev_warn(&port->dd->pdev->dev,
|
|
||||||
"COM reset failed\n");
|
|
||||||
|
|
||||||
/* Clear SError, the PxSERR.DIAG.x should be set so clear it */
|
|
||||||
writel(readl(port->mmio + PORT_SCR_ERR), port->mmio + PORT_SCR_ERR);
|
|
||||||
|
|
||||||
/* Enable the DMA engine */
|
|
||||||
mtip_enable_engine(port, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Helper function for tag logging
|
* Helper function for tag logging
|
||||||
*/
|
*/
|
||||||
@ -1276,7 +1342,7 @@ static int mtip_standby_immediate(struct mtip_port *port)
|
|||||||
* 1 Capacity was returned successfully.
|
* 1 Capacity was returned successfully.
|
||||||
* 0 The identify information is invalid.
|
* 0 The identify information is invalid.
|
||||||
*/
|
*/
|
||||||
bool mtip_hw_get_capacity(struct driver_data *dd, sector_t *sectors)
|
static bool mtip_hw_get_capacity(struct driver_data *dd, sector_t *sectors)
|
||||||
{
|
{
|
||||||
struct mtip_port *port = dd->port;
|
struct mtip_port *port = dd->port;
|
||||||
u64 total, raw0, raw1, raw2, raw3;
|
u64 total, raw0, raw1, raw2, raw3;
|
||||||
@ -1423,7 +1489,7 @@ static inline void fill_command_sg(struct driver_data *dd,
|
|||||||
* return value 0 The command completed successfully.
|
* return value 0 The command completed successfully.
|
||||||
* return value -1 An error occurred while executing the command.
|
* return value -1 An error occurred while executing the command.
|
||||||
*/
|
*/
|
||||||
int exec_drive_task(struct mtip_port *port, u8 *command)
|
static int exec_drive_task(struct mtip_port *port, u8 *command)
|
||||||
{
|
{
|
||||||
struct host_to_dev_fis fis;
|
struct host_to_dev_fis fis;
|
||||||
struct host_to_dev_fis *reply = (port->rxfis + RX_FIS_D2H_REG);
|
struct host_to_dev_fis *reply = (port->rxfis + RX_FIS_D2H_REG);
|
||||||
@ -1499,8 +1565,8 @@ int exec_drive_task(struct mtip_port *port, u8 *command)
|
|||||||
* data to the user space buffer.
|
* data to the user space buffer.
|
||||||
* return value -1 An error occurred while executing the command.
|
* return value -1 An error occurred while executing the command.
|
||||||
*/
|
*/
|
||||||
int exec_drive_command(struct mtip_port *port, u8 *command,
|
static int exec_drive_command(struct mtip_port *port, u8 *command,
|
||||||
void __user *user_buffer)
|
void __user *user_buffer)
|
||||||
{
|
{
|
||||||
struct host_to_dev_fis fis;
|
struct host_to_dev_fis fis;
|
||||||
struct host_to_dev_fis *reply = (port->rxfis + RX_FIS_D2H_REG);
|
struct host_to_dev_fis *reply = (port->rxfis + RX_FIS_D2H_REG);
|
||||||
@ -2020,15 +2086,9 @@ static int mtip_hw_ioctl(struct driver_data *dd, unsigned int cmd,
|
|||||||
* return value
|
* return value
|
||||||
* None
|
* None
|
||||||
*/
|
*/
|
||||||
void mtip_hw_submit_io(struct driver_data *dd,
|
static void mtip_hw_submit_io(struct driver_data *dd, sector_t start,
|
||||||
sector_t start,
|
int nsect, int nents, int tag, void *callback,
|
||||||
int nsect,
|
void *data, int barrier, int dir)
|
||||||
int nents,
|
|
||||||
int tag,
|
|
||||||
void *callback,
|
|
||||||
void *data,
|
|
||||||
int barrier,
|
|
||||||
int dir)
|
|
||||||
{
|
{
|
||||||
struct host_to_dev_fis *fis;
|
struct host_to_dev_fis *fis;
|
||||||
struct mtip_port *port = dd->port;
|
struct mtip_port *port = dd->port;
|
||||||
@ -2115,7 +2175,7 @@ void mtip_hw_submit_io(struct driver_data *dd,
|
|||||||
* return value
|
* return value
|
||||||
* None
|
* None
|
||||||
*/
|
*/
|
||||||
void mtip_hw_release_scatterlist(struct driver_data *dd, int tag)
|
static void mtip_hw_release_scatterlist(struct driver_data *dd, int tag)
|
||||||
{
|
{
|
||||||
release_slot(dd->port, tag);
|
release_slot(dd->port, tag);
|
||||||
}
|
}
|
||||||
@ -2131,8 +2191,8 @@ void mtip_hw_release_scatterlist(struct driver_data *dd, int tag)
|
|||||||
* Pointer to the scatter list for the allocated command slot
|
* Pointer to the scatter list for the allocated command slot
|
||||||
* or NULL if no command slots are available.
|
* or NULL if no command slots are available.
|
||||||
*/
|
*/
|
||||||
struct scatterlist *mtip_hw_get_scatterlist(struct driver_data *dd,
|
static struct scatterlist *mtip_hw_get_scatterlist(struct driver_data *dd,
|
||||||
int *tag)
|
int *tag)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* It is possible that, even with this semaphore, a thread
|
* It is possible that, even with this semaphore, a thread
|
||||||
@ -2216,7 +2276,7 @@ static DEVICE_ATTR(registers, S_IRUGO, hw_show_registers, NULL);
|
|||||||
* 0 Operation completed successfully.
|
* 0 Operation completed successfully.
|
||||||
* -EINVAL Invalid parameter.
|
* -EINVAL Invalid parameter.
|
||||||
*/
|
*/
|
||||||
int mtip_hw_sysfs_init(struct driver_data *dd, struct kobject *kobj)
|
static int mtip_hw_sysfs_init(struct driver_data *dd, struct kobject *kobj)
|
||||||
{
|
{
|
||||||
if (!kobj || !dd)
|
if (!kobj || !dd)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
@ -2237,7 +2297,7 @@ int mtip_hw_sysfs_init(struct driver_data *dd, struct kobject *kobj)
|
|||||||
* 0 Operation completed successfully.
|
* 0 Operation completed successfully.
|
||||||
* -EINVAL Invalid parameter.
|
* -EINVAL Invalid parameter.
|
||||||
*/
|
*/
|
||||||
int mtip_hw_sysfs_exit(struct driver_data *dd, struct kobject *kobj)
|
static int mtip_hw_sysfs_exit(struct driver_data *dd, struct kobject *kobj)
|
||||||
{
|
{
|
||||||
if (!kobj || !dd)
|
if (!kobj || !dd)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
@ -2385,7 +2445,7 @@ static int mtip_ftl_rebuild_poll(struct driver_data *dd)
|
|||||||
* return value
|
* return value
|
||||||
* 0 on success, else an error code.
|
* 0 on success, else an error code.
|
||||||
*/
|
*/
|
||||||
int mtip_hw_init(struct driver_data *dd)
|
static int mtip_hw_init(struct driver_data *dd)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
int rv;
|
int rv;
|
||||||
@ -2586,7 +2646,7 @@ out1:
|
|||||||
* return value
|
* return value
|
||||||
* 0
|
* 0
|
||||||
*/
|
*/
|
||||||
int mtip_hw_exit(struct driver_data *dd)
|
static int mtip_hw_exit(struct driver_data *dd)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* Send standby immediate (E0h) to the drive so that it
|
* Send standby immediate (E0h) to the drive so that it
|
||||||
@ -2634,7 +2694,7 @@ int mtip_hw_exit(struct driver_data *dd)
|
|||||||
* return value
|
* return value
|
||||||
* 0
|
* 0
|
||||||
*/
|
*/
|
||||||
int mtip_hw_shutdown(struct driver_data *dd)
|
static int mtip_hw_shutdown(struct driver_data *dd)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* Send standby immediate (E0h) to the drive so that it
|
* Send standby immediate (E0h) to the drive so that it
|
||||||
@ -2657,7 +2717,7 @@ int mtip_hw_shutdown(struct driver_data *dd)
|
|||||||
* 0 Suspend was successful
|
* 0 Suspend was successful
|
||||||
* -EFAULT Suspend was not successful
|
* -EFAULT Suspend was not successful
|
||||||
*/
|
*/
|
||||||
int mtip_hw_suspend(struct driver_data *dd)
|
static int mtip_hw_suspend(struct driver_data *dd)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* Send standby immediate (E0h) to the drive
|
* Send standby immediate (E0h) to the drive
|
||||||
@ -2689,7 +2749,7 @@ int mtip_hw_suspend(struct driver_data *dd)
|
|||||||
* 0 Resume was successful
|
* 0 Resume was successful
|
||||||
* -EFAULT Resume was not successful
|
* -EFAULT Resume was not successful
|
||||||
*/
|
*/
|
||||||
int mtip_hw_resume(struct driver_data *dd)
|
static int mtip_hw_resume(struct driver_data *dd)
|
||||||
{
|
{
|
||||||
/* Perform any needed hardware setup steps */
|
/* Perform any needed hardware setup steps */
|
||||||
hba_setup(dd);
|
hba_setup(dd);
|
||||||
@ -2715,50 +2775,6 @@ int mtip_hw_resume(struct driver_data *dd)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* This function is called for clean the pending command in the
|
|
||||||
* command slot during the surprise removal of device and return
|
|
||||||
* error to the upper layer.
|
|
||||||
*
|
|
||||||
* @dd Pointer to the DRIVER_DATA structure.
|
|
||||||
*
|
|
||||||
* return value
|
|
||||||
* None
|
|
||||||
*/
|
|
||||||
void mtip_command_cleanup(struct driver_data *dd)
|
|
||||||
{
|
|
||||||
int group = 0, commandslot = 0, commandindex = 0;
|
|
||||||
struct mtip_cmd *command;
|
|
||||||
struct mtip_port *port = dd->port;
|
|
||||||
|
|
||||||
for (group = 0; group < 4; group++) {
|
|
||||||
for (commandslot = 0; commandslot < 32; commandslot++) {
|
|
||||||
if (!(port->allocated[group] & (1 << commandslot)))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
commandindex = group << 5 | commandslot;
|
|
||||||
command = &port->commands[commandindex];
|
|
||||||
|
|
||||||
if (atomic_read(&command->active)
|
|
||||||
&& (command->async_callback)) {
|
|
||||||
command->async_callback(command->async_data,
|
|
||||||
-ENODEV);
|
|
||||||
command->async_callback = NULL;
|
|
||||||
command->async_data = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
dma_unmap_sg(&port->dd->pdev->dev,
|
|
||||||
command->sg,
|
|
||||||
command->scatter_ents,
|
|
||||||
command->direction);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
up(&port->cmd_slot);
|
|
||||||
|
|
||||||
atomic_set(&dd->drv_cleanup_done, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Helper function for reusing disk name
|
* Helper function for reusing disk name
|
||||||
* upon hot insertion.
|
* upon hot insertion.
|
||||||
@ -3037,7 +3053,7 @@ static int mtip_make_request(struct request_queue *queue, struct bio *bio)
|
|||||||
* return value
|
* return value
|
||||||
* 0 on success else an error code.
|
* 0 on success else an error code.
|
||||||
*/
|
*/
|
||||||
int mtip_block_initialize(struct driver_data *dd)
|
static int mtip_block_initialize(struct driver_data *dd)
|
||||||
{
|
{
|
||||||
int rv = 0;
|
int rv = 0;
|
||||||
sector_t capacity;
|
sector_t capacity;
|
||||||
@ -3168,7 +3184,7 @@ protocol_init_error:
|
|||||||
* return value
|
* return value
|
||||||
* 0
|
* 0
|
||||||
*/
|
*/
|
||||||
int mtip_block_remove(struct driver_data *dd)
|
static int mtip_block_remove(struct driver_data *dd)
|
||||||
{
|
{
|
||||||
struct kobject *kobj;
|
struct kobject *kobj;
|
||||||
/* Clean up the sysfs attributes managed by the protocol layer. */
|
/* Clean up the sysfs attributes managed by the protocol layer. */
|
||||||
@ -3205,7 +3221,7 @@ int mtip_block_remove(struct driver_data *dd)
|
|||||||
* return value
|
* return value
|
||||||
* 0
|
* 0
|
||||||
*/
|
*/
|
||||||
int mtip_block_shutdown(struct driver_data *dd)
|
static int mtip_block_shutdown(struct driver_data *dd)
|
||||||
{
|
{
|
||||||
dev_info(&dd->pdev->dev,
|
dev_info(&dd->pdev->dev,
|
||||||
"Shutting down %s ...\n", dd->disk->disk_name);
|
"Shutting down %s ...\n", dd->disk->disk_name);
|
||||||
@ -3220,7 +3236,7 @@ int mtip_block_shutdown(struct driver_data *dd)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int mtip_block_suspend(struct driver_data *dd)
|
static int mtip_block_suspend(struct driver_data *dd)
|
||||||
{
|
{
|
||||||
dev_info(&dd->pdev->dev,
|
dev_info(&dd->pdev->dev,
|
||||||
"Suspending %s ...\n", dd->disk->disk_name);
|
"Suspending %s ...\n", dd->disk->disk_name);
|
||||||
@ -3228,7 +3244,7 @@ int mtip_block_suspend(struct driver_data *dd)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int mtip_block_resume(struct driver_data *dd)
|
static int mtip_block_resume(struct driver_data *dd)
|
||||||
{
|
{
|
||||||
dev_info(&dd->pdev->dev, "Resuming %s ...\n",
|
dev_info(&dd->pdev->dev, "Resuming %s ...\n",
|
||||||
dd->disk->disk_name);
|
dd->disk->disk_name);
|
||||||
@ -3479,28 +3495,6 @@ static void mtip_pci_shutdown(struct pci_dev *pdev)
|
|||||||
mtip_block_shutdown(dd);
|
mtip_block_shutdown(dd);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* This function check_for_surprise_removal is called
|
|
||||||
* while card is removed from the system and it will
|
|
||||||
* read the vendor id from the configration space
|
|
||||||
*
|
|
||||||
* @pdev Pointer to the pci_dev structure.
|
|
||||||
*
|
|
||||||
* return value
|
|
||||||
* true if device removed, else false
|
|
||||||
*/
|
|
||||||
bool mtip_check_surprise_removal(struct pci_dev *pdev)
|
|
||||||
{
|
|
||||||
u16 vendor_id = 0;
|
|
||||||
|
|
||||||
/* Read the vendorID from the configuration space */
|
|
||||||
pci_read_config_word(pdev, 0x00, &vendor_id);
|
|
||||||
if (vendor_id == 0xFFFF)
|
|
||||||
return true; /* device removed */
|
|
||||||
|
|
||||||
return false; /* device present */
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Table of device ids supported by this driver. */
|
/* Table of device ids supported by this driver. */
|
||||||
static DEFINE_PCI_DEVICE_TABLE(mtip_pci_tbl) = {
|
static DEFINE_PCI_DEVICE_TABLE(mtip_pci_tbl) = {
|
||||||
{ PCI_DEVICE(PCI_VENDOR_ID_MICRON, P320_DEVICE_ID) },
|
{ PCI_DEVICE(PCI_VENDOR_ID_MICRON, P320_DEVICE_ID) },
|
||||||
|
@ -405,37 +405,4 @@ struct driver_data {
|
|||||||
atomic_t eh_active; /* Flag for error handling tracking */
|
atomic_t eh_active; /* Flag for error handling tracking */
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Function declarations */
|
|
||||||
extern int mtip_block_initialize(struct driver_data *dd);
|
|
||||||
extern int mtip_block_remove(struct driver_data *dd);
|
|
||||||
extern int mtip_block_shutdown(struct driver_data *dd);
|
|
||||||
extern int mtip_block_suspend(struct driver_data *dd);
|
|
||||||
extern int mtip_block_resume(struct driver_data *dd);
|
|
||||||
extern int mtip_hw_init(struct driver_data *dd);
|
|
||||||
extern int mtip_hw_exit(struct driver_data *dd);
|
|
||||||
extern int mtip_hw_shutdown(struct driver_data *dd);
|
|
||||||
extern bool mtip_hw_get_capacity(struct driver_data *dd, sector_t *sectors);
|
|
||||||
extern void mtip_hw_release_scatterlist(
|
|
||||||
struct driver_data *dd,
|
|
||||||
int tag);
|
|
||||||
extern struct scatterlist *mtip_hw_get_scatterlist(
|
|
||||||
struct driver_data *dd,
|
|
||||||
int *tag);
|
|
||||||
extern void mtip_hw_submit_io(struct driver_data *dd,
|
|
||||||
sector_t start,
|
|
||||||
int nsect,
|
|
||||||
int nents,
|
|
||||||
int tag,
|
|
||||||
void *callback,
|
|
||||||
void *data,
|
|
||||||
int barrier,
|
|
||||||
int dir);
|
|
||||||
extern int mtip_hw_sysfs_init(struct driver_data *dd, struct kobject *kobj);
|
|
||||||
extern int mtip_hw_sysfs_exit(struct driver_data *dd, struct kobject *kobj);
|
|
||||||
extern int mtip_hw_resume(struct driver_data *dd);
|
|
||||||
extern int mtip_hw_suspend(struct driver_data *dd);
|
|
||||||
void mtip_command_cleanup(struct driver_data *dd);
|
|
||||||
bool mtip_check_surprise_removal(struct pci_dev *pdev);
|
|
||||||
void mtip_restart_port(struct mtip_port *port);
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
Loading…
Reference in New Issue
Block a user