mirror of
https://github.com/torvalds/linux.git
synced 2024-11-22 12:11:40 +00:00
SCSI misc on 20230303
Updates that missed the first pull, mostly because of needing more soak time. Driver updates (zfcp, ufs, mpi3mr, plus two ipr bug fixes), an enclosure services (ses) update (mostly bug fixes) and other minor bug fixes and changes. Signed-off-by: James E.J. Bottomley <jejb@linux.ibm.com> -----BEGIN PGP SIGNATURE----- iJwEABMIAEQWIQTnYEDbdso9F2cI+arnQslM7pishQUCZAJf2SYcamFtZXMuYm90 dG9tbGV5QGhhbnNlbnBhcnRuZXJzaGlwLmNvbQAKCRDnQslM7pishWYeAP9u6umX 5Trq6mtfdPyhSxIhgD6AwJDgVkeApSKAHZRu0AD/dfMTQmeaJory4LD4JW+uAgVl yFPVz9VPlKTiaM2lwUI= =BKzr -----END PGP SIGNATURE----- Merge tag 'scsi-misc' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi Pull more SCSI updates from James Bottomley: "Updates that missed the first pull, mostly because of needing more soak time. Driver updates (zfcp, ufs, mpi3mr, plus two ipr bug fixes), an enclosure services (ses) update (mostly bug fixes) and other minor bug fixes and changes" * tag 'scsi-misc' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi: (32 commits) scsi: zfcp: Trace when request remove fails after qdio send fails scsi: zfcp: Change the type of all fsf request id fields and variables to u64 scsi: zfcp: Make the type for accessing request hashtable buckets size_t scsi: ufs: core: Simplify ufshcd_execute_start_stop() scsi: ufs: core: Rely on the block layer for setting RQF_PM scsi: core: Extend struct scsi_exec_args scsi: lpfc: Fix double word in comments scsi: core: Remove the /proc/scsi/${proc_name} directory earlier scsi: core: Fix a source code comment scsi: cxgbi: Remove unneeded version.h include scsi: qedi: Remove unneeded version.h include scsi: mpi3mr: Remove unneeded version.h include scsi: mpi3mr: Fix missing mrioc->evtack_cmds initialization scsi: mpi3mr: Use number of bits to manage bitmap sizes scsi: mpi3mr: Remove unnecessary memcpy() to alltgt_info->dmi scsi: mpi3mr: Fix issues in mpi3mr_get_all_tgt_info() scsi: mpi3mr: Fix an issue found by KASAN scsi: mpi3mr: Replace 1-element array with flex-array scsi: ipr: Work around fortify-string warning scsi: ipr: Make ipr_probe_ioa_part2() return void ...
This commit is contained in:
commit
06caa75154
@ -4,7 +4,7 @@
|
|||||||
*
|
*
|
||||||
* Debug traces for zfcp.
|
* Debug traces for zfcp.
|
||||||
*
|
*
|
||||||
* Copyright IBM Corp. 2002, 2020
|
* Copyright IBM Corp. 2002, 2023
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define KMSG_COMPONENT "zfcp"
|
#define KMSG_COMPONENT "zfcp"
|
||||||
@ -145,6 +145,48 @@ void zfcp_dbf_hba_fsf_fces(char *tag, const struct zfcp_fsf_req *req, u64 wwpn,
|
|||||||
spin_unlock_irqrestore(&dbf->hba_lock, flags);
|
spin_unlock_irqrestore(&dbf->hba_lock, flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* zfcp_dbf_hba_fsf_reqid - trace only the tag and a request ID
|
||||||
|
* @tag: tag documenting the source
|
||||||
|
* @level: trace level
|
||||||
|
* @adapter: adapter instance the request ID belongs to
|
||||||
|
* @req_id: the request ID to trace
|
||||||
|
*/
|
||||||
|
void zfcp_dbf_hba_fsf_reqid(const char *const tag, const int level,
|
||||||
|
struct zfcp_adapter *const adapter,
|
||||||
|
const u64 req_id)
|
||||||
|
{
|
||||||
|
struct zfcp_dbf *const dbf = adapter->dbf;
|
||||||
|
struct zfcp_dbf_hba *const rec = &dbf->hba_buf;
|
||||||
|
struct zfcp_dbf_hba_res *const res = &rec->u.res;
|
||||||
|
unsigned long flags;
|
||||||
|
|
||||||
|
if (unlikely(!debug_level_enabled(dbf->hba, level)))
|
||||||
|
return;
|
||||||
|
|
||||||
|
spin_lock_irqsave(&dbf->hba_lock, flags);
|
||||||
|
memset(rec, 0, sizeof(*rec));
|
||||||
|
|
||||||
|
memcpy(rec->tag, tag, ZFCP_DBF_TAG_LEN);
|
||||||
|
|
||||||
|
rec->id = ZFCP_DBF_HBA_RES;
|
||||||
|
rec->fsf_req_id = req_id;
|
||||||
|
rec->fsf_req_status = ~0u;
|
||||||
|
rec->fsf_cmd = ~0u;
|
||||||
|
rec->fsf_seq_no = ~0u;
|
||||||
|
|
||||||
|
res->req_issued = ~0ull;
|
||||||
|
res->prot_status = ~0u;
|
||||||
|
memset(res->prot_status_qual, 0xff, sizeof(res->prot_status_qual));
|
||||||
|
res->fsf_status = ~0u;
|
||||||
|
memset(res->fsf_status_qual, 0xff, sizeof(res->fsf_status_qual));
|
||||||
|
res->port_handle = ~0u;
|
||||||
|
res->lun_handle = ~0u;
|
||||||
|
|
||||||
|
debug_event(dbf->hba, level, rec, sizeof(*rec));
|
||||||
|
spin_unlock_irqrestore(&dbf->hba_lock, flags);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* zfcp_dbf_hba_fsf_uss - trace event for an unsolicited status buffer
|
* zfcp_dbf_hba_fsf_uss - trace event for an unsolicited status buffer
|
||||||
* @tag: tag indicating which kind of unsolicited status has been received
|
* @tag: tag indicating which kind of unsolicited status has been received
|
||||||
@ -649,7 +691,7 @@ void zfcp_dbf_scsi_common(char *tag, int level, struct scsi_device *sdev,
|
|||||||
rec->scsi_id = sc->device->id;
|
rec->scsi_id = sc->device->id;
|
||||||
rec->scsi_lun = (u32)sc->device->lun;
|
rec->scsi_lun = (u32)sc->device->lun;
|
||||||
rec->scsi_lun_64_hi = (u32)(sc->device->lun >> 32);
|
rec->scsi_lun_64_hi = (u32)(sc->device->lun >> 32);
|
||||||
rec->host_scribble = (unsigned long)sc->host_scribble;
|
rec->host_scribble = (u64)sc->host_scribble;
|
||||||
|
|
||||||
memcpy(rec->scsi_opcode, sc->cmnd,
|
memcpy(rec->scsi_opcode, sc->cmnd,
|
||||||
min_t(int, sc->cmd_len, ZFCP_DBF_SCSI_OPCODE));
|
min_t(int, sc->cmd_len, ZFCP_DBF_SCSI_OPCODE));
|
||||||
|
@ -129,7 +129,7 @@ struct zfcp_erp_action {
|
|||||||
struct scsi_device *sdev;
|
struct scsi_device *sdev;
|
||||||
u32 status; /* recovery status */
|
u32 status; /* recovery status */
|
||||||
enum zfcp_erp_steps step; /* active step of this erp action */
|
enum zfcp_erp_steps step; /* active step of this erp action */
|
||||||
unsigned long fsf_req_id;
|
u64 fsf_req_id;
|
||||||
struct timer_list timer;
|
struct timer_list timer;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -163,7 +163,7 @@ struct zfcp_adapter {
|
|||||||
struct Scsi_Host *scsi_host; /* Pointer to mid-layer */
|
struct Scsi_Host *scsi_host; /* Pointer to mid-layer */
|
||||||
struct list_head port_list; /* remote port list */
|
struct list_head port_list; /* remote port list */
|
||||||
rwlock_t port_list_lock; /* port list lock */
|
rwlock_t port_list_lock; /* port list lock */
|
||||||
unsigned long req_no; /* unique FSF req number */
|
u64 req_no; /* unique FSF req number */
|
||||||
struct zfcp_reqlist *req_list;
|
struct zfcp_reqlist *req_list;
|
||||||
u32 fsf_req_seq_no; /* FSF cmnd seq number */
|
u32 fsf_req_seq_no; /* FSF cmnd seq number */
|
||||||
rwlock_t abort_lock; /* Protects against SCSI
|
rwlock_t abort_lock; /* Protects against SCSI
|
||||||
@ -325,7 +325,7 @@ static inline u64 zfcp_scsi_dev_lun(struct scsi_device *sdev)
|
|||||||
*/
|
*/
|
||||||
struct zfcp_fsf_req {
|
struct zfcp_fsf_req {
|
||||||
struct list_head list;
|
struct list_head list;
|
||||||
unsigned long req_id;
|
u64 req_id;
|
||||||
struct zfcp_adapter *adapter;
|
struct zfcp_adapter *adapter;
|
||||||
struct zfcp_qdio_req qdio_req;
|
struct zfcp_qdio_req qdio_req;
|
||||||
struct completion completion;
|
struct completion completion;
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
*
|
*
|
||||||
* External function declarations.
|
* External function declarations.
|
||||||
*
|
*
|
||||||
* Copyright IBM Corp. 2002, 2020
|
* Copyright IBM Corp. 2002, 2023
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef ZFCP_EXT_H
|
#ifndef ZFCP_EXT_H
|
||||||
@ -46,6 +46,9 @@ extern void zfcp_dbf_hba_fsf_res(char *, int, struct zfcp_fsf_req *);
|
|||||||
extern void zfcp_dbf_hba_fsf_fces(char *tag, const struct zfcp_fsf_req *req,
|
extern void zfcp_dbf_hba_fsf_fces(char *tag, const struct zfcp_fsf_req *req,
|
||||||
u64 wwpn, u32 fc_security_old,
|
u64 wwpn, u32 fc_security_old,
|
||||||
u32 fc_security_new);
|
u32 fc_security_new);
|
||||||
|
extern void zfcp_dbf_hba_fsf_reqid(const char *const tag, const int level,
|
||||||
|
struct zfcp_adapter *const adapter,
|
||||||
|
const u64 req_id);
|
||||||
extern void zfcp_dbf_hba_bit_err(char *, struct zfcp_fsf_req *);
|
extern void zfcp_dbf_hba_bit_err(char *, struct zfcp_fsf_req *);
|
||||||
extern void zfcp_dbf_hba_def_err(struct zfcp_adapter *, u64, u16, void **);
|
extern void zfcp_dbf_hba_def_err(struct zfcp_adapter *, u64, u16, void **);
|
||||||
extern void zfcp_dbf_san_req(char *, struct zfcp_fsf_req *, u32);
|
extern void zfcp_dbf_san_req(char *, struct zfcp_fsf_req *, u32);
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
*
|
*
|
||||||
* Implementation of FSF commands.
|
* Implementation of FSF commands.
|
||||||
*
|
*
|
||||||
* Copyright IBM Corp. 2002, 2020
|
* Copyright IBM Corp. 2002, 2023
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define KMSG_COMPONENT "zfcp"
|
#define KMSG_COMPONENT "zfcp"
|
||||||
@ -884,7 +884,7 @@ static int zfcp_fsf_req_send(struct zfcp_fsf_req *req)
|
|||||||
const bool is_srb = zfcp_fsf_req_is_status_read_buffer(req);
|
const bool is_srb = zfcp_fsf_req_is_status_read_buffer(req);
|
||||||
struct zfcp_adapter *adapter = req->adapter;
|
struct zfcp_adapter *adapter = req->adapter;
|
||||||
struct zfcp_qdio *qdio = adapter->qdio;
|
struct zfcp_qdio *qdio = adapter->qdio;
|
||||||
unsigned long req_id = req->req_id;
|
u64 req_id = req->req_id;
|
||||||
|
|
||||||
zfcp_reqlist_add(adapter->req_list, req);
|
zfcp_reqlist_add(adapter->req_list, req);
|
||||||
|
|
||||||
@ -892,8 +892,11 @@ static int zfcp_fsf_req_send(struct zfcp_fsf_req *req)
|
|||||||
req->issued = get_tod_clock();
|
req->issued = get_tod_clock();
|
||||||
if (zfcp_qdio_send(qdio, &req->qdio_req)) {
|
if (zfcp_qdio_send(qdio, &req->qdio_req)) {
|
||||||
del_timer_sync(&req->timer);
|
del_timer_sync(&req->timer);
|
||||||
|
|
||||||
/* lookup request again, list might have changed */
|
/* lookup request again, list might have changed */
|
||||||
zfcp_reqlist_find_rm(adapter->req_list, req_id);
|
if (zfcp_reqlist_find_rm(adapter->req_list, req_id) == NULL)
|
||||||
|
zfcp_dbf_hba_fsf_reqid("fsrsrmf", 1, adapter, req_id);
|
||||||
|
|
||||||
zfcp_erp_adapter_reopen(adapter, 0, "fsrs__1");
|
zfcp_erp_adapter_reopen(adapter, 0, "fsrs__1");
|
||||||
return -EIO;
|
return -EIO;
|
||||||
}
|
}
|
||||||
@ -1042,7 +1045,7 @@ struct zfcp_fsf_req *zfcp_fsf_abort_fcp_cmnd(struct scsi_cmnd *scmnd)
|
|||||||
struct scsi_device *sdev = scmnd->device;
|
struct scsi_device *sdev = scmnd->device;
|
||||||
struct zfcp_scsi_dev *zfcp_sdev = sdev_to_zfcp(sdev);
|
struct zfcp_scsi_dev *zfcp_sdev = sdev_to_zfcp(sdev);
|
||||||
struct zfcp_qdio *qdio = zfcp_sdev->port->adapter->qdio;
|
struct zfcp_qdio *qdio = zfcp_sdev->port->adapter->qdio;
|
||||||
unsigned long old_req_id = (unsigned long) scmnd->host_scribble;
|
u64 old_req_id = (u64) scmnd->host_scribble;
|
||||||
|
|
||||||
spin_lock_irq(&qdio->req_q_lock);
|
spin_lock_irq(&qdio->req_q_lock);
|
||||||
if (zfcp_qdio_sbal_get(qdio))
|
if (zfcp_qdio_sbal_get(qdio))
|
||||||
@ -1065,7 +1068,7 @@ struct zfcp_fsf_req *zfcp_fsf_abort_fcp_cmnd(struct scsi_cmnd *scmnd)
|
|||||||
req->handler = zfcp_fsf_abort_fcp_command_handler;
|
req->handler = zfcp_fsf_abort_fcp_command_handler;
|
||||||
req->qtcb->header.lun_handle = zfcp_sdev->lun_handle;
|
req->qtcb->header.lun_handle = zfcp_sdev->lun_handle;
|
||||||
req->qtcb->header.port_handle = zfcp_sdev->port->handle;
|
req->qtcb->header.port_handle = zfcp_sdev->port->handle;
|
||||||
req->qtcb->bottom.support.req_handle = (u64) old_req_id;
|
req->qtcb->bottom.support.req_handle = old_req_id;
|
||||||
|
|
||||||
zfcp_fsf_start_timer(req, ZFCP_FSF_SCSI_ER_TIMEOUT);
|
zfcp_fsf_start_timer(req, ZFCP_FSF_SCSI_ER_TIMEOUT);
|
||||||
if (!zfcp_fsf_req_send(req)) {
|
if (!zfcp_fsf_req_send(req)) {
|
||||||
@ -1919,7 +1922,7 @@ int zfcp_fsf_open_wka_port(struct zfcp_fc_wka_port *wka_port)
|
|||||||
{
|
{
|
||||||
struct zfcp_qdio *qdio = wka_port->adapter->qdio;
|
struct zfcp_qdio *qdio = wka_port->adapter->qdio;
|
||||||
struct zfcp_fsf_req *req;
|
struct zfcp_fsf_req *req;
|
||||||
unsigned long req_id = 0;
|
u64 req_id = 0;
|
||||||
int retval = -EIO;
|
int retval = -EIO;
|
||||||
|
|
||||||
spin_lock_irq(&qdio->req_q_lock);
|
spin_lock_irq(&qdio->req_q_lock);
|
||||||
@ -1978,7 +1981,7 @@ int zfcp_fsf_close_wka_port(struct zfcp_fc_wka_port *wka_port)
|
|||||||
{
|
{
|
||||||
struct zfcp_qdio *qdio = wka_port->adapter->qdio;
|
struct zfcp_qdio *qdio = wka_port->adapter->qdio;
|
||||||
struct zfcp_fsf_req *req;
|
struct zfcp_fsf_req *req;
|
||||||
unsigned long req_id = 0;
|
u64 req_id = 0;
|
||||||
int retval = -EIO;
|
int retval = -EIO;
|
||||||
|
|
||||||
spin_lock_irq(&qdio->req_q_lock);
|
spin_lock_irq(&qdio->req_q_lock);
|
||||||
@ -2587,6 +2590,7 @@ int zfcp_fsf_fcp_cmnd(struct scsi_cmnd *scsi_cmnd)
|
|||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BUILD_BUG_ON(sizeof(scsi_cmnd->host_scribble) < sizeof(req->req_id));
|
||||||
scsi_cmnd->host_scribble = (unsigned char *) req->req_id;
|
scsi_cmnd->host_scribble = (unsigned char *) req->req_id;
|
||||||
|
|
||||||
io = &req->qtcb->bottom.io;
|
io = &req->qtcb->bottom.io;
|
||||||
@ -2732,7 +2736,7 @@ void zfcp_fsf_reqid_check(struct zfcp_qdio *qdio, int sbal_idx)
|
|||||||
struct qdio_buffer *sbal = qdio->res_q[sbal_idx];
|
struct qdio_buffer *sbal = qdio->res_q[sbal_idx];
|
||||||
struct qdio_buffer_element *sbale;
|
struct qdio_buffer_element *sbale;
|
||||||
struct zfcp_fsf_req *fsf_req;
|
struct zfcp_fsf_req *fsf_req;
|
||||||
unsigned long req_id;
|
u64 req_id;
|
||||||
int idx;
|
int idx;
|
||||||
|
|
||||||
for (idx = 0; idx < QDIO_MAX_ELEMENTS_PER_BUFFER; idx++) {
|
for (idx = 0; idx < QDIO_MAX_ELEMENTS_PER_BUFFER; idx++) {
|
||||||
@ -2747,7 +2751,7 @@ void zfcp_fsf_reqid_check(struct zfcp_qdio *qdio, int sbal_idx)
|
|||||||
* corruption and must stop the machine immediately.
|
* corruption and must stop the machine immediately.
|
||||||
*/
|
*/
|
||||||
zfcp_qdio_siosl(adapter);
|
zfcp_qdio_siosl(adapter);
|
||||||
panic("error: unknown req_id (%lx) on adapter %s.\n",
|
panic("error: unknown req_id (%llx) on adapter %s.\n",
|
||||||
req_id, dev_name(&adapter->ccw_device->dev));
|
req_id, dev_name(&adapter->ccw_device->dev));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -115,7 +115,7 @@ zfcp_qdio_sbale_curr(struct zfcp_qdio *qdio, struct zfcp_qdio_req *q_req)
|
|||||||
*/
|
*/
|
||||||
static inline
|
static inline
|
||||||
void zfcp_qdio_req_init(struct zfcp_qdio *qdio, struct zfcp_qdio_req *q_req,
|
void zfcp_qdio_req_init(struct zfcp_qdio *qdio, struct zfcp_qdio_req *q_req,
|
||||||
unsigned long req_id, u8 sbtype, void *data, u32 len)
|
u64 req_id, u8 sbtype, void *data, u32 len)
|
||||||
{
|
{
|
||||||
struct qdio_buffer_element *sbale;
|
struct qdio_buffer_element *sbale;
|
||||||
int count = min(atomic_read(&qdio->req_q_free),
|
int count = min(atomic_read(&qdio->req_q_free),
|
||||||
|
@ -5,14 +5,16 @@
|
|||||||
* Data structure and helper functions for tracking pending FSF
|
* Data structure and helper functions for tracking pending FSF
|
||||||
* requests.
|
* requests.
|
||||||
*
|
*
|
||||||
* Copyright IBM Corp. 2009, 2016
|
* Copyright IBM Corp. 2009, 2023
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef ZFCP_REQLIST_H
|
#ifndef ZFCP_REQLIST_H
|
||||||
#define ZFCP_REQLIST_H
|
#define ZFCP_REQLIST_H
|
||||||
|
|
||||||
|
#include <linux/types.h>
|
||||||
|
|
||||||
/* number of hash buckets */
|
/* number of hash buckets */
|
||||||
#define ZFCP_REQ_LIST_BUCKETS 128
|
#define ZFCP_REQ_LIST_BUCKETS 128u
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* struct zfcp_reqlist - Container for request list (reqlist)
|
* struct zfcp_reqlist - Container for request list (reqlist)
|
||||||
@ -24,7 +26,7 @@ struct zfcp_reqlist {
|
|||||||
struct list_head buckets[ZFCP_REQ_LIST_BUCKETS];
|
struct list_head buckets[ZFCP_REQ_LIST_BUCKETS];
|
||||||
};
|
};
|
||||||
|
|
||||||
static inline int zfcp_reqlist_hash(unsigned long req_id)
|
static inline size_t zfcp_reqlist_hash(u64 req_id)
|
||||||
{
|
{
|
||||||
return req_id % ZFCP_REQ_LIST_BUCKETS;
|
return req_id % ZFCP_REQ_LIST_BUCKETS;
|
||||||
}
|
}
|
||||||
@ -37,7 +39,7 @@ static inline int zfcp_reqlist_hash(unsigned long req_id)
|
|||||||
*/
|
*/
|
||||||
static inline struct zfcp_reqlist *zfcp_reqlist_alloc(void)
|
static inline struct zfcp_reqlist *zfcp_reqlist_alloc(void)
|
||||||
{
|
{
|
||||||
unsigned int i;
|
size_t i;
|
||||||
struct zfcp_reqlist *rl;
|
struct zfcp_reqlist *rl;
|
||||||
|
|
||||||
rl = kzalloc(sizeof(struct zfcp_reqlist), GFP_KERNEL);
|
rl = kzalloc(sizeof(struct zfcp_reqlist), GFP_KERNEL);
|
||||||
@ -60,7 +62,7 @@ static inline struct zfcp_reqlist *zfcp_reqlist_alloc(void)
|
|||||||
*/
|
*/
|
||||||
static inline int zfcp_reqlist_isempty(struct zfcp_reqlist *rl)
|
static inline int zfcp_reqlist_isempty(struct zfcp_reqlist *rl)
|
||||||
{
|
{
|
||||||
unsigned int i;
|
size_t i;
|
||||||
|
|
||||||
for (i = 0; i < ZFCP_REQ_LIST_BUCKETS; i++)
|
for (i = 0; i < ZFCP_REQ_LIST_BUCKETS; i++)
|
||||||
if (!list_empty(&rl->buckets[i]))
|
if (!list_empty(&rl->buckets[i]))
|
||||||
@ -81,10 +83,10 @@ static inline void zfcp_reqlist_free(struct zfcp_reqlist *rl)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static inline struct zfcp_fsf_req *
|
static inline struct zfcp_fsf_req *
|
||||||
_zfcp_reqlist_find(struct zfcp_reqlist *rl, unsigned long req_id)
|
_zfcp_reqlist_find(struct zfcp_reqlist *rl, u64 req_id)
|
||||||
{
|
{
|
||||||
struct zfcp_fsf_req *req;
|
struct zfcp_fsf_req *req;
|
||||||
unsigned int i;
|
size_t i;
|
||||||
|
|
||||||
i = zfcp_reqlist_hash(req_id);
|
i = zfcp_reqlist_hash(req_id);
|
||||||
list_for_each_entry(req, &rl->buckets[i], list)
|
list_for_each_entry(req, &rl->buckets[i], list)
|
||||||
@ -102,7 +104,7 @@ _zfcp_reqlist_find(struct zfcp_reqlist *rl, unsigned long req_id)
|
|||||||
* or NULL if there is no known FSF request with this id.
|
* or NULL if there is no known FSF request with this id.
|
||||||
*/
|
*/
|
||||||
static inline struct zfcp_fsf_req *
|
static inline struct zfcp_fsf_req *
|
||||||
zfcp_reqlist_find(struct zfcp_reqlist *rl, unsigned long req_id)
|
zfcp_reqlist_find(struct zfcp_reqlist *rl, u64 req_id)
|
||||||
{
|
{
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
struct zfcp_fsf_req *req;
|
struct zfcp_fsf_req *req;
|
||||||
@ -127,7 +129,7 @@ zfcp_reqlist_find(struct zfcp_reqlist *rl, unsigned long req_id)
|
|||||||
* NULL if it has not been found.
|
* NULL if it has not been found.
|
||||||
*/
|
*/
|
||||||
static inline struct zfcp_fsf_req *
|
static inline struct zfcp_fsf_req *
|
||||||
zfcp_reqlist_find_rm(struct zfcp_reqlist *rl, unsigned long req_id)
|
zfcp_reqlist_find_rm(struct zfcp_reqlist *rl, u64 req_id)
|
||||||
{
|
{
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
struct zfcp_fsf_req *req;
|
struct zfcp_fsf_req *req;
|
||||||
@ -154,7 +156,7 @@ zfcp_reqlist_find_rm(struct zfcp_reqlist *rl, unsigned long req_id)
|
|||||||
static inline void zfcp_reqlist_add(struct zfcp_reqlist *rl,
|
static inline void zfcp_reqlist_add(struct zfcp_reqlist *rl,
|
||||||
struct zfcp_fsf_req *req)
|
struct zfcp_fsf_req *req)
|
||||||
{
|
{
|
||||||
unsigned int i;
|
size_t i;
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
|
|
||||||
i = zfcp_reqlist_hash(req->req_id);
|
i = zfcp_reqlist_hash(req->req_id);
|
||||||
@ -172,7 +174,7 @@ static inline void zfcp_reqlist_add(struct zfcp_reqlist *rl,
|
|||||||
static inline void zfcp_reqlist_move(struct zfcp_reqlist *rl,
|
static inline void zfcp_reqlist_move(struct zfcp_reqlist *rl,
|
||||||
struct list_head *list)
|
struct list_head *list)
|
||||||
{
|
{
|
||||||
unsigned int i;
|
size_t i;
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
|
|
||||||
spin_lock_irqsave(&rl->lock, flags);
|
spin_lock_irqsave(&rl->lock, flags);
|
||||||
@ -200,7 +202,7 @@ zfcp_reqlist_apply_for_all(struct zfcp_reqlist *rl,
|
|||||||
{
|
{
|
||||||
struct zfcp_fsf_req *req;
|
struct zfcp_fsf_req *req;
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
unsigned int i;
|
size_t i;
|
||||||
|
|
||||||
spin_lock_irqsave(&rl->lock, flags);
|
spin_lock_irqsave(&rl->lock, flags);
|
||||||
for (i = 0; i < ZFCP_REQ_LIST_BUCKETS; i++)
|
for (i = 0; i < ZFCP_REQ_LIST_BUCKETS; i++)
|
||||||
|
@ -170,7 +170,7 @@ static int zfcp_scsi_eh_abort_handler(struct scsi_cmnd *scpnt)
|
|||||||
(struct zfcp_adapter *) scsi_host->hostdata[0];
|
(struct zfcp_adapter *) scsi_host->hostdata[0];
|
||||||
struct zfcp_fsf_req *old_req, *abrt_req;
|
struct zfcp_fsf_req *old_req, *abrt_req;
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
unsigned long old_reqid = (unsigned long) scpnt->host_scribble;
|
u64 old_reqid = (u64) scpnt->host_scribble;
|
||||||
int retval = SUCCESS, ret;
|
int retval = SUCCESS, ret;
|
||||||
int retry = 3;
|
int retry = 3;
|
||||||
char *dbf_tag;
|
char *dbf_tag;
|
||||||
|
@ -24,7 +24,6 @@
|
|||||||
#include <linux/scatterlist.h>
|
#include <linux/scatterlist.h>
|
||||||
#include <linux/skbuff.h>
|
#include <linux/skbuff.h>
|
||||||
#include <linux/vmalloc.h>
|
#include <linux/vmalloc.h>
|
||||||
#include <linux/version.h>
|
|
||||||
#include <scsi/scsi_device.h>
|
#include <scsi/scsi_device.h>
|
||||||
#include <scsi/libiscsi_tcp.h>
|
#include <scsi/libiscsi_tcp.h>
|
||||||
|
|
||||||
|
@ -181,6 +181,7 @@ void scsi_remove_host(struct Scsi_Host *shost)
|
|||||||
scsi_forget_host(shost);
|
scsi_forget_host(shost);
|
||||||
mutex_unlock(&shost->scan_mutex);
|
mutex_unlock(&shost->scan_mutex);
|
||||||
scsi_proc_host_rm(shost);
|
scsi_proc_host_rm(shost);
|
||||||
|
scsi_proc_hostdir_rm(shost->hostt);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* New SCSI devices cannot be attached anymore because of the SCSI host
|
* New SCSI devices cannot be attached anymore because of the SCSI host
|
||||||
@ -340,6 +341,7 @@ static void scsi_host_dev_release(struct device *dev)
|
|||||||
struct Scsi_Host *shost = dev_to_shost(dev);
|
struct Scsi_Host *shost = dev_to_shost(dev);
|
||||||
struct device *parent = dev->parent;
|
struct device *parent = dev->parent;
|
||||||
|
|
||||||
|
/* In case scsi_remove_host() has not been called. */
|
||||||
scsi_proc_hostdir_rm(shost->hostt);
|
scsi_proc_hostdir_rm(shost->hostt);
|
||||||
|
|
||||||
/* Wait for functions invoked through call_rcu(&scmd->rcu, ...) */
|
/* Wait for functions invoked through call_rcu(&scmd->rcu, ...) */
|
||||||
@ -356,7 +358,7 @@ static void scsi_host_dev_release(struct device *dev)
|
|||||||
/*
|
/*
|
||||||
* Free the shost_dev device name here if scsi_host_alloc()
|
* Free the shost_dev device name here if scsi_host_alloc()
|
||||||
* and scsi_host_put() have been called but neither
|
* and scsi_host_put() have been called but neither
|
||||||
* scsi_host_add() nor scsi_host_remove() has been called.
|
* scsi_host_add() nor scsi_remove_host() has been called.
|
||||||
* This avoids that the memory allocated for the shost_dev
|
* This avoids that the memory allocated for the shost_dev
|
||||||
* name is leaked.
|
* name is leaked.
|
||||||
*/
|
*/
|
||||||
|
@ -1516,23 +1516,22 @@ static void ipr_process_ccn(struct ipr_cmnd *ipr_cmd)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* strip_and_pad_whitespace - Strip and pad trailing whitespace.
|
* strip_whitespace - Strip and pad trailing whitespace.
|
||||||
* @i: index into buffer
|
* @i: size of buffer
|
||||||
* @buf: string to modify
|
* @buf: string to modify
|
||||||
*
|
*
|
||||||
* This function will strip all trailing whitespace, pad the end
|
* This function will strip all trailing whitespace and
|
||||||
* of the string with a single space, and NULL terminate the string.
|
* NUL terminate the string.
|
||||||
*
|
*
|
||||||
* Return value:
|
|
||||||
* new length of string
|
|
||||||
**/
|
**/
|
||||||
static int strip_and_pad_whitespace(int i, char *buf)
|
static void strip_whitespace(int i, char *buf)
|
||||||
{
|
{
|
||||||
|
if (i < 1)
|
||||||
|
return;
|
||||||
|
i--;
|
||||||
while (i && buf[i] == ' ')
|
while (i && buf[i] == ' ')
|
||||||
i--;
|
i--;
|
||||||
buf[i+1] = ' ';
|
buf[i+1] = '\0';
|
||||||
buf[i+2] = '\0';
|
|
||||||
return i + 2;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1547,19 +1546,21 @@ static int strip_and_pad_whitespace(int i, char *buf)
|
|||||||
static void ipr_log_vpd_compact(char *prefix, struct ipr_hostrcb *hostrcb,
|
static void ipr_log_vpd_compact(char *prefix, struct ipr_hostrcb *hostrcb,
|
||||||
struct ipr_vpd *vpd)
|
struct ipr_vpd *vpd)
|
||||||
{
|
{
|
||||||
char buffer[IPR_VENDOR_ID_LEN + IPR_PROD_ID_LEN + IPR_SERIAL_NUM_LEN + 3];
|
char vendor_id[IPR_VENDOR_ID_LEN + 1];
|
||||||
int i = 0;
|
char product_id[IPR_PROD_ID_LEN + 1];
|
||||||
|
char sn[IPR_SERIAL_NUM_LEN + 1];
|
||||||
|
|
||||||
memcpy(buffer, vpd->vpids.vendor_id, IPR_VENDOR_ID_LEN);
|
memcpy(vendor_id, vpd->vpids.vendor_id, IPR_VENDOR_ID_LEN);
|
||||||
i = strip_and_pad_whitespace(IPR_VENDOR_ID_LEN - 1, buffer);
|
strip_whitespace(IPR_VENDOR_ID_LEN, vendor_id);
|
||||||
|
|
||||||
memcpy(&buffer[i], vpd->vpids.product_id, IPR_PROD_ID_LEN);
|
memcpy(product_id, vpd->vpids.product_id, IPR_PROD_ID_LEN);
|
||||||
i = strip_and_pad_whitespace(i + IPR_PROD_ID_LEN - 1, buffer);
|
strip_whitespace(IPR_PROD_ID_LEN, product_id);
|
||||||
|
|
||||||
memcpy(&buffer[i], vpd->sn, IPR_SERIAL_NUM_LEN);
|
memcpy(sn, vpd->sn, IPR_SERIAL_NUM_LEN);
|
||||||
buffer[IPR_SERIAL_NUM_LEN + i] = '\0';
|
strip_whitespace(IPR_SERIAL_NUM_LEN, sn);
|
||||||
|
|
||||||
ipr_hcam_err(hostrcb, "%s VPID/SN: %s\n", prefix, buffer);
|
ipr_hcam_err(hostrcb, "%s VPID/SN: %s %s %s\n", prefix,
|
||||||
|
vendor_id, product_id, sn);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -9495,11 +9496,10 @@ static pci_ers_result_t ipr_pci_error_detected(struct pci_dev *pdev,
|
|||||||
* This function takes care of initilizing the adapter to the point
|
* This function takes care of initilizing the adapter to the point
|
||||||
* where it can accept new commands.
|
* where it can accept new commands.
|
||||||
* Return value:
|
* Return value:
|
||||||
* 0 on success / -EIO on failure
|
* none
|
||||||
**/
|
**/
|
||||||
static int ipr_probe_ioa_part2(struct ipr_ioa_cfg *ioa_cfg)
|
static void ipr_probe_ioa_part2(struct ipr_ioa_cfg *ioa_cfg)
|
||||||
{
|
{
|
||||||
int rc = 0;
|
|
||||||
unsigned long host_lock_flags = 0;
|
unsigned long host_lock_flags = 0;
|
||||||
|
|
||||||
ENTER;
|
ENTER;
|
||||||
@ -9515,7 +9515,6 @@ static int ipr_probe_ioa_part2(struct ipr_ioa_cfg *ioa_cfg)
|
|||||||
spin_unlock_irqrestore(ioa_cfg->host->host_lock, host_lock_flags);
|
spin_unlock_irqrestore(ioa_cfg->host->host_lock, host_lock_flags);
|
||||||
|
|
||||||
LEAVE;
|
LEAVE;
|
||||||
return rc;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -10558,12 +10557,7 @@ static int ipr_probe(struct pci_dev *pdev, const struct pci_device_id *dev_id)
|
|||||||
return rc;
|
return rc;
|
||||||
|
|
||||||
ioa_cfg = pci_get_drvdata(pdev);
|
ioa_cfg = pci_get_drvdata(pdev);
|
||||||
rc = ipr_probe_ioa_part2(ioa_cfg);
|
ipr_probe_ioa_part2(ioa_cfg);
|
||||||
|
|
||||||
if (rc) {
|
|
||||||
__ipr_remove(pdev);
|
|
||||||
return rc;
|
|
||||||
}
|
|
||||||
|
|
||||||
rc = scsi_add_host(ioa_cfg->host, &pdev->dev);
|
rc = scsi_add_host(ioa_cfg->host, &pdev->dev);
|
||||||
|
|
||||||
|
@ -2541,7 +2541,7 @@ lpfc_sriov_hw_max_virtfn_show(struct device *dev,
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* lpfc_enable_bbcr_set: Sets an attribute value.
|
* lpfc_enable_bbcr_set: Sets an attribute value.
|
||||||
* @phba: pointer the the adapter structure.
|
* @phba: pointer to the adapter structure.
|
||||||
* @val: integer attribute value.
|
* @val: integer attribute value.
|
||||||
*
|
*
|
||||||
* Description:
|
* Description:
|
||||||
@ -2632,7 +2632,7 @@ lpfc_##attr##_show(struct device *dev, struct device_attribute *attr, \
|
|||||||
* takes a default argument, a minimum and maximum argument.
|
* takes a default argument, a minimum and maximum argument.
|
||||||
*
|
*
|
||||||
* lpfc_##attr##_init: Initializes an attribute.
|
* lpfc_##attr##_init: Initializes an attribute.
|
||||||
* @phba: pointer the the adapter structure.
|
* @phba: pointer to the adapter structure.
|
||||||
* @val: integer attribute value.
|
* @val: integer attribute value.
|
||||||
*
|
*
|
||||||
* Validates the min and max values then sets the adapter config field
|
* Validates the min and max values then sets the adapter config field
|
||||||
@ -2665,7 +2665,7 @@ lpfc_##attr##_init(struct lpfc_hba *phba, uint val) \
|
|||||||
* into a function with the name lpfc_hba_queue_depth_set
|
* into a function with the name lpfc_hba_queue_depth_set
|
||||||
*
|
*
|
||||||
* lpfc_##attr##_set: Sets an attribute value.
|
* lpfc_##attr##_set: Sets an attribute value.
|
||||||
* @phba: pointer the the adapter structure.
|
* @phba: pointer to the adapter structure.
|
||||||
* @val: integer attribute value.
|
* @val: integer attribute value.
|
||||||
*
|
*
|
||||||
* Description:
|
* Description:
|
||||||
@ -2794,7 +2794,7 @@ lpfc_##attr##_show(struct device *dev, struct device_attribute *attr, \
|
|||||||
* lpfc_##attr##_init: validates the min and max values then sets the
|
* lpfc_##attr##_init: validates the min and max values then sets the
|
||||||
* adapter config field accordingly, or uses the default if out of range
|
* adapter config field accordingly, or uses the default if out of range
|
||||||
* and prints an error message.
|
* and prints an error message.
|
||||||
* @phba: pointer the the adapter structure.
|
* @phba: pointer to the adapter structure.
|
||||||
* @val: integer attribute value.
|
* @val: integer attribute value.
|
||||||
*
|
*
|
||||||
* Returns:
|
* Returns:
|
||||||
@ -2826,7 +2826,7 @@ lpfc_##attr##_init(struct lpfc_vport *vport, uint val) \
|
|||||||
* lpfc_##attr##_set: validates the min and max values then sets the
|
* lpfc_##attr##_set: validates the min and max values then sets the
|
||||||
* adapter config field if in the valid range. prints error message
|
* adapter config field if in the valid range. prints error message
|
||||||
* and does not set the parameter if invalid.
|
* and does not set the parameter if invalid.
|
||||||
* @phba: pointer the the adapter structure.
|
* @phba: pointer to the adapter structure.
|
||||||
* @val: integer attribute value.
|
* @val: integer attribute value.
|
||||||
*
|
*
|
||||||
* Returns:
|
* Returns:
|
||||||
|
@ -8886,7 +8886,7 @@ reject_out:
|
|||||||
* @rrq: Pointer to the rrq struct.
|
* @rrq: Pointer to the rrq struct.
|
||||||
*
|
*
|
||||||
* Build a ELS RRQ command and send it to the target. If the issue_iocb is
|
* Build a ELS RRQ command and send it to the target. If the issue_iocb is
|
||||||
* Successful the the completion handler will clear the RRQ.
|
* successful, the completion handler will clear the RRQ.
|
||||||
*
|
*
|
||||||
* Return codes
|
* Return codes
|
||||||
* 0 - Successfully sent rrq els iocb.
|
* 0 - Successfully sent rrq els iocb.
|
||||||
@ -10287,7 +10287,7 @@ lpfc_els_rcv_fpin(struct lpfc_vport *vport, void *p, u32 fpin_length)
|
|||||||
/* Send every descriptor individually to the upper layer */
|
/* Send every descriptor individually to the upper layer */
|
||||||
if (deliver)
|
if (deliver)
|
||||||
fc_host_fpin_rcv(lpfc_shost_from_vport(vport),
|
fc_host_fpin_rcv(lpfc_shost_from_vport(vport),
|
||||||
fpin_length, (char *)fpin);
|
fpin_length, (char *)fpin, 0);
|
||||||
desc_cnt++;
|
desc_cnt++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2459,7 +2459,7 @@ static void lpfc_sli4_fcf_pri_list_del(struct lpfc_hba *phba,
|
|||||||
* @phba: pointer to lpfc hba data structure.
|
* @phba: pointer to lpfc hba data structure.
|
||||||
* @fcf_index: the index of the fcf record to update
|
* @fcf_index: the index of the fcf record to update
|
||||||
* This routine acquires the hbalock and then set the LPFC_FCF_FLOGI_FAILED
|
* This routine acquires the hbalock and then set the LPFC_FCF_FLOGI_FAILED
|
||||||
* flag so the the round robin slection for the particular priority level
|
* flag so the round robin selection for the particular priority level
|
||||||
* will try a different fcf record that does not have this bit set.
|
* will try a different fcf record that does not have this bit set.
|
||||||
* If the fcf record is re-read for any reason this flag is cleared brfore
|
* If the fcf record is re-read for any reason this flag is cleared brfore
|
||||||
* adding it to the priority list.
|
* adding it to the priority list.
|
||||||
|
@ -5502,7 +5502,7 @@ lpfc_sli4_async_link_evt(struct lpfc_hba *phba,
|
|||||||
bf_set(lpfc_mbx_read_top_link_spd, la,
|
bf_set(lpfc_mbx_read_top_link_spd, la,
|
||||||
(bf_get(lpfc_acqe_link_speed, acqe_link)));
|
(bf_get(lpfc_acqe_link_speed, acqe_link)));
|
||||||
|
|
||||||
/* Fake the the following irrelvant fields */
|
/* Fake the following irrelevant fields */
|
||||||
bf_set(lpfc_mbx_read_top_topology, la, LPFC_TOPOLOGY_PT_PT);
|
bf_set(lpfc_mbx_read_top_topology, la, LPFC_TOPOLOGY_PT_PT);
|
||||||
bf_set(lpfc_mbx_read_top_alpa_granted, la, 0);
|
bf_set(lpfc_mbx_read_top_alpa_granted, la, 0);
|
||||||
bf_set(lpfc_mbx_read_top_il, la, 0);
|
bf_set(lpfc_mbx_read_top_il, la, 0);
|
||||||
@ -12549,7 +12549,7 @@ lpfc_cpu_affinity_check(struct lpfc_hba *phba, int vectors)
|
|||||||
/* Mark CPU as IRQ not assigned by the kernel */
|
/* Mark CPU as IRQ not assigned by the kernel */
|
||||||
cpup->flag |= LPFC_CPU_MAP_UNASSIGN;
|
cpup->flag |= LPFC_CPU_MAP_UNASSIGN;
|
||||||
|
|
||||||
/* If so, find a new_cpup thats on the the SAME
|
/* If so, find a new_cpup that is on the SAME
|
||||||
* phys_id as cpup. start_cpu will start where we
|
* phys_id as cpup. start_cpu will start where we
|
||||||
* left off so all unassigned entries don't get assgined
|
* left off so all unassigned entries don't get assgined
|
||||||
* the IRQ of the first entry.
|
* the IRQ of the first entry.
|
||||||
|
@ -2509,7 +2509,7 @@ lpfc_sli4_dump_page_a0(struct lpfc_hba *phba, struct lpfcMboxq *mbox)
|
|||||||
* information via a READ_FCF mailbox command. This mailbox command also is used
|
* information via a READ_FCF mailbox command. This mailbox command also is used
|
||||||
* to indicate where received unsolicited frames from this FCF will be sent. By
|
* to indicate where received unsolicited frames from this FCF will be sent. By
|
||||||
* default this routine will set up the FCF to forward all unsolicited frames
|
* default this routine will set up the FCF to forward all unsolicited frames
|
||||||
* the the RQ ID passed in the @phba. This can be overridden by the caller for
|
* to the RQ ID passed in the @phba. This can be overridden by the caller for
|
||||||
* more complicated setups.
|
* more complicated setups.
|
||||||
**/
|
**/
|
||||||
void
|
void
|
||||||
@ -2577,7 +2577,7 @@ lpfc_reg_fcfi(struct lpfc_hba *phba, struct lpfcMboxq *mbox)
|
|||||||
* information via a READ_FCF mailbox command. This mailbox command also is used
|
* information via a READ_FCF mailbox command. This mailbox command also is used
|
||||||
* to indicate where received unsolicited frames from this FCF will be sent. By
|
* to indicate where received unsolicited frames from this FCF will be sent. By
|
||||||
* default this routine will set up the FCF to forward all unsolicited frames
|
* default this routine will set up the FCF to forward all unsolicited frames
|
||||||
* the the RQ ID passed in the @phba. This can be overridden by the caller for
|
* to the RQ ID passed in the @phba. This can be overridden by the caller for
|
||||||
* more complicated setups.
|
* more complicated setups.
|
||||||
**/
|
**/
|
||||||
void
|
void
|
||||||
|
@ -1469,7 +1469,7 @@ lpfc_nvmet_cleanup_io_context(struct lpfc_hba *phba)
|
|||||||
if (!infop)
|
if (!infop)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/* Cycle the the entire CPU context list for every MRQ */
|
/* Cycle the entire CPU context list for every MRQ */
|
||||||
for (i = 0; i < phba->cfg_nvmet_mrq; i++) {
|
for (i = 0; i < phba->cfg_nvmet_mrq; i++) {
|
||||||
for_each_present_cpu(j) {
|
for_each_present_cpu(j) {
|
||||||
infop = lpfc_get_ctx_list(phba, j, i);
|
infop = lpfc_get_ctx_list(phba, j, i);
|
||||||
|
@ -20804,7 +20804,7 @@ lpfc_log_fw_write_cmpl(struct lpfc_hba *phba, u32 shdr_status,
|
|||||||
* the offset after the write object mailbox has completed. @size is used to
|
* the offset after the write object mailbox has completed. @size is used to
|
||||||
* determine the end of the object and whether the eof bit should be set.
|
* determine the end of the object and whether the eof bit should be set.
|
||||||
*
|
*
|
||||||
* Return 0 is successful and offset will contain the the new offset to use
|
* Return 0 is successful and offset will contain the new offset to use
|
||||||
* for the next write.
|
* for the next write.
|
||||||
* Return negative value for error cases.
|
* Return negative value for error cases.
|
||||||
**/
|
**/
|
||||||
|
@ -29,7 +29,6 @@
|
|||||||
#include <linux/types.h>
|
#include <linux/types.h>
|
||||||
#include <linux/uaccess.h>
|
#include <linux/uaccess.h>
|
||||||
#include <linux/utsname.h>
|
#include <linux/utsname.h>
|
||||||
#include <linux/version.h>
|
|
||||||
#include <linux/workqueue.h>
|
#include <linux/workqueue.h>
|
||||||
#include <asm/unaligned.h>
|
#include <asm/unaligned.h>
|
||||||
#include <scsi/scsi.h>
|
#include <scsi/scsi.h>
|
||||||
@ -955,19 +954,16 @@ struct scmd_priv {
|
|||||||
* @chain_buf_count: Chain buffer count
|
* @chain_buf_count: Chain buffer count
|
||||||
* @chain_buf_pool: Chain buffer pool
|
* @chain_buf_pool: Chain buffer pool
|
||||||
* @chain_sgl_list: Chain SGL list
|
* @chain_sgl_list: Chain SGL list
|
||||||
* @chain_bitmap_sz: Chain buffer allocator bitmap size
|
|
||||||
* @chain_bitmap: Chain buffer allocator bitmap
|
* @chain_bitmap: Chain buffer allocator bitmap
|
||||||
* @chain_buf_lock: Chain buffer list lock
|
* @chain_buf_lock: Chain buffer list lock
|
||||||
* @bsg_cmds: Command tracker for BSG command
|
* @bsg_cmds: Command tracker for BSG command
|
||||||
* @host_tm_cmds: Command tracker for task management commands
|
* @host_tm_cmds: Command tracker for task management commands
|
||||||
* @dev_rmhs_cmds: Command tracker for device removal commands
|
* @dev_rmhs_cmds: Command tracker for device removal commands
|
||||||
* @evtack_cmds: Command tracker for event ack commands
|
* @evtack_cmds: Command tracker for event ack commands
|
||||||
* @devrem_bitmap_sz: Device removal bitmap size
|
|
||||||
* @devrem_bitmap: Device removal bitmap
|
* @devrem_bitmap: Device removal bitmap
|
||||||
* @dev_handle_bitmap_sz: Device handle bitmap size
|
* @dev_handle_bitmap_bits: Number of bits in device handle bitmap
|
||||||
* @removepend_bitmap: Remove pending bitmap
|
* @removepend_bitmap: Remove pending bitmap
|
||||||
* @delayed_rmhs_list: Delayed device removal list
|
* @delayed_rmhs_list: Delayed device removal list
|
||||||
* @evtack_cmds_bitmap_sz: Event Ack bitmap size
|
|
||||||
* @evtack_cmds_bitmap: Event Ack bitmap
|
* @evtack_cmds_bitmap: Event Ack bitmap
|
||||||
* @delayed_evtack_cmds_list: Delayed event acknowledgment list
|
* @delayed_evtack_cmds_list: Delayed event acknowledgment list
|
||||||
* @ts_update_counter: Timestamp update counter
|
* @ts_update_counter: Timestamp update counter
|
||||||
@ -1128,7 +1124,6 @@ struct mpi3mr_ioc {
|
|||||||
u32 chain_buf_count;
|
u32 chain_buf_count;
|
||||||
struct dma_pool *chain_buf_pool;
|
struct dma_pool *chain_buf_pool;
|
||||||
struct chain_element *chain_sgl_list;
|
struct chain_element *chain_sgl_list;
|
||||||
u16 chain_bitmap_sz;
|
|
||||||
void *chain_bitmap;
|
void *chain_bitmap;
|
||||||
spinlock_t chain_buf_lock;
|
spinlock_t chain_buf_lock;
|
||||||
|
|
||||||
@ -1136,12 +1131,10 @@ struct mpi3mr_ioc {
|
|||||||
struct mpi3mr_drv_cmd host_tm_cmds;
|
struct mpi3mr_drv_cmd host_tm_cmds;
|
||||||
struct mpi3mr_drv_cmd dev_rmhs_cmds[MPI3MR_NUM_DEVRMCMD];
|
struct mpi3mr_drv_cmd dev_rmhs_cmds[MPI3MR_NUM_DEVRMCMD];
|
||||||
struct mpi3mr_drv_cmd evtack_cmds[MPI3MR_NUM_EVTACKCMD];
|
struct mpi3mr_drv_cmd evtack_cmds[MPI3MR_NUM_EVTACKCMD];
|
||||||
u16 devrem_bitmap_sz;
|
|
||||||
void *devrem_bitmap;
|
void *devrem_bitmap;
|
||||||
u16 dev_handle_bitmap_sz;
|
u16 dev_handle_bitmap_bits;
|
||||||
void *removepend_bitmap;
|
void *removepend_bitmap;
|
||||||
struct list_head delayed_rmhs_list;
|
struct list_head delayed_rmhs_list;
|
||||||
u16 evtack_cmds_bitmap_sz;
|
|
||||||
void *evtack_cmds_bitmap;
|
void *evtack_cmds_bitmap;
|
||||||
struct list_head delayed_evtack_cmds_list;
|
struct list_head delayed_evtack_cmds_list;
|
||||||
|
|
||||||
|
@ -293,7 +293,6 @@ out:
|
|||||||
static long mpi3mr_get_all_tgt_info(struct mpi3mr_ioc *mrioc,
|
static long mpi3mr_get_all_tgt_info(struct mpi3mr_ioc *mrioc,
|
||||||
struct bsg_job *job)
|
struct bsg_job *job)
|
||||||
{
|
{
|
||||||
long rval = -EINVAL;
|
|
||||||
u16 num_devices = 0, i = 0, size;
|
u16 num_devices = 0, i = 0, size;
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
struct mpi3mr_tgt_dev *tgtdev;
|
struct mpi3mr_tgt_dev *tgtdev;
|
||||||
@ -304,7 +303,7 @@ static long mpi3mr_get_all_tgt_info(struct mpi3mr_ioc *mrioc,
|
|||||||
if (job->request_payload.payload_len < sizeof(u32)) {
|
if (job->request_payload.payload_len < sizeof(u32)) {
|
||||||
dprint_bsg_err(mrioc, "%s: invalid size argument\n",
|
dprint_bsg_err(mrioc, "%s: invalid size argument\n",
|
||||||
__func__);
|
__func__);
|
||||||
return rval;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
spin_lock_irqsave(&mrioc->tgtdev_lock, flags);
|
spin_lock_irqsave(&mrioc->tgtdev_lock, flags);
|
||||||
@ -312,7 +311,7 @@ static long mpi3mr_get_all_tgt_info(struct mpi3mr_ioc *mrioc,
|
|||||||
num_devices++;
|
num_devices++;
|
||||||
spin_unlock_irqrestore(&mrioc->tgtdev_lock, flags);
|
spin_unlock_irqrestore(&mrioc->tgtdev_lock, flags);
|
||||||
|
|
||||||
if ((job->request_payload.payload_len == sizeof(u32)) ||
|
if ((job->request_payload.payload_len <= sizeof(u64)) ||
|
||||||
list_empty(&mrioc->tgtdev_list)) {
|
list_empty(&mrioc->tgtdev_list)) {
|
||||||
sg_copy_from_buffer(job->request_payload.sg_list,
|
sg_copy_from_buffer(job->request_payload.sg_list,
|
||||||
job->request_payload.sg_cnt,
|
job->request_payload.sg_cnt,
|
||||||
@ -320,14 +319,14 @@ static long mpi3mr_get_all_tgt_info(struct mpi3mr_ioc *mrioc,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
kern_entrylen = (num_devices - 1) * sizeof(*devmap_info);
|
kern_entrylen = num_devices * sizeof(*devmap_info);
|
||||||
size = sizeof(*alltgt_info) + kern_entrylen;
|
size = sizeof(u64) + kern_entrylen;
|
||||||
alltgt_info = kzalloc(size, GFP_KERNEL);
|
alltgt_info = kzalloc(size, GFP_KERNEL);
|
||||||
if (!alltgt_info)
|
if (!alltgt_info)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
devmap_info = alltgt_info->dmi;
|
devmap_info = alltgt_info->dmi;
|
||||||
memset((u8 *)devmap_info, 0xFF, (kern_entrylen + sizeof(*devmap_info)));
|
memset((u8 *)devmap_info, 0xFF, kern_entrylen);
|
||||||
spin_lock_irqsave(&mrioc->tgtdev_lock, flags);
|
spin_lock_irqsave(&mrioc->tgtdev_lock, flags);
|
||||||
list_for_each_entry(tgtdev, &mrioc->tgtdev_list, list) {
|
list_for_each_entry(tgtdev, &mrioc->tgtdev_list, list) {
|
||||||
if (i < num_devices) {
|
if (i < num_devices) {
|
||||||
@ -344,25 +343,18 @@ static long mpi3mr_get_all_tgt_info(struct mpi3mr_ioc *mrioc,
|
|||||||
num_devices = i;
|
num_devices = i;
|
||||||
spin_unlock_irqrestore(&mrioc->tgtdev_lock, flags);
|
spin_unlock_irqrestore(&mrioc->tgtdev_lock, flags);
|
||||||
|
|
||||||
memcpy(&alltgt_info->num_devices, &num_devices, sizeof(num_devices));
|
alltgt_info->num_devices = num_devices;
|
||||||
|
|
||||||
usr_entrylen = (job->request_payload.payload_len - sizeof(u32)) / sizeof(*devmap_info);
|
usr_entrylen = (job->request_payload.payload_len - sizeof(u64)) /
|
||||||
|
sizeof(*devmap_info);
|
||||||
usr_entrylen *= sizeof(*devmap_info);
|
usr_entrylen *= sizeof(*devmap_info);
|
||||||
min_entrylen = min(usr_entrylen, kern_entrylen);
|
min_entrylen = min(usr_entrylen, kern_entrylen);
|
||||||
if (min_entrylen && (!memcpy(&alltgt_info->dmi, devmap_info, min_entrylen))) {
|
|
||||||
dprint_bsg_err(mrioc, "%s:%d: device map info copy failed\n",
|
|
||||||
__func__, __LINE__);
|
|
||||||
rval = -EFAULT;
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
|
|
||||||
sg_copy_from_buffer(job->request_payload.sg_list,
|
sg_copy_from_buffer(job->request_payload.sg_list,
|
||||||
job->request_payload.sg_cnt,
|
job->request_payload.sg_cnt,
|
||||||
alltgt_info, job->request_payload.payload_len);
|
alltgt_info, (min_entrylen + sizeof(u64)));
|
||||||
rval = 0;
|
|
||||||
out:
|
|
||||||
kfree(alltgt_info);
|
kfree(alltgt_info);
|
||||||
return rval;
|
return 0;
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* mpi3mr_get_change_count - Get topology change count
|
* mpi3mr_get_change_count - Get topology change count
|
||||||
|
@ -1128,7 +1128,6 @@ static int mpi3mr_issue_and_process_mur(struct mpi3mr_ioc *mrioc,
|
|||||||
static int
|
static int
|
||||||
mpi3mr_revalidate_factsdata(struct mpi3mr_ioc *mrioc)
|
mpi3mr_revalidate_factsdata(struct mpi3mr_ioc *mrioc)
|
||||||
{
|
{
|
||||||
u16 dev_handle_bitmap_sz;
|
|
||||||
void *removepend_bitmap;
|
void *removepend_bitmap;
|
||||||
|
|
||||||
if (mrioc->facts.reply_sz > mrioc->reply_sz) {
|
if (mrioc->facts.reply_sz > mrioc->reply_sz) {
|
||||||
@ -1160,25 +1159,23 @@ mpi3mr_revalidate_factsdata(struct mpi3mr_ioc *mrioc)
|
|||||||
"\tcontroller while sas transport support is enabled at the\n"
|
"\tcontroller while sas transport support is enabled at the\n"
|
||||||
"\tdriver, please reboot the system or reload the driver\n");
|
"\tdriver, please reboot the system or reload the driver\n");
|
||||||
|
|
||||||
dev_handle_bitmap_sz = mrioc->facts.max_devhandle / 8;
|
if (mrioc->facts.max_devhandle > mrioc->dev_handle_bitmap_bits) {
|
||||||
if (mrioc->facts.max_devhandle % 8)
|
removepend_bitmap = bitmap_zalloc(mrioc->facts.max_devhandle,
|
||||||
dev_handle_bitmap_sz++;
|
GFP_KERNEL);
|
||||||
if (dev_handle_bitmap_sz > mrioc->dev_handle_bitmap_sz) {
|
|
||||||
removepend_bitmap = krealloc(mrioc->removepend_bitmap,
|
|
||||||
dev_handle_bitmap_sz, GFP_KERNEL);
|
|
||||||
if (!removepend_bitmap) {
|
if (!removepend_bitmap) {
|
||||||
ioc_err(mrioc,
|
ioc_err(mrioc,
|
||||||
"failed to increase removepend_bitmap sz from: %d to %d\n",
|
"failed to increase removepend_bitmap bits from %d to %d\n",
|
||||||
mrioc->dev_handle_bitmap_sz, dev_handle_bitmap_sz);
|
mrioc->dev_handle_bitmap_bits,
|
||||||
|
mrioc->facts.max_devhandle);
|
||||||
return -EPERM;
|
return -EPERM;
|
||||||
}
|
}
|
||||||
memset(removepend_bitmap + mrioc->dev_handle_bitmap_sz, 0,
|
bitmap_free(mrioc->removepend_bitmap);
|
||||||
dev_handle_bitmap_sz - mrioc->dev_handle_bitmap_sz);
|
|
||||||
mrioc->removepend_bitmap = removepend_bitmap;
|
mrioc->removepend_bitmap = removepend_bitmap;
|
||||||
ioc_info(mrioc,
|
ioc_info(mrioc,
|
||||||
"increased dev_handle_bitmap_sz from %d to %d\n",
|
"increased bits of dev_handle_bitmap from %d to %d\n",
|
||||||
mrioc->dev_handle_bitmap_sz, dev_handle_bitmap_sz);
|
mrioc->dev_handle_bitmap_bits,
|
||||||
mrioc->dev_handle_bitmap_sz = dev_handle_bitmap_sz;
|
mrioc->facts.max_devhandle);
|
||||||
|
mrioc->dev_handle_bitmap_bits = mrioc->facts.max_devhandle;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@ -2957,27 +2954,18 @@ static int mpi3mr_alloc_reply_sense_bufs(struct mpi3mr_ioc *mrioc)
|
|||||||
if (!mrioc->pel_abort_cmd.reply)
|
if (!mrioc->pel_abort_cmd.reply)
|
||||||
goto out_failed;
|
goto out_failed;
|
||||||
|
|
||||||
mrioc->dev_handle_bitmap_sz = mrioc->facts.max_devhandle / 8;
|
mrioc->dev_handle_bitmap_bits = mrioc->facts.max_devhandle;
|
||||||
if (mrioc->facts.max_devhandle % 8)
|
mrioc->removepend_bitmap = bitmap_zalloc(mrioc->dev_handle_bitmap_bits,
|
||||||
mrioc->dev_handle_bitmap_sz++;
|
GFP_KERNEL);
|
||||||
mrioc->removepend_bitmap = kzalloc(mrioc->dev_handle_bitmap_sz,
|
|
||||||
GFP_KERNEL);
|
|
||||||
if (!mrioc->removepend_bitmap)
|
if (!mrioc->removepend_bitmap)
|
||||||
goto out_failed;
|
goto out_failed;
|
||||||
|
|
||||||
mrioc->devrem_bitmap_sz = MPI3MR_NUM_DEVRMCMD / 8;
|
mrioc->devrem_bitmap = bitmap_zalloc(MPI3MR_NUM_DEVRMCMD, GFP_KERNEL);
|
||||||
if (MPI3MR_NUM_DEVRMCMD % 8)
|
|
||||||
mrioc->devrem_bitmap_sz++;
|
|
||||||
mrioc->devrem_bitmap = kzalloc(mrioc->devrem_bitmap_sz,
|
|
||||||
GFP_KERNEL);
|
|
||||||
if (!mrioc->devrem_bitmap)
|
if (!mrioc->devrem_bitmap)
|
||||||
goto out_failed;
|
goto out_failed;
|
||||||
|
|
||||||
mrioc->evtack_cmds_bitmap_sz = MPI3MR_NUM_EVTACKCMD / 8;
|
mrioc->evtack_cmds_bitmap = bitmap_zalloc(MPI3MR_NUM_EVTACKCMD,
|
||||||
if (MPI3MR_NUM_EVTACKCMD % 8)
|
GFP_KERNEL);
|
||||||
mrioc->evtack_cmds_bitmap_sz++;
|
|
||||||
mrioc->evtack_cmds_bitmap = kzalloc(mrioc->evtack_cmds_bitmap_sz,
|
|
||||||
GFP_KERNEL);
|
|
||||||
if (!mrioc->evtack_cmds_bitmap)
|
if (!mrioc->evtack_cmds_bitmap)
|
||||||
goto out_failed;
|
goto out_failed;
|
||||||
|
|
||||||
@ -3415,10 +3403,7 @@ static int mpi3mr_alloc_chain_bufs(struct mpi3mr_ioc *mrioc)
|
|||||||
if (!mrioc->chain_sgl_list[i].addr)
|
if (!mrioc->chain_sgl_list[i].addr)
|
||||||
goto out_failed;
|
goto out_failed;
|
||||||
}
|
}
|
||||||
mrioc->chain_bitmap_sz = num_chains / 8;
|
mrioc->chain_bitmap = bitmap_zalloc(num_chains, GFP_KERNEL);
|
||||||
if (num_chains % 8)
|
|
||||||
mrioc->chain_bitmap_sz++;
|
|
||||||
mrioc->chain_bitmap = kzalloc(mrioc->chain_bitmap_sz, GFP_KERNEL);
|
|
||||||
if (!mrioc->chain_bitmap)
|
if (!mrioc->chain_bitmap)
|
||||||
goto out_failed;
|
goto out_failed;
|
||||||
return retval;
|
return retval;
|
||||||
@ -4189,10 +4174,11 @@ void mpi3mr_memset_buffers(struct mpi3mr_ioc *mrioc)
|
|||||||
for (i = 0; i < MPI3MR_NUM_EVTACKCMD; i++)
|
for (i = 0; i < MPI3MR_NUM_EVTACKCMD; i++)
|
||||||
memset(mrioc->evtack_cmds[i].reply, 0,
|
memset(mrioc->evtack_cmds[i].reply, 0,
|
||||||
sizeof(*mrioc->evtack_cmds[i].reply));
|
sizeof(*mrioc->evtack_cmds[i].reply));
|
||||||
memset(mrioc->removepend_bitmap, 0, mrioc->dev_handle_bitmap_sz);
|
bitmap_clear(mrioc->removepend_bitmap, 0,
|
||||||
memset(mrioc->devrem_bitmap, 0, mrioc->devrem_bitmap_sz);
|
mrioc->dev_handle_bitmap_bits);
|
||||||
memset(mrioc->evtack_cmds_bitmap, 0,
|
bitmap_clear(mrioc->devrem_bitmap, 0, MPI3MR_NUM_DEVRMCMD);
|
||||||
mrioc->evtack_cmds_bitmap_sz);
|
bitmap_clear(mrioc->evtack_cmds_bitmap, 0,
|
||||||
|
MPI3MR_NUM_EVTACKCMD);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < mrioc->num_queues; i++) {
|
for (i = 0; i < mrioc->num_queues; i++) {
|
||||||
@ -4318,16 +4304,16 @@ void mpi3mr_free_mem(struct mpi3mr_ioc *mrioc)
|
|||||||
mrioc->evtack_cmds[i].reply = NULL;
|
mrioc->evtack_cmds[i].reply = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
kfree(mrioc->removepend_bitmap);
|
bitmap_free(mrioc->removepend_bitmap);
|
||||||
mrioc->removepend_bitmap = NULL;
|
mrioc->removepend_bitmap = NULL;
|
||||||
|
|
||||||
kfree(mrioc->devrem_bitmap);
|
bitmap_free(mrioc->devrem_bitmap);
|
||||||
mrioc->devrem_bitmap = NULL;
|
mrioc->devrem_bitmap = NULL;
|
||||||
|
|
||||||
kfree(mrioc->evtack_cmds_bitmap);
|
bitmap_free(mrioc->evtack_cmds_bitmap);
|
||||||
mrioc->evtack_cmds_bitmap = NULL;
|
mrioc->evtack_cmds_bitmap = NULL;
|
||||||
|
|
||||||
kfree(mrioc->chain_bitmap);
|
bitmap_free(mrioc->chain_bitmap);
|
||||||
mrioc->chain_bitmap = NULL;
|
mrioc->chain_bitmap = NULL;
|
||||||
|
|
||||||
kfree(mrioc->transport_cmds.reply);
|
kfree(mrioc->transport_cmds.reply);
|
||||||
@ -4886,9 +4872,10 @@ int mpi3mr_soft_reset_handler(struct mpi3mr_ioc *mrioc,
|
|||||||
|
|
||||||
mpi3mr_flush_delayed_cmd_lists(mrioc);
|
mpi3mr_flush_delayed_cmd_lists(mrioc);
|
||||||
mpi3mr_flush_drv_cmds(mrioc);
|
mpi3mr_flush_drv_cmds(mrioc);
|
||||||
memset(mrioc->devrem_bitmap, 0, mrioc->devrem_bitmap_sz);
|
bitmap_clear(mrioc->devrem_bitmap, 0, MPI3MR_NUM_DEVRMCMD);
|
||||||
memset(mrioc->removepend_bitmap, 0, mrioc->dev_handle_bitmap_sz);
|
bitmap_clear(mrioc->removepend_bitmap, 0,
|
||||||
memset(mrioc->evtack_cmds_bitmap, 0, mrioc->evtack_cmds_bitmap_sz);
|
mrioc->dev_handle_bitmap_bits);
|
||||||
|
bitmap_clear(mrioc->evtack_cmds_bitmap, 0, MPI3MR_NUM_EVTACKCMD);
|
||||||
mpi3mr_flush_host_io(mrioc);
|
mpi3mr_flush_host_io(mrioc);
|
||||||
mpi3mr_cleanup_fwevt_list(mrioc);
|
mpi3mr_cleanup_fwevt_list(mrioc);
|
||||||
mpi3mr_invalidate_devhandles(mrioc);
|
mpi3mr_invalidate_devhandles(mrioc);
|
||||||
|
@ -4952,6 +4952,10 @@ mpi3mr_probe(struct pci_dev *pdev, const struct pci_device_id *id)
|
|||||||
mpi3mr_init_drv_cmd(&mrioc->dev_rmhs_cmds[i],
|
mpi3mr_init_drv_cmd(&mrioc->dev_rmhs_cmds[i],
|
||||||
MPI3MR_HOSTTAG_DEVRMCMD_MIN + i);
|
MPI3MR_HOSTTAG_DEVRMCMD_MIN + i);
|
||||||
|
|
||||||
|
for (i = 0; i < MPI3MR_NUM_EVTACKCMD; i++)
|
||||||
|
mpi3mr_init_drv_cmd(&mrioc->evtack_cmds[i],
|
||||||
|
MPI3MR_HOSTTAG_EVTACKCMD_MIN + i);
|
||||||
|
|
||||||
if (pdev->revision)
|
if (pdev->revision)
|
||||||
mrioc->enable_segqueue = true;
|
mrioc->enable_segqueue = true;
|
||||||
|
|
||||||
|
@ -1280,7 +1280,7 @@ void mpi3mr_sas_host_add(struct mpi3mr_ioc *mrioc)
|
|||||||
|
|
||||||
if (mrioc->sas_hba.enclosure_handle) {
|
if (mrioc->sas_hba.enclosure_handle) {
|
||||||
if (!(mpi3mr_cfg_get_enclosure_pg0(mrioc, &ioc_status,
|
if (!(mpi3mr_cfg_get_enclosure_pg0(mrioc, &ioc_status,
|
||||||
&encl_pg0, sizeof(dev_pg0),
|
&encl_pg0, sizeof(encl_pg0),
|
||||||
MPI3_ENCLOS_PGAD_FORM_HANDLE,
|
MPI3_ENCLOS_PGAD_FORM_HANDLE,
|
||||||
mrioc->sas_hba.enclosure_handle)) &&
|
mrioc->sas_hba.enclosure_handle)) &&
|
||||||
(ioc_status == MPI3_IOCSTATUS_SUCCESS))
|
(ioc_status == MPI3_IOCSTATUS_SUCCESS))
|
||||||
|
@ -11,7 +11,6 @@
|
|||||||
#include <linux/kernel.h>
|
#include <linux/kernel.h>
|
||||||
#include <linux/compiler.h>
|
#include <linux/compiler.h>
|
||||||
#include <linux/string.h>
|
#include <linux/string.h>
|
||||||
#include <linux/version.h>
|
|
||||||
#include <linux/pci.h>
|
#include <linux/pci.h>
|
||||||
#include <linux/delay.h>
|
#include <linux/delay.h>
|
||||||
#include <scsi/scsi_transport.h>
|
#include <scsi/scsi_transport.h>
|
||||||
|
@ -45,7 +45,7 @@ qla27xx_process_purex_fpin(struct scsi_qla_host *vha, struct purex_item *item)
|
|||||||
ql_dump_buffer(ql_dbg_init + ql_dbg_verbose, vha, 0x508f,
|
ql_dump_buffer(ql_dbg_init + ql_dbg_verbose, vha, 0x508f,
|
||||||
pkt, pkt_size);
|
pkt, pkt_size);
|
||||||
|
|
||||||
fc_host_fpin_rcv(vha->host, pkt_size, (char *)pkt);
|
fc_host_fpin_rcv(vha->host, pkt_size, (char *)pkt, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
const char *const port_state_str[] = {
|
const char *const port_state_str[] = {
|
||||||
|
@ -229,6 +229,7 @@ int scsi_execute_cmd(struct scsi_device *sdev, const unsigned char *cmd,
|
|||||||
scmd->cmd_len = COMMAND_SIZE(cmd[0]);
|
scmd->cmd_len = COMMAND_SIZE(cmd[0]);
|
||||||
memcpy(scmd->cmnd, cmd, scmd->cmd_len);
|
memcpy(scmd->cmnd, cmd, scmd->cmd_len);
|
||||||
scmd->allowed = retries;
|
scmd->allowed = retries;
|
||||||
|
scmd->flags |= args->scmd_flags;
|
||||||
req->timeout = timeout;
|
req->timeout = timeout;
|
||||||
req->rq_flags |= RQF_QUIET;
|
req->rq_flags |= RQF_QUIET;
|
||||||
|
|
||||||
|
@ -137,6 +137,7 @@ static const struct {
|
|||||||
{ FCH_EVT_PORT_FABRIC, "port_fabric" },
|
{ FCH_EVT_PORT_FABRIC, "port_fabric" },
|
||||||
{ FCH_EVT_LINK_UNKNOWN, "link_unknown" },
|
{ FCH_EVT_LINK_UNKNOWN, "link_unknown" },
|
||||||
{ FCH_EVT_LINK_FPIN, "link_FPIN" },
|
{ FCH_EVT_LINK_FPIN, "link_FPIN" },
|
||||||
|
{ FCH_EVT_LINK_FPIN_ACK, "link_FPIN_ACK" },
|
||||||
{ FCH_EVT_VENDOR_UNIQUE, "vendor_unique" },
|
{ FCH_EVT_VENDOR_UNIQUE, "vendor_unique" },
|
||||||
};
|
};
|
||||||
fc_enum_name_search(host_event_code, fc_host_event_code,
|
fc_enum_name_search(host_event_code, fc_host_event_code,
|
||||||
@ -894,17 +895,20 @@ fc_fpin_congn_stats_update(struct Scsi_Host *shost,
|
|||||||
* @shost: host the FPIN was received on
|
* @shost: host the FPIN was received on
|
||||||
* @fpin_len: length of FPIN payload, in bytes
|
* @fpin_len: length of FPIN payload, in bytes
|
||||||
* @fpin_buf: pointer to FPIN payload
|
* @fpin_buf: pointer to FPIN payload
|
||||||
*
|
* @event_acknowledge: 1, if LLDD handles this event.
|
||||||
* Notes:
|
* Notes:
|
||||||
* This routine assumes no locks are held on entry.
|
* This routine assumes no locks are held on entry.
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
fc_host_fpin_rcv(struct Scsi_Host *shost, u32 fpin_len, char *fpin_buf)
|
fc_host_fpin_rcv(struct Scsi_Host *shost, u32 fpin_len, char *fpin_buf,
|
||||||
|
u8 event_acknowledge)
|
||||||
{
|
{
|
||||||
struct fc_els_fpin *fpin = (struct fc_els_fpin *)fpin_buf;
|
struct fc_els_fpin *fpin = (struct fc_els_fpin *)fpin_buf;
|
||||||
struct fc_tlv_desc *tlv;
|
struct fc_tlv_desc *tlv;
|
||||||
u32 desc_cnt = 0, bytes_remain;
|
u32 desc_cnt = 0, bytes_remain;
|
||||||
u32 dtag;
|
u32 dtag;
|
||||||
|
enum fc_host_event_code event_code =
|
||||||
|
event_acknowledge ? FCH_EVT_LINK_FPIN_ACK : FCH_EVT_LINK_FPIN;
|
||||||
|
|
||||||
/* Update Statistics */
|
/* Update Statistics */
|
||||||
tlv = (struct fc_tlv_desc *)&fpin->fpin_desc[0];
|
tlv = (struct fc_tlv_desc *)&fpin->fpin_desc[0];
|
||||||
@ -934,7 +938,7 @@ fc_host_fpin_rcv(struct Scsi_Host *shost, u32 fpin_len, char *fpin_buf)
|
|||||||
}
|
}
|
||||||
|
|
||||||
fc_host_post_fc_event(shost, fc_get_event_number(),
|
fc_host_post_fc_event(shost, fc_get_event_number(),
|
||||||
FCH_EVT_LINK_FPIN, fpin_len, fpin_buf, 0);
|
event_code, fpin_len, fpin_buf, 0);
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(fc_host_fpin_rcv);
|
EXPORT_SYMBOL(fc_host_fpin_rcv);
|
||||||
|
|
||||||
|
@ -121,7 +121,6 @@ static void scsi_disk_release(struct device *cdev);
|
|||||||
|
|
||||||
static DEFINE_IDA(sd_index_ida);
|
static DEFINE_IDA(sd_index_ida);
|
||||||
|
|
||||||
static struct kmem_cache *sd_cdb_cache;
|
|
||||||
static mempool_t *sd_page_pool;
|
static mempool_t *sd_page_pool;
|
||||||
static struct lock_class_key sd_bio_compl_lkclass;
|
static struct lock_class_key sd_bio_compl_lkclass;
|
||||||
|
|
||||||
@ -2252,23 +2251,20 @@ static void sd_config_protection(struct scsi_disk *sdkp)
|
|||||||
{
|
{
|
||||||
struct scsi_device *sdp = sdkp->device;
|
struct scsi_device *sdp = sdkp->device;
|
||||||
|
|
||||||
if (!sdkp->first_scan)
|
|
||||||
return;
|
|
||||||
|
|
||||||
sd_dif_config_host(sdkp);
|
sd_dif_config_host(sdkp);
|
||||||
|
|
||||||
if (!sdkp->protection_type)
|
if (!sdkp->protection_type)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (!scsi_host_dif_capable(sdp->host, sdkp->protection_type)) {
|
if (!scsi_host_dif_capable(sdp->host, sdkp->protection_type)) {
|
||||||
sd_printk(KERN_NOTICE, sdkp,
|
sd_first_printk(KERN_NOTICE, sdkp,
|
||||||
"Disabling DIF Type %u protection\n",
|
"Disabling DIF Type %u protection\n",
|
||||||
sdkp->protection_type);
|
sdkp->protection_type);
|
||||||
sdkp->protection_type = 0;
|
sdkp->protection_type = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
sd_printk(KERN_NOTICE, sdkp, "Enabling DIF Type %u protection\n",
|
sd_first_printk(KERN_NOTICE, sdkp, "Enabling DIF Type %u protection\n",
|
||||||
sdkp->protection_type);
|
sdkp->protection_type);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void read_capacity_error(struct scsi_disk *sdkp, struct scsi_device *sdp,
|
static void read_capacity_error(struct scsi_disk *sdkp, struct scsi_device *sdp,
|
||||||
@ -3851,19 +3847,11 @@ static int __init init_sd(void)
|
|||||||
if (err)
|
if (err)
|
||||||
goto err_out;
|
goto err_out;
|
||||||
|
|
||||||
sd_cdb_cache = kmem_cache_create("sd_ext_cdb", SD_EXT_CDB_SIZE,
|
|
||||||
0, 0, NULL);
|
|
||||||
if (!sd_cdb_cache) {
|
|
||||||
printk(KERN_ERR "sd: can't init extended cdb cache\n");
|
|
||||||
err = -ENOMEM;
|
|
||||||
goto err_out_class;
|
|
||||||
}
|
|
||||||
|
|
||||||
sd_page_pool = mempool_create_page_pool(SD_MEMPOOL_SIZE, 0);
|
sd_page_pool = mempool_create_page_pool(SD_MEMPOOL_SIZE, 0);
|
||||||
if (!sd_page_pool) {
|
if (!sd_page_pool) {
|
||||||
printk(KERN_ERR "sd: can't init discard page pool\n");
|
printk(KERN_ERR "sd: can't init discard page pool\n");
|
||||||
err = -ENOMEM;
|
err = -ENOMEM;
|
||||||
goto err_out_cache;
|
goto err_out_class;
|
||||||
}
|
}
|
||||||
|
|
||||||
err = scsi_register_driver(&sd_template.gendrv);
|
err = scsi_register_driver(&sd_template.gendrv);
|
||||||
@ -3874,10 +3862,6 @@ static int __init init_sd(void)
|
|||||||
|
|
||||||
err_out_driver:
|
err_out_driver:
|
||||||
mempool_destroy(sd_page_pool);
|
mempool_destroy(sd_page_pool);
|
||||||
|
|
||||||
err_out_cache:
|
|
||||||
kmem_cache_destroy(sd_cdb_cache);
|
|
||||||
|
|
||||||
err_out_class:
|
err_out_class:
|
||||||
class_unregister(&sd_disk_class);
|
class_unregister(&sd_disk_class);
|
||||||
err_out:
|
err_out:
|
||||||
@ -3899,7 +3883,6 @@ static void __exit exit_sd(void)
|
|||||||
|
|
||||||
scsi_unregister_driver(&sd_template.gendrv);
|
scsi_unregister_driver(&sd_template.gendrv);
|
||||||
mempool_destroy(sd_page_pool);
|
mempool_destroy(sd_page_pool);
|
||||||
kmem_cache_destroy(sd_cdb_cache);
|
|
||||||
|
|
||||||
class_unregister(&sd_disk_class);
|
class_unregister(&sd_disk_class);
|
||||||
|
|
||||||
|
@ -39,8 +39,10 @@ void sd_dif_config_host(struct scsi_disk *sdkp)
|
|||||||
dif = 0; dix = 1;
|
dif = 0; dix = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!dix)
|
if (!dix) {
|
||||||
|
blk_integrity_unregister(disk);
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
memset(&bi, 0, sizeof(bi));
|
memset(&bi, 0, sizeof(bi));
|
||||||
|
|
||||||
@ -72,9 +74,9 @@ void sd_dif_config_host(struct scsi_disk *sdkp)
|
|||||||
bi.tag_size = sizeof(u16);
|
bi.tag_size = sizeof(u16);
|
||||||
}
|
}
|
||||||
|
|
||||||
sd_printk(KERN_NOTICE, sdkp,
|
sd_first_printk(KERN_NOTICE, sdkp,
|
||||||
"Enabling DIX %s, application tag size %u bytes\n",
|
"Enabling DIX %s, application tag size %u bytes\n",
|
||||||
bi.profile->name, bi.tag_size);
|
bi.profile->name, bi.tag_size);
|
||||||
out:
|
out:
|
||||||
blk_integrity_register(disk, &bi);
|
blk_integrity_register(disk, &bi);
|
||||||
}
|
}
|
||||||
|
@ -439,8 +439,8 @@ int ses_match_host(struct enclosure_device *edev, void *data)
|
|||||||
}
|
}
|
||||||
#endif /* 0 */
|
#endif /* 0 */
|
||||||
|
|
||||||
static void ses_process_descriptor(struct enclosure_component *ecomp,
|
static int ses_process_descriptor(struct enclosure_component *ecomp,
|
||||||
unsigned char *desc)
|
unsigned char *desc, int max_desc_len)
|
||||||
{
|
{
|
||||||
int eip = desc[0] & 0x10;
|
int eip = desc[0] & 0x10;
|
||||||
int invalid = desc[0] & 0x80;
|
int invalid = desc[0] & 0x80;
|
||||||
@ -451,22 +451,32 @@ static void ses_process_descriptor(struct enclosure_component *ecomp,
|
|||||||
unsigned char *d;
|
unsigned char *d;
|
||||||
|
|
||||||
if (invalid)
|
if (invalid)
|
||||||
return;
|
return 0;
|
||||||
|
|
||||||
switch (proto) {
|
switch (proto) {
|
||||||
case SCSI_PROTOCOL_FCP:
|
case SCSI_PROTOCOL_FCP:
|
||||||
if (eip) {
|
if (eip) {
|
||||||
|
if (max_desc_len <= 7)
|
||||||
|
return 1;
|
||||||
d = desc + 4;
|
d = desc + 4;
|
||||||
slot = d[3];
|
slot = d[3];
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case SCSI_PROTOCOL_SAS:
|
case SCSI_PROTOCOL_SAS:
|
||||||
|
|
||||||
if (eip) {
|
if (eip) {
|
||||||
|
if (max_desc_len <= 27)
|
||||||
|
return 1;
|
||||||
d = desc + 4;
|
d = desc + 4;
|
||||||
slot = d[3];
|
slot = d[3];
|
||||||
d = desc + 8;
|
d = desc + 8;
|
||||||
} else
|
} else {
|
||||||
|
if (max_desc_len <= 23)
|
||||||
|
return 1;
|
||||||
d = desc + 4;
|
d = desc + 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* only take the phy0 addr */
|
/* only take the phy0 addr */
|
||||||
addr = (u64)d[12] << 56 |
|
addr = (u64)d[12] << 56 |
|
||||||
(u64)d[13] << 48 |
|
(u64)d[13] << 48 |
|
||||||
@ -483,6 +493,8 @@ static void ses_process_descriptor(struct enclosure_component *ecomp,
|
|||||||
}
|
}
|
||||||
ecomp->slot = slot;
|
ecomp->slot = slot;
|
||||||
scomp->addr = addr;
|
scomp->addr = addr;
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct efd {
|
struct efd {
|
||||||
@ -555,7 +567,7 @@ static void ses_enclosure_data_process(struct enclosure_device *edev,
|
|||||||
/* skip past overall descriptor */
|
/* skip past overall descriptor */
|
||||||
desc_ptr += len + 4;
|
desc_ptr += len + 4;
|
||||||
}
|
}
|
||||||
if (ses_dev->page10)
|
if (ses_dev->page10 && ses_dev->page10_len > 9)
|
||||||
addl_desc_ptr = ses_dev->page10 + 8;
|
addl_desc_ptr = ses_dev->page10 + 8;
|
||||||
type_ptr = ses_dev->page1_types;
|
type_ptr = ses_dev->page1_types;
|
||||||
components = 0;
|
components = 0;
|
||||||
@ -563,17 +575,22 @@ static void ses_enclosure_data_process(struct enclosure_device *edev,
|
|||||||
for (j = 0; j < type_ptr[1]; j++) {
|
for (j = 0; j < type_ptr[1]; j++) {
|
||||||
char *name = NULL;
|
char *name = NULL;
|
||||||
struct enclosure_component *ecomp;
|
struct enclosure_component *ecomp;
|
||||||
|
int max_desc_len;
|
||||||
|
|
||||||
if (desc_ptr) {
|
if (desc_ptr) {
|
||||||
if (desc_ptr >= buf + page7_len) {
|
if (desc_ptr + 3 >= buf + page7_len) {
|
||||||
desc_ptr = NULL;
|
desc_ptr = NULL;
|
||||||
} else {
|
} else {
|
||||||
len = (desc_ptr[2] << 8) + desc_ptr[3];
|
len = (desc_ptr[2] << 8) + desc_ptr[3];
|
||||||
desc_ptr += 4;
|
desc_ptr += 4;
|
||||||
/* Add trailing zero - pushes into
|
if (desc_ptr + len > buf + page7_len)
|
||||||
* reserved space */
|
desc_ptr = NULL;
|
||||||
desc_ptr[len] = '\0';
|
else {
|
||||||
name = desc_ptr;
|
/* Add trailing zero - pushes into
|
||||||
|
* reserved space */
|
||||||
|
desc_ptr[len] = '\0';
|
||||||
|
name = desc_ptr;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (type_ptr[0] == ENCLOSURE_COMPONENT_DEVICE ||
|
if (type_ptr[0] == ENCLOSURE_COMPONENT_DEVICE ||
|
||||||
@ -589,10 +606,14 @@ static void ses_enclosure_data_process(struct enclosure_device *edev,
|
|||||||
ecomp = &edev->component[components++];
|
ecomp = &edev->component[components++];
|
||||||
|
|
||||||
if (!IS_ERR(ecomp)) {
|
if (!IS_ERR(ecomp)) {
|
||||||
if (addl_desc_ptr)
|
if (addl_desc_ptr) {
|
||||||
ses_process_descriptor(
|
max_desc_len = ses_dev->page10_len -
|
||||||
ecomp,
|
(addl_desc_ptr - ses_dev->page10);
|
||||||
addl_desc_ptr);
|
if (ses_process_descriptor(ecomp,
|
||||||
|
addl_desc_ptr,
|
||||||
|
max_desc_len))
|
||||||
|
addl_desc_ptr = NULL;
|
||||||
|
}
|
||||||
if (create)
|
if (create)
|
||||||
enclosure_component_register(
|
enclosure_component_register(
|
||||||
ecomp);
|
ecomp);
|
||||||
@ -609,9 +630,11 @@ static void ses_enclosure_data_process(struct enclosure_device *edev,
|
|||||||
/* these elements are optional */
|
/* these elements are optional */
|
||||||
type_ptr[0] == ENCLOSURE_COMPONENT_SCSI_TARGET_PORT ||
|
type_ptr[0] == ENCLOSURE_COMPONENT_SCSI_TARGET_PORT ||
|
||||||
type_ptr[0] == ENCLOSURE_COMPONENT_SCSI_INITIATOR_PORT ||
|
type_ptr[0] == ENCLOSURE_COMPONENT_SCSI_INITIATOR_PORT ||
|
||||||
type_ptr[0] == ENCLOSURE_COMPONENT_CONTROLLER_ELECTRONICS))
|
type_ptr[0] == ENCLOSURE_COMPONENT_CONTROLLER_ELECTRONICS)) {
|
||||||
addl_desc_ptr += addl_desc_ptr[1] + 2;
|
addl_desc_ptr += addl_desc_ptr[1] + 2;
|
||||||
|
if (addl_desc_ptr + 1 >= ses_dev->page10 + ses_dev->page10_len)
|
||||||
|
addl_desc_ptr = NULL;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
kfree(buf);
|
kfree(buf);
|
||||||
@ -710,6 +733,12 @@ static int ses_intf_add(struct device *cdev,
|
|||||||
type_ptr[0] == ENCLOSURE_COMPONENT_ARRAY_DEVICE)
|
type_ptr[0] == ENCLOSURE_COMPONENT_ARRAY_DEVICE)
|
||||||
components += type_ptr[1];
|
components += type_ptr[1];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (components == 0) {
|
||||||
|
sdev_printk(KERN_WARNING, sdev, "enclosure has no enumerated components\n");
|
||||||
|
goto err_free;
|
||||||
|
}
|
||||||
|
|
||||||
ses_dev->page1 = buf;
|
ses_dev->page1 = buf;
|
||||||
ses_dev->page1_len = len;
|
ses_dev->page1_len = len;
|
||||||
buf = NULL;
|
buf = NULL;
|
||||||
@ -833,7 +862,8 @@ static void ses_intf_remove_enclosure(struct scsi_device *sdev)
|
|||||||
kfree(ses_dev->page2);
|
kfree(ses_dev->page2);
|
||||||
kfree(ses_dev);
|
kfree(ses_dev);
|
||||||
|
|
||||||
kfree(edev->component[0].scratch);
|
if (edev->components)
|
||||||
|
kfree(edev->component[0].scratch);
|
||||||
|
|
||||||
put_device(&edev->edev);
|
put_device(&edev->edev);
|
||||||
enclosure_unregister(edev);
|
enclosure_unregister(edev);
|
||||||
|
@ -1409,6 +1409,13 @@ static int ufshcd_devfreq_target(struct device *dev,
|
|||||||
struct ufs_clk_info *clki;
|
struct ufs_clk_info *clki;
|
||||||
unsigned long irq_flags;
|
unsigned long irq_flags;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Skip devfreq if UFS initialization is not finished.
|
||||||
|
* Otherwise ufs could be in a inconsistent state.
|
||||||
|
*/
|
||||||
|
if (!smp_load_acquire(&hba->logical_unit_scan_finished))
|
||||||
|
return 0;
|
||||||
|
|
||||||
if (!ufshcd_is_clkscaling_supported(hba))
|
if (!ufshcd_is_clkscaling_supported(hba))
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
@ -8392,22 +8399,6 @@ static int ufshcd_add_lus(struct ufs_hba *hba)
|
|||||||
if (ret)
|
if (ret)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
/* Initialize devfreq after UFS device is detected */
|
|
||||||
if (ufshcd_is_clkscaling_supported(hba)) {
|
|
||||||
memcpy(&hba->clk_scaling.saved_pwr_info.info,
|
|
||||||
&hba->pwr_info,
|
|
||||||
sizeof(struct ufs_pa_layer_attr));
|
|
||||||
hba->clk_scaling.saved_pwr_info.is_valid = true;
|
|
||||||
hba->clk_scaling.is_allowed = true;
|
|
||||||
|
|
||||||
ret = ufshcd_devfreq_init(hba);
|
|
||||||
if (ret)
|
|
||||||
goto out;
|
|
||||||
|
|
||||||
hba->clk_scaling.is_enabled = true;
|
|
||||||
ufshcd_init_clk_scaling_sysfs(hba);
|
|
||||||
}
|
|
||||||
|
|
||||||
ufs_bsg_probe(hba);
|
ufs_bsg_probe(hba);
|
||||||
ufshpb_init(hba);
|
ufshpb_init(hba);
|
||||||
scsi_scan_host(hba->host);
|
scsi_scan_host(hba->host);
|
||||||
@ -8538,7 +8529,9 @@ static int ufshcd_device_init(struct ufs_hba *hba, bool init_dev_params)
|
|||||||
return ret;
|
return ret;
|
||||||
if (is_mcq_supported(hba) && !hba->scsi_host_added) {
|
if (is_mcq_supported(hba) && !hba->scsi_host_added) {
|
||||||
ret = ufshcd_alloc_mcq(hba);
|
ret = ufshcd_alloc_mcq(hba);
|
||||||
if (ret) {
|
if (!ret) {
|
||||||
|
ufshcd_config_mcq(hba);
|
||||||
|
} else {
|
||||||
/* Continue with SDB mode */
|
/* Continue with SDB mode */
|
||||||
use_mcq_mode = false;
|
use_mcq_mode = false;
|
||||||
dev_err(hba->dev, "MCQ mode is disabled, err=%d\n",
|
dev_err(hba->dev, "MCQ mode is disabled, err=%d\n",
|
||||||
@ -8550,10 +8543,10 @@ static int ufshcd_device_init(struct ufs_hba *hba, bool init_dev_params)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
hba->scsi_host_added = true;
|
hba->scsi_host_added = true;
|
||||||
}
|
} else if (is_mcq_supported(hba)) {
|
||||||
/* MCQ may be disabled if ufshcd_alloc_mcq() fails */
|
/* UFSHCD_QUIRK_REINIT_AFTER_MAX_GEAR_SWITCH is set */
|
||||||
if (is_mcq_supported(hba) && use_mcq_mode)
|
|
||||||
ufshcd_config_mcq(hba);
|
ufshcd_config_mcq(hba);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ufshcd_tune_unipro_params(hba);
|
ufshcd_tune_unipro_params(hba);
|
||||||
@ -8677,6 +8670,12 @@ out:
|
|||||||
if (ret) {
|
if (ret) {
|
||||||
pm_runtime_put_sync(hba->dev);
|
pm_runtime_put_sync(hba->dev);
|
||||||
ufshcd_hba_exit(hba);
|
ufshcd_hba_exit(hba);
|
||||||
|
} else {
|
||||||
|
/*
|
||||||
|
* Make sure that when reader code sees UFS initialization has finished,
|
||||||
|
* all initialization steps have really been executed.
|
||||||
|
*/
|
||||||
|
smp_store_release(&hba->logical_unit_scan_finished, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -9143,34 +9142,15 @@ static int ufshcd_execute_start_stop(struct scsi_device *sdev,
|
|||||||
enum ufs_dev_pwr_mode pwr_mode,
|
enum ufs_dev_pwr_mode pwr_mode,
|
||||||
struct scsi_sense_hdr *sshdr)
|
struct scsi_sense_hdr *sshdr)
|
||||||
{
|
{
|
||||||
unsigned char cdb[6] = { START_STOP, 0, 0, 0, pwr_mode << 4, 0 };
|
const unsigned char cdb[6] = { START_STOP, 0, 0, 0, pwr_mode << 4, 0 };
|
||||||
struct request *req;
|
const struct scsi_exec_args args = {
|
||||||
struct scsi_cmnd *scmd;
|
.sshdr = sshdr,
|
||||||
int ret;
|
.req_flags = BLK_MQ_REQ_PM,
|
||||||
|
.scmd_flags = SCMD_FAIL_IF_RECOVERING,
|
||||||
|
};
|
||||||
|
|
||||||
req = scsi_alloc_request(sdev->request_queue, REQ_OP_DRV_IN,
|
return scsi_execute_cmd(sdev, cdb, REQ_OP_DRV_IN, /*buffer=*/NULL,
|
||||||
BLK_MQ_REQ_PM);
|
/*bufflen=*/0, /*timeout=*/HZ, /*retries=*/0, &args);
|
||||||
if (IS_ERR(req))
|
|
||||||
return PTR_ERR(req);
|
|
||||||
|
|
||||||
scmd = blk_mq_rq_to_pdu(req);
|
|
||||||
scmd->cmd_len = COMMAND_SIZE(cdb[0]);
|
|
||||||
memcpy(scmd->cmnd, cdb, scmd->cmd_len);
|
|
||||||
scmd->allowed = 0/*retries*/;
|
|
||||||
scmd->flags |= SCMD_FAIL_IF_RECOVERING;
|
|
||||||
req->timeout = 1 * HZ;
|
|
||||||
req->rq_flags |= RQF_PM | RQF_QUIET;
|
|
||||||
|
|
||||||
blk_execute_rq(req, /*at_head=*/true);
|
|
||||||
|
|
||||||
if (sshdr)
|
|
||||||
scsi_normalize_sense(scmd->sense_buffer, scmd->sense_len,
|
|
||||||
sshdr);
|
|
||||||
ret = scmd->result;
|
|
||||||
|
|
||||||
blk_mq_free_request(req);
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -10336,12 +10316,30 @@ int ufshcd_init(struct ufs_hba *hba, void __iomem *mmio_base, unsigned int irq)
|
|||||||
*/
|
*/
|
||||||
ufshcd_set_ufs_dev_active(hba);
|
ufshcd_set_ufs_dev_active(hba);
|
||||||
|
|
||||||
|
/* Initialize devfreq */
|
||||||
|
if (ufshcd_is_clkscaling_supported(hba)) {
|
||||||
|
memcpy(&hba->clk_scaling.saved_pwr_info.info,
|
||||||
|
&hba->pwr_info,
|
||||||
|
sizeof(struct ufs_pa_layer_attr));
|
||||||
|
hba->clk_scaling.saved_pwr_info.is_valid = true;
|
||||||
|
hba->clk_scaling.is_allowed = true;
|
||||||
|
|
||||||
|
err = ufshcd_devfreq_init(hba);
|
||||||
|
if (err)
|
||||||
|
goto rpm_put_sync;
|
||||||
|
|
||||||
|
hba->clk_scaling.is_enabled = true;
|
||||||
|
ufshcd_init_clk_scaling_sysfs(hba);
|
||||||
|
}
|
||||||
|
|
||||||
async_schedule(ufshcd_async_scan, hba);
|
async_schedule(ufshcd_async_scan, hba);
|
||||||
ufs_sysfs_add_nodes(hba->dev);
|
ufs_sysfs_add_nodes(hba->dev);
|
||||||
|
|
||||||
device_enable_async_suspend(dev);
|
device_enable_async_suspend(dev);
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
rpm_put_sync:
|
||||||
|
pm_runtime_put_sync(dev);
|
||||||
free_tmf_queue:
|
free_tmf_queue:
|
||||||
blk_mq_destroy_queue(hba->tmf_queue);
|
blk_mq_destroy_queue(hba->tmf_queue);
|
||||||
blk_put_queue(hba->tmf_queue);
|
blk_put_queue(hba->tmf_queue);
|
||||||
|
@ -48,7 +48,7 @@ config SCSI_UFS_CDNS_PLATFORM
|
|||||||
|
|
||||||
config SCSI_UFS_DWC_TC_PLATFORM
|
config SCSI_UFS_DWC_TC_PLATFORM
|
||||||
tristate "DesignWare platform support using a G210 Test Chip"
|
tristate "DesignWare platform support using a G210 Test Chip"
|
||||||
depends on SCSI_UFSHCD_PLATFORM
|
depends on OF && SCSI_UFSHCD_PLATFORM
|
||||||
help
|
help
|
||||||
Synopsys Test Chip is a PHY for prototyping purposes.
|
Synopsys Test Chip is a PHY for prototyping purposes.
|
||||||
|
|
||||||
|
@ -1613,6 +1613,7 @@ static int ufs_mtk_system_resume(struct device *dev)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef CONFIG_PM
|
||||||
static int ufs_mtk_runtime_suspend(struct device *dev)
|
static int ufs_mtk_runtime_suspend(struct device *dev)
|
||||||
{
|
{
|
||||||
struct ufs_hba *hba = dev_get_drvdata(dev);
|
struct ufs_hba *hba = dev_get_drvdata(dev);
|
||||||
@ -1635,6 +1636,7 @@ static int ufs_mtk_runtime_resume(struct device *dev)
|
|||||||
|
|
||||||
return ufshcd_runtime_resume(dev);
|
return ufshcd_runtime_resume(dev);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
static const struct dev_pm_ops ufs_mtk_pm_ops = {
|
static const struct dev_pm_ops ufs_mtk_pm_ops = {
|
||||||
SET_SYSTEM_SLEEP_PM_OPS(ufs_mtk_system_suspend,
|
SET_SYSTEM_SLEEP_PM_OPS(ufs_mtk_system_suspend,
|
||||||
|
@ -462,6 +462,7 @@ struct scsi_exec_args {
|
|||||||
unsigned int sense_len; /* sense buffer len */
|
unsigned int sense_len; /* sense buffer len */
|
||||||
struct scsi_sense_hdr *sshdr; /* decoded sense header */
|
struct scsi_sense_hdr *sshdr; /* decoded sense header */
|
||||||
blk_mq_req_flags_t req_flags; /* BLK_MQ_REQ flags */
|
blk_mq_req_flags_t req_flags; /* BLK_MQ_REQ flags */
|
||||||
|
int scmd_flags; /* SCMD flags */
|
||||||
int *resid; /* residual length */
|
int *resid; /* residual length */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -496,6 +496,7 @@ enum fc_host_event_code {
|
|||||||
FCH_EVT_PORT_FABRIC = 0x204,
|
FCH_EVT_PORT_FABRIC = 0x204,
|
||||||
FCH_EVT_LINK_UNKNOWN = 0x500,
|
FCH_EVT_LINK_UNKNOWN = 0x500,
|
||||||
FCH_EVT_LINK_FPIN = 0x501,
|
FCH_EVT_LINK_FPIN = 0x501,
|
||||||
|
FCH_EVT_LINK_FPIN_ACK = 0x502,
|
||||||
FCH_EVT_VENDOR_UNIQUE = 0xffff,
|
FCH_EVT_VENDOR_UNIQUE = 0xffff,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -856,7 +857,8 @@ void fc_host_post_fc_event(struct Scsi_Host *shost, u32 event_number,
|
|||||||
* Note: when calling fc_host_post_fc_event(), vendor_id may be
|
* Note: when calling fc_host_post_fc_event(), vendor_id may be
|
||||||
* specified as 0.
|
* specified as 0.
|
||||||
*/
|
*/
|
||||||
void fc_host_fpin_rcv(struct Scsi_Host *shost, u32 fpin_len, char *fpin_buf);
|
void fc_host_fpin_rcv(struct Scsi_Host *shost, u32 fpin_len, char *fpin_buf,
|
||||||
|
u8 event_acknowledge);
|
||||||
struct fc_vport *fc_vport_create(struct Scsi_Host *shost, int channel,
|
struct fc_vport *fc_vport_create(struct Scsi_Host *shost, int channel,
|
||||||
struct fc_vport_identifiers *);
|
struct fc_vport_identifiers *);
|
||||||
int fc_vport_terminate(struct fc_vport *vport);
|
int fc_vport_terminate(struct fc_vport *vport);
|
||||||
|
@ -455,12 +455,6 @@ struct mpi3mr_bsg_packet {
|
|||||||
} cmd;
|
} cmd;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/* MPI3: NVMe Encasulation related definitions */
|
|
||||||
#ifndef MPI3_NVME_ENCAP_CMD_MAX
|
|
||||||
#define MPI3_NVME_ENCAP_CMD_MAX (1)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
struct mpi3_nvme_encapsulated_request {
|
struct mpi3_nvme_encapsulated_request {
|
||||||
__le16 host_tag;
|
__le16 host_tag;
|
||||||
__u8 ioc_use_only02;
|
__u8 ioc_use_only02;
|
||||||
@ -474,7 +468,7 @@ struct mpi3_nvme_encapsulated_request {
|
|||||||
__le16 flags;
|
__le16 flags;
|
||||||
__le32 data_length;
|
__le32 data_length;
|
||||||
__le32 reserved14[3];
|
__le32 reserved14[3];
|
||||||
__le32 command[MPI3_NVME_ENCAP_CMD_MAX];
|
__le32 command[];
|
||||||
};
|
};
|
||||||
|
|
||||||
struct mpi3_nvme_encapsulated_error_reply {
|
struct mpi3_nvme_encapsulated_error_reply {
|
||||||
|
@ -979,6 +979,7 @@ struct ufs_hba {
|
|||||||
struct completion *uic_async_done;
|
struct completion *uic_async_done;
|
||||||
|
|
||||||
enum ufshcd_state ufshcd_state;
|
enum ufshcd_state ufshcd_state;
|
||||||
|
bool logical_unit_scan_finished;
|
||||||
u32 eh_flags;
|
u32 eh_flags;
|
||||||
u32 intr_mask;
|
u32 intr_mask;
|
||||||
u16 ee_ctrl_mask;
|
u16 ee_ctrl_mask;
|
||||||
|
Loading…
Reference in New Issue
Block a user