SCSI misc on 20181224

This is mostly update of the usual drivers: smarpqi, lpfc, qedi,
 megaraid_sas, libsas, zfcp, mpt3sas, hisi_sas.  Additionally, we have
 a pile of annotation, unused variable and minor updates.  The big API
 change is the updates for Christoph's DMA rework which include
 removing the DISABLE_CLUSTERING flag.  And finally there are a couple
 of target tree updates.
 
 Signed-off-by: James E.J. Bottomley <jejb@linux.ibm.com>
 -----BEGIN PGP SIGNATURE-----
 
 iJwEABMIAEQWIQTnYEDbdso9F2cI+arnQslM7pishQUCXCEUNiYcamFtZXMuYm90
 dG9tbGV5QGhhbnNlbnBhcnRuZXJzaGlwLmNvbQAKCRDnQslM7pishdjKAP9vrTTv
 qFaYmAoRSbPq9ZiixaXLMy0K/6o76Uay0gnBqgD/fgn3jg/KQ6alNaCjmfeV3wAj
 u1j3H7tha9j1it+4pUw=
 =GDa+
 -----END PGP SIGNATURE-----

Merge tag 'scsi-misc' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi

Pull SCSI updates from James Bottomley:
 "This is mostly update of the usual drivers: smarpqi, lpfc, qedi,
  megaraid_sas, libsas, zfcp, mpt3sas, hisi_sas.

  Additionally, we have a pile of annotation, unused variable and minor
  updates.

  The big API change is the updates for Christoph's DMA rework which
  include removing the DISABLE_CLUSTERING flag.

  And finally there are a couple of target tree updates"

* tag 'scsi-misc' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi: (259 commits)
  scsi: isci: request: mark expected switch fall-through
  scsi: isci: remote_node_context: mark expected switch fall-throughs
  scsi: isci: remote_device: Mark expected switch fall-throughs
  scsi: isci: phy: Mark expected switch fall-through
  scsi: iscsi: Capture iscsi debug messages using tracepoints
  scsi: myrb: Mark expected switch fall-throughs
  scsi: megaraid: fix out-of-bound array accesses
  scsi: mpt3sas: mpt3sas_scsih: Mark expected switch fall-through
  scsi: fcoe: remove set but not used variable 'port'
  scsi: smartpqi: call pqi_free_interrupts() in pqi_shutdown()
  scsi: smartpqi: fix build warnings
  scsi: smartpqi: update driver version
  scsi: smartpqi: add ofa support
  scsi: smartpqi: increase fw status register read timeout
  scsi: smartpqi: bump driver version
  scsi: smartpqi: add smp_utils support
  scsi: smartpqi: correct lun reset issues
  scsi: smartpqi: correct volume status
  scsi: smartpqi: do not offline disks for transient did no connect conditions
  scsi: smartpqi: allow for larger raid maps
  ...
This commit is contained in:
Linus Torvalds 2018-12-28 14:48:06 -08:00
commit 938edb8a31
269 changed files with 7993 additions and 3853 deletions

View File

@ -0,0 +1,31 @@
* Cadence Universal Flash Storage (UFS) Controller
UFS nodes are defined to describe on-chip UFS host controllers.
Each UFS controller instance should have its own node.
Please see the ufshcd-pltfrm.txt for a list of all available properties.
Required properties:
- compatible : Compatible list, contains the following controller:
"cdns,ufshc"
complemented with the JEDEC version:
"jedec,ufs-2.0"
- reg : Address and length of the UFS register set.
- interrupts : One interrupt mapping.
- freq-table-hz : Clock frequency table.
See the ufshcd-pltfrm.txt for details.
- clocks : List of phandle and clock specifier pairs.
- clock-names : List of clock input name strings sorted in the same
order as the clocks property. "core_clk" is mandatory.
Depending on a type of a PHY,
the "phy_clk" clock can also be added, if needed.
Example:
ufs@fd030000 {
compatible = "cdns,ufshc", "jedec,ufs-2.0";
reg = <0xfd030000 0x10000>;
interrupts = <0 1 IRQ_TYPE_LEVEL_HIGH>;
freq-table-hz = <0 0>, <0 0>;
clocks = <&ufs_core_clk>, <&ufs_phy_clk>;
clock-names = "core_clk", "phy_clk";
};

View File

@ -33,6 +33,12 @@ Optional properties:
- clocks : List of phandle and clock specifier pairs - clocks : List of phandle and clock specifier pairs
- clock-names : List of clock input name strings sorted in the same - clock-names : List of clock input name strings sorted in the same
order as the clocks property. order as the clocks property.
"ref_clk" indicates reference clock frequency.
UFS host supplies reference clock to UFS device and UFS device
specification allows host to provide one of the 4 frequencies (19.2 MHz,
26 MHz, 38.4 MHz, 52MHz) for reference clock. This "ref_clk" entry is
parsed and used to update the reference clock setting in device.
Defaults to 26 MHz(as per specification) if not specified by host.
- freq-table-hz : Array of <min max> operating frequencies stored in the same - freq-table-hz : Array of <min max> operating frequencies stored in the same
order as the clocks property. If this property is not order as the clocks property. If this property is not
defined or a value in the array is "0" then it is assumed defined or a value in the array is "0" then it is assumed

View File

@ -1098,8 +1098,6 @@ of interest:
unchecked_isa_dma - 1=>only use bottom 16 MB of ram (ISA DMA addressing unchecked_isa_dma - 1=>only use bottom 16 MB of ram (ISA DMA addressing
restriction), 0=>can use full 32 bit (or better) DMA restriction), 0=>can use full 32 bit (or better) DMA
address space address space
use_clustering - 1=>SCSI commands in mid level's queue can be merged,
0=>disallow SCSI command merging
no_async_abort - 1=>Asynchronous aborts are not supported no_async_abort - 1=>Asynchronous aborts are not supported
0=>Timed-out commands will be aborted asynchronously 0=>Timed-out commands will be aborted asynchronously
hostt - pointer to driver's struct scsi_host_template from which hostt - pointer to driver's struct scsi_host_template from which

View File

@ -347,7 +347,7 @@ static struct scsi_host_template driver_template = {
.sg_tablesize = SG_ALL, .sg_tablesize = SG_ALL,
.max_sectors = 1024, .max_sectors = 1024,
.cmd_per_lun = SIMSCSI_REQ_QUEUE_LEN, .cmd_per_lun = SIMSCSI_REQ_QUEUE_LEN,
.use_clustering = DISABLE_CLUSTERING, .dma_boundary = PAGE_SIZE - 1,
}; };
static int __init static int __init

View File

@ -195,7 +195,7 @@ static struct bio *blk_bio_segment_split(struct request_queue *q,
goto split; goto split;
} }
if (bvprvp && blk_queue_cluster(q)) { if (bvprvp) {
if (seg_size + bv.bv_len > queue_max_segment_size(q)) if (seg_size + bv.bv_len > queue_max_segment_size(q))
goto new_segment; goto new_segment;
if (!biovec_phys_mergeable(q, bvprvp, &bv)) if (!biovec_phys_mergeable(q, bvprvp, &bv))
@ -295,7 +295,7 @@ static unsigned int __blk_recalc_rq_segments(struct request_queue *q,
bool no_sg_merge) bool no_sg_merge)
{ {
struct bio_vec bv, bvprv = { NULL }; struct bio_vec bv, bvprv = { NULL };
int cluster, prev = 0; int prev = 0;
unsigned int seg_size, nr_phys_segs; unsigned int seg_size, nr_phys_segs;
struct bio *fbio, *bbio; struct bio *fbio, *bbio;
struct bvec_iter iter; struct bvec_iter iter;
@ -313,7 +313,6 @@ static unsigned int __blk_recalc_rq_segments(struct request_queue *q,
} }
fbio = bio; fbio = bio;
cluster = blk_queue_cluster(q);
seg_size = 0; seg_size = 0;
nr_phys_segs = 0; nr_phys_segs = 0;
for_each_bio(bio) { for_each_bio(bio) {
@ -325,7 +324,7 @@ static unsigned int __blk_recalc_rq_segments(struct request_queue *q,
if (no_sg_merge) if (no_sg_merge)
goto new_segment; goto new_segment;
if (prev && cluster) { if (prev) {
if (seg_size + bv.bv_len if (seg_size + bv.bv_len
> queue_max_segment_size(q)) > queue_max_segment_size(q))
goto new_segment; goto new_segment;
@ -395,9 +394,6 @@ static int blk_phys_contig_segment(struct request_queue *q, struct bio *bio,
{ {
struct bio_vec end_bv = { NULL }, nxt_bv; struct bio_vec end_bv = { NULL }, nxt_bv;
if (!blk_queue_cluster(q))
return 0;
if (bio->bi_seg_back_size + nxt->bi_seg_front_size > if (bio->bi_seg_back_size + nxt->bi_seg_front_size >
queue_max_segment_size(q)) queue_max_segment_size(q))
return 0; return 0;
@ -414,12 +410,12 @@ static int blk_phys_contig_segment(struct request_queue *q, struct bio *bio,
static inline void static inline void
__blk_segment_map_sg(struct request_queue *q, struct bio_vec *bvec, __blk_segment_map_sg(struct request_queue *q, struct bio_vec *bvec,
struct scatterlist *sglist, struct bio_vec *bvprv, struct scatterlist *sglist, struct bio_vec *bvprv,
struct scatterlist **sg, int *nsegs, int *cluster) struct scatterlist **sg, int *nsegs)
{ {
int nbytes = bvec->bv_len; int nbytes = bvec->bv_len;
if (*sg && *cluster) { if (*sg) {
if ((*sg)->length + nbytes > queue_max_segment_size(q)) if ((*sg)->length + nbytes > queue_max_segment_size(q))
goto new_segment; goto new_segment;
if (!biovec_phys_mergeable(q, bvprv, bvec)) if (!biovec_phys_mergeable(q, bvprv, bvec))
@ -465,12 +461,12 @@ static int __blk_bios_map_sg(struct request_queue *q, struct bio *bio,
{ {
struct bio_vec bvec, bvprv = { NULL }; struct bio_vec bvec, bvprv = { NULL };
struct bvec_iter iter; struct bvec_iter iter;
int cluster = blk_queue_cluster(q), nsegs = 0; int nsegs = 0;
for_each_bio(bio) for_each_bio(bio)
bio_for_each_segment(bvec, bio, iter) bio_for_each_segment(bvec, bio, iter)
__blk_segment_map_sg(q, &bvec, sglist, &bvprv, sg, __blk_segment_map_sg(q, &bvec, sglist, &bvprv, sg,
&nsegs, &cluster); &nsegs);
return nsegs; return nsegs;
} }

View File

@ -56,7 +56,6 @@ void blk_set_default_limits(struct queue_limits *lim)
lim->alignment_offset = 0; lim->alignment_offset = 0;
lim->io_opt = 0; lim->io_opt = 0;
lim->misaligned = 0; lim->misaligned = 0;
lim->cluster = 1;
lim->zoned = BLK_ZONED_NONE; lim->zoned = BLK_ZONED_NONE;
} }
EXPORT_SYMBOL(blk_set_default_limits); EXPORT_SYMBOL(blk_set_default_limits);
@ -547,8 +546,6 @@ int blk_stack_limits(struct queue_limits *t, struct queue_limits *b,
t->io_min = max(t->io_min, b->io_min); t->io_min = max(t->io_min, b->io_min);
t->io_opt = lcm_not_zero(t->io_opt, b->io_opt); t->io_opt = lcm_not_zero(t->io_opt, b->io_opt);
t->cluster &= b->cluster;
/* Physical block size a multiple of the logical block size? */ /* Physical block size a multiple of the logical block size? */
if (t->physical_block_size & (t->logical_block_size - 1)) { if (t->physical_block_size & (t->logical_block_size - 1)) {
t->physical_block_size = t->logical_block_size; t->physical_block_size = t->logical_block_size;

View File

@ -132,10 +132,7 @@ static ssize_t queue_max_integrity_segments_show(struct request_queue *q, char *
static ssize_t queue_max_segment_size_show(struct request_queue *q, char *page) static ssize_t queue_max_segment_size_show(struct request_queue *q, char *page)
{ {
if (blk_queue_cluster(q)) return queue_var_show(queue_max_segment_size(q), (page));
return queue_var_show(queue_max_segment_size(q), (page));
return queue_var_show(PAGE_SIZE, (page));
} }
static ssize_t queue_logical_block_size_show(struct request_queue *q, char *page) static ssize_t queue_logical_block_size_show(struct request_queue *q, char *page)

View File

@ -1610,7 +1610,6 @@ static struct scsi_host_template scsi_driver_template = {
.eh_abort_handler = sbp2_scsi_abort, .eh_abort_handler = sbp2_scsi_abort,
.this_id = -1, .this_id = -1,
.sg_tablesize = SG_ALL, .sg_tablesize = SG_ALL,
.use_clustering = ENABLE_CLUSTERING,
.can_queue = 1, .can_queue = 1,
.sdev_attrs = sbp2_scsi_sysfs_attrs, .sdev_attrs = sbp2_scsi_sysfs_attrs,
}; };

View File

@ -997,7 +997,6 @@ static struct scsi_host_template iscsi_iser_sht = {
.eh_device_reset_handler= iscsi_eh_device_reset, .eh_device_reset_handler= iscsi_eh_device_reset,
.eh_target_reset_handler = iscsi_eh_recover_target, .eh_target_reset_handler = iscsi_eh_recover_target,
.target_alloc = iscsi_target_alloc, .target_alloc = iscsi_target_alloc,
.use_clustering = ENABLE_CLUSTERING,
.slave_alloc = iscsi_iser_slave_alloc, .slave_alloc = iscsi_iser_slave_alloc,
.proc_name = "iscsi_iser", .proc_name = "iscsi_iser",
.this_id = -1, .this_id = -1,

View File

@ -3215,7 +3215,6 @@ static struct scsi_host_template srp_template = {
.can_queue = SRP_DEFAULT_CMD_SQ_SIZE, .can_queue = SRP_DEFAULT_CMD_SQ_SIZE,
.this_id = -1, .this_id = -1,
.cmd_per_lun = SRP_DEFAULT_CMD_SQ_SIZE, .cmd_per_lun = SRP_DEFAULT_CMD_SQ_SIZE,
.use_clustering = ENABLE_CLUSTERING,
.shost_attrs = srp_host_attrs, .shost_attrs = srp_host_attrs,
.track_queue_depth = 1, .track_queue_depth = 1,
}; };

View File

@ -3147,11 +3147,6 @@ static int srpt_check_false(struct se_portal_group *se_tpg)
return 0; return 0;
} }
static char *srpt_get_fabric_name(void)
{
return "srpt";
}
static struct srpt_port *srpt_tpg_to_sport(struct se_portal_group *tpg) static struct srpt_port *srpt_tpg_to_sport(struct se_portal_group *tpg)
{ {
return tpg->se_tpg_wwn->priv; return tpg->se_tpg_wwn->priv;
@ -3678,8 +3673,7 @@ static struct configfs_attribute *srpt_wwn_attrs[] = {
static const struct target_core_fabric_ops srpt_template = { static const struct target_core_fabric_ops srpt_template = {
.module = THIS_MODULE, .module = THIS_MODULE,
.name = "srpt", .fabric_name = "srpt",
.get_fabric_name = srpt_get_fabric_name,
.tpg_get_wwn = srpt_get_fabric_wwn, .tpg_get_wwn = srpt_get_fabric_wwn,
.tpg_get_tag = srpt_get_tag, .tpg_get_tag = srpt_get_tag,
.tpg_check_demo_mode = srpt_check_false, .tpg_check_demo_mode = srpt_check_false,

View File

@ -129,7 +129,6 @@ static struct scsi_host_template mptfc_driver_template = {
.sg_tablesize = MPT_SCSI_SG_DEPTH, .sg_tablesize = MPT_SCSI_SG_DEPTH,
.max_sectors = 8192, .max_sectors = 8192,
.cmd_per_lun = 7, .cmd_per_lun = 7,
.use_clustering = ENABLE_CLUSTERING,
.shost_attrs = mptscsih_host_attrs, .shost_attrs = mptscsih_host_attrs,
}; };

View File

@ -1992,7 +1992,6 @@ static struct scsi_host_template mptsas_driver_template = {
.sg_tablesize = MPT_SCSI_SG_DEPTH, .sg_tablesize = MPT_SCSI_SG_DEPTH,
.max_sectors = 8192, .max_sectors = 8192,
.cmd_per_lun = 7, .cmd_per_lun = 7,
.use_clustering = ENABLE_CLUSTERING,
.shost_attrs = mptscsih_host_attrs, .shost_attrs = mptscsih_host_attrs,
.no_write_same = 1, .no_write_same = 1,
}; };

View File

@ -848,7 +848,6 @@ static struct scsi_host_template mptspi_driver_template = {
.sg_tablesize = MPT_SCSI_SG_DEPTH, .sg_tablesize = MPT_SCSI_SG_DEPTH,
.max_sectors = 8192, .max_sectors = 8192,
.cmd_per_lun = 7, .cmd_per_lun = 7,
.use_clustering = ENABLE_CLUSTERING,
.shost_attrs = mptscsih_host_attrs, .shost_attrs = mptscsih_host_attrs,
}; };

View File

@ -4,7 +4,7 @@
* *
* Module interface and handling of zfcp data structures. * Module interface and handling of zfcp data structures.
* *
* Copyright IBM Corp. 2002, 2013 * Copyright IBM Corp. 2002, 2017
*/ */
/* /*
@ -124,6 +124,9 @@ static int __init zfcp_module_init(void)
{ {
int retval = -ENOMEM; int retval = -ENOMEM;
if (zfcp_experimental_dix)
pr_warn("DIX is enabled. It is experimental and might cause problems\n");
zfcp_fsf_qtcb_cache = zfcp_cache_hw_align("zfcp_fsf_qtcb", zfcp_fsf_qtcb_cache = zfcp_cache_hw_align("zfcp_fsf_qtcb",
sizeof(struct fsf_qtcb)); sizeof(struct fsf_qtcb));
if (!zfcp_fsf_qtcb_cache) if (!zfcp_fsf_qtcb_cache)
@ -248,43 +251,36 @@ static int zfcp_allocate_low_mem_buffers(struct zfcp_adapter *adapter)
static void zfcp_free_low_mem_buffers(struct zfcp_adapter *adapter) static void zfcp_free_low_mem_buffers(struct zfcp_adapter *adapter)
{ {
if (adapter->pool.erp_req) mempool_destroy(adapter->pool.erp_req);
mempool_destroy(adapter->pool.erp_req); mempool_destroy(adapter->pool.scsi_req);
if (adapter->pool.scsi_req) mempool_destroy(adapter->pool.scsi_abort);
mempool_destroy(adapter->pool.scsi_req); mempool_destroy(adapter->pool.qtcb_pool);
if (adapter->pool.scsi_abort) mempool_destroy(adapter->pool.status_read_req);
mempool_destroy(adapter->pool.scsi_abort); mempool_destroy(adapter->pool.sr_data);
if (adapter->pool.qtcb_pool) mempool_destroy(adapter->pool.gid_pn);
mempool_destroy(adapter->pool.qtcb_pool);
if (adapter->pool.status_read_req)
mempool_destroy(adapter->pool.status_read_req);
if (adapter->pool.sr_data)
mempool_destroy(adapter->pool.sr_data);
if (adapter->pool.gid_pn)
mempool_destroy(adapter->pool.gid_pn);
} }
/** /**
* zfcp_status_read_refill - refill the long running status_read_requests * zfcp_status_read_refill - refill the long running status_read_requests
* @adapter: ptr to struct zfcp_adapter for which the buffers should be refilled * @adapter: ptr to struct zfcp_adapter for which the buffers should be refilled
* *
* Returns: 0 on success, 1 otherwise * Return:
* * * 0 on success meaning at least one status read is pending
* if there are 16 or more status_read requests missing an adapter_reopen * * 1 if posting failed and not a single status read buffer is pending,
* is triggered * also triggers adapter reopen recovery
*/ */
int zfcp_status_read_refill(struct zfcp_adapter *adapter) int zfcp_status_read_refill(struct zfcp_adapter *adapter)
{ {
while (atomic_read(&adapter->stat_miss) > 0) while (atomic_add_unless(&adapter->stat_miss, -1, 0))
if (zfcp_fsf_status_read(adapter->qdio)) { if (zfcp_fsf_status_read(adapter->qdio)) {
atomic_inc(&adapter->stat_miss); /* undo add -1 */
if (atomic_read(&adapter->stat_miss) >= if (atomic_read(&adapter->stat_miss) >=
adapter->stat_read_buf_num) { adapter->stat_read_buf_num) {
zfcp_erp_adapter_reopen(adapter, 0, "axsref1"); zfcp_erp_adapter_reopen(adapter, 0, "axsref1");
return 1; return 1;
} }
break; break;
} else }
atomic_dec(&adapter->stat_miss);
return 0; return 0;
} }
@ -542,45 +538,3 @@ err_out:
zfcp_ccw_adapter_put(adapter); zfcp_ccw_adapter_put(adapter);
return ERR_PTR(retval); return ERR_PTR(retval);
} }
/**
* zfcp_sg_free_table - free memory used by scatterlists
* @sg: pointer to scatterlist
* @count: number of scatterlist which are to be free'ed
* the scatterlist are expected to reference pages always
*/
void zfcp_sg_free_table(struct scatterlist *sg, int count)
{
int i;
for (i = 0; i < count; i++, sg++)
if (sg)
free_page((unsigned long) sg_virt(sg));
else
break;
}
/**
* zfcp_sg_setup_table - init scatterlist and allocate, assign buffers
* @sg: pointer to struct scatterlist
* @count: number of scatterlists which should be assigned with buffers
* of size page
*
* Returns: 0 on success, -ENOMEM otherwise
*/
int zfcp_sg_setup_table(struct scatterlist *sg, int count)
{
void *addr;
int i;
sg_init_table(sg, count);
for (i = 0; i < count; i++, sg++) {
addr = (void *) get_zeroed_page(GFP_KERNEL);
if (!addr) {
zfcp_sg_free_table(sg, i);
return -ENOMEM;
}
sg_set_buf(sg, addr, PAGE_SIZE);
}
return 0;
}

View File

@ -63,7 +63,8 @@ void zfcp_dbf_pl_write(struct zfcp_dbf *dbf, void *data, u16 length, char *area,
/** /**
* zfcp_dbf_hba_fsf_res - trace event for fsf responses * zfcp_dbf_hba_fsf_res - trace event for fsf responses
* @tag: tag indicating which kind of unsolicited status has been received * @tag: tag indicating which kind of FSF response has been received
* @level: trace level to be used for event
* @req: request for which a response was received * @req: request for which a response was received
*/ */
void zfcp_dbf_hba_fsf_res(char *tag, int level, struct zfcp_fsf_req *req) void zfcp_dbf_hba_fsf_res(char *tag, int level, struct zfcp_fsf_req *req)
@ -81,8 +82,8 @@ void zfcp_dbf_hba_fsf_res(char *tag, int level, struct zfcp_fsf_req *req)
rec->id = ZFCP_DBF_HBA_RES; rec->id = ZFCP_DBF_HBA_RES;
rec->fsf_req_id = req->req_id; rec->fsf_req_id = req->req_id;
rec->fsf_req_status = req->status; rec->fsf_req_status = req->status;
rec->fsf_cmd = req->fsf_command; rec->fsf_cmd = q_head->fsf_command;
rec->fsf_seq_no = req->seq_no; rec->fsf_seq_no = q_pref->req_seq_no;
rec->u.res.req_issued = req->issued; rec->u.res.req_issued = req->issued;
rec->u.res.prot_status = q_pref->prot_status; rec->u.res.prot_status = q_pref->prot_status;
rec->u.res.fsf_status = q_head->fsf_status; rec->u.res.fsf_status = q_head->fsf_status;
@ -94,7 +95,7 @@ void zfcp_dbf_hba_fsf_res(char *tag, int level, struct zfcp_fsf_req *req)
memcpy(rec->u.res.fsf_status_qual, &q_head->fsf_status_qual, memcpy(rec->u.res.fsf_status_qual, &q_head->fsf_status_qual,
FSF_STATUS_QUALIFIER_SIZE); FSF_STATUS_QUALIFIER_SIZE);
if (req->fsf_command != FSF_QTCB_FCP_CMND) { if (q_head->fsf_command != FSF_QTCB_FCP_CMND) {
rec->pl_len = q_head->log_length; rec->pl_len = q_head->log_length;
zfcp_dbf_pl_write(dbf, (char *)q_pref + q_head->log_start, zfcp_dbf_pl_write(dbf, (char *)q_pref + q_head->log_start,
rec->pl_len, "fsf_res", req->req_id); rec->pl_len, "fsf_res", req->req_id);
@ -127,7 +128,7 @@ void zfcp_dbf_hba_fsf_uss(char *tag, struct zfcp_fsf_req *req)
rec->id = ZFCP_DBF_HBA_USS; rec->id = ZFCP_DBF_HBA_USS;
rec->fsf_req_id = req->req_id; rec->fsf_req_id = req->req_id;
rec->fsf_req_status = req->status; rec->fsf_req_status = req->status;
rec->fsf_cmd = req->fsf_command; rec->fsf_cmd = FSF_QTCB_UNSOLICITED_STATUS;
if (!srb) if (!srb)
goto log; goto log;
@ -153,7 +154,7 @@ log:
/** /**
* zfcp_dbf_hba_bit_err - trace event for bit error conditions * zfcp_dbf_hba_bit_err - trace event for bit error conditions
* @tag: tag indicating which kind of unsolicited status has been received * @tag: tag indicating which kind of bit error unsolicited status was received
* @req: request which caused the bit_error condition * @req: request which caused the bit_error condition
*/ */
void zfcp_dbf_hba_bit_err(char *tag, struct zfcp_fsf_req *req) void zfcp_dbf_hba_bit_err(char *tag, struct zfcp_fsf_req *req)
@ -174,7 +175,7 @@ void zfcp_dbf_hba_bit_err(char *tag, struct zfcp_fsf_req *req)
rec->id = ZFCP_DBF_HBA_BIT; rec->id = ZFCP_DBF_HBA_BIT;
rec->fsf_req_id = req->req_id; rec->fsf_req_id = req->req_id;
rec->fsf_req_status = req->status; rec->fsf_req_status = req->status;
rec->fsf_cmd = req->fsf_command; rec->fsf_cmd = FSF_QTCB_UNSOLICITED_STATUS;
memcpy(&rec->u.be, &sr_buf->payload.bit_error, memcpy(&rec->u.be, &sr_buf->payload.bit_error,
sizeof(struct fsf_bit_error_payload)); sizeof(struct fsf_bit_error_payload));
@ -224,6 +225,7 @@ void zfcp_dbf_hba_def_err(struct zfcp_adapter *adapter, u64 req_id, u16 scount,
/** /**
* zfcp_dbf_hba_basic - trace event for basic adapter events * zfcp_dbf_hba_basic - trace event for basic adapter events
* @tag: identifier for event
* @adapter: pointer to struct zfcp_adapter * @adapter: pointer to struct zfcp_adapter
*/ */
void zfcp_dbf_hba_basic(char *tag, struct zfcp_adapter *adapter) void zfcp_dbf_hba_basic(char *tag, struct zfcp_adapter *adapter)
@ -357,7 +359,7 @@ void zfcp_dbf_rec_run_lvl(int level, char *tag, struct zfcp_erp_action *erp)
rec->u.run.fsf_req_id = erp->fsf_req_id; rec->u.run.fsf_req_id = erp->fsf_req_id;
rec->u.run.rec_status = erp->status; rec->u.run.rec_status = erp->status;
rec->u.run.rec_step = erp->step; rec->u.run.rec_step = erp->step;
rec->u.run.rec_action = erp->action; rec->u.run.rec_action = erp->type;
if (erp->sdev) if (erp->sdev)
rec->u.run.rec_count = rec->u.run.rec_count =
@ -478,7 +480,8 @@ out:
/** /**
* zfcp_dbf_san_req - trace event for issued SAN request * zfcp_dbf_san_req - trace event for issued SAN request
* @tag: identifier for event * @tag: identifier for event
* @fsf_req: request containing issued CT data * @fsf: request containing issued CT or ELS data
* @d_id: N_Port_ID where SAN request is sent to
* d_id: destination ID * d_id: destination ID
*/ */
void zfcp_dbf_san_req(char *tag, struct zfcp_fsf_req *fsf, u32 d_id) void zfcp_dbf_san_req(char *tag, struct zfcp_fsf_req *fsf, u32 d_id)
@ -560,7 +563,7 @@ static u16 zfcp_dbf_san_res_cap_len_if_gpn_ft(char *tag,
/** /**
* zfcp_dbf_san_res - trace event for received SAN request * zfcp_dbf_san_res - trace event for received SAN request
* @tag: identifier for event * @tag: identifier for event
* @fsf_req: request containing issued CT data * @fsf: request containing received CT or ELS data
*/ */
void zfcp_dbf_san_res(char *tag, struct zfcp_fsf_req *fsf) void zfcp_dbf_san_res(char *tag, struct zfcp_fsf_req *fsf)
{ {
@ -580,7 +583,7 @@ void zfcp_dbf_san_res(char *tag, struct zfcp_fsf_req *fsf)
/** /**
* zfcp_dbf_san_in_els - trace event for incoming ELS * zfcp_dbf_san_in_els - trace event for incoming ELS
* @tag: identifier for event * @tag: identifier for event
* @fsf_req: request containing issued CT data * @fsf: request containing received ELS data
*/ */
void zfcp_dbf_san_in_els(char *tag, struct zfcp_fsf_req *fsf) void zfcp_dbf_san_in_els(char *tag, struct zfcp_fsf_req *fsf)
{ {

View File

@ -42,7 +42,8 @@ struct zfcp_dbf_rec_trigger {
* @fsf_req_id: request id for fsf requests * @fsf_req_id: request id for fsf requests
* @rec_status: status of the fsf request * @rec_status: status of the fsf request
* @rec_step: current step of the recovery action * @rec_step: current step of the recovery action
* rec_count: recovery counter * @rec_action: ERP action type
* @rec_count: recoveries including retries for particular @rec_action
*/ */
struct zfcp_dbf_rec_running { struct zfcp_dbf_rec_running {
u64 fsf_req_id; u64 fsf_req_id;
@ -72,6 +73,7 @@ enum zfcp_dbf_rec_id {
* @adapter_status: current status of the adapter * @adapter_status: current status of the adapter
* @port_status: current status of the port * @port_status: current status of the port
* @lun_status: current status of the lun * @lun_status: current status of the lun
* @u: record type specific data
* @u.trig: structure zfcp_dbf_rec_trigger * @u.trig: structure zfcp_dbf_rec_trigger
* @u.run: structure zfcp_dbf_rec_running * @u.run: structure zfcp_dbf_rec_running
*/ */
@ -126,6 +128,8 @@ struct zfcp_dbf_san {
* @prot_status_qual: protocol status qualifier * @prot_status_qual: protocol status qualifier
* @fsf_status: fsf status * @fsf_status: fsf status
* @fsf_status_qual: fsf status qualifier * @fsf_status_qual: fsf status qualifier
* @port_handle: handle for port
* @lun_handle: handle for LUN
*/ */
struct zfcp_dbf_hba_res { struct zfcp_dbf_hba_res {
u64 req_issued; u64 req_issued;
@ -158,6 +162,7 @@ struct zfcp_dbf_hba_uss {
* @ZFCP_DBF_HBA_RES: response trace record * @ZFCP_DBF_HBA_RES: response trace record
* @ZFCP_DBF_HBA_USS: unsolicited status trace record * @ZFCP_DBF_HBA_USS: unsolicited status trace record
* @ZFCP_DBF_HBA_BIT: bit error trace record * @ZFCP_DBF_HBA_BIT: bit error trace record
* @ZFCP_DBF_HBA_BASIC: basic adapter event, only trace tag, no other data
*/ */
enum zfcp_dbf_hba_id { enum zfcp_dbf_hba_id {
ZFCP_DBF_HBA_RES = 1, ZFCP_DBF_HBA_RES = 1,
@ -176,6 +181,9 @@ enum zfcp_dbf_hba_id {
* @fsf_seq_no: fsf sequence number * @fsf_seq_no: fsf sequence number
* @pl_len: length of payload stored as zfcp_dbf_pay * @pl_len: length of payload stored as zfcp_dbf_pay
* @u: record type specific data * @u: record type specific data
* @u.res: data for fsf responses
* @u.uss: data for unsolicited status buffer
* @u.be: data for bit error unsolicited status buffer
*/ */
struct zfcp_dbf_hba { struct zfcp_dbf_hba {
u8 id; u8 id;
@ -339,8 +347,8 @@ void zfcp_dbf_hba_fsf_response(struct zfcp_fsf_req *req)
zfcp_dbf_hba_fsf_resp_suppress(req) zfcp_dbf_hba_fsf_resp_suppress(req)
? 5 : 1, req); ? 5 : 1, req);
} else if ((req->fsf_command == FSF_QTCB_OPEN_PORT_WITH_DID) || } else if ((qtcb->header.fsf_command == FSF_QTCB_OPEN_PORT_WITH_DID) ||
(req->fsf_command == FSF_QTCB_OPEN_LUN)) { (qtcb->header.fsf_command == FSF_QTCB_OPEN_LUN)) {
zfcp_dbf_hba_fsf_resp("fs_open", 4, req); zfcp_dbf_hba_fsf_resp("fs_open", 4, req);
} else if (qtcb->header.log_length) { } else if (qtcb->header.log_length) {

View File

@ -4,7 +4,7 @@
* *
* Global definitions for the zfcp device driver. * Global definitions for the zfcp device driver.
* *
* Copyright IBM Corp. 2002, 2010 * Copyright IBM Corp. 2002, 2017
*/ */
#ifndef ZFCP_DEF_H #ifndef ZFCP_DEF_H
@ -41,24 +41,16 @@
#include "zfcp_fc.h" #include "zfcp_fc.h"
#include "zfcp_qdio.h" #include "zfcp_qdio.h"
struct zfcp_reqlist;
/********************* SCSI SPECIFIC DEFINES *********************************/
#define ZFCP_SCSI_ER_TIMEOUT (10*HZ)
/********************* FSF SPECIFIC DEFINES *********************************/ /********************* FSF SPECIFIC DEFINES *********************************/
/* ATTENTION: value must not be used by hardware */ /* ATTENTION: value must not be used by hardware */
#define FSF_QTCB_UNSOLICITED_STATUS 0x6305 #define FSF_QTCB_UNSOLICITED_STATUS 0x6305
/* timeout value for "default timer" for fsf requests */
#define ZFCP_FSF_REQUEST_TIMEOUT (60*HZ)
/*************** ADAPTER/PORT/UNIT AND FSF_REQ STATUS FLAGS ******************/ /*************** ADAPTER/PORT/UNIT AND FSF_REQ STATUS FLAGS ******************/
/* /*
* Note, the leftmost status byte is common among adapter, port * Note, the leftmost 12 status bits (3 nibbles) are common among adapter, port
* and unit * and unit. This is a mask for bitwise 'and' with status values.
*/ */
#define ZFCP_COMMON_FLAGS 0xfff00000 #define ZFCP_COMMON_FLAGS 0xfff00000
@ -97,7 +89,49 @@ struct zfcp_reqlist;
/************************* STRUCTURE DEFINITIONS *****************************/ /************************* STRUCTURE DEFINITIONS *****************************/
struct zfcp_fsf_req; /**
* enum zfcp_erp_act_type - Type of ERP action object.
* @ZFCP_ERP_ACTION_REOPEN_LUN: LUN recovery.
* @ZFCP_ERP_ACTION_REOPEN_PORT: Port recovery.
* @ZFCP_ERP_ACTION_REOPEN_PORT_FORCED: Forced port recovery.
* @ZFCP_ERP_ACTION_REOPEN_ADAPTER: Adapter recovery.
*
* Values must fit into u8 because of code dependencies:
* zfcp_dbf_rec_trig(), &zfcp_dbf_rec_trigger.want, &zfcp_dbf_rec_trigger.need;
* zfcp_dbf_rec_run_lvl(), zfcp_dbf_rec_run(), &zfcp_dbf_rec_running.rec_action.
*/
enum zfcp_erp_act_type {
ZFCP_ERP_ACTION_REOPEN_LUN = 1,
ZFCP_ERP_ACTION_REOPEN_PORT = 2,
ZFCP_ERP_ACTION_REOPEN_PORT_FORCED = 3,
ZFCP_ERP_ACTION_REOPEN_ADAPTER = 4,
};
/*
* Values must fit into u16 because of code dependencies:
* zfcp_dbf_rec_run_lvl(), zfcp_dbf_rec_run(), zfcp_dbf_rec_run_wka(),
* &zfcp_dbf_rec_running.rec_step.
*/
enum zfcp_erp_steps {
ZFCP_ERP_STEP_UNINITIALIZED = 0x0000,
ZFCP_ERP_STEP_PHYS_PORT_CLOSING = 0x0010,
ZFCP_ERP_STEP_PORT_CLOSING = 0x0100,
ZFCP_ERP_STEP_PORT_OPENING = 0x0800,
ZFCP_ERP_STEP_LUN_CLOSING = 0x1000,
ZFCP_ERP_STEP_LUN_OPENING = 0x2000,
};
struct zfcp_erp_action {
struct list_head list;
enum zfcp_erp_act_type type; /* requested action code */
struct zfcp_adapter *adapter; /* device which should be recovered */
struct zfcp_port *port;
struct scsi_device *sdev;
u32 status; /* recovery status */
enum zfcp_erp_steps step; /* active step of this erp action */
unsigned long fsf_req_id;
struct timer_list timer;
};
/* holds various memory pools of an adapter */ /* holds various memory pools of an adapter */
struct zfcp_adapter_mempool { struct zfcp_adapter_mempool {
@ -111,37 +145,6 @@ struct zfcp_adapter_mempool {
mempool_t *qtcb_pool; mempool_t *qtcb_pool;
}; };
struct zfcp_erp_action {
struct list_head list;
int action; /* requested action code */
struct zfcp_adapter *adapter; /* device which should be recovered */
struct zfcp_port *port;
struct scsi_device *sdev;
u32 status; /* recovery status */
u32 step; /* active step of this erp action */
unsigned long fsf_req_id;
struct timer_list timer;
};
struct fsf_latency_record {
u32 min;
u32 max;
u64 sum;
};
struct latency_cont {
struct fsf_latency_record channel;
struct fsf_latency_record fabric;
u64 counter;
};
struct zfcp_latencies {
struct latency_cont read;
struct latency_cont write;
struct latency_cont cmd;
spinlock_t lock;
};
struct zfcp_adapter { struct zfcp_adapter {
struct kref ref; struct kref ref;
u64 peer_wwnn; /* P2P peer WWNN */ u64 peer_wwnn; /* P2P peer WWNN */
@ -220,6 +223,25 @@ struct zfcp_port {
unsigned int starget_id; unsigned int starget_id;
}; };
struct zfcp_latency_record {
u32 min;
u32 max;
u64 sum;
};
struct zfcp_latency_cont {
struct zfcp_latency_record channel;
struct zfcp_latency_record fabric;
u64 counter;
};
struct zfcp_latencies {
struct zfcp_latency_cont read;
struct zfcp_latency_cont write;
struct zfcp_latency_cont cmd;
spinlock_t lock;
};
/** /**
* struct zfcp_unit - LUN configured via zfcp sysfs * struct zfcp_unit - LUN configured via zfcp sysfs
* @dev: struct device for sysfs representation and reference counting * @dev: struct device for sysfs representation and reference counting
@ -287,9 +309,7 @@ static inline u64 zfcp_scsi_dev_lun(struct scsi_device *sdev)
* @qdio_req: qdio queue related values * @qdio_req: qdio queue related values
* @completion: used to signal the completion of the request * @completion: used to signal the completion of the request
* @status: status of the request * @status: status of the request
* @fsf_command: FSF command issued
* @qtcb: associated QTCB * @qtcb: associated QTCB
* @seq_no: sequence number of this request
* @data: private data * @data: private data
* @timer: timer data of this request * @timer: timer data of this request
* @erp_action: reference to erp action if request issued on behalf of ERP * @erp_action: reference to erp action if request issued on behalf of ERP
@ -304,9 +324,7 @@ struct zfcp_fsf_req {
struct zfcp_qdio_req qdio_req; struct zfcp_qdio_req qdio_req;
struct completion completion; struct completion completion;
u32 status; u32 status;
u32 fsf_command;
struct fsf_qtcb *qtcb; struct fsf_qtcb *qtcb;
u32 seq_no;
void *data; void *data;
struct timer_list timer; struct timer_list timer;
struct zfcp_erp_action *erp_action; struct zfcp_erp_action *erp_action;
@ -321,4 +339,9 @@ int zfcp_adapter_multi_buffer_active(struct zfcp_adapter *adapter)
return atomic_read(&adapter->status) & ZFCP_STATUS_ADAPTER_MB_ACT; return atomic_read(&adapter->status) & ZFCP_STATUS_ADAPTER_MB_ACT;
} }
static inline bool zfcp_fsf_req_is_status_read_buffer(struct zfcp_fsf_req *req)
{
return req->qtcb == NULL;
}
#endif /* ZFCP_DEF_H */ #endif /* ZFCP_DEF_H */

View File

@ -4,7 +4,7 @@
* *
* Error Recovery Procedures (ERP). * Error Recovery Procedures (ERP).
* *
* Copyright IBM Corp. 2002, 2016 * Copyright IBM Corp. 2002, 2017
*/ */
#define KMSG_COMPONENT "zfcp" #define KMSG_COMPONENT "zfcp"
@ -24,38 +24,18 @@ enum zfcp_erp_act_flags {
ZFCP_STATUS_ERP_NO_REF = 0x00800000, ZFCP_STATUS_ERP_NO_REF = 0x00800000,
}; };
enum zfcp_erp_steps { /*
ZFCP_ERP_STEP_UNINITIALIZED = 0x0000, * Eyecatcher pseudo flag to bitwise or-combine with enum zfcp_erp_act_type.
ZFCP_ERP_STEP_PHYS_PORT_CLOSING = 0x0010, * Used to indicate that an ERP action could not be set up despite a detected
ZFCP_ERP_STEP_PORT_CLOSING = 0x0100, * need for some recovery.
ZFCP_ERP_STEP_PORT_OPENING = 0x0800,
ZFCP_ERP_STEP_LUN_CLOSING = 0x1000,
ZFCP_ERP_STEP_LUN_OPENING = 0x2000,
};
/**
* enum zfcp_erp_act_type - Type of ERP action object.
* @ZFCP_ERP_ACTION_REOPEN_LUN: LUN recovery.
* @ZFCP_ERP_ACTION_REOPEN_PORT: Port recovery.
* @ZFCP_ERP_ACTION_REOPEN_PORT_FORCED: Forced port recovery.
* @ZFCP_ERP_ACTION_REOPEN_ADAPTER: Adapter recovery.
* @ZFCP_ERP_ACTION_NONE: Eyecatcher pseudo flag to bitwise or-combine with
* either of the first four enum values.
* Used to indicate that an ERP action could not be
* set up despite a detected need for some recovery.
* @ZFCP_ERP_ACTION_FAILED: Eyecatcher pseudo flag to bitwise or-combine with
* either of the first four enum values.
* Used to indicate that ERP not needed because
* the object has ZFCP_STATUS_COMMON_ERP_FAILED.
*/ */
enum zfcp_erp_act_type { #define ZFCP_ERP_ACTION_NONE 0xc0
ZFCP_ERP_ACTION_REOPEN_LUN = 1, /*
ZFCP_ERP_ACTION_REOPEN_PORT = 2, * Eyecatcher pseudo flag to bitwise or-combine with enum zfcp_erp_act_type.
ZFCP_ERP_ACTION_REOPEN_PORT_FORCED = 3, * Used to indicate that ERP not needed because the object has
ZFCP_ERP_ACTION_REOPEN_ADAPTER = 4, * ZFCP_STATUS_COMMON_ERP_FAILED.
ZFCP_ERP_ACTION_NONE = 0xc0, */
ZFCP_ERP_ACTION_FAILED = 0xe0, #define ZFCP_ERP_ACTION_FAILED 0xe0
};
enum zfcp_erp_act_result { enum zfcp_erp_act_result {
ZFCP_ERP_SUCCEEDED = 0, ZFCP_ERP_SUCCEEDED = 0,
@ -136,11 +116,11 @@ static void zfcp_erp_action_dismiss_adapter(struct zfcp_adapter *adapter)
} }
} }
static int zfcp_erp_handle_failed(int want, struct zfcp_adapter *adapter, static enum zfcp_erp_act_type zfcp_erp_handle_failed(
struct zfcp_port *port, enum zfcp_erp_act_type want, struct zfcp_adapter *adapter,
struct scsi_device *sdev) struct zfcp_port *port, struct scsi_device *sdev)
{ {
int need = want; enum zfcp_erp_act_type need = want;
struct zfcp_scsi_dev *zsdev; struct zfcp_scsi_dev *zsdev;
switch (want) { switch (want) {
@ -171,19 +151,17 @@ static int zfcp_erp_handle_failed(int want, struct zfcp_adapter *adapter,
adapter, ZFCP_STATUS_COMMON_ERP_FAILED); adapter, ZFCP_STATUS_COMMON_ERP_FAILED);
} }
break; break;
default:
need = 0;
break;
} }
return need; return need;
} }
static int zfcp_erp_required_act(int want, struct zfcp_adapter *adapter, static enum zfcp_erp_act_type zfcp_erp_required_act(enum zfcp_erp_act_type want,
struct zfcp_adapter *adapter,
struct zfcp_port *port, struct zfcp_port *port,
struct scsi_device *sdev) struct scsi_device *sdev)
{ {
int need = want; enum zfcp_erp_act_type need = want;
int l_status, p_status, a_status; int l_status, p_status, a_status;
struct zfcp_scsi_dev *zfcp_sdev; struct zfcp_scsi_dev *zfcp_sdev;
@ -230,7 +208,8 @@ static int zfcp_erp_required_act(int want, struct zfcp_adapter *adapter,
return need; return need;
} }
static struct zfcp_erp_action *zfcp_erp_setup_act(int need, u32 act_status, static struct zfcp_erp_action *zfcp_erp_setup_act(enum zfcp_erp_act_type need,
u32 act_status,
struct zfcp_adapter *adapter, struct zfcp_adapter *adapter,
struct zfcp_port *port, struct zfcp_port *port,
struct scsi_device *sdev) struct scsi_device *sdev)
@ -278,9 +257,6 @@ static struct zfcp_erp_action *zfcp_erp_setup_act(int need, u32 act_status,
ZFCP_STATUS_COMMON_RUNNING)) ZFCP_STATUS_COMMON_RUNNING))
act_status |= ZFCP_STATUS_ERP_CLOSE_ONLY; act_status |= ZFCP_STATUS_ERP_CLOSE_ONLY;
break; break;
default:
return NULL;
} }
WARN_ON_ONCE(erp_action->adapter != adapter); WARN_ON_ONCE(erp_action->adapter != adapter);
@ -288,18 +264,19 @@ static struct zfcp_erp_action *zfcp_erp_setup_act(int need, u32 act_status,
memset(&erp_action->timer, 0, sizeof(erp_action->timer)); memset(&erp_action->timer, 0, sizeof(erp_action->timer));
erp_action->step = ZFCP_ERP_STEP_UNINITIALIZED; erp_action->step = ZFCP_ERP_STEP_UNINITIALIZED;
erp_action->fsf_req_id = 0; erp_action->fsf_req_id = 0;
erp_action->action = need; erp_action->type = need;
erp_action->status = act_status; erp_action->status = act_status;
return erp_action; return erp_action;
} }
static void zfcp_erp_action_enqueue(int want, struct zfcp_adapter *adapter, static void zfcp_erp_action_enqueue(enum zfcp_erp_act_type want,
struct zfcp_adapter *adapter,
struct zfcp_port *port, struct zfcp_port *port,
struct scsi_device *sdev, struct scsi_device *sdev,
char *id, u32 act_status) char *dbftag, u32 act_status)
{ {
int need; enum zfcp_erp_act_type need;
struct zfcp_erp_action *act; struct zfcp_erp_action *act;
need = zfcp_erp_handle_failed(want, adapter, port, sdev); need = zfcp_erp_handle_failed(want, adapter, port, sdev);
@ -327,10 +304,11 @@ static void zfcp_erp_action_enqueue(int want, struct zfcp_adapter *adapter,
list_add_tail(&act->list, &adapter->erp_ready_head); list_add_tail(&act->list, &adapter->erp_ready_head);
wake_up(&adapter->erp_ready_wq); wake_up(&adapter->erp_ready_wq);
out: out:
zfcp_dbf_rec_trig(id, adapter, port, sdev, want, need); zfcp_dbf_rec_trig(dbftag, adapter, port, sdev, want, need);
} }
void zfcp_erp_port_forced_no_port_dbf(char *id, struct zfcp_adapter *adapter, void zfcp_erp_port_forced_no_port_dbf(char *dbftag,
struct zfcp_adapter *adapter,
u64 port_name, u32 port_id) u64 port_name, u32 port_id)
{ {
unsigned long flags; unsigned long flags;
@ -344,29 +322,30 @@ void zfcp_erp_port_forced_no_port_dbf(char *id, struct zfcp_adapter *adapter,
atomic_set(&tmpport.status, -1); /* unknown */ atomic_set(&tmpport.status, -1); /* unknown */
tmpport.wwpn = port_name; tmpport.wwpn = port_name;
tmpport.d_id = port_id; tmpport.d_id = port_id;
zfcp_dbf_rec_trig(id, adapter, &tmpport, NULL, zfcp_dbf_rec_trig(dbftag, adapter, &tmpport, NULL,
ZFCP_ERP_ACTION_REOPEN_PORT_FORCED, ZFCP_ERP_ACTION_REOPEN_PORT_FORCED,
ZFCP_ERP_ACTION_NONE); ZFCP_ERP_ACTION_NONE);
write_unlock_irqrestore(&adapter->erp_lock, flags); write_unlock_irqrestore(&adapter->erp_lock, flags);
} }
static void _zfcp_erp_adapter_reopen(struct zfcp_adapter *adapter, static void _zfcp_erp_adapter_reopen(struct zfcp_adapter *adapter,
int clear_mask, char *id) int clear_mask, char *dbftag)
{ {
zfcp_erp_adapter_block(adapter, clear_mask); zfcp_erp_adapter_block(adapter, clear_mask);
zfcp_scsi_schedule_rports_block(adapter); zfcp_scsi_schedule_rports_block(adapter);
zfcp_erp_action_enqueue(ZFCP_ERP_ACTION_REOPEN_ADAPTER, zfcp_erp_action_enqueue(ZFCP_ERP_ACTION_REOPEN_ADAPTER,
adapter, NULL, NULL, id, 0); adapter, NULL, NULL, dbftag, 0);
} }
/** /**
* zfcp_erp_adapter_reopen - Reopen adapter. * zfcp_erp_adapter_reopen - Reopen adapter.
* @adapter: Adapter to reopen. * @adapter: Adapter to reopen.
* @clear: Status flags to clear. * @clear: Status flags to clear.
* @id: Id for debug trace event. * @dbftag: Tag for debug trace event.
*/ */
void zfcp_erp_adapter_reopen(struct zfcp_adapter *adapter, int clear, char *id) void zfcp_erp_adapter_reopen(struct zfcp_adapter *adapter, int clear,
char *dbftag)
{ {
unsigned long flags; unsigned long flags;
@ -375,7 +354,7 @@ void zfcp_erp_adapter_reopen(struct zfcp_adapter *adapter, int clear, char *id)
write_lock_irqsave(&adapter->erp_lock, flags); write_lock_irqsave(&adapter->erp_lock, flags);
zfcp_erp_action_enqueue(ZFCP_ERP_ACTION_REOPEN_ADAPTER, adapter, zfcp_erp_action_enqueue(ZFCP_ERP_ACTION_REOPEN_ADAPTER, adapter,
NULL, NULL, id, 0); NULL, NULL, dbftag, 0);
write_unlock_irqrestore(&adapter->erp_lock, flags); write_unlock_irqrestore(&adapter->erp_lock, flags);
} }
@ -383,25 +362,25 @@ void zfcp_erp_adapter_reopen(struct zfcp_adapter *adapter, int clear, char *id)
* zfcp_erp_adapter_shutdown - Shutdown adapter. * zfcp_erp_adapter_shutdown - Shutdown adapter.
* @adapter: Adapter to shut down. * @adapter: Adapter to shut down.
* @clear: Status flags to clear. * @clear: Status flags to clear.
* @id: Id for debug trace event. * @dbftag: Tag for debug trace event.
*/ */
void zfcp_erp_adapter_shutdown(struct zfcp_adapter *adapter, int clear, void zfcp_erp_adapter_shutdown(struct zfcp_adapter *adapter, int clear,
char *id) char *dbftag)
{ {
int flags = ZFCP_STATUS_COMMON_RUNNING | ZFCP_STATUS_COMMON_ERP_FAILED; int flags = ZFCP_STATUS_COMMON_RUNNING | ZFCP_STATUS_COMMON_ERP_FAILED;
zfcp_erp_adapter_reopen(adapter, clear | flags, id); zfcp_erp_adapter_reopen(adapter, clear | flags, dbftag);
} }
/** /**
* zfcp_erp_port_shutdown - Shutdown port * zfcp_erp_port_shutdown - Shutdown port
* @port: Port to shut down. * @port: Port to shut down.
* @clear: Status flags to clear. * @clear: Status flags to clear.
* @id: Id for debug trace event. * @dbftag: Tag for debug trace event.
*/ */
void zfcp_erp_port_shutdown(struct zfcp_port *port, int clear, char *id) void zfcp_erp_port_shutdown(struct zfcp_port *port, int clear, char *dbftag)
{ {
int flags = ZFCP_STATUS_COMMON_RUNNING | ZFCP_STATUS_COMMON_ERP_FAILED; int flags = ZFCP_STATUS_COMMON_RUNNING | ZFCP_STATUS_COMMON_ERP_FAILED;
zfcp_erp_port_reopen(port, clear | flags, id); zfcp_erp_port_reopen(port, clear | flags, dbftag);
} }
static void zfcp_erp_port_block(struct zfcp_port *port, int clear) static void zfcp_erp_port_block(struct zfcp_port *port, int clear)
@ -411,53 +390,55 @@ static void zfcp_erp_port_block(struct zfcp_port *port, int clear)
} }
static void _zfcp_erp_port_forced_reopen(struct zfcp_port *port, int clear, static void _zfcp_erp_port_forced_reopen(struct zfcp_port *port, int clear,
char *id) char *dbftag)
{ {
zfcp_erp_port_block(port, clear); zfcp_erp_port_block(port, clear);
zfcp_scsi_schedule_rport_block(port); zfcp_scsi_schedule_rport_block(port);
zfcp_erp_action_enqueue(ZFCP_ERP_ACTION_REOPEN_PORT_FORCED, zfcp_erp_action_enqueue(ZFCP_ERP_ACTION_REOPEN_PORT_FORCED,
port->adapter, port, NULL, id, 0); port->adapter, port, NULL, dbftag, 0);
} }
/** /**
* zfcp_erp_port_forced_reopen - Forced close of port and open again * zfcp_erp_port_forced_reopen - Forced close of port and open again
* @port: Port to force close and to reopen. * @port: Port to force close and to reopen.
* @clear: Status flags to clear. * @clear: Status flags to clear.
* @id: Id for debug trace event. * @dbftag: Tag for debug trace event.
*/ */
void zfcp_erp_port_forced_reopen(struct zfcp_port *port, int clear, char *id) void zfcp_erp_port_forced_reopen(struct zfcp_port *port, int clear,
char *dbftag)
{ {
unsigned long flags; unsigned long flags;
struct zfcp_adapter *adapter = port->adapter; struct zfcp_adapter *adapter = port->adapter;
write_lock_irqsave(&adapter->erp_lock, flags); write_lock_irqsave(&adapter->erp_lock, flags);
_zfcp_erp_port_forced_reopen(port, clear, id); _zfcp_erp_port_forced_reopen(port, clear, dbftag);
write_unlock_irqrestore(&adapter->erp_lock, flags); write_unlock_irqrestore(&adapter->erp_lock, flags);
} }
static void _zfcp_erp_port_reopen(struct zfcp_port *port, int clear, char *id) static void _zfcp_erp_port_reopen(struct zfcp_port *port, int clear,
char *dbftag)
{ {
zfcp_erp_port_block(port, clear); zfcp_erp_port_block(port, clear);
zfcp_scsi_schedule_rport_block(port); zfcp_scsi_schedule_rport_block(port);
zfcp_erp_action_enqueue(ZFCP_ERP_ACTION_REOPEN_PORT, zfcp_erp_action_enqueue(ZFCP_ERP_ACTION_REOPEN_PORT,
port->adapter, port, NULL, id, 0); port->adapter, port, NULL, dbftag, 0);
} }
/** /**
* zfcp_erp_port_reopen - trigger remote port recovery * zfcp_erp_port_reopen - trigger remote port recovery
* @port: port to recover * @port: port to recover
* @clear_mask: flags in port status to be cleared * @clear: flags in port status to be cleared
* @id: Id for debug trace event. * @dbftag: Tag for debug trace event.
*/ */
void zfcp_erp_port_reopen(struct zfcp_port *port, int clear, char *id) void zfcp_erp_port_reopen(struct zfcp_port *port, int clear, char *dbftag)
{ {
unsigned long flags; unsigned long flags;
struct zfcp_adapter *adapter = port->adapter; struct zfcp_adapter *adapter = port->adapter;
write_lock_irqsave(&adapter->erp_lock, flags); write_lock_irqsave(&adapter->erp_lock, flags);
_zfcp_erp_port_reopen(port, clear, id); _zfcp_erp_port_reopen(port, clear, dbftag);
write_unlock_irqrestore(&adapter->erp_lock, flags); write_unlock_irqrestore(&adapter->erp_lock, flags);
} }
@ -467,8 +448,8 @@ static void zfcp_erp_lun_block(struct scsi_device *sdev, int clear_mask)
ZFCP_STATUS_COMMON_UNBLOCKED | clear_mask); ZFCP_STATUS_COMMON_UNBLOCKED | clear_mask);
} }
static void _zfcp_erp_lun_reopen(struct scsi_device *sdev, int clear, char *id, static void _zfcp_erp_lun_reopen(struct scsi_device *sdev, int clear,
u32 act_status) char *dbftag, u32 act_status)
{ {
struct zfcp_scsi_dev *zfcp_sdev = sdev_to_zfcp(sdev); struct zfcp_scsi_dev *zfcp_sdev = sdev_to_zfcp(sdev);
struct zfcp_adapter *adapter = zfcp_sdev->port->adapter; struct zfcp_adapter *adapter = zfcp_sdev->port->adapter;
@ -476,18 +457,18 @@ static void _zfcp_erp_lun_reopen(struct scsi_device *sdev, int clear, char *id,
zfcp_erp_lun_block(sdev, clear); zfcp_erp_lun_block(sdev, clear);
zfcp_erp_action_enqueue(ZFCP_ERP_ACTION_REOPEN_LUN, adapter, zfcp_erp_action_enqueue(ZFCP_ERP_ACTION_REOPEN_LUN, adapter,
zfcp_sdev->port, sdev, id, act_status); zfcp_sdev->port, sdev, dbftag, act_status);
} }
/** /**
* zfcp_erp_lun_reopen - initiate reopen of a LUN * zfcp_erp_lun_reopen - initiate reopen of a LUN
* @sdev: SCSI device / LUN to be reopened * @sdev: SCSI device / LUN to be reopened
* @clear_mask: specifies flags in LUN status to be cleared * @clear: specifies flags in LUN status to be cleared
* @id: Id for debug trace event. * @dbftag: Tag for debug trace event.
* *
* Return: 0 on success, < 0 on error * Return: 0 on success, < 0 on error
*/ */
void zfcp_erp_lun_reopen(struct scsi_device *sdev, int clear, char *id) void zfcp_erp_lun_reopen(struct scsi_device *sdev, int clear, char *dbftag)
{ {
unsigned long flags; unsigned long flags;
struct zfcp_scsi_dev *zfcp_sdev = sdev_to_zfcp(sdev); struct zfcp_scsi_dev *zfcp_sdev = sdev_to_zfcp(sdev);
@ -495,7 +476,7 @@ void zfcp_erp_lun_reopen(struct scsi_device *sdev, int clear, char *id)
struct zfcp_adapter *adapter = port->adapter; struct zfcp_adapter *adapter = port->adapter;
write_lock_irqsave(&adapter->erp_lock, flags); write_lock_irqsave(&adapter->erp_lock, flags);
_zfcp_erp_lun_reopen(sdev, clear, id, 0); _zfcp_erp_lun_reopen(sdev, clear, dbftag, 0);
write_unlock_irqrestore(&adapter->erp_lock, flags); write_unlock_irqrestore(&adapter->erp_lock, flags);
} }
@ -503,25 +484,25 @@ void zfcp_erp_lun_reopen(struct scsi_device *sdev, int clear, char *id)
* zfcp_erp_lun_shutdown - Shutdown LUN * zfcp_erp_lun_shutdown - Shutdown LUN
* @sdev: SCSI device / LUN to shut down. * @sdev: SCSI device / LUN to shut down.
* @clear: Status flags to clear. * @clear: Status flags to clear.
* @id: Id for debug trace event. * @dbftag: Tag for debug trace event.
*/ */
void zfcp_erp_lun_shutdown(struct scsi_device *sdev, int clear, char *id) void zfcp_erp_lun_shutdown(struct scsi_device *sdev, int clear, char *dbftag)
{ {
int flags = ZFCP_STATUS_COMMON_RUNNING | ZFCP_STATUS_COMMON_ERP_FAILED; int flags = ZFCP_STATUS_COMMON_RUNNING | ZFCP_STATUS_COMMON_ERP_FAILED;
zfcp_erp_lun_reopen(sdev, clear | flags, id); zfcp_erp_lun_reopen(sdev, clear | flags, dbftag);
} }
/** /**
* zfcp_erp_lun_shutdown_wait - Shutdown LUN and wait for erp completion * zfcp_erp_lun_shutdown_wait - Shutdown LUN and wait for erp completion
* @sdev: SCSI device / LUN to shut down. * @sdev: SCSI device / LUN to shut down.
* @id: Id for debug trace event. * @dbftag: Tag for debug trace event.
* *
* Do not acquire a reference for the LUN when creating the ERP * Do not acquire a reference for the LUN when creating the ERP
* action. It is safe, because this function waits for the ERP to * action. It is safe, because this function waits for the ERP to
* complete first. This allows to shutdown the LUN, even when the SCSI * complete first. This allows to shutdown the LUN, even when the SCSI
* device is in the state SDEV_DEL when scsi_device_get will fail. * device is in the state SDEV_DEL when scsi_device_get will fail.
*/ */
void zfcp_erp_lun_shutdown_wait(struct scsi_device *sdev, char *id) void zfcp_erp_lun_shutdown_wait(struct scsi_device *sdev, char *dbftag)
{ {
unsigned long flags; unsigned long flags;
struct zfcp_scsi_dev *zfcp_sdev = sdev_to_zfcp(sdev); struct zfcp_scsi_dev *zfcp_sdev = sdev_to_zfcp(sdev);
@ -530,7 +511,7 @@ void zfcp_erp_lun_shutdown_wait(struct scsi_device *sdev, char *id)
int clear = ZFCP_STATUS_COMMON_RUNNING | ZFCP_STATUS_COMMON_ERP_FAILED; int clear = ZFCP_STATUS_COMMON_RUNNING | ZFCP_STATUS_COMMON_ERP_FAILED;
write_lock_irqsave(&adapter->erp_lock, flags); write_lock_irqsave(&adapter->erp_lock, flags);
_zfcp_erp_lun_reopen(sdev, clear, id, ZFCP_STATUS_ERP_NO_REF); _zfcp_erp_lun_reopen(sdev, clear, dbftag, ZFCP_STATUS_ERP_NO_REF);
write_unlock_irqrestore(&adapter->erp_lock, flags); write_unlock_irqrestore(&adapter->erp_lock, flags);
zfcp_erp_wait(adapter); zfcp_erp_wait(adapter);
@ -619,7 +600,7 @@ void zfcp_erp_notify(struct zfcp_erp_action *erp_action, unsigned long set_mask)
/** /**
* zfcp_erp_timeout_handler - Trigger ERP action from timed out ERP request * zfcp_erp_timeout_handler - Trigger ERP action from timed out ERP request
* @data: ERP action (from timer data) * @t: timer list entry embedded in zfcp FSF request
*/ */
void zfcp_erp_timeout_handler(struct timer_list *t) void zfcp_erp_timeout_handler(struct timer_list *t)
{ {
@ -644,31 +625,31 @@ static void zfcp_erp_strategy_memwait(struct zfcp_erp_action *erp_action)
} }
static void _zfcp_erp_port_reopen_all(struct zfcp_adapter *adapter, static void _zfcp_erp_port_reopen_all(struct zfcp_adapter *adapter,
int clear, char *id) int clear, char *dbftag)
{ {
struct zfcp_port *port; struct zfcp_port *port;
read_lock(&adapter->port_list_lock); read_lock(&adapter->port_list_lock);
list_for_each_entry(port, &adapter->port_list, list) list_for_each_entry(port, &adapter->port_list, list)
_zfcp_erp_port_reopen(port, clear, id); _zfcp_erp_port_reopen(port, clear, dbftag);
read_unlock(&adapter->port_list_lock); read_unlock(&adapter->port_list_lock);
} }
static void _zfcp_erp_lun_reopen_all(struct zfcp_port *port, int clear, static void _zfcp_erp_lun_reopen_all(struct zfcp_port *port, int clear,
char *id) char *dbftag)
{ {
struct scsi_device *sdev; struct scsi_device *sdev;
spin_lock(port->adapter->scsi_host->host_lock); spin_lock(port->adapter->scsi_host->host_lock);
__shost_for_each_device(sdev, port->adapter->scsi_host) __shost_for_each_device(sdev, port->adapter->scsi_host)
if (sdev_to_zfcp(sdev)->port == port) if (sdev_to_zfcp(sdev)->port == port)
_zfcp_erp_lun_reopen(sdev, clear, id, 0); _zfcp_erp_lun_reopen(sdev, clear, dbftag, 0);
spin_unlock(port->adapter->scsi_host->host_lock); spin_unlock(port->adapter->scsi_host->host_lock);
} }
static void zfcp_erp_strategy_followup_failed(struct zfcp_erp_action *act) static void zfcp_erp_strategy_followup_failed(struct zfcp_erp_action *act)
{ {
switch (act->action) { switch (act->type) {
case ZFCP_ERP_ACTION_REOPEN_ADAPTER: case ZFCP_ERP_ACTION_REOPEN_ADAPTER:
_zfcp_erp_adapter_reopen(act->adapter, 0, "ersff_1"); _zfcp_erp_adapter_reopen(act->adapter, 0, "ersff_1");
break; break;
@ -686,7 +667,7 @@ static void zfcp_erp_strategy_followup_failed(struct zfcp_erp_action *act)
static void zfcp_erp_strategy_followup_success(struct zfcp_erp_action *act) static void zfcp_erp_strategy_followup_success(struct zfcp_erp_action *act)
{ {
switch (act->action) { switch (act->type) {
case ZFCP_ERP_ACTION_REOPEN_ADAPTER: case ZFCP_ERP_ACTION_REOPEN_ADAPTER:
_zfcp_erp_port_reopen_all(act->adapter, 0, "ersfs_1"); _zfcp_erp_port_reopen_all(act->adapter, 0, "ersfs_1");
break; break;
@ -696,6 +677,9 @@ static void zfcp_erp_strategy_followup_success(struct zfcp_erp_action *act)
case ZFCP_ERP_ACTION_REOPEN_PORT: case ZFCP_ERP_ACTION_REOPEN_PORT:
_zfcp_erp_lun_reopen_all(act->port, 0, "ersfs_3"); _zfcp_erp_lun_reopen_all(act->port, 0, "ersfs_3");
break; break;
case ZFCP_ERP_ACTION_REOPEN_LUN:
/* NOP */
break;
} }
} }
@ -723,7 +707,8 @@ static void zfcp_erp_enqueue_ptp_port(struct zfcp_adapter *adapter)
_zfcp_erp_port_reopen(port, 0, "ereptp1"); _zfcp_erp_port_reopen(port, 0, "ereptp1");
} }
static int zfcp_erp_adapter_strat_fsf_xconf(struct zfcp_erp_action *erp_action) static enum zfcp_erp_act_result zfcp_erp_adapter_strat_fsf_xconf(
struct zfcp_erp_action *erp_action)
{ {
int retries; int retries;
int sleep = 1; int sleep = 1;
@ -768,7 +753,8 @@ static int zfcp_erp_adapter_strat_fsf_xconf(struct zfcp_erp_action *erp_action)
return ZFCP_ERP_SUCCEEDED; return ZFCP_ERP_SUCCEEDED;
} }
static int zfcp_erp_adapter_strategy_open_fsf_xport(struct zfcp_erp_action *act) static enum zfcp_erp_act_result zfcp_erp_adapter_strategy_open_fsf_xport(
struct zfcp_erp_action *act)
{ {
int ret; int ret;
struct zfcp_adapter *adapter = act->adapter; struct zfcp_adapter *adapter = act->adapter;
@ -793,7 +779,8 @@ static int zfcp_erp_adapter_strategy_open_fsf_xport(struct zfcp_erp_action *act)
return ZFCP_ERP_SUCCEEDED; return ZFCP_ERP_SUCCEEDED;
} }
static int zfcp_erp_adapter_strategy_open_fsf(struct zfcp_erp_action *act) static enum zfcp_erp_act_result zfcp_erp_adapter_strategy_open_fsf(
struct zfcp_erp_action *act)
{ {
if (zfcp_erp_adapter_strat_fsf_xconf(act) == ZFCP_ERP_FAILED) if (zfcp_erp_adapter_strat_fsf_xconf(act) == ZFCP_ERP_FAILED)
return ZFCP_ERP_FAILED; return ZFCP_ERP_FAILED;
@ -832,7 +819,8 @@ static void zfcp_erp_adapter_strategy_close(struct zfcp_erp_action *act)
ZFCP_STATUS_ADAPTER_LINK_UNPLUGGED, &adapter->status); ZFCP_STATUS_ADAPTER_LINK_UNPLUGGED, &adapter->status);
} }
static int zfcp_erp_adapter_strategy_open(struct zfcp_erp_action *act) static enum zfcp_erp_act_result zfcp_erp_adapter_strategy_open(
struct zfcp_erp_action *act)
{ {
struct zfcp_adapter *adapter = act->adapter; struct zfcp_adapter *adapter = act->adapter;
@ -853,7 +841,8 @@ static int zfcp_erp_adapter_strategy_open(struct zfcp_erp_action *act)
return ZFCP_ERP_SUCCEEDED; return ZFCP_ERP_SUCCEEDED;
} }
static int zfcp_erp_adapter_strategy(struct zfcp_erp_action *act) static enum zfcp_erp_act_result zfcp_erp_adapter_strategy(
struct zfcp_erp_action *act)
{ {
struct zfcp_adapter *adapter = act->adapter; struct zfcp_adapter *adapter = act->adapter;
@ -871,7 +860,8 @@ static int zfcp_erp_adapter_strategy(struct zfcp_erp_action *act)
return ZFCP_ERP_SUCCEEDED; return ZFCP_ERP_SUCCEEDED;
} }
static int zfcp_erp_port_forced_strategy_close(struct zfcp_erp_action *act) static enum zfcp_erp_act_result zfcp_erp_port_forced_strategy_close(
struct zfcp_erp_action *act)
{ {
int retval; int retval;
@ -885,7 +875,8 @@ static int zfcp_erp_port_forced_strategy_close(struct zfcp_erp_action *act)
return ZFCP_ERP_CONTINUES; return ZFCP_ERP_CONTINUES;
} }
static int zfcp_erp_port_forced_strategy(struct zfcp_erp_action *erp_action) static enum zfcp_erp_act_result zfcp_erp_port_forced_strategy(
struct zfcp_erp_action *erp_action)
{ {
struct zfcp_port *port = erp_action->port; struct zfcp_port *port = erp_action->port;
int status = atomic_read(&port->status); int status = atomic_read(&port->status);
@ -901,11 +892,19 @@ static int zfcp_erp_port_forced_strategy(struct zfcp_erp_action *erp_action)
case ZFCP_ERP_STEP_PHYS_PORT_CLOSING: case ZFCP_ERP_STEP_PHYS_PORT_CLOSING:
if (!(status & ZFCP_STATUS_PORT_PHYS_OPEN)) if (!(status & ZFCP_STATUS_PORT_PHYS_OPEN))
return ZFCP_ERP_SUCCEEDED; return ZFCP_ERP_SUCCEEDED;
break;
case ZFCP_ERP_STEP_PORT_CLOSING:
case ZFCP_ERP_STEP_PORT_OPENING:
case ZFCP_ERP_STEP_LUN_CLOSING:
case ZFCP_ERP_STEP_LUN_OPENING:
/* NOP */
break;
} }
return ZFCP_ERP_FAILED; return ZFCP_ERP_FAILED;
} }
static int zfcp_erp_port_strategy_close(struct zfcp_erp_action *erp_action) static enum zfcp_erp_act_result zfcp_erp_port_strategy_close(
struct zfcp_erp_action *erp_action)
{ {
int retval; int retval;
@ -918,7 +917,8 @@ static int zfcp_erp_port_strategy_close(struct zfcp_erp_action *erp_action)
return ZFCP_ERP_CONTINUES; return ZFCP_ERP_CONTINUES;
} }
static int zfcp_erp_port_strategy_open_port(struct zfcp_erp_action *erp_action) static enum zfcp_erp_act_result zfcp_erp_port_strategy_open_port(
struct zfcp_erp_action *erp_action)
{ {
int retval; int retval;
@ -944,7 +944,8 @@ static int zfcp_erp_open_ptp_port(struct zfcp_erp_action *act)
return zfcp_erp_port_strategy_open_port(act); return zfcp_erp_port_strategy_open_port(act);
} }
static int zfcp_erp_port_strategy_open_common(struct zfcp_erp_action *act) static enum zfcp_erp_act_result zfcp_erp_port_strategy_open_common(
struct zfcp_erp_action *act)
{ {
struct zfcp_adapter *adapter = act->adapter; struct zfcp_adapter *adapter = act->adapter;
struct zfcp_port *port = act->port; struct zfcp_port *port = act->port;
@ -975,12 +976,18 @@ static int zfcp_erp_port_strategy_open_common(struct zfcp_erp_action *act)
port->d_id = 0; port->d_id = 0;
return ZFCP_ERP_FAILED; return ZFCP_ERP_FAILED;
} }
/* fall through otherwise */ /* no early return otherwise, continue after switch case */
break;
case ZFCP_ERP_STEP_LUN_CLOSING:
case ZFCP_ERP_STEP_LUN_OPENING:
/* NOP */
break;
} }
return ZFCP_ERP_FAILED; return ZFCP_ERP_FAILED;
} }
static int zfcp_erp_port_strategy(struct zfcp_erp_action *erp_action) static enum zfcp_erp_act_result zfcp_erp_port_strategy(
struct zfcp_erp_action *erp_action)
{ {
struct zfcp_port *port = erp_action->port; struct zfcp_port *port = erp_action->port;
int p_status = atomic_read(&port->status); int p_status = atomic_read(&port->status);
@ -999,6 +1006,12 @@ static int zfcp_erp_port_strategy(struct zfcp_erp_action *erp_action)
if (p_status & ZFCP_STATUS_COMMON_OPEN) if (p_status & ZFCP_STATUS_COMMON_OPEN)
return ZFCP_ERP_FAILED; return ZFCP_ERP_FAILED;
break; break;
case ZFCP_ERP_STEP_PHYS_PORT_CLOSING:
case ZFCP_ERP_STEP_PORT_OPENING:
case ZFCP_ERP_STEP_LUN_CLOSING:
case ZFCP_ERP_STEP_LUN_OPENING:
/* NOP */
break;
} }
close_init_done: close_init_done:
@ -1016,7 +1029,8 @@ static void zfcp_erp_lun_strategy_clearstati(struct scsi_device *sdev)
&zfcp_sdev->status); &zfcp_sdev->status);
} }
static int zfcp_erp_lun_strategy_close(struct zfcp_erp_action *erp_action) static enum zfcp_erp_act_result zfcp_erp_lun_strategy_close(
struct zfcp_erp_action *erp_action)
{ {
int retval = zfcp_fsf_close_lun(erp_action); int retval = zfcp_fsf_close_lun(erp_action);
if (retval == -ENOMEM) if (retval == -ENOMEM)
@ -1027,7 +1041,8 @@ static int zfcp_erp_lun_strategy_close(struct zfcp_erp_action *erp_action)
return ZFCP_ERP_CONTINUES; return ZFCP_ERP_CONTINUES;
} }
static int zfcp_erp_lun_strategy_open(struct zfcp_erp_action *erp_action) static enum zfcp_erp_act_result zfcp_erp_lun_strategy_open(
struct zfcp_erp_action *erp_action)
{ {
int retval = zfcp_fsf_open_lun(erp_action); int retval = zfcp_fsf_open_lun(erp_action);
if (retval == -ENOMEM) if (retval == -ENOMEM)
@ -1038,7 +1053,8 @@ static int zfcp_erp_lun_strategy_open(struct zfcp_erp_action *erp_action)
return ZFCP_ERP_CONTINUES; return ZFCP_ERP_CONTINUES;
} }
static int zfcp_erp_lun_strategy(struct zfcp_erp_action *erp_action) static enum zfcp_erp_act_result zfcp_erp_lun_strategy(
struct zfcp_erp_action *erp_action)
{ {
struct scsi_device *sdev = erp_action->sdev; struct scsi_device *sdev = erp_action->sdev;
struct zfcp_scsi_dev *zfcp_sdev = sdev_to_zfcp(sdev); struct zfcp_scsi_dev *zfcp_sdev = sdev_to_zfcp(sdev);
@ -1048,7 +1064,8 @@ static int zfcp_erp_lun_strategy(struct zfcp_erp_action *erp_action)
zfcp_erp_lun_strategy_clearstati(sdev); zfcp_erp_lun_strategy_clearstati(sdev);
if (atomic_read(&zfcp_sdev->status) & ZFCP_STATUS_COMMON_OPEN) if (atomic_read(&zfcp_sdev->status) & ZFCP_STATUS_COMMON_OPEN)
return zfcp_erp_lun_strategy_close(erp_action); return zfcp_erp_lun_strategy_close(erp_action);
/* already closed, fall through */ /* already closed */
/* fall through */
case ZFCP_ERP_STEP_LUN_CLOSING: case ZFCP_ERP_STEP_LUN_CLOSING:
if (atomic_read(&zfcp_sdev->status) & ZFCP_STATUS_COMMON_OPEN) if (atomic_read(&zfcp_sdev->status) & ZFCP_STATUS_COMMON_OPEN)
return ZFCP_ERP_FAILED; return ZFCP_ERP_FAILED;
@ -1059,11 +1076,18 @@ static int zfcp_erp_lun_strategy(struct zfcp_erp_action *erp_action)
case ZFCP_ERP_STEP_LUN_OPENING: case ZFCP_ERP_STEP_LUN_OPENING:
if (atomic_read(&zfcp_sdev->status) & ZFCP_STATUS_COMMON_OPEN) if (atomic_read(&zfcp_sdev->status) & ZFCP_STATUS_COMMON_OPEN)
return ZFCP_ERP_SUCCEEDED; return ZFCP_ERP_SUCCEEDED;
break;
case ZFCP_ERP_STEP_PHYS_PORT_CLOSING:
case ZFCP_ERP_STEP_PORT_CLOSING:
case ZFCP_ERP_STEP_PORT_OPENING:
/* NOP */
break;
} }
return ZFCP_ERP_FAILED; return ZFCP_ERP_FAILED;
} }
static int zfcp_erp_strategy_check_lun(struct scsi_device *sdev, int result) static enum zfcp_erp_act_result zfcp_erp_strategy_check_lun(
struct scsi_device *sdev, enum zfcp_erp_act_result result)
{ {
struct zfcp_scsi_dev *zfcp_sdev = sdev_to_zfcp(sdev); struct zfcp_scsi_dev *zfcp_sdev = sdev_to_zfcp(sdev);
@ -1084,6 +1108,12 @@ static int zfcp_erp_strategy_check_lun(struct scsi_device *sdev, int result)
ZFCP_STATUS_COMMON_ERP_FAILED); ZFCP_STATUS_COMMON_ERP_FAILED);
} }
break; break;
case ZFCP_ERP_CONTINUES:
case ZFCP_ERP_EXIT:
case ZFCP_ERP_DISMISSED:
case ZFCP_ERP_NOMEM:
/* NOP */
break;
} }
if (atomic_read(&zfcp_sdev->status) & ZFCP_STATUS_COMMON_ERP_FAILED) { if (atomic_read(&zfcp_sdev->status) & ZFCP_STATUS_COMMON_ERP_FAILED) {
@ -1093,7 +1123,8 @@ static int zfcp_erp_strategy_check_lun(struct scsi_device *sdev, int result)
return result; return result;
} }
static int zfcp_erp_strategy_check_port(struct zfcp_port *port, int result) static enum zfcp_erp_act_result zfcp_erp_strategy_check_port(
struct zfcp_port *port, enum zfcp_erp_act_result result)
{ {
switch (result) { switch (result) {
case ZFCP_ERP_SUCCEEDED : case ZFCP_ERP_SUCCEEDED :
@ -1115,6 +1146,12 @@ static int zfcp_erp_strategy_check_port(struct zfcp_port *port, int result)
ZFCP_STATUS_COMMON_ERP_FAILED); ZFCP_STATUS_COMMON_ERP_FAILED);
} }
break; break;
case ZFCP_ERP_CONTINUES:
case ZFCP_ERP_EXIT:
case ZFCP_ERP_DISMISSED:
case ZFCP_ERP_NOMEM:
/* NOP */
break;
} }
if (atomic_read(&port->status) & ZFCP_STATUS_COMMON_ERP_FAILED) { if (atomic_read(&port->status) & ZFCP_STATUS_COMMON_ERP_FAILED) {
@ -1124,8 +1161,8 @@ static int zfcp_erp_strategy_check_port(struct zfcp_port *port, int result)
return result; return result;
} }
static int zfcp_erp_strategy_check_adapter(struct zfcp_adapter *adapter, static enum zfcp_erp_act_result zfcp_erp_strategy_check_adapter(
int result) struct zfcp_adapter *adapter, enum zfcp_erp_act_result result)
{ {
switch (result) { switch (result) {
case ZFCP_ERP_SUCCEEDED : case ZFCP_ERP_SUCCEEDED :
@ -1143,6 +1180,12 @@ static int zfcp_erp_strategy_check_adapter(struct zfcp_adapter *adapter,
ZFCP_STATUS_COMMON_ERP_FAILED); ZFCP_STATUS_COMMON_ERP_FAILED);
} }
break; break;
case ZFCP_ERP_CONTINUES:
case ZFCP_ERP_EXIT:
case ZFCP_ERP_DISMISSED:
case ZFCP_ERP_NOMEM:
/* NOP */
break;
} }
if (atomic_read(&adapter->status) & ZFCP_STATUS_COMMON_ERP_FAILED) { if (atomic_read(&adapter->status) & ZFCP_STATUS_COMMON_ERP_FAILED) {
@ -1152,14 +1195,14 @@ static int zfcp_erp_strategy_check_adapter(struct zfcp_adapter *adapter,
return result; return result;
} }
static int zfcp_erp_strategy_check_target(struct zfcp_erp_action *erp_action, static enum zfcp_erp_act_result zfcp_erp_strategy_check_target(
int result) struct zfcp_erp_action *erp_action, enum zfcp_erp_act_result result)
{ {
struct zfcp_adapter *adapter = erp_action->adapter; struct zfcp_adapter *adapter = erp_action->adapter;
struct zfcp_port *port = erp_action->port; struct zfcp_port *port = erp_action->port;
struct scsi_device *sdev = erp_action->sdev; struct scsi_device *sdev = erp_action->sdev;
switch (erp_action->action) { switch (erp_action->type) {
case ZFCP_ERP_ACTION_REOPEN_LUN: case ZFCP_ERP_ACTION_REOPEN_LUN:
result = zfcp_erp_strategy_check_lun(sdev, result); result = zfcp_erp_strategy_check_lun(sdev, result);
@ -1192,16 +1235,17 @@ static int zfcp_erp_strat_change_det(atomic_t *target_status, u32 erp_status)
return 0; return 0;
} }
static int zfcp_erp_strategy_statechange(struct zfcp_erp_action *act, int ret) static enum zfcp_erp_act_result zfcp_erp_strategy_statechange(
struct zfcp_erp_action *act, enum zfcp_erp_act_result result)
{ {
int action = act->action; enum zfcp_erp_act_type type = act->type;
struct zfcp_adapter *adapter = act->adapter; struct zfcp_adapter *adapter = act->adapter;
struct zfcp_port *port = act->port; struct zfcp_port *port = act->port;
struct scsi_device *sdev = act->sdev; struct scsi_device *sdev = act->sdev;
struct zfcp_scsi_dev *zfcp_sdev; struct zfcp_scsi_dev *zfcp_sdev;
u32 erp_status = act->status; u32 erp_status = act->status;
switch (action) { switch (type) {
case ZFCP_ERP_ACTION_REOPEN_ADAPTER: case ZFCP_ERP_ACTION_REOPEN_ADAPTER:
if (zfcp_erp_strat_change_det(&adapter->status, erp_status)) { if (zfcp_erp_strat_change_det(&adapter->status, erp_status)) {
_zfcp_erp_adapter_reopen(adapter, _zfcp_erp_adapter_reopen(adapter,
@ -1231,7 +1275,7 @@ static int zfcp_erp_strategy_statechange(struct zfcp_erp_action *act, int ret)
} }
break; break;
} }
return ret; return result;
} }
static void zfcp_erp_action_dequeue(struct zfcp_erp_action *erp_action) static void zfcp_erp_action_dequeue(struct zfcp_erp_action *erp_action)
@ -1248,7 +1292,7 @@ static void zfcp_erp_action_dequeue(struct zfcp_erp_action *erp_action)
list_del(&erp_action->list); list_del(&erp_action->list);
zfcp_dbf_rec_run("eractd1", erp_action); zfcp_dbf_rec_run("eractd1", erp_action);
switch (erp_action->action) { switch (erp_action->type) {
case ZFCP_ERP_ACTION_REOPEN_LUN: case ZFCP_ERP_ACTION_REOPEN_LUN:
zfcp_sdev = sdev_to_zfcp(erp_action->sdev); zfcp_sdev = sdev_to_zfcp(erp_action->sdev);
atomic_andnot(ZFCP_STATUS_COMMON_ERP_INUSE, atomic_andnot(ZFCP_STATUS_COMMON_ERP_INUSE,
@ -1324,13 +1368,14 @@ static void zfcp_erp_try_rport_unblock(struct zfcp_port *port)
write_unlock_irqrestore(&adapter->erp_lock, flags); write_unlock_irqrestore(&adapter->erp_lock, flags);
} }
static void zfcp_erp_action_cleanup(struct zfcp_erp_action *act, int result) static void zfcp_erp_action_cleanup(struct zfcp_erp_action *act,
enum zfcp_erp_act_result result)
{ {
struct zfcp_adapter *adapter = act->adapter; struct zfcp_adapter *adapter = act->adapter;
struct zfcp_port *port = act->port; struct zfcp_port *port = act->port;
struct scsi_device *sdev = act->sdev; struct scsi_device *sdev = act->sdev;
switch (act->action) { switch (act->type) {
case ZFCP_ERP_ACTION_REOPEN_LUN: case ZFCP_ERP_ACTION_REOPEN_LUN:
if (!(act->status & ZFCP_STATUS_ERP_NO_REF)) if (!(act->status & ZFCP_STATUS_ERP_NO_REF))
scsi_device_put(sdev); scsi_device_put(sdev);
@ -1364,9 +1409,10 @@ static void zfcp_erp_action_cleanup(struct zfcp_erp_action *act, int result)
} }
} }
static int zfcp_erp_strategy_do_action(struct zfcp_erp_action *erp_action) static enum zfcp_erp_act_result zfcp_erp_strategy_do_action(
struct zfcp_erp_action *erp_action)
{ {
switch (erp_action->action) { switch (erp_action->type) {
case ZFCP_ERP_ACTION_REOPEN_ADAPTER: case ZFCP_ERP_ACTION_REOPEN_ADAPTER:
return zfcp_erp_adapter_strategy(erp_action); return zfcp_erp_adapter_strategy(erp_action);
case ZFCP_ERP_ACTION_REOPEN_PORT_FORCED: case ZFCP_ERP_ACTION_REOPEN_PORT_FORCED:
@ -1379,9 +1425,10 @@ static int zfcp_erp_strategy_do_action(struct zfcp_erp_action *erp_action)
return ZFCP_ERP_FAILED; return ZFCP_ERP_FAILED;
} }
static int zfcp_erp_strategy(struct zfcp_erp_action *erp_action) static enum zfcp_erp_act_result zfcp_erp_strategy(
struct zfcp_erp_action *erp_action)
{ {
int retval; enum zfcp_erp_act_result result;
unsigned long flags; unsigned long flags;
struct zfcp_adapter *adapter = erp_action->adapter; struct zfcp_adapter *adapter = erp_action->adapter;
@ -1392,12 +1439,12 @@ static int zfcp_erp_strategy(struct zfcp_erp_action *erp_action)
if (erp_action->status & ZFCP_STATUS_ERP_DISMISSED) { if (erp_action->status & ZFCP_STATUS_ERP_DISMISSED) {
zfcp_erp_action_dequeue(erp_action); zfcp_erp_action_dequeue(erp_action);
retval = ZFCP_ERP_DISMISSED; result = ZFCP_ERP_DISMISSED;
goto unlock; goto unlock;
} }
if (erp_action->status & ZFCP_STATUS_ERP_TIMEDOUT) { if (erp_action->status & ZFCP_STATUS_ERP_TIMEDOUT) {
retval = ZFCP_ERP_FAILED; result = ZFCP_ERP_FAILED;
goto check_target; goto check_target;
} }
@ -1405,13 +1452,13 @@ static int zfcp_erp_strategy(struct zfcp_erp_action *erp_action)
/* no lock to allow for blocking operations */ /* no lock to allow for blocking operations */
write_unlock_irqrestore(&adapter->erp_lock, flags); write_unlock_irqrestore(&adapter->erp_lock, flags);
retval = zfcp_erp_strategy_do_action(erp_action); result = zfcp_erp_strategy_do_action(erp_action);
write_lock_irqsave(&adapter->erp_lock, flags); write_lock_irqsave(&adapter->erp_lock, flags);
if (erp_action->status & ZFCP_STATUS_ERP_DISMISSED) if (erp_action->status & ZFCP_STATUS_ERP_DISMISSED)
retval = ZFCP_ERP_CONTINUES; result = ZFCP_ERP_CONTINUES;
switch (retval) { switch (result) {
case ZFCP_ERP_NOMEM: case ZFCP_ERP_NOMEM:
if (!(erp_action->status & ZFCP_STATUS_ERP_LOWMEM)) { if (!(erp_action->status & ZFCP_STATUS_ERP_LOWMEM)) {
++adapter->erp_low_mem_count; ++adapter->erp_low_mem_count;
@ -1421,7 +1468,7 @@ static int zfcp_erp_strategy(struct zfcp_erp_action *erp_action)
_zfcp_erp_adapter_reopen(adapter, 0, "erstgy1"); _zfcp_erp_adapter_reopen(adapter, 0, "erstgy1");
else { else {
zfcp_erp_strategy_memwait(erp_action); zfcp_erp_strategy_memwait(erp_action);
retval = ZFCP_ERP_CONTINUES; result = ZFCP_ERP_CONTINUES;
} }
goto unlock; goto unlock;
@ -1431,27 +1478,33 @@ static int zfcp_erp_strategy(struct zfcp_erp_action *erp_action)
erp_action->status &= ~ZFCP_STATUS_ERP_LOWMEM; erp_action->status &= ~ZFCP_STATUS_ERP_LOWMEM;
} }
goto unlock; goto unlock;
case ZFCP_ERP_SUCCEEDED:
case ZFCP_ERP_FAILED:
case ZFCP_ERP_EXIT:
case ZFCP_ERP_DISMISSED:
/* NOP */
break;
} }
check_target: check_target:
retval = zfcp_erp_strategy_check_target(erp_action, retval); result = zfcp_erp_strategy_check_target(erp_action, result);
zfcp_erp_action_dequeue(erp_action); zfcp_erp_action_dequeue(erp_action);
retval = zfcp_erp_strategy_statechange(erp_action, retval); result = zfcp_erp_strategy_statechange(erp_action, result);
if (retval == ZFCP_ERP_EXIT) if (result == ZFCP_ERP_EXIT)
goto unlock; goto unlock;
if (retval == ZFCP_ERP_SUCCEEDED) if (result == ZFCP_ERP_SUCCEEDED)
zfcp_erp_strategy_followup_success(erp_action); zfcp_erp_strategy_followup_success(erp_action);
if (retval == ZFCP_ERP_FAILED) if (result == ZFCP_ERP_FAILED)
zfcp_erp_strategy_followup_failed(erp_action); zfcp_erp_strategy_followup_failed(erp_action);
unlock: unlock:
write_unlock_irqrestore(&adapter->erp_lock, flags); write_unlock_irqrestore(&adapter->erp_lock, flags);
if (retval != ZFCP_ERP_CONTINUES) if (result != ZFCP_ERP_CONTINUES)
zfcp_erp_action_cleanup(erp_action, retval); zfcp_erp_action_cleanup(erp_action, result);
kref_put(&adapter->ref, zfcp_adapter_release); kref_put(&adapter->ref, zfcp_adapter_release);
return retval; return result;
} }
static int zfcp_erp_thread(void *data) static int zfcp_erp_thread(void *data)
@ -1489,7 +1542,7 @@ static int zfcp_erp_thread(void *data)
* zfcp_erp_thread_setup - Start ERP thread for adapter * zfcp_erp_thread_setup - Start ERP thread for adapter
* @adapter: Adapter to start the ERP thread for * @adapter: Adapter to start the ERP thread for
* *
* Returns 0 on success or error code from kernel_thread() * Return: 0 on success, or error code from kthread_run().
*/ */
int zfcp_erp_thread_setup(struct zfcp_adapter *adapter) int zfcp_erp_thread_setup(struct zfcp_adapter *adapter)
{ {
@ -1694,11 +1747,11 @@ void zfcp_erp_clear_lun_status(struct scsi_device *sdev, u32 mask)
/** /**
* zfcp_erp_adapter_reset_sync() - Really reopen adapter and wait. * zfcp_erp_adapter_reset_sync() - Really reopen adapter and wait.
* @adapter: Pointer to zfcp_adapter to reopen. * @adapter: Pointer to zfcp_adapter to reopen.
* @id: Trace tag string of length %ZFCP_DBF_TAG_LEN. * @dbftag: Trace tag string of length %ZFCP_DBF_TAG_LEN.
*/ */
void zfcp_erp_adapter_reset_sync(struct zfcp_adapter *adapter, char *id) void zfcp_erp_adapter_reset_sync(struct zfcp_adapter *adapter, char *dbftag)
{ {
zfcp_erp_set_adapter_status(adapter, ZFCP_STATUS_COMMON_RUNNING); zfcp_erp_set_adapter_status(adapter, ZFCP_STATUS_COMMON_RUNNING);
zfcp_erp_adapter_reopen(adapter, ZFCP_STATUS_COMMON_ERP_FAILED, id); zfcp_erp_adapter_reopen(adapter, ZFCP_STATUS_COMMON_ERP_FAILED, dbftag);
zfcp_erp_wait(adapter); zfcp_erp_wait(adapter);
} }

View File

@ -59,14 +59,15 @@ extern void zfcp_dbf_scsi_eh(char *tag, struct zfcp_adapter *adapter,
/* zfcp_erp.c */ /* zfcp_erp.c */
extern void zfcp_erp_set_adapter_status(struct zfcp_adapter *, u32); extern void zfcp_erp_set_adapter_status(struct zfcp_adapter *, u32);
extern void zfcp_erp_clear_adapter_status(struct zfcp_adapter *, u32); extern void zfcp_erp_clear_adapter_status(struct zfcp_adapter *, u32);
extern void zfcp_erp_port_forced_no_port_dbf(char *id, extern void zfcp_erp_port_forced_no_port_dbf(char *dbftag,
struct zfcp_adapter *adapter, struct zfcp_adapter *adapter,
u64 port_name, u32 port_id); u64 port_name, u32 port_id);
extern void zfcp_erp_adapter_reopen(struct zfcp_adapter *, int, char *); extern void zfcp_erp_adapter_reopen(struct zfcp_adapter *, int, char *);
extern void zfcp_erp_adapter_shutdown(struct zfcp_adapter *, int, char *); extern void zfcp_erp_adapter_shutdown(struct zfcp_adapter *, int, char *);
extern void zfcp_erp_set_port_status(struct zfcp_port *, u32); extern void zfcp_erp_set_port_status(struct zfcp_port *, u32);
extern void zfcp_erp_clear_port_status(struct zfcp_port *, u32); extern void zfcp_erp_clear_port_status(struct zfcp_port *, u32);
extern void zfcp_erp_port_reopen(struct zfcp_port *port, int clear, char *id); extern void zfcp_erp_port_reopen(struct zfcp_port *port, int clear,
char *dbftag);
extern void zfcp_erp_port_shutdown(struct zfcp_port *, int, char *); extern void zfcp_erp_port_shutdown(struct zfcp_port *, int, char *);
extern void zfcp_erp_port_forced_reopen(struct zfcp_port *, int, char *); extern void zfcp_erp_port_forced_reopen(struct zfcp_port *, int, char *);
extern void zfcp_erp_set_lun_status(struct scsi_device *, u32); extern void zfcp_erp_set_lun_status(struct scsi_device *, u32);
@ -79,7 +80,8 @@ extern void zfcp_erp_thread_kill(struct zfcp_adapter *);
extern void zfcp_erp_wait(struct zfcp_adapter *); extern void zfcp_erp_wait(struct zfcp_adapter *);
extern void zfcp_erp_notify(struct zfcp_erp_action *, unsigned long); extern void zfcp_erp_notify(struct zfcp_erp_action *, unsigned long);
extern void zfcp_erp_timeout_handler(struct timer_list *t); extern void zfcp_erp_timeout_handler(struct timer_list *t);
extern void zfcp_erp_adapter_reset_sync(struct zfcp_adapter *adapter, char *id); extern void zfcp_erp_adapter_reset_sync(struct zfcp_adapter *adapter,
char *dbftag);
/* zfcp_fc.c */ /* zfcp_fc.c */
extern struct kmem_cache *zfcp_fc_req_cache; extern struct kmem_cache *zfcp_fc_req_cache;
@ -144,6 +146,7 @@ extern void zfcp_qdio_close(struct zfcp_qdio *);
extern void zfcp_qdio_siosl(struct zfcp_adapter *); extern void zfcp_qdio_siosl(struct zfcp_adapter *);
/* zfcp_scsi.c */ /* zfcp_scsi.c */
extern bool zfcp_experimental_dix;
extern struct scsi_transport_template *zfcp_scsi_transport_template; extern struct scsi_transport_template *zfcp_scsi_transport_template;
extern int zfcp_scsi_adapter_register(struct zfcp_adapter *); extern int zfcp_scsi_adapter_register(struct zfcp_adapter *);
extern void zfcp_scsi_adapter_unregister(struct zfcp_adapter *); extern void zfcp_scsi_adapter_unregister(struct zfcp_adapter *);

View File

@ -312,7 +312,7 @@ static void zfcp_fc_incoming_logo(struct zfcp_fsf_req *req)
/** /**
* zfcp_fc_incoming_els - handle incoming ELS * zfcp_fc_incoming_els - handle incoming ELS
* @fsf_req - request which contains incoming ELS * @fsf_req: request which contains incoming ELS
*/ */
void zfcp_fc_incoming_els(struct zfcp_fsf_req *fsf_req) void zfcp_fc_incoming_els(struct zfcp_fsf_req *fsf_req)
{ {
@ -597,6 +597,48 @@ void zfcp_fc_test_link(struct zfcp_port *port)
put_device(&port->dev); put_device(&port->dev);
} }
/**
* zfcp_fc_sg_free_table - free memory used by scatterlists
* @sg: pointer to scatterlist
* @count: number of scatterlist which are to be free'ed
* the scatterlist are expected to reference pages always
*/
static void zfcp_fc_sg_free_table(struct scatterlist *sg, int count)
{
int i;
for (i = 0; i < count; i++, sg++)
if (sg)
free_page((unsigned long) sg_virt(sg));
else
break;
}
/**
* zfcp_fc_sg_setup_table - init scatterlist and allocate, assign buffers
* @sg: pointer to struct scatterlist
* @count: number of scatterlists which should be assigned with buffers
* of size page
*
* Returns: 0 on success, -ENOMEM otherwise
*/
static int zfcp_fc_sg_setup_table(struct scatterlist *sg, int count)
{
void *addr;
int i;
sg_init_table(sg, count);
for (i = 0; i < count; i++, sg++) {
addr = (void *) get_zeroed_page(GFP_KERNEL);
if (!addr) {
zfcp_fc_sg_free_table(sg, i);
return -ENOMEM;
}
sg_set_buf(sg, addr, PAGE_SIZE);
}
return 0;
}
static struct zfcp_fc_req *zfcp_fc_alloc_sg_env(int buf_num) static struct zfcp_fc_req *zfcp_fc_alloc_sg_env(int buf_num)
{ {
struct zfcp_fc_req *fc_req; struct zfcp_fc_req *fc_req;
@ -605,7 +647,7 @@ static struct zfcp_fc_req *zfcp_fc_alloc_sg_env(int buf_num)
if (!fc_req) if (!fc_req)
return NULL; return NULL;
if (zfcp_sg_setup_table(&fc_req->sg_rsp, buf_num)) { if (zfcp_fc_sg_setup_table(&fc_req->sg_rsp, buf_num)) {
kmem_cache_free(zfcp_fc_req_cache, fc_req); kmem_cache_free(zfcp_fc_req_cache, fc_req);
return NULL; return NULL;
} }
@ -763,7 +805,7 @@ void zfcp_fc_scan_ports(struct work_struct *work)
break; break;
} }
} }
zfcp_sg_free_table(&fc_req->sg_rsp, buf_num); zfcp_fc_sg_free_table(&fc_req->sg_rsp, buf_num);
kmem_cache_free(zfcp_fc_req_cache, fc_req); kmem_cache_free(zfcp_fc_req_cache, fc_req);
out: out:
zfcp_fc_wka_port_put(&adapter->gs->ds); zfcp_fc_wka_port_put(&adapter->gs->ds);

View File

@ -121,9 +121,24 @@ struct zfcp_fc_rspn_req {
/** /**
* struct zfcp_fc_req - Container for FC ELS and CT requests sent from zfcp * struct zfcp_fc_req - Container for FC ELS and CT requests sent from zfcp
* @ct_els: data required for issuing fsf command * @ct_els: data required for issuing fsf command
* @sg_req: scatterlist entry for request data * @sg_req: scatterlist entry for request data, refers to embedded @u submember
* @sg_rsp: scatterlist entry for response data * @sg_rsp: scatterlist entry for response data, refers to embedded @u submember
* @u: request specific data * @u: request and response specific data
* @u.adisc: ADISC specific data
* @u.adisc.req: ADISC request
* @u.adisc.rsp: ADISC response
* @u.gid_pn: GID_PN specific data
* @u.gid_pn.req: GID_PN request
* @u.gid_pn.rsp: GID_PN response
* @u.gpn_ft: GPN_FT specific data
* @u.gpn_ft.sg_rsp2: GPN_FT response, not embedded here, allocated elsewhere
* @u.gpn_ft.req: GPN_FT request
* @u.gspn: GSPN specific data
* @u.gspn.req: GSPN request
* @u.gspn.rsp: GSPN response
* @u.rspn: RSPN specific data
* @u.rspn.req: RSPN request
* @u.rspn.rsp: RSPN response
*/ */
struct zfcp_fc_req { struct zfcp_fc_req {
struct zfcp_fsf_ct_els ct_els; struct zfcp_fsf_ct_els ct_els;

View File

@ -19,6 +19,11 @@
#include "zfcp_qdio.h" #include "zfcp_qdio.h"
#include "zfcp_reqlist.h" #include "zfcp_reqlist.h"
/* timeout for FSF requests sent during scsi_eh: abort or FCP TMF */
#define ZFCP_FSF_SCSI_ER_TIMEOUT (10*HZ)
/* timeout for: exchange config/port data outside ERP, or open/close WKA port */
#define ZFCP_FSF_REQUEST_TIMEOUT (60*HZ)
struct kmem_cache *zfcp_fsf_qtcb_cache; struct kmem_cache *zfcp_fsf_qtcb_cache;
static void zfcp_fsf_request_timeout_handler(struct timer_list *t) static void zfcp_fsf_request_timeout_handler(struct timer_list *t)
@ -74,18 +79,18 @@ static void zfcp_fsf_class_not_supp(struct zfcp_fsf_req *req)
/** /**
* zfcp_fsf_req_free - free memory used by fsf request * zfcp_fsf_req_free - free memory used by fsf request
* @fsf_req: pointer to struct zfcp_fsf_req * @req: pointer to struct zfcp_fsf_req
*/ */
void zfcp_fsf_req_free(struct zfcp_fsf_req *req) void zfcp_fsf_req_free(struct zfcp_fsf_req *req)
{ {
if (likely(req->pool)) { if (likely(req->pool)) {
if (likely(req->qtcb)) if (likely(!zfcp_fsf_req_is_status_read_buffer(req)))
mempool_free(req->qtcb, req->adapter->pool.qtcb_pool); mempool_free(req->qtcb, req->adapter->pool.qtcb_pool);
mempool_free(req, req->pool); mempool_free(req, req->pool);
return; return;
} }
if (likely(req->qtcb)) if (likely(!zfcp_fsf_req_is_status_read_buffer(req)))
kmem_cache_free(zfcp_fsf_qtcb_cache, req->qtcb); kmem_cache_free(zfcp_fsf_qtcb_cache, req->qtcb);
kfree(req); kfree(req);
} }
@ -379,7 +384,7 @@ static void zfcp_fsf_protstatus_eval(struct zfcp_fsf_req *req)
/** /**
* zfcp_fsf_req_complete - process completion of a FSF request * zfcp_fsf_req_complete - process completion of a FSF request
* @fsf_req: The FSF request that has been completed. * @req: The FSF request that has been completed.
* *
* When a request has been completed either from the FCP adapter, * When a request has been completed either from the FCP adapter,
* or it has been dismissed due to a queue shutdown, this function * or it has been dismissed due to a queue shutdown, this function
@ -388,7 +393,7 @@ static void zfcp_fsf_protstatus_eval(struct zfcp_fsf_req *req)
*/ */
static void zfcp_fsf_req_complete(struct zfcp_fsf_req *req) static void zfcp_fsf_req_complete(struct zfcp_fsf_req *req)
{ {
if (unlikely(req->fsf_command == FSF_QTCB_UNSOLICITED_STATUS)) { if (unlikely(zfcp_fsf_req_is_status_read_buffer(req))) {
zfcp_fsf_status_read_handler(req); zfcp_fsf_status_read_handler(req);
return; return;
} }
@ -705,7 +710,6 @@ static struct zfcp_fsf_req *zfcp_fsf_req_create(struct zfcp_qdio *qdio,
init_completion(&req->completion); init_completion(&req->completion);
req->adapter = adapter; req->adapter = adapter;
req->fsf_command = fsf_cmd;
req->req_id = adapter->req_no; req->req_id = adapter->req_no;
if (likely(fsf_cmd != FSF_QTCB_UNSOLICITED_STATUS)) { if (likely(fsf_cmd != FSF_QTCB_UNSOLICITED_STATUS)) {
@ -720,14 +724,13 @@ static struct zfcp_fsf_req *zfcp_fsf_req_create(struct zfcp_qdio *qdio,
return ERR_PTR(-ENOMEM); return ERR_PTR(-ENOMEM);
} }
req->seq_no = adapter->fsf_req_seq_no;
req->qtcb->prefix.req_seq_no = adapter->fsf_req_seq_no; req->qtcb->prefix.req_seq_no = adapter->fsf_req_seq_no;
req->qtcb->prefix.req_id = req->req_id; req->qtcb->prefix.req_id = req->req_id;
req->qtcb->prefix.ulp_info = 26; req->qtcb->prefix.ulp_info = 26;
req->qtcb->prefix.qtcb_type = fsf_qtcb_type[req->fsf_command]; req->qtcb->prefix.qtcb_type = fsf_qtcb_type[fsf_cmd];
req->qtcb->prefix.qtcb_version = FSF_QTCB_CURRENT_VERSION; req->qtcb->prefix.qtcb_version = FSF_QTCB_CURRENT_VERSION;
req->qtcb->header.req_handle = req->req_id; req->qtcb->header.req_handle = req->req_id;
req->qtcb->header.fsf_command = req->fsf_command; req->qtcb->header.fsf_command = fsf_cmd;
} }
zfcp_qdio_req_init(adapter->qdio, &req->qdio_req, req->req_id, sbtype, zfcp_qdio_req_init(adapter->qdio, &req->qdio_req, req->req_id, sbtype,
@ -740,7 +743,6 @@ static int zfcp_fsf_req_send(struct zfcp_fsf_req *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;
int with_qtcb = (req->qtcb != NULL);
int req_id = req->req_id; int req_id = req->req_id;
zfcp_reqlist_add(adapter->req_list, req); zfcp_reqlist_add(adapter->req_list, req);
@ -756,7 +758,7 @@ static int zfcp_fsf_req_send(struct zfcp_fsf_req *req)
} }
/* Don't increase for unsolicited status */ /* Don't increase for unsolicited status */
if (with_qtcb) if (!zfcp_fsf_req_is_status_read_buffer(req))
adapter->fsf_req_seq_no++; adapter->fsf_req_seq_no++;
adapter->req_no++; adapter->req_no++;
@ -765,8 +767,7 @@ static int zfcp_fsf_req_send(struct zfcp_fsf_req *req)
/** /**
* zfcp_fsf_status_read - send status read request * zfcp_fsf_status_read - send status read request
* @adapter: pointer to struct zfcp_adapter * @qdio: pointer to struct zfcp_qdio
* @req_flags: request flags
* Returns: 0 on success, ERROR otherwise * Returns: 0 on success, ERROR otherwise
*/ */
int zfcp_fsf_status_read(struct zfcp_qdio *qdio) int zfcp_fsf_status_read(struct zfcp_qdio *qdio)
@ -912,7 +913,7 @@ struct zfcp_fsf_req *zfcp_fsf_abort_fcp_cmnd(struct scsi_cmnd *scmnd)
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 = (u64) old_req_id;
zfcp_fsf_start_timer(req, ZFCP_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))
goto out; goto out;
@ -1057,8 +1058,10 @@ static int zfcp_fsf_setup_ct_els(struct zfcp_fsf_req *req,
/** /**
* zfcp_fsf_send_ct - initiate a Generic Service request (FC-GS) * zfcp_fsf_send_ct - initiate a Generic Service request (FC-GS)
* @wka_port: pointer to zfcp WKA port to send CT/GS to
* @ct: pointer to struct zfcp_send_ct with data for request * @ct: pointer to struct zfcp_send_ct with data for request
* @pool: if non-null this mempool is used to allocate struct zfcp_fsf_req * @pool: if non-null this mempool is used to allocate struct zfcp_fsf_req
* @timeout: timeout that hardware should use, and a later software timeout
*/ */
int zfcp_fsf_send_ct(struct zfcp_fc_wka_port *wka_port, int zfcp_fsf_send_ct(struct zfcp_fc_wka_port *wka_port,
struct zfcp_fsf_ct_els *ct, mempool_t *pool, struct zfcp_fsf_ct_els *ct, mempool_t *pool,
@ -1151,7 +1154,10 @@ skip_fsfstatus:
/** /**
* zfcp_fsf_send_els - initiate an ELS command (FC-FS) * zfcp_fsf_send_els - initiate an ELS command (FC-FS)
* @adapter: pointer to zfcp adapter
* @d_id: N_Port_ID to send ELS to
* @els: pointer to struct zfcp_send_els with data for the command * @els: pointer to struct zfcp_send_els with data for the command
* @timeout: timeout that hardware should use, and a later software timeout
*/ */
int zfcp_fsf_send_els(struct zfcp_adapter *adapter, u32 d_id, int zfcp_fsf_send_els(struct zfcp_adapter *adapter, u32 d_id,
struct zfcp_fsf_ct_els *els, unsigned int timeout) struct zfcp_fsf_ct_els *els, unsigned int timeout)
@ -1809,7 +1815,7 @@ static void zfcp_fsf_open_lun_handler(struct zfcp_fsf_req *req)
case FSF_LUN_SHARING_VIOLATION: case FSF_LUN_SHARING_VIOLATION:
if (qual->word[0]) if (qual->word[0])
dev_warn(&zfcp_sdev->port->adapter->ccw_device->dev, dev_warn(&zfcp_sdev->port->adapter->ccw_device->dev,
"LUN 0x%Lx on port 0x%Lx is already in " "LUN 0x%016Lx on port 0x%016Lx is already in "
"use by CSS%d, MIF Image ID %x\n", "use by CSS%d, MIF Image ID %x\n",
zfcp_scsi_dev_lun(sdev), zfcp_scsi_dev_lun(sdev),
(unsigned long long)zfcp_sdev->port->wwpn, (unsigned long long)zfcp_sdev->port->wwpn,
@ -1986,7 +1992,7 @@ out:
return retval; return retval;
} }
static void zfcp_fsf_update_lat(struct fsf_latency_record *lat_rec, u32 lat) static void zfcp_fsf_update_lat(struct zfcp_latency_record *lat_rec, u32 lat)
{ {
lat_rec->sum += lat; lat_rec->sum += lat;
lat_rec->min = min(lat_rec->min, lat); lat_rec->min = min(lat_rec->min, lat);
@ -1996,7 +2002,7 @@ static void zfcp_fsf_update_lat(struct fsf_latency_record *lat_rec, u32 lat)
static void zfcp_fsf_req_trace(struct zfcp_fsf_req *req, struct scsi_cmnd *scsi) static void zfcp_fsf_req_trace(struct zfcp_fsf_req *req, struct scsi_cmnd *scsi)
{ {
struct fsf_qual_latency_info *lat_in; struct fsf_qual_latency_info *lat_in;
struct latency_cont *lat = NULL; struct zfcp_latency_cont *lat = NULL;
struct zfcp_scsi_dev *zfcp_sdev; struct zfcp_scsi_dev *zfcp_sdev;
struct zfcp_blk_drv_data blktrc; struct zfcp_blk_drv_data blktrc;
int ticks = req->adapter->timer_ticks; int ticks = req->adapter->timer_ticks;
@ -2088,11 +2094,8 @@ static void zfcp_fsf_fcp_handler_common(struct zfcp_fsf_req *req,
break; break;
case FSF_CMND_LENGTH_NOT_VALID: case FSF_CMND_LENGTH_NOT_VALID:
dev_err(&req->adapter->ccw_device->dev, dev_err(&req->adapter->ccw_device->dev,
"Incorrect CDB length %d, LUN 0x%016Lx on " "Incorrect FCP_CMND length %d, FCP device closed\n",
"port 0x%016Lx closed\n", req->qtcb->bottom.io.fcp_cmnd_length);
req->qtcb->bottom.io.fcp_cmnd_length,
(unsigned long long)zfcp_scsi_dev_lun(sdev),
(unsigned long long)zfcp_sdev->port->wwpn);
zfcp_erp_adapter_shutdown(req->adapter, 0, "fssfch4"); zfcp_erp_adapter_shutdown(req->adapter, 0, "fssfch4");
req->status |= ZFCP_STATUS_FSFREQ_ERROR; req->status |= ZFCP_STATUS_FSFREQ_ERROR;
break; break;
@ -2369,7 +2372,7 @@ struct zfcp_fsf_req *zfcp_fsf_fcp_task_mgmt(struct scsi_device *sdev,
fcp_cmnd = &req->qtcb->bottom.io.fcp_cmnd.iu; fcp_cmnd = &req->qtcb->bottom.io.fcp_cmnd.iu;
zfcp_fc_fcp_tm(fcp_cmnd, sdev, tm_flags); zfcp_fc_fcp_tm(fcp_cmnd, sdev, tm_flags);
zfcp_fsf_start_timer(req, ZFCP_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))
goto out; goto out;
@ -2382,7 +2385,7 @@ out:
/** /**
* zfcp_fsf_reqid_check - validate req_id contained in SBAL returned by QDIO * zfcp_fsf_reqid_check - validate req_id contained in SBAL returned by QDIO
* @adapter: pointer to struct zfcp_adapter * @qdio: pointer to struct zfcp_qdio
* @sbal_idx: response queue index of SBAL to be processed * @sbal_idx: response queue index of SBAL to be processed
*/ */
void zfcp_fsf_reqid_check(struct zfcp_qdio *qdio, int sbal_idx) void zfcp_fsf_reqid_check(struct zfcp_qdio *qdio, int sbal_idx)

View File

@ -438,8 +438,8 @@ struct zfcp_blk_drv_data {
/** /**
* struct zfcp_fsf_ct_els - zfcp data for ct or els request * struct zfcp_fsf_ct_els - zfcp data for ct or els request
* @req: scatter-gather list for request * @req: scatter-gather list for request, points to &zfcp_fc_req.sg_req or BSG
* @resp: scatter-gather list for response * @resp: scatter-gather list for response, points to &zfcp_fc_req.sg_rsp or BSG
* @handler: handler function (called for response to the request) * @handler: handler function (called for response to the request)
* @handler_data: data passed to handler function * @handler_data: data passed to handler function
* @port: Optional pointer to port for zfcp internal ELS (only test link ADISC) * @port: Optional pointer to port for zfcp internal ELS (only test link ADISC)

View File

@ -4,7 +4,7 @@
* *
* Setup and helper functions to access QDIO. * Setup and helper functions to access QDIO.
* *
* Copyright IBM Corp. 2002, 2010 * Copyright IBM Corp. 2002, 2017
*/ */
#define KMSG_COMPONENT "zfcp" #define KMSG_COMPONENT "zfcp"
@ -19,7 +19,7 @@ static bool enable_multibuffer = true;
module_param_named(datarouter, enable_multibuffer, bool, 0400); module_param_named(datarouter, enable_multibuffer, bool, 0400);
MODULE_PARM_DESC(datarouter, "Enable hardware data router support (default on)"); MODULE_PARM_DESC(datarouter, "Enable hardware data router support (default on)");
static void zfcp_qdio_handler_error(struct zfcp_qdio *qdio, char *id, static void zfcp_qdio_handler_error(struct zfcp_qdio *qdio, char *dbftag,
unsigned int qdio_err) unsigned int qdio_err)
{ {
struct zfcp_adapter *adapter = qdio->adapter; struct zfcp_adapter *adapter = qdio->adapter;
@ -28,12 +28,12 @@ static void zfcp_qdio_handler_error(struct zfcp_qdio *qdio, char *id,
if (qdio_err & QDIO_ERROR_SLSB_STATE) { if (qdio_err & QDIO_ERROR_SLSB_STATE) {
zfcp_qdio_siosl(adapter); zfcp_qdio_siosl(adapter);
zfcp_erp_adapter_shutdown(adapter, 0, id); zfcp_erp_adapter_shutdown(adapter, 0, dbftag);
return; return;
} }
zfcp_erp_adapter_reopen(adapter, zfcp_erp_adapter_reopen(adapter,
ZFCP_STATUS_ADAPTER_LINK_UNPLUGGED | ZFCP_STATUS_ADAPTER_LINK_UNPLUGGED |
ZFCP_STATUS_COMMON_ERP_FAILED, id); ZFCP_STATUS_COMMON_ERP_FAILED, dbftag);
} }
static void zfcp_qdio_zero_sbals(struct qdio_buffer *sbal[], int first, int cnt) static void zfcp_qdio_zero_sbals(struct qdio_buffer *sbal[], int first, int cnt)
@ -180,7 +180,6 @@ zfcp_qdio_sbale_next(struct zfcp_qdio *qdio, struct zfcp_qdio_req *q_req)
* @qdio: pointer to struct zfcp_qdio * @qdio: pointer to struct zfcp_qdio
* @q_req: pointer to struct zfcp_qdio_req * @q_req: pointer to struct zfcp_qdio_req
* @sg: scatter-gather list * @sg: scatter-gather list
* @max_sbals: upper bound for number of SBALs to be used
* Returns: zero or -EINVAL on error * Returns: zero or -EINVAL on error
*/ */
int zfcp_qdio_sbals_from_sg(struct zfcp_qdio *qdio, struct zfcp_qdio_req *q_req, int zfcp_qdio_sbals_from_sg(struct zfcp_qdio *qdio, struct zfcp_qdio_req *q_req,
@ -303,7 +302,7 @@ static void zfcp_qdio_setup_init_data(struct qdio_initialize *id,
/** /**
* zfcp_qdio_allocate - allocate queue memory and initialize QDIO data * zfcp_qdio_allocate - allocate queue memory and initialize QDIO data
* @adapter: pointer to struct zfcp_adapter * @qdio: pointer to struct zfcp_qdio
* Returns: -ENOMEM on memory allocation error or return value from * Returns: -ENOMEM on memory allocation error or return value from
* qdio_allocate * qdio_allocate
*/ */

View File

@ -30,6 +30,8 @@
* @req_q_full: queue full incidents * @req_q_full: queue full incidents
* @req_q_wq: used to wait for SBAL availability * @req_q_wq: used to wait for SBAL availability
* @adapter: adapter used in conjunction with this qdio structure * @adapter: adapter used in conjunction with this qdio structure
* @max_sbale_per_sbal: qdio limit per sbal
* @max_sbale_per_req: qdio limit per request
*/ */
struct zfcp_qdio { struct zfcp_qdio {
struct qdio_buffer *res_q[QDIO_MAX_BUFFERS_PER_Q]; struct qdio_buffer *res_q[QDIO_MAX_BUFFERS_PER_Q];
@ -70,7 +72,7 @@ struct zfcp_qdio_req {
/** /**
* zfcp_qdio_sbale_req - return pointer to sbale on req_q for a request * zfcp_qdio_sbale_req - return pointer to sbale on req_q for a request
* @qdio: pointer to struct zfcp_qdio * @qdio: pointer to struct zfcp_qdio
* @q_rec: pointer to struct zfcp_qdio_req * @q_req: pointer to struct zfcp_qdio_req
* Returns: pointer to qdio_buffer_element (sbale) structure * Returns: pointer to qdio_buffer_element (sbale) structure
*/ */
static inline struct qdio_buffer_element * static inline struct qdio_buffer_element *
@ -82,7 +84,7 @@ zfcp_qdio_sbale_req(struct zfcp_qdio *qdio, struct zfcp_qdio_req *q_req)
/** /**
* zfcp_qdio_sbale_curr - return current sbale on req_q for a request * zfcp_qdio_sbale_curr - return current sbale on req_q for a request
* @qdio: pointer to struct zfcp_qdio * @qdio: pointer to struct zfcp_qdio
* @fsf_req: pointer to struct zfcp_fsf_req * @q_req: pointer to struct zfcp_qdio_req
* Returns: pointer to qdio_buffer_element (sbale) structure * Returns: pointer to qdio_buffer_element (sbale) structure
*/ */
static inline struct qdio_buffer_element * static inline struct qdio_buffer_element *
@ -135,6 +137,8 @@ void zfcp_qdio_req_init(struct zfcp_qdio *qdio, struct zfcp_qdio_req *q_req,
* zfcp_qdio_fill_next - Fill next sbale, only for single sbal requests * zfcp_qdio_fill_next - Fill next sbale, only for single sbal requests
* @qdio: pointer to struct zfcp_qdio * @qdio: pointer to struct zfcp_qdio
* @q_req: pointer to struct zfcp_queue_req * @q_req: pointer to struct zfcp_queue_req
* @data: pointer to data
* @len: length of data
* *
* This is only required for single sbal requests, calling it when * This is only required for single sbal requests, calling it when
* wrapping around to the next sbal is a bug. * wrapping around to the next sbal is a bug.
@ -182,6 +186,7 @@ int zfcp_qdio_sg_one_sbale(struct scatterlist *sg)
/** /**
* zfcp_qdio_skip_to_last_sbale - skip to last sbale in sbal * zfcp_qdio_skip_to_last_sbale - skip to last sbale in sbal
* @qdio: pointer to struct zfcp_qdio
* @q_req: The current zfcp_qdio_req * @q_req: The current zfcp_qdio_req
*/ */
static inline static inline

View File

@ -17,7 +17,7 @@
/** /**
* struct zfcp_reqlist - Container for request list (reqlist) * struct zfcp_reqlist - Container for request list (reqlist)
* @lock: Spinlock for protecting the hash list * @lock: Spinlock for protecting the hash list
* @list: Array of hashbuckets, each is a list of requests in this bucket * @buckets: Array of hashbuckets, each is a list of requests in this bucket
*/ */
struct zfcp_reqlist { struct zfcp_reqlist {
spinlock_t lock; spinlock_t lock;

View File

@ -27,7 +27,11 @@ MODULE_PARM_DESC(queue_depth, "Default queue depth for new SCSI devices");
static bool enable_dif; static bool enable_dif;
module_param_named(dif, enable_dif, bool, 0400); module_param_named(dif, enable_dif, bool, 0400);
MODULE_PARM_DESC(dif, "Enable DIF/DIX data integrity support"); MODULE_PARM_DESC(dif, "Enable DIF data integrity support (default off)");
bool zfcp_experimental_dix;
module_param_named(dix, zfcp_experimental_dix, bool, 0400);
MODULE_PARM_DESC(dix, "Enable experimental DIX (data integrity extension) support which implies DIF support (default off)");
static bool allow_lun_scan = true; static bool allow_lun_scan = true;
module_param(allow_lun_scan, bool, 0600); module_param(allow_lun_scan, bool, 0600);
@ -226,7 +230,9 @@ static void zfcp_scsi_forget_cmnd(struct zfcp_fsf_req *old_req, void *data)
(struct zfcp_scsi_req_filter *)data; (struct zfcp_scsi_req_filter *)data;
/* already aborted - prevent side-effects - or not a SCSI command */ /* already aborted - prevent side-effects - or not a SCSI command */
if (old_req->data == NULL || old_req->fsf_command != FSF_QTCB_FCP_CMND) if (old_req->data == NULL ||
zfcp_fsf_req_is_status_read_buffer(old_req) ||
old_req->qtcb->header.fsf_command != FSF_QTCB_FCP_CMND)
return; return;
/* (tmf_scope == FCP_TMF_TGT_RESET || tmf_scope == FCP_TMF_LUN_RESET) */ /* (tmf_scope == FCP_TMF_TGT_RESET || tmf_scope == FCP_TMF_LUN_RESET) */
@ -423,7 +429,6 @@ static struct scsi_host_template zfcp_scsi_host_template = {
* ZFCP_QDIO_MAX_SBALS_PER_REQ) - 2) * 8, * ZFCP_QDIO_MAX_SBALS_PER_REQ) - 2) * 8,
/* GCD, adjusted later */ /* GCD, adjusted later */
.dma_boundary = ZFCP_QDIO_SBALE_LEN - 1, .dma_boundary = ZFCP_QDIO_SBALE_LEN - 1,
.use_clustering = 1,
.shost_attrs = zfcp_sysfs_shost_attrs, .shost_attrs = zfcp_sysfs_shost_attrs,
.sdev_attrs = zfcp_sysfs_sdev_attrs, .sdev_attrs = zfcp_sysfs_sdev_attrs,
.track_queue_depth = 1, .track_queue_depth = 1,
@ -788,11 +793,11 @@ void zfcp_scsi_set_prot(struct zfcp_adapter *adapter)
data_div = atomic_read(&adapter->status) & data_div = atomic_read(&adapter->status) &
ZFCP_STATUS_ADAPTER_DATA_DIV_ENABLED; ZFCP_STATUS_ADAPTER_DATA_DIV_ENABLED;
if (enable_dif && if ((enable_dif || zfcp_experimental_dix) &&
adapter->adapter_features & FSF_FEATURE_DIF_PROT_TYPE1) adapter->adapter_features & FSF_FEATURE_DIF_PROT_TYPE1)
mask |= SHOST_DIF_TYPE1_PROTECTION; mask |= SHOST_DIF_TYPE1_PROTECTION;
if (enable_dif && data_div && if (zfcp_experimental_dix && data_div &&
adapter->adapter_features & FSF_FEATURE_DIX_PROT_TCPIP) { adapter->adapter_features & FSF_FEATURE_DIX_PROT_TCPIP) {
mask |= SHOST_DIX_TYPE1_PROTECTION; mask |= SHOST_DIX_TYPE1_PROTECTION;
scsi_host_set_guard(shost, SHOST_DIX_GUARD_IP); scsi_host_set_guard(shost, SHOST_DIX_GUARD_IP);

View File

@ -1998,7 +1998,6 @@ static struct scsi_host_template driver_template = {
.sg_tablesize = TW_APACHE_MAX_SGL_LENGTH, .sg_tablesize = TW_APACHE_MAX_SGL_LENGTH,
.max_sectors = TW_MAX_SECTORS, .max_sectors = TW_MAX_SECTORS,
.cmd_per_lun = TW_MAX_CMDS_PER_LUN, .cmd_per_lun = TW_MAX_CMDS_PER_LUN,
.use_clustering = ENABLE_CLUSTERING,
.shost_attrs = twa_host_attrs, .shost_attrs = twa_host_attrs,
.emulated = 1, .emulated = 1,
.no_write_same = 1, .no_write_same = 1,

View File

@ -1550,7 +1550,6 @@ static struct scsi_host_template driver_template = {
.sg_tablesize = TW_LIBERATOR_MAX_SGL_LENGTH, .sg_tablesize = TW_LIBERATOR_MAX_SGL_LENGTH,
.max_sectors = TW_MAX_SECTORS, .max_sectors = TW_MAX_SECTORS,
.cmd_per_lun = TW_MAX_CMDS_PER_LUN, .cmd_per_lun = TW_MAX_CMDS_PER_LUN,
.use_clustering = ENABLE_CLUSTERING,
.shost_attrs = twl_host_attrs, .shost_attrs = twl_host_attrs,
.emulated = 1, .emulated = 1,
.no_write_same = 1, .no_write_same = 1,

View File

@ -1174,7 +1174,7 @@ static int tw_setfeature(TW_Device_Extension *tw_dev, int parm, int param_size,
command_que_value = tw_dev->command_packet_physical_address[request_id]; command_que_value = tw_dev->command_packet_physical_address[request_id];
if (command_que_value == 0) { if (command_que_value == 0) {
printk(KERN_WARNING "3w-xxxx: tw_setfeature(): Bad command packet physical address.\n"); printk(KERN_WARNING "3w-xxxx: tw_setfeature(): Bad command packet physical address.\n");
return 1; return 1;
} }
/* Send command packet to the board */ /* Send command packet to the board */
@ -2247,7 +2247,6 @@ static struct scsi_host_template driver_template = {
.sg_tablesize = TW_MAX_SGL_LENGTH, .sg_tablesize = TW_MAX_SGL_LENGTH,
.max_sectors = TW_MAX_SECTORS, .max_sectors = TW_MAX_SECTORS,
.cmd_per_lun = TW_MAX_CMDS_PER_LUN, .cmd_per_lun = TW_MAX_CMDS_PER_LUN,
.use_clustering = ENABLE_CLUSTERING,
.shost_attrs = tw_host_attrs, .shost_attrs = tw_host_attrs,
.emulated = 1, .emulated = 1,
.no_write_same = 1, .no_write_same = 1,

View File

@ -318,7 +318,6 @@ NCR_700_detect(struct scsi_host_template *tpnt,
tpnt->can_queue = NCR_700_COMMAND_SLOTS_PER_HOST; tpnt->can_queue = NCR_700_COMMAND_SLOTS_PER_HOST;
tpnt->sg_tablesize = NCR_700_SG_SEGMENTS; tpnt->sg_tablesize = NCR_700_SG_SEGMENTS;
tpnt->cmd_per_lun = NCR_700_CMD_PER_LUN; tpnt->cmd_per_lun = NCR_700_CMD_PER_LUN;
tpnt->use_clustering = ENABLE_CLUSTERING;
tpnt->slave_configure = NCR_700_slave_configure; tpnt->slave_configure = NCR_700_slave_configure;
tpnt->slave_destroy = NCR_700_slave_destroy; tpnt->slave_destroy = NCR_700_slave_destroy;
tpnt->slave_alloc = NCR_700_slave_alloc; tpnt->slave_alloc = NCR_700_slave_alloc;

View File

@ -2641,6 +2641,7 @@ static int blogic_resultcode(struct blogic_adapter *adapter,
case BLOGIC_BAD_CMD_PARAM: case BLOGIC_BAD_CMD_PARAM:
blogic_warn("BusLogic Driver Protocol Error 0x%02X\n", blogic_warn("BusLogic Driver Protocol Error 0x%02X\n",
adapter, adapter_status); adapter, adapter_status);
/* fall through */
case BLOGIC_DATA_UNDERRUN: case BLOGIC_DATA_UNDERRUN:
case BLOGIC_DATA_OVERRUN: case BLOGIC_DATA_OVERRUN:
case BLOGIC_NOEXPECT_BUSFREE: case BLOGIC_NOEXPECT_BUSFREE:
@ -3857,7 +3858,6 @@ static struct scsi_host_template blogic_template = {
#endif #endif
.unchecked_isa_dma = 1, .unchecked_isa_dma = 1,
.max_sectors = 128, .max_sectors = 128,
.use_clustering = ENABLE_CLUSTERING,
}; };
/* /*

View File

@ -1078,7 +1078,6 @@ static struct scsi_host_template inia100_template = {
.can_queue = 1, .can_queue = 1,
.this_id = 1, .this_id = 1,
.sg_tablesize = SG_ALL, .sg_tablesize = SG_ALL,
.use_clustering = ENABLE_CLUSTERING,
}; };
static int inia100_probe_one(struct pci_dev *pdev, static int inia100_probe_one(struct pci_dev *pdev,

View File

@ -160,7 +160,7 @@ static struct scsi_host_template a2091_scsi_template = {
.this_id = 7, .this_id = 7,
.sg_tablesize = SG_ALL, .sg_tablesize = SG_ALL,
.cmd_per_lun = CMD_PER_LUN, .cmd_per_lun = CMD_PER_LUN,
.use_clustering = DISABLE_CLUSTERING .dma_boundary = PAGE_SIZE - 1,
}; };
static int a2091_probe(struct zorro_dev *z, const struct zorro_device_id *ent) static int a2091_probe(struct zorro_dev *z, const struct zorro_device_id *ent)

View File

@ -175,7 +175,6 @@ static struct scsi_host_template amiga_a3000_scsi_template = {
.this_id = 7, .this_id = 7,
.sg_tablesize = SG_ALL, .sg_tablesize = SG_ALL,
.cmd_per_lun = CMD_PER_LUN, .cmd_per_lun = CMD_PER_LUN,
.use_clustering = ENABLE_CLUSTERING
}; };
static int __init amiga_a3000_scsi_probe(struct platform_device *pdev) static int __init amiga_a3000_scsi_probe(struct platform_device *pdev)

View File

@ -2892,6 +2892,7 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd)
!(dev->raw_io_64) || !(dev->raw_io_64) ||
((scsicmd->cmnd[1] & 0x1f) != SAI_READ_CAPACITY_16)) ((scsicmd->cmnd[1] & 0x1f) != SAI_READ_CAPACITY_16))
break; break;
/* fall through */
case INQUIRY: case INQUIRY:
case READ_CAPACITY: case READ_CAPACITY:
case TEST_UNIT_READY: case TEST_UNIT_READY:
@ -2966,6 +2967,7 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd)
/* Issue FIB to tell Firmware to flush it's cache */ /* Issue FIB to tell Firmware to flush it's cache */
if ((aac_cache & 6) != 2) if ((aac_cache & 6) != 2)
return aac_synchronize(scsicmd); return aac_synchronize(scsicmd);
/* fall through */
case INQUIRY: case INQUIRY:
{ {
struct inquiry_data inq_data; struct inquiry_data inq_data;
@ -3319,8 +3321,9 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd)
min_t(size_t, min_t(size_t,
sizeof(dev->fsa_dev[cid].sense_data), sizeof(dev->fsa_dev[cid].sense_data),
SCSI_SENSE_BUFFERSIZE)); SCSI_SENSE_BUFFERSIZE));
break; break;
} }
/* fall through */
case RESERVE: case RESERVE:
case RELEASE: case RELEASE:
case REZERO_UNIT: case REZERO_UNIT:

View File

@ -40,6 +40,7 @@
#define nblank(x) _nblank(x)[0] #define nblank(x) _nblank(x)[0]
#include <linux/interrupt.h> #include <linux/interrupt.h>
#include <linux/completion.h>
#include <linux/pci.h> #include <linux/pci.h>
#include <scsi/scsi_host.h> #include <scsi/scsi_host.h>
@ -1241,7 +1242,7 @@ struct aac_fib_context {
u32 unique; // unique value representing this context u32 unique; // unique value representing this context
ulong jiffies; // used for cleanup - dmb changed to ulong ulong jiffies; // used for cleanup - dmb changed to ulong
struct list_head next; // used to link context's into a linked list struct list_head next; // used to link context's into a linked list
struct semaphore wait_sem; // this is used to wait for the next fib to arrive. struct completion completion; // this is used to wait for the next fib to arrive.
int wait; // Set to true when thread is in WaitForSingleObject int wait; // Set to true when thread is in WaitForSingleObject
unsigned long count; // total number of FIBs on FibList unsigned long count; // total number of FIBs on FibList
struct list_head fib_list; // this holds fibs and their attachd hw_fibs struct list_head fib_list; // this holds fibs and their attachd hw_fibs
@ -1313,7 +1314,7 @@ struct fib {
* This is the event the sendfib routine will wait on if the * This is the event the sendfib routine will wait on if the
* caller did not pass one and this is synch io. * caller did not pass one and this is synch io.
*/ */
struct semaphore event_wait; struct completion event_wait;
spinlock_t event_lock; spinlock_t event_lock;
u32 done; /* gets set to 1 when fib is complete */ u32 done; /* gets set to 1 when fib is complete */

View File

@ -41,7 +41,6 @@
#include <linux/blkdev.h> #include <linux/blkdev.h>
#include <linux/delay.h> /* ssleep prototype */ #include <linux/delay.h> /* ssleep prototype */
#include <linux/kthread.h> #include <linux/kthread.h>
#include <linux/semaphore.h>
#include <linux/uaccess.h> #include <linux/uaccess.h>
#include <scsi/scsi_host.h> #include <scsi/scsi_host.h>
@ -203,7 +202,7 @@ static int open_getadapter_fib(struct aac_dev * dev, void __user *arg)
/* /*
* Initialize the mutex used to wait for the next AIF. * Initialize the mutex used to wait for the next AIF.
*/ */
sema_init(&fibctx->wait_sem, 0); init_completion(&fibctx->completion);
fibctx->wait = 0; fibctx->wait = 0;
/* /*
* Initialize the fibs and set the count of fibs on * Initialize the fibs and set the count of fibs on
@ -335,7 +334,7 @@ return_fib:
ssleep(1); ssleep(1);
} }
if (f.wait) { if (f.wait) {
if(down_interruptible(&fibctx->wait_sem) < 0) { if (wait_for_completion_interruptible(&fibctx->completion) < 0) {
status = -ERESTARTSYS; status = -ERESTARTSYS;
} else { } else {
/* Lock again and retry */ /* Lock again and retry */

View File

@ -44,7 +44,6 @@
#include <linux/delay.h> #include <linux/delay.h>
#include <linux/kthread.h> #include <linux/kthread.h>
#include <linux/interrupt.h> #include <linux/interrupt.h>
#include <linux/semaphore.h>
#include <linux/bcd.h> #include <linux/bcd.h>
#include <scsi/scsi.h> #include <scsi/scsi.h>
#include <scsi/scsi_host.h> #include <scsi/scsi_host.h>
@ -189,7 +188,7 @@ int aac_fib_setup(struct aac_dev * dev)
fibptr->hw_fib_va = hw_fib; fibptr->hw_fib_va = hw_fib;
fibptr->data = (void *) fibptr->hw_fib_va->data; fibptr->data = (void *) fibptr->hw_fib_va->data;
fibptr->next = fibptr+1; /* Forward chain the fibs */ fibptr->next = fibptr+1; /* Forward chain the fibs */
sema_init(&fibptr->event_wait, 0); init_completion(&fibptr->event_wait);
spin_lock_init(&fibptr->event_lock); spin_lock_init(&fibptr->event_lock);
hw_fib->header.XferState = cpu_to_le32(0xffffffff); hw_fib->header.XferState = cpu_to_le32(0xffffffff);
hw_fib->header.SenderSize = hw_fib->header.SenderSize =
@ -623,7 +622,7 @@ int aac_fib_send(u16 command, struct fib *fibptr, unsigned long size,
} }
if (wait) { if (wait) {
fibptr->flags |= FIB_CONTEXT_FLAG_WAIT; fibptr->flags |= FIB_CONTEXT_FLAG_WAIT;
if (down_interruptible(&fibptr->event_wait)) { if (wait_for_completion_interruptible(&fibptr->event_wait)) {
fibptr->flags &= ~FIB_CONTEXT_FLAG_WAIT; fibptr->flags &= ~FIB_CONTEXT_FLAG_WAIT;
return -EFAULT; return -EFAULT;
} }
@ -659,7 +658,7 @@ int aac_fib_send(u16 command, struct fib *fibptr, unsigned long size,
* hardware failure has occurred. * hardware failure has occurred.
*/ */
unsigned long timeout = jiffies + (180 * HZ); /* 3 minutes */ unsigned long timeout = jiffies + (180 * HZ); /* 3 minutes */
while (down_trylock(&fibptr->event_wait)) { while (!try_wait_for_completion(&fibptr->event_wait)) {
int blink; int blink;
if (time_is_before_eq_jiffies(timeout)) { if (time_is_before_eq_jiffies(timeout)) {
struct aac_queue * q = &dev->queues->queue[AdapNormCmdQueue]; struct aac_queue * q = &dev->queues->queue[AdapNormCmdQueue];
@ -689,9 +688,9 @@ int aac_fib_send(u16 command, struct fib *fibptr, unsigned long size,
*/ */
schedule(); schedule();
} }
} else if (down_interruptible(&fibptr->event_wait)) { } else if (wait_for_completion_interruptible(&fibptr->event_wait)) {
/* Do nothing ... satisfy /* Do nothing ... satisfy
* down_interruptible must_check */ * wait_for_completion_interruptible must_check */
} }
spin_lock_irqsave(&fibptr->event_lock, flags); spin_lock_irqsave(&fibptr->event_lock, flags);
@ -777,7 +776,7 @@ int aac_hba_send(u8 command, struct fib *fibptr, fib_callback callback,
return -EFAULT; return -EFAULT;
fibptr->flags |= FIB_CONTEXT_FLAG_WAIT; fibptr->flags |= FIB_CONTEXT_FLAG_WAIT;
if (down_interruptible(&fibptr->event_wait)) if (wait_for_completion_interruptible(&fibptr->event_wait))
fibptr->done = 2; fibptr->done = 2;
fibptr->flags &= ~(FIB_CONTEXT_FLAG_WAIT); fibptr->flags &= ~(FIB_CONTEXT_FLAG_WAIT);
@ -1538,7 +1537,7 @@ static int _aac_reset_adapter(struct aac_dev *aac, int forced, u8 reset_type)
|| fib->flags & FIB_CONTEXT_FLAG_WAIT) { || fib->flags & FIB_CONTEXT_FLAG_WAIT) {
unsigned long flagv; unsigned long flagv;
spin_lock_irqsave(&fib->event_lock, flagv); spin_lock_irqsave(&fib->event_lock, flagv);
up(&fib->event_wait); complete(&fib->event_wait);
spin_unlock_irqrestore(&fib->event_lock, flagv); spin_unlock_irqrestore(&fib->event_lock, flagv);
schedule(); schedule();
retval = 0; retval = 0;
@ -1828,7 +1827,7 @@ int aac_check_health(struct aac_dev * aac)
* Set the event to wake up the * Set the event to wake up the
* thread that will waiting. * thread that will waiting.
*/ */
up(&fibctx->wait_sem); complete(&fibctx->completion);
} else { } else {
printk(KERN_WARNING "aifd: didn't allocate NewFib.\n"); printk(KERN_WARNING "aifd: didn't allocate NewFib.\n");
kfree(fib); kfree(fib);
@ -2165,7 +2164,7 @@ static void wakeup_fibctx_threads(struct aac_dev *dev,
* Set the event to wake up the * Set the event to wake up the
* thread that is waiting. * thread that is waiting.
*/ */
up(&fibctx->wait_sem); complete(&fibctx->completion);
entry = entry->next; entry = entry->next;
} }

View File

@ -38,7 +38,6 @@
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/completion.h> #include <linux/completion.h>
#include <linux/blkdev.h> #include <linux/blkdev.h>
#include <linux/semaphore.h>
#include "aacraid.h" #include "aacraid.h"
@ -129,7 +128,7 @@ unsigned int aac_response_normal(struct aac_queue * q)
spin_lock_irqsave(&fib->event_lock, flagv); spin_lock_irqsave(&fib->event_lock, flagv);
if (!fib->done) { if (!fib->done) {
fib->done = 1; fib->done = 1;
up(&fib->event_wait); complete(&fib->event_wait);
} }
spin_unlock_irqrestore(&fib->event_lock, flagv); spin_unlock_irqrestore(&fib->event_lock, flagv);
@ -376,16 +375,16 @@ unsigned int aac_intr_normal(struct aac_dev *dev, u32 index, int isAif,
start_callback = 1; start_callback = 1;
} else { } else {
unsigned long flagv; unsigned long flagv;
int complete = 0; int completed = 0;
dprintk((KERN_INFO "event_wait up\n")); dprintk((KERN_INFO "event_wait up\n"));
spin_lock_irqsave(&fib->event_lock, flagv); spin_lock_irqsave(&fib->event_lock, flagv);
if (fib->done == 2) { if (fib->done == 2) {
fib->done = 1; fib->done = 1;
complete = 1; completed = 1;
} else { } else {
fib->done = 1; fib->done = 1;
up(&fib->event_wait); complete(&fib->event_wait);
} }
spin_unlock_irqrestore(&fib->event_lock, flagv); spin_unlock_irqrestore(&fib->event_lock, flagv);
@ -395,7 +394,7 @@ unsigned int aac_intr_normal(struct aac_dev *dev, u32 index, int isAif,
mflags); mflags);
FIB_COUNTER_INCREMENT(aac_config.NativeRecved); FIB_COUNTER_INCREMENT(aac_config.NativeRecved);
if (complete) if (completed)
aac_fib_complete(fib); aac_fib_complete(fib);
} }
} else { } else {
@ -428,16 +427,16 @@ unsigned int aac_intr_normal(struct aac_dev *dev, u32 index, int isAif,
start_callback = 1; start_callback = 1;
} else { } else {
unsigned long flagv; unsigned long flagv;
int complete = 0; int completed = 0;
dprintk((KERN_INFO "event_wait up\n")); dprintk((KERN_INFO "event_wait up\n"));
spin_lock_irqsave(&fib->event_lock, flagv); spin_lock_irqsave(&fib->event_lock, flagv);
if (fib->done == 2) { if (fib->done == 2) {
fib->done = 1; fib->done = 1;
complete = 1; completed = 1;
} else { } else {
fib->done = 1; fib->done = 1;
up(&fib->event_wait); complete(&fib->event_wait);
} }
spin_unlock_irqrestore(&fib->event_lock, flagv); spin_unlock_irqrestore(&fib->event_lock, flagv);
@ -447,7 +446,7 @@ unsigned int aac_intr_normal(struct aac_dev *dev, u32 index, int isAif,
mflags); mflags);
FIB_COUNTER_INCREMENT(aac_config.NormalRecved); FIB_COUNTER_INCREMENT(aac_config.NormalRecved);
if (complete) if (completed)
aac_fib_complete(fib); aac_fib_complete(fib);
} }
} }

View File

@ -759,6 +759,7 @@ static int aac_eh_abort(struct scsi_cmnd* cmd)
!(aac->raw_io_64) || !(aac->raw_io_64) ||
((cmd->cmnd[1] & 0x1f) != SAI_READ_CAPACITY_16)) ((cmd->cmnd[1] & 0x1f) != SAI_READ_CAPACITY_16))
break; break;
/* fall through */
case INQUIRY: case INQUIRY:
case READ_CAPACITY: case READ_CAPACITY:
/* /*
@ -1539,7 +1540,6 @@ static struct scsi_host_template aac_driver_template = {
#else #else
.cmd_per_lun = AAC_NUM_IO_FIB, .cmd_per_lun = AAC_NUM_IO_FIB,
#endif #endif
.use_clustering = ENABLE_CLUSTERING,
.emulated = 1, .emulated = 1,
.no_write_same = 1, .no_write_same = 1,
}; };
@ -1559,7 +1559,7 @@ static void __aac_shutdown(struct aac_dev * aac)
struct fib *fib = &aac->fibs[i]; struct fib *fib = &aac->fibs[i];
if (!(fib->hw_fib_va->header.XferState & cpu_to_le32(NoResponseExpected | Async)) && if (!(fib->hw_fib_va->header.XferState & cpu_to_le32(NoResponseExpected | Async)) &&
(fib->hw_fib_va->header.XferState & cpu_to_le32(ResponseExpected))) (fib->hw_fib_va->header.XferState & cpu_to_le32(ResponseExpected)))
up(&fib->event_wait); complete(&fib->event_wait);
} }
kthread_stop(aac->thread); kthread_stop(aac->thread);
aac->thread = NULL; aac->thread = NULL;

View File

@ -106,7 +106,7 @@ static irqreturn_t aac_src_intr_message(int irq, void *dev_id)
spin_lock_irqsave(&dev->sync_fib->event_lock, sflags); spin_lock_irqsave(&dev->sync_fib->event_lock, sflags);
if (dev->sync_fib->flags & FIB_CONTEXT_FLAG_WAIT) { if (dev->sync_fib->flags & FIB_CONTEXT_FLAG_WAIT) {
dev->management_fib_count--; dev->management_fib_count--;
up(&dev->sync_fib->event_wait); complete(&dev->sync_fib->event_wait);
} }
spin_unlock_irqrestore(&dev->sync_fib->event_lock, spin_unlock_irqrestore(&dev->sync_fib->event_lock,
sflags); sflags);

View File

@ -3192,8 +3192,8 @@ static void asc_prt_driver_conf(struct seq_file *m, struct Scsi_Host *shost)
shost->sg_tablesize, shost->cmd_per_lun); shost->sg_tablesize, shost->cmd_per_lun);
seq_printf(m, seq_printf(m,
" unchecked_isa_dma %d, use_clustering %d\n", " unchecked_isa_dma %d\n",
shost->unchecked_isa_dma, shost->use_clustering); shost->unchecked_isa_dma);
seq_printf(m, seq_printf(m,
" flags 0x%x, last_reset 0x%lx, jiffies 0x%lx, asc_n_io_port 0x%x\n", " flags 0x%x, last_reset 0x%lx, jiffies 0x%lx, asc_n_io_port 0x%x\n",
@ -10808,14 +10808,6 @@ static struct scsi_host_template advansys_template = {
* for non-ISA adapters. * for non-ISA adapters.
*/ */
.unchecked_isa_dma = true, .unchecked_isa_dma = true,
/*
* All adapters controlled by this driver are capable of large
* scatter-gather lists. According to the mid-level SCSI documentation
* this obviates any performance gain provided by setting
* 'use_clustering'. But empirically while CPU utilization is increased
* by enabling clustering, I/O throughput increases as well.
*/
.use_clustering = ENABLE_CLUSTERING,
}; };
static int advansys_wide_init_chip(struct Scsi_Host *shost) static int advansys_wide_init_chip(struct Scsi_Host *shost)

View File

@ -2920,7 +2920,7 @@ static struct scsi_host_template aha152x_driver_template = {
.can_queue = 1, .can_queue = 1,
.this_id = 7, .this_id = 7,
.sg_tablesize = SG_ALL, .sg_tablesize = SG_ALL,
.use_clustering = DISABLE_CLUSTERING, .dma_boundary = PAGE_SIZE - 1,
.slave_alloc = aha152x_adjust_queue, .slave_alloc = aha152x_adjust_queue,
}; };

View File

@ -58,8 +58,15 @@ struct aha1542_hostdata {
int aha1542_last_mbi_used; int aha1542_last_mbi_used;
int aha1542_last_mbo_used; int aha1542_last_mbo_used;
struct scsi_cmnd *int_cmds[AHA1542_MAILBOXES]; struct scsi_cmnd *int_cmds[AHA1542_MAILBOXES];
struct mailbox mb[2 * AHA1542_MAILBOXES]; struct mailbox *mb;
struct ccb ccb[AHA1542_MAILBOXES]; dma_addr_t mb_handle;
struct ccb *ccb;
dma_addr_t ccb_handle;
};
struct aha1542_cmd {
struct chain *chain;
dma_addr_t chain_handle;
}; };
static inline void aha1542_intr_reset(u16 base) static inline void aha1542_intr_reset(u16 base)
@ -233,6 +240,21 @@ static int aha1542_test_port(struct Scsi_Host *sh)
return 1; return 1;
} }
static void aha1542_free_cmd(struct scsi_cmnd *cmd)
{
struct aha1542_cmd *acmd = scsi_cmd_priv(cmd);
struct device *dev = cmd->device->host->dma_dev;
size_t len = scsi_sg_count(cmd) * sizeof(struct chain);
if (acmd->chain) {
dma_unmap_single(dev, acmd->chain_handle, len, DMA_TO_DEVICE);
kfree(acmd->chain);
}
acmd->chain = NULL;
scsi_dma_unmap(cmd);
}
static irqreturn_t aha1542_interrupt(int irq, void *dev_id) static irqreturn_t aha1542_interrupt(int irq, void *dev_id)
{ {
struct Scsi_Host *sh = dev_id; struct Scsi_Host *sh = dev_id;
@ -303,7 +325,7 @@ static irqreturn_t aha1542_interrupt(int irq, void *dev_id)
return IRQ_HANDLED; return IRQ_HANDLED;
}; };
mbo = (scsi2int(mb[mbi].ccbptr) - (isa_virt_to_bus(&ccb[0]))) / sizeof(struct ccb); mbo = (scsi2int(mb[mbi].ccbptr) - (unsigned long)aha1542->ccb_handle) / sizeof(struct ccb);
mbistatus = mb[mbi].status; mbistatus = mb[mbi].status;
mb[mbi].status = 0; mb[mbi].status = 0;
aha1542->aha1542_last_mbi_used = mbi; aha1542->aha1542_last_mbi_used = mbi;
@ -331,8 +353,7 @@ static irqreturn_t aha1542_interrupt(int irq, void *dev_id)
return IRQ_HANDLED; return IRQ_HANDLED;
} }
my_done = tmp_cmd->scsi_done; my_done = tmp_cmd->scsi_done;
kfree(tmp_cmd->host_scribble); aha1542_free_cmd(tmp_cmd);
tmp_cmd->host_scribble = NULL;
/* Fetch the sense data, and tuck it away, in the required slot. The /* Fetch the sense data, and tuck it away, in the required slot. The
Adaptec automatically fetches it, and there is no guarantee that Adaptec automatically fetches it, and there is no guarantee that
we will still have it in the cdb when we come back */ we will still have it in the cdb when we come back */
@ -369,6 +390,7 @@ static irqreturn_t aha1542_interrupt(int irq, void *dev_id)
static int aha1542_queuecommand(struct Scsi_Host *sh, struct scsi_cmnd *cmd) static int aha1542_queuecommand(struct Scsi_Host *sh, struct scsi_cmnd *cmd)
{ {
struct aha1542_cmd *acmd = scsi_cmd_priv(cmd);
struct aha1542_hostdata *aha1542 = shost_priv(sh); struct aha1542_hostdata *aha1542 = shost_priv(sh);
u8 direction; u8 direction;
u8 target = cmd->device->id; u8 target = cmd->device->id;
@ -378,7 +400,6 @@ static int aha1542_queuecommand(struct Scsi_Host *sh, struct scsi_cmnd *cmd)
int mbo, sg_count; int mbo, sg_count;
struct mailbox *mb = aha1542->mb; struct mailbox *mb = aha1542->mb;
struct ccb *ccb = aha1542->ccb; struct ccb *ccb = aha1542->ccb;
struct chain *cptr;
if (*cmd->cmnd == REQUEST_SENSE) { if (*cmd->cmnd == REQUEST_SENSE) {
/* Don't do the command - we have the sense data already */ /* Don't do the command - we have the sense data already */
@ -398,15 +419,17 @@ static int aha1542_queuecommand(struct Scsi_Host *sh, struct scsi_cmnd *cmd)
print_hex_dump_bytes("command: ", DUMP_PREFIX_NONE, cmd->cmnd, cmd->cmd_len); print_hex_dump_bytes("command: ", DUMP_PREFIX_NONE, cmd->cmnd, cmd->cmd_len);
} }
#endif #endif
if (bufflen) { /* allocate memory before taking host_lock */ sg_count = scsi_dma_map(cmd);
sg_count = scsi_sg_count(cmd); if (sg_count) {
cptr = kmalloc_array(sg_count, sizeof(*cptr), size_t len = sg_count * sizeof(struct chain);
GFP_KERNEL | GFP_DMA);
if (!cptr) acmd->chain = kmalloc(len, GFP_DMA);
return SCSI_MLQUEUE_HOST_BUSY; if (!acmd->chain)
} else { goto out_unmap;
sg_count = 0; acmd->chain_handle = dma_map_single(sh->dma_dev, acmd->chain,
cptr = NULL; len, DMA_TO_DEVICE);
if (dma_mapping_error(sh->dma_dev, acmd->chain_handle))
goto out_free_chain;
} }
/* Use the outgoing mailboxes in a round-robin fashion, because this /* Use the outgoing mailboxes in a round-robin fashion, because this
@ -437,7 +460,8 @@ static int aha1542_queuecommand(struct Scsi_Host *sh, struct scsi_cmnd *cmd)
shost_printk(KERN_DEBUG, sh, "Sending command (%d %p)...", mbo, cmd->scsi_done); shost_printk(KERN_DEBUG, sh, "Sending command (%d %p)...", mbo, cmd->scsi_done);
#endif #endif
any2scsi(mb[mbo].ccbptr, isa_virt_to_bus(&ccb[mbo])); /* This gets trashed for some reason */ /* This gets trashed for some reason */
any2scsi(mb[mbo].ccbptr, aha1542->ccb_handle + mbo * sizeof(*ccb));
memset(&ccb[mbo], 0, sizeof(struct ccb)); memset(&ccb[mbo], 0, sizeof(struct ccb));
@ -456,21 +480,18 @@ static int aha1542_queuecommand(struct Scsi_Host *sh, struct scsi_cmnd *cmd)
int i; int i;
ccb[mbo].op = 2; /* SCSI Initiator Command w/scatter-gather */ ccb[mbo].op = 2; /* SCSI Initiator Command w/scatter-gather */
cmd->host_scribble = (void *)cptr;
scsi_for_each_sg(cmd, sg, sg_count, i) { scsi_for_each_sg(cmd, sg, sg_count, i) {
any2scsi(cptr[i].dataptr, isa_page_to_bus(sg_page(sg)) any2scsi(acmd->chain[i].dataptr, sg_dma_address(sg));
+ sg->offset); any2scsi(acmd->chain[i].datalen, sg_dma_len(sg));
any2scsi(cptr[i].datalen, sg->length);
}; };
any2scsi(ccb[mbo].datalen, sg_count * sizeof(struct chain)); any2scsi(ccb[mbo].datalen, sg_count * sizeof(struct chain));
any2scsi(ccb[mbo].dataptr, isa_virt_to_bus(cptr)); any2scsi(ccb[mbo].dataptr, acmd->chain_handle);
#ifdef DEBUG #ifdef DEBUG
shost_printk(KERN_DEBUG, sh, "cptr %p: ", cptr); shost_printk(KERN_DEBUG, sh, "cptr %p: ", acmd->chain);
print_hex_dump_bytes("cptr: ", DUMP_PREFIX_NONE, cptr, 18); print_hex_dump_bytes("cptr: ", DUMP_PREFIX_NONE, acmd->chain, 18);
#endif #endif
} else { } else {
ccb[mbo].op = 0; /* SCSI Initiator Command */ ccb[mbo].op = 0; /* SCSI Initiator Command */
cmd->host_scribble = NULL;
any2scsi(ccb[mbo].datalen, 0); any2scsi(ccb[mbo].datalen, 0);
any2scsi(ccb[mbo].dataptr, 0); any2scsi(ccb[mbo].dataptr, 0);
}; };
@ -488,24 +509,29 @@ static int aha1542_queuecommand(struct Scsi_Host *sh, struct scsi_cmnd *cmd)
spin_unlock_irqrestore(sh->host_lock, flags); spin_unlock_irqrestore(sh->host_lock, flags);
return 0; return 0;
out_free_chain:
kfree(acmd->chain);
acmd->chain = NULL;
out_unmap:
scsi_dma_unmap(cmd);
return SCSI_MLQUEUE_HOST_BUSY;
} }
/* Initialize mailboxes */ /* Initialize mailboxes */
static void setup_mailboxes(struct Scsi_Host *sh) static void setup_mailboxes(struct Scsi_Host *sh)
{ {
struct aha1542_hostdata *aha1542 = shost_priv(sh); struct aha1542_hostdata *aha1542 = shost_priv(sh);
int i;
struct mailbox *mb = aha1542->mb;
struct ccb *ccb = aha1542->ccb;
u8 mb_cmd[5] = { CMD_MBINIT, AHA1542_MAILBOXES, 0, 0, 0}; u8 mb_cmd[5] = { CMD_MBINIT, AHA1542_MAILBOXES, 0, 0, 0};
int i;
for (i = 0; i < AHA1542_MAILBOXES; i++) { for (i = 0; i < AHA1542_MAILBOXES; i++) {
mb[i].status = mb[AHA1542_MAILBOXES + i].status = 0; aha1542->mb[i].status = 0;
any2scsi(mb[i].ccbptr, isa_virt_to_bus(&ccb[i])); any2scsi(aha1542->mb[i].ccbptr,
aha1542->ccb_handle + i * sizeof(struct ccb));
aha1542->mb[AHA1542_MAILBOXES + i].status = 0;
}; };
aha1542_intr_reset(sh->io_port); /* reset interrupts, so they don't block */ aha1542_intr_reset(sh->io_port); /* reset interrupts, so they don't block */
any2scsi((mb_cmd + 2), isa_virt_to_bus(mb)); any2scsi(mb_cmd + 2, aha1542->mb_handle);
if (aha1542_out(sh->io_port, mb_cmd, 5)) if (aha1542_out(sh->io_port, mb_cmd, 5))
shost_printk(KERN_ERR, sh, "failed setting up mailboxes\n"); shost_printk(KERN_ERR, sh, "failed setting up mailboxes\n");
aha1542_intr_reset(sh->io_port); aha1542_intr_reset(sh->io_port);
@ -739,11 +765,26 @@ static struct Scsi_Host *aha1542_hw_init(struct scsi_host_template *tpnt, struct
if (aha1542->bios_translation == BIOS_TRANSLATION_25563) if (aha1542->bios_translation == BIOS_TRANSLATION_25563)
shost_printk(KERN_INFO, sh, "Using extended bios translation\n"); shost_printk(KERN_INFO, sh, "Using extended bios translation\n");
if (dma_set_mask_and_coherent(pdev, DMA_BIT_MASK(24)) < 0)
goto unregister;
aha1542->mb = dma_alloc_coherent(pdev,
AHA1542_MAILBOXES * 2 * sizeof(struct mailbox),
&aha1542->mb_handle, GFP_KERNEL);
if (!aha1542->mb)
goto unregister;
aha1542->ccb = dma_alloc_coherent(pdev,
AHA1542_MAILBOXES * sizeof(struct ccb),
&aha1542->ccb_handle, GFP_KERNEL);
if (!aha1542->ccb)
goto free_mb;
setup_mailboxes(sh); setup_mailboxes(sh);
if (request_irq(sh->irq, aha1542_interrupt, 0, "aha1542", sh)) { if (request_irq(sh->irq, aha1542_interrupt, 0, "aha1542", sh)) {
shost_printk(KERN_ERR, sh, "Unable to allocate IRQ.\n"); shost_printk(KERN_ERR, sh, "Unable to allocate IRQ.\n");
goto unregister; goto free_ccb;
} }
if (sh->dma_channel != 0xFF) { if (sh->dma_channel != 0xFF) {
if (request_dma(sh->dma_channel, "aha1542")) { if (request_dma(sh->dma_channel, "aha1542")) {
@ -762,11 +803,18 @@ static struct Scsi_Host *aha1542_hw_init(struct scsi_host_template *tpnt, struct
scsi_scan_host(sh); scsi_scan_host(sh);
return sh; return sh;
free_dma: free_dma:
if (sh->dma_channel != 0xff) if (sh->dma_channel != 0xff)
free_dma(sh->dma_channel); free_dma(sh->dma_channel);
free_irq: free_irq:
free_irq(sh->irq, sh); free_irq(sh->irq, sh);
free_ccb:
dma_free_coherent(pdev, AHA1542_MAILBOXES * sizeof(struct ccb),
aha1542->ccb, aha1542->ccb_handle);
free_mb:
dma_free_coherent(pdev, AHA1542_MAILBOXES * 2 * sizeof(struct mailbox),
aha1542->mb, aha1542->mb_handle);
unregister: unregister:
scsi_host_put(sh); scsi_host_put(sh);
release: release:
@ -777,9 +825,16 @@ release:
static int aha1542_release(struct Scsi_Host *sh) static int aha1542_release(struct Scsi_Host *sh)
{ {
struct aha1542_hostdata *aha1542 = shost_priv(sh);
struct device *dev = sh->dma_dev;
scsi_remove_host(sh); scsi_remove_host(sh);
if (sh->dma_channel != 0xff) if (sh->dma_channel != 0xff)
free_dma(sh->dma_channel); free_dma(sh->dma_channel);
dma_free_coherent(dev, AHA1542_MAILBOXES * sizeof(struct ccb),
aha1542->ccb, aha1542->ccb_handle);
dma_free_coherent(dev, AHA1542_MAILBOXES * 2 * sizeof(struct mailbox),
aha1542->mb, aha1542->mb_handle);
if (sh->irq) if (sh->irq)
free_irq(sh->irq, sh); free_irq(sh->irq, sh);
if (sh->io_port && sh->n_io_port) if (sh->io_port && sh->n_io_port)
@ -826,7 +881,8 @@ static int aha1542_dev_reset(struct scsi_cmnd *cmd)
aha1542->aha1542_last_mbo_used = mbo; aha1542->aha1542_last_mbo_used = mbo;
any2scsi(mb[mbo].ccbptr, isa_virt_to_bus(&ccb[mbo])); /* This gets trashed for some reason */ /* This gets trashed for some reason */
any2scsi(mb[mbo].ccbptr, aha1542->ccb_handle + mbo * sizeof(*ccb));
memset(&ccb[mbo], 0, sizeof(struct ccb)); memset(&ccb[mbo], 0, sizeof(struct ccb));
@ -901,8 +957,7 @@ static int aha1542_reset(struct scsi_cmnd *cmd, u8 reset_cmd)
*/ */
continue; continue;
} }
kfree(tmp_cmd->host_scribble); aha1542_free_cmd(tmp_cmd);
tmp_cmd->host_scribble = NULL;
aha1542->int_cmds[i] = NULL; aha1542->int_cmds[i] = NULL;
aha1542->mb[i].status = 0; aha1542->mb[i].status = 0;
} }
@ -946,6 +1001,7 @@ static struct scsi_host_template driver_template = {
.module = THIS_MODULE, .module = THIS_MODULE,
.proc_name = "aha1542", .proc_name = "aha1542",
.name = "Adaptec 1542", .name = "Adaptec 1542",
.cmd_size = sizeof(struct aha1542_cmd),
.queuecommand = aha1542_queuecommand, .queuecommand = aha1542_queuecommand,
.eh_device_reset_handler= aha1542_dev_reset, .eh_device_reset_handler= aha1542_dev_reset,
.eh_bus_reset_handler = aha1542_bus_reset, .eh_bus_reset_handler = aha1542_bus_reset,
@ -955,7 +1011,6 @@ static struct scsi_host_template driver_template = {
.this_id = 7, .this_id = 7,
.sg_tablesize = 16, .sg_tablesize = 16,
.unchecked_isa_dma = 1, .unchecked_isa_dma = 1,
.use_clustering = ENABLE_CLUSTERING,
}; };
static int aha1542_isa_match(struct device *pdev, unsigned int ndev) static int aha1542_isa_match(struct device *pdev, unsigned int ndev)

View File

@ -545,7 +545,6 @@ static struct scsi_host_template aha1740_template = {
.can_queue = AHA1740_ECBS, .can_queue = AHA1740_ECBS,
.this_id = 7, .this_id = 7,
.sg_tablesize = AHA1740_SCATTER, .sg_tablesize = AHA1740_SCATTER,
.use_clustering = ENABLE_CLUSTERING,
.eh_abort_handler = aha1740_eh_abort_handler, .eh_abort_handler = aha1740_eh_abort_handler,
}; };

View File

@ -920,7 +920,6 @@ struct scsi_host_template aic79xx_driver_template = {
.this_id = -1, .this_id = -1,
.max_sectors = 8192, .max_sectors = 8192,
.cmd_per_lun = 2, .cmd_per_lun = 2,
.use_clustering = ENABLE_CLUSTERING,
.slave_alloc = ahd_linux_slave_alloc, .slave_alloc = ahd_linux_slave_alloc,
.slave_configure = ahd_linux_slave_configure, .slave_configure = ahd_linux_slave_configure,
.target_alloc = ahd_linux_target_alloc, .target_alloc = ahd_linux_target_alloc,

View File

@ -807,7 +807,6 @@ struct scsi_host_template aic7xxx_driver_template = {
.this_id = -1, .this_id = -1,
.max_sectors = 8192, .max_sectors = 8192,
.cmd_per_lun = 2, .cmd_per_lun = 2,
.use_clustering = ENABLE_CLUSTERING,
.slave_alloc = ahc_linux_slave_alloc, .slave_alloc = ahc_linux_slave_alloc,
.slave_configure = ahc_linux_slave_configure, .slave_configure = ahc_linux_slave_configure,
.target_alloc = ahc_linux_target_alloc, .target_alloc = ahc_linux_target_alloc,

View File

@ -1057,14 +1057,13 @@ static struct asd_ascb *asd_ascb_alloc(struct asd_ha_struct *asd_ha,
if (ascb) { if (ascb) {
ascb->dma_scb.size = sizeof(struct scb); ascb->dma_scb.size = sizeof(struct scb);
ascb->dma_scb.vaddr = dma_pool_alloc(asd_ha->scb_pool, ascb->dma_scb.vaddr = dma_pool_zalloc(asd_ha->scb_pool,
gfp_flags, gfp_flags,
&ascb->dma_scb.dma_handle); &ascb->dma_scb.dma_handle);
if (!ascb->dma_scb.vaddr) { if (!ascb->dma_scb.vaddr) {
kmem_cache_free(asd_ascb_cache, ascb); kmem_cache_free(asd_ascb_cache, ascb);
return NULL; return NULL;
} }
memset(ascb->dma_scb.vaddr, 0, sizeof(struct scb));
asd_init_ascb(asd_ha, ascb); asd_init_ascb(asd_ha, ascb);
spin_lock_irqsave(&seq->tc_index_lock, flags); spin_lock_irqsave(&seq->tc_index_lock, flags);

View File

@ -68,7 +68,6 @@ static struct scsi_host_template aic94xx_sht = {
.this_id = -1, .this_id = -1,
.sg_tablesize = SG_ALL, .sg_tablesize = SG_ALL,
.max_sectors = SCSI_DEFAULT_MAX_SECTORS, .max_sectors = SCSI_DEFAULT_MAX_SECTORS,
.use_clustering = ENABLE_CLUSTERING,
.eh_device_reset_handler = sas_eh_device_reset_handler, .eh_device_reset_handler = sas_eh_device_reset_handler,
.eh_target_reset_handler = sas_eh_target_reset_handler, .eh_target_reset_handler = sas_eh_target_reset_handler,
.target_destroy = sas_target_destroy, .target_destroy = sas_target_destroy,

View File

@ -156,7 +156,6 @@ static struct scsi_host_template arcmsr_scsi_host_template = {
.sg_tablesize = ARCMSR_DEFAULT_SG_ENTRIES, .sg_tablesize = ARCMSR_DEFAULT_SG_ENTRIES,
.max_sectors = ARCMSR_MAX_XFER_SECTORS_C, .max_sectors = ARCMSR_MAX_XFER_SECTORS_C,
.cmd_per_lun = ARCMSR_DEFAULT_CMD_PERLUN, .cmd_per_lun = ARCMSR_DEFAULT_CMD_PERLUN,
.use_clustering = ENABLE_CLUSTERING,
.shost_attrs = arcmsr_host_attrs, .shost_attrs = arcmsr_host_attrs,
.no_write_same = 1, .no_write_same = 1,
}; };
@ -903,9 +902,9 @@ static int arcmsr_probe(struct pci_dev *pdev, const struct pci_device_id *id)
if(!host){ if(!host){
goto pci_disable_dev; goto pci_disable_dev;
} }
error = pci_set_dma_mask(pdev, DMA_BIT_MASK(64)); error = dma_set_mask(&pdev->dev, DMA_BIT_MASK(64));
if(error){ if(error){
error = pci_set_dma_mask(pdev, DMA_BIT_MASK(32)); error = dma_set_mask(&pdev->dev, DMA_BIT_MASK(32));
if(error){ if(error){
printk(KERN_WARNING printk(KERN_WARNING
"scsi%d: No suitable DMA mask available\n", "scsi%d: No suitable DMA mask available\n",
@ -1049,9 +1048,9 @@ static int arcmsr_resume(struct pci_dev *pdev)
pr_warn("%s: pci_enable_device error\n", __func__); pr_warn("%s: pci_enable_device error\n", __func__);
return -ENODEV; return -ENODEV;
} }
error = pci_set_dma_mask(pdev, DMA_BIT_MASK(64)); error = dma_set_mask(&pdev->dev, DMA_BIT_MASK(64));
if (error) { if (error) {
error = pci_set_dma_mask(pdev, DMA_BIT_MASK(32)); error = dma_set_mask(&pdev->dev, DMA_BIT_MASK(32));
if (error) { if (error) {
pr_warn("scsi%d: No suitable DMA mask available\n", pr_warn("scsi%d: No suitable DMA mask available\n",
host->host_no); host->host_no);

View File

@ -2890,7 +2890,7 @@ static struct scsi_host_template acornscsi_template = {
.this_id = 7, .this_id = 7,
.sg_tablesize = SG_ALL, .sg_tablesize = SG_ALL,
.cmd_per_lun = 2, .cmd_per_lun = 2,
.use_clustering = DISABLE_CLUSTERING, .dma_boundary = PAGE_SIZE - 1,
.proc_name = "acornscsi", .proc_name = "acornscsi",
}; };

View File

@ -245,7 +245,7 @@ static struct scsi_host_template arxescsi_template = {
.can_queue = 0, .can_queue = 0,
.this_id = 7, .this_id = 7,
.sg_tablesize = SG_ALL, .sg_tablesize = SG_ALL,
.use_clustering = DISABLE_CLUSTERING, .dma_boundary = PAGE_SIZE - 1,
.proc_name = "arxescsi", .proc_name = "arxescsi",
}; };

View File

@ -221,10 +221,10 @@ static struct scsi_host_template cumanascsi_template = {
.this_id = 7, .this_id = 7,
.sg_tablesize = SG_ALL, .sg_tablesize = SG_ALL,
.cmd_per_lun = 2, .cmd_per_lun = 2,
.use_clustering = DISABLE_CLUSTERING,
.proc_name = "CumanaSCSI-1", .proc_name = "CumanaSCSI-1",
.cmd_size = NCR5380_CMD_SIZE, .cmd_size = NCR5380_CMD_SIZE,
.max_sectors = 128, .max_sectors = 128,
.dma_boundary = PAGE_SIZE - 1,
}; };
static int cumanascsi1_probe(struct expansion_card *ec, static int cumanascsi1_probe(struct expansion_card *ec,

View File

@ -367,7 +367,6 @@ static struct scsi_host_template cumanascsi2_template = {
.this_id = 7, .this_id = 7,
.sg_tablesize = SG_MAX_SEGMENTS, .sg_tablesize = SG_MAX_SEGMENTS,
.dma_boundary = IOMD_DMA_BOUNDARY, .dma_boundary = IOMD_DMA_BOUNDARY,
.use_clustering = DISABLE_CLUSTERING,
.proc_name = "cumanascsi2", .proc_name = "cumanascsi2",
}; };

View File

@ -486,7 +486,6 @@ static struct scsi_host_template eesox_template = {
.this_id = 7, .this_id = 7,
.sg_tablesize = SG_MAX_SEGMENTS, .sg_tablesize = SG_MAX_SEGMENTS,
.dma_boundary = IOMD_DMA_BOUNDARY, .dma_boundary = IOMD_DMA_BOUNDARY,
.use_clustering = DISABLE_CLUSTERING,
.proc_name = "eesox", .proc_name = "eesox",
}; };

View File

@ -110,7 +110,7 @@ static struct scsi_host_template oakscsi_template = {
.this_id = 7, .this_id = 7,
.sg_tablesize = SG_ALL, .sg_tablesize = SG_ALL,
.cmd_per_lun = 2, .cmd_per_lun = 2,
.use_clustering = DISABLE_CLUSTERING, .dma_boundary = PAGE_SIZE - 1,
.proc_name = "oakscsi", .proc_name = "oakscsi",
.cmd_size = NCR5380_CMD_SIZE, .cmd_size = NCR5380_CMD_SIZE,
.max_sectors = 128, .max_sectors = 128,

View File

@ -294,7 +294,6 @@ static struct scsi_host_template powertecscsi_template = {
.sg_tablesize = SG_MAX_SEGMENTS, .sg_tablesize = SG_MAX_SEGMENTS,
.dma_boundary = IOMD_DMA_BOUNDARY, .dma_boundary = IOMD_DMA_BOUNDARY,
.cmd_per_lun = 2, .cmd_per_lun = 2,
.use_clustering = ENABLE_CLUSTERING,
.proc_name = "powertec", .proc_name = "powertec",
}; };

View File

@ -714,7 +714,7 @@ static struct scsi_host_template atari_scsi_template = {
.eh_host_reset_handler = atari_scsi_host_reset, .eh_host_reset_handler = atari_scsi_host_reset,
.this_id = 7, .this_id = 7,
.cmd_per_lun = 2, .cmd_per_lun = 2,
.use_clustering = DISABLE_CLUSTERING, .dma_boundary = PAGE_SIZE - 1,
.cmd_size = NCR5380_CMD_SIZE, .cmd_size = NCR5380_CMD_SIZE,
}; };

View File

@ -1681,7 +1681,6 @@ static struct scsi_host_template atp870u_template = {
.can_queue = qcnt /* can_queue */, .can_queue = qcnt /* can_queue */,
.this_id = 7 /* SCSI ID */, .this_id = 7 /* SCSI ID */,
.sg_tablesize = ATP870U_SCATTER /*SG_ALL*/ /*SG_NONE*/, .sg_tablesize = ATP870U_SCATTER /*SG_ALL*/ /*SG_NONE*/,
.use_clustering = ENABLE_CLUSTERING,
.max_sectors = ATP870U_MAX_SECTORS, .max_sectors = ATP870U_MAX_SECTORS,
}; };

View File

@ -214,12 +214,6 @@ static char const *cqe_desc[] = {
"CXN_KILLED_IMM_DATA_RCVD" "CXN_KILLED_IMM_DATA_RCVD"
}; };
static int beiscsi_slave_configure(struct scsi_device *sdev)
{
blk_queue_max_segment_size(sdev->request_queue, 65536);
return 0;
}
static int beiscsi_eh_abort(struct scsi_cmnd *sc) static int beiscsi_eh_abort(struct scsi_cmnd *sc)
{ {
struct iscsi_task *abrt_task = (struct iscsi_task *)sc->SCp.ptr; struct iscsi_task *abrt_task = (struct iscsi_task *)sc->SCp.ptr;
@ -393,7 +387,6 @@ static struct scsi_host_template beiscsi_sht = {
.proc_name = DRV_NAME, .proc_name = DRV_NAME,
.queuecommand = iscsi_queuecommand, .queuecommand = iscsi_queuecommand,
.change_queue_depth = scsi_change_queue_depth, .change_queue_depth = scsi_change_queue_depth,
.slave_configure = beiscsi_slave_configure,
.target_alloc = iscsi_target_alloc, .target_alloc = iscsi_target_alloc,
.eh_timed_out = iscsi_eh_cmd_timed_out, .eh_timed_out = iscsi_eh_cmd_timed_out,
.eh_abort_handler = beiscsi_eh_abort, .eh_abort_handler = beiscsi_eh_abort,
@ -404,8 +397,8 @@ static struct scsi_host_template beiscsi_sht = {
.can_queue = BE2_IO_DEPTH, .can_queue = BE2_IO_DEPTH,
.this_id = -1, .this_id = -1,
.max_sectors = BEISCSI_MAX_SECTORS, .max_sectors = BEISCSI_MAX_SECTORS,
.max_segment_size = 65536,
.cmd_per_lun = BEISCSI_CMD_PER_LUN, .cmd_per_lun = BEISCSI_CMD_PER_LUN,
.use_clustering = ENABLE_CLUSTERING,
.vendor_id = SCSI_NL_VID_TYPE_PCI | BE_VENDOR_ID, .vendor_id = SCSI_NL_VID_TYPE_PCI | BE_VENDOR_ID,
.track_queue_depth = 1, .track_queue_depth = 1,
}; };

View File

@ -3819,7 +3819,7 @@ bfa_sfp_scn(struct bfa_sfp_s *sfp, struct bfi_mbmsg_s *msg)
sfp->state = BFA_SFP_STATE_REMOVED; sfp->state = BFA_SFP_STATE_REMOVED;
sfp->data_valid = 0; sfp->data_valid = 0;
bfa_sfp_scn_aen_post(sfp, rsp); bfa_sfp_scn_aen_post(sfp, rsp);
break; break;
case BFA_SFP_SCN_FAILED: case BFA_SFP_SCN_FAILED:
sfp->state = BFA_SFP_STATE_FAILED; sfp->state = BFA_SFP_STATE_FAILED;
sfp->data_valid = 0; sfp->data_valid = 0;
@ -5763,7 +5763,7 @@ bfa_phy_intr(void *phyarg, struct bfi_mbmsg_s *msg)
(struct bfa_phy_stats_s *) phy->ubuf; (struct bfa_phy_stats_s *) phy->ubuf;
bfa_phy_ntoh32((u32 *)stats, (u32 *)phy->dbuf_kva, bfa_phy_ntoh32((u32 *)stats, (u32 *)phy->dbuf_kva,
sizeof(struct bfa_phy_stats_s)); sizeof(struct bfa_phy_stats_s));
bfa_trc(phy, stats->status); bfa_trc(phy, stats->status);
} }
phy->status = status; phy->status = status;

View File

@ -739,14 +739,10 @@ bfad_pci_init(struct pci_dev *pdev, struct bfad_s *bfad)
pci_set_master(pdev); pci_set_master(pdev);
if (dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(64)) ||
if ((pci_set_dma_mask(pdev, DMA_BIT_MASK(64)) != 0) || dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32))) {
(pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(64)) != 0)) { printk(KERN_ERR "dma_set_mask_and_coherent fail %p\n", pdev);
if ((pci_set_dma_mask(pdev, DMA_BIT_MASK(32)) != 0) || goto out_release_region;
(pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32)) != 0)) {
printk(KERN_ERR "pci_set_dma_mask fail %p\n", pdev);
goto out_release_region;
}
} }
/* Enable PCIE Advanced Error Recovery (AER) if kernel supports */ /* Enable PCIE Advanced Error Recovery (AER) if kernel supports */
@ -1565,9 +1561,9 @@ bfad_pci_slot_reset(struct pci_dev *pdev)
pci_save_state(pdev); pci_save_state(pdev);
pci_set_master(pdev); pci_set_master(pdev);
if (pci_set_dma_mask(bfad->pcidev, DMA_BIT_MASK(64)) != 0) if (dma_set_mask_and_coherent(&bfad->pcidev->dev, DMA_BIT_MASK(64)) ||
if (pci_set_dma_mask(bfad->pcidev, DMA_BIT_MASK(32)) != 0) dma_set_mask_and_coherent(&bfad->pcidev->dev, DMA_BIT_MASK(32)))
goto out_disable_device; goto out_disable_device;
if (restart_bfa(bfad) == -1) if (restart_bfa(bfad) == -1)
goto out_disable_device; goto out_disable_device;

View File

@ -817,7 +817,6 @@ struct scsi_host_template bfad_im_scsi_host_template = {
.this_id = -1, .this_id = -1,
.sg_tablesize = BFAD_IO_MAX_SGE, .sg_tablesize = BFAD_IO_MAX_SGE,
.cmd_per_lun = 3, .cmd_per_lun = 3,
.use_clustering = ENABLE_CLUSTERING,
.shost_attrs = bfad_im_host_attrs, .shost_attrs = bfad_im_host_attrs,
.max_sectors = BFAD_MAX_SECTORS, .max_sectors = BFAD_MAX_SECTORS,
.vendor_id = BFA_PCI_VENDOR_ID_BROCADE, .vendor_id = BFA_PCI_VENDOR_ID_BROCADE,
@ -840,7 +839,6 @@ struct scsi_host_template bfad_im_vport_template = {
.this_id = -1, .this_id = -1,
.sg_tablesize = BFAD_IO_MAX_SGE, .sg_tablesize = BFAD_IO_MAX_SGE,
.cmd_per_lun = 3, .cmd_per_lun = 3,
.use_clustering = ENABLE_CLUSTERING,
.shost_attrs = bfad_im_vport_attrs, .shost_attrs = bfad_im_vport_attrs,
.max_sectors = BFAD_MAX_SECTORS, .max_sectors = BFAD_MAX_SECTORS,
}; };

View File

@ -2970,7 +2970,6 @@ static struct scsi_host_template bnx2fc_shost_template = {
.change_queue_depth = scsi_change_queue_depth, .change_queue_depth = scsi_change_queue_depth,
.this_id = -1, .this_id = -1,
.cmd_per_lun = 3, .cmd_per_lun = 3,
.use_clustering = ENABLE_CLUSTERING,
.sg_tablesize = BNX2FC_MAX_BDS_PER_CMD, .sg_tablesize = BNX2FC_MAX_BDS_PER_CMD,
.max_sectors = 1024, .max_sectors = 1024,
.track_queue_depth = 1, .track_queue_depth = 1,

View File

@ -2427,7 +2427,6 @@ static void bnx2i_process_ofld_cmpl(struct bnx2i_hba *hba,
{ {
u32 cid_addr; u32 cid_addr;
struct bnx2i_endpoint *ep; struct bnx2i_endpoint *ep;
u32 cid_num;
ep = bnx2i_find_ep_in_ofld_list(hba, ofld_kcqe->iscsi_conn_id); ep = bnx2i_find_ep_in_ofld_list(hba, ofld_kcqe->iscsi_conn_id);
if (!ep) { if (!ep) {
@ -2462,7 +2461,6 @@ static void bnx2i_process_ofld_cmpl(struct bnx2i_hba *hba,
} else { } else {
ep->state = EP_STATE_OFLD_COMPL; ep->state = EP_STATE_OFLD_COMPL;
cid_addr = ofld_kcqe->iscsi_conn_context_id; cid_addr = ofld_kcqe->iscsi_conn_context_id;
cid_num = bnx2i_get_cid_num(ep);
ep->ep_cid = cid_addr; ep->ep_cid = cid_addr;
ep->qp.ctx_base = NULL; ep->qp.ctx_base = NULL;
} }

View File

@ -2263,7 +2263,6 @@ static struct scsi_host_template bnx2i_host_template = {
.max_sectors = 127, .max_sectors = 127,
.cmd_per_lun = 128, .cmd_per_lun = 128,
.this_id = -1, .this_id = -1,
.use_clustering = ENABLE_CLUSTERING,
.sg_tablesize = ISCSI_MAX_BDS_PER_CMD, .sg_tablesize = ISCSI_MAX_BDS_PER_CMD,
.shost_attrs = bnx2i_dev_attributes, .shost_attrs = bnx2i_dev_attributes,
.track_queue_depth = 1, .track_queue_depth = 1,

View File

@ -255,7 +255,6 @@ static void
csio_hw_exit_workers(struct csio_hw *hw) csio_hw_exit_workers(struct csio_hw *hw)
{ {
cancel_work_sync(&hw->evtq_work); cancel_work_sync(&hw->evtq_work);
flush_scheduled_work();
} }
static int static int
@ -646,7 +645,7 @@ csio_shost_init(struct csio_hw *hw, struct device *dev,
if (csio_lnode_init(ln, hw, pln)) if (csio_lnode_init(ln, hw, pln))
goto err_shost_put; goto err_shost_put;
if (scsi_add_host(shost, dev)) if (scsi_add_host_with_dma(shost, dev, &hw->pdev->dev))
goto err_lnode_exit; goto err_lnode_exit;
return ln; return ln;

View File

@ -2274,7 +2274,6 @@ struct scsi_host_template csio_fcoe_shost_template = {
.this_id = -1, .this_id = -1,
.sg_tablesize = CSIO_SCSI_MAX_SGE, .sg_tablesize = CSIO_SCSI_MAX_SGE,
.cmd_per_lun = CSIO_MAX_CMD_PER_LUN, .cmd_per_lun = CSIO_MAX_CMD_PER_LUN,
.use_clustering = ENABLE_CLUSTERING,
.shost_attrs = csio_fcoe_lport_attrs, .shost_attrs = csio_fcoe_lport_attrs,
.max_sectors = CSIO_MAX_SECTOR_SIZE, .max_sectors = CSIO_MAX_SECTOR_SIZE,
}; };
@ -2294,7 +2293,6 @@ struct scsi_host_template csio_fcoe_shost_vport_template = {
.this_id = -1, .this_id = -1,
.sg_tablesize = CSIO_SCSI_MAX_SGE, .sg_tablesize = CSIO_SCSI_MAX_SGE,
.cmd_per_lun = CSIO_MAX_CMD_PER_LUN, .cmd_per_lun = CSIO_MAX_CMD_PER_LUN,
.use_clustering = ENABLE_CLUSTERING,
.shost_attrs = csio_fcoe_vport_attrs, .shost_attrs = csio_fcoe_vport_attrs,
.max_sectors = CSIO_MAX_SECTOR_SIZE, .max_sectors = CSIO_MAX_SECTOR_SIZE,
}; };

View File

@ -95,7 +95,7 @@ static struct scsi_host_template cxgb3i_host_template = {
.eh_device_reset_handler = iscsi_eh_device_reset, .eh_device_reset_handler = iscsi_eh_device_reset,
.eh_target_reset_handler = iscsi_eh_recover_target, .eh_target_reset_handler = iscsi_eh_recover_target,
.target_alloc = iscsi_target_alloc, .target_alloc = iscsi_target_alloc,
.use_clustering = DISABLE_CLUSTERING, .dma_boundary = PAGE_SIZE - 1,
.this_id = -1, .this_id = -1,
.track_queue_depth = 1, .track_queue_depth = 1,
}; };

View File

@ -1,8 +1,8 @@
config SCSI_CXGB4_ISCSI config SCSI_CXGB4_ISCSI
tristate "Chelsio T4 iSCSI support" tristate "Chelsio T4 iSCSI support"
depends on PCI && INET && (IPV6 || IPV6=n) depends on PCI && INET && (IPV6 || IPV6=n)
select NETDEVICES depends on THERMAL || !THERMAL
select ETHERNET depends on ETHERNET
select NET_VENDOR_CHELSIO select NET_VENDOR_CHELSIO
select CHELSIO_T4 select CHELSIO_T4
select CHELSIO_LIB select CHELSIO_LIB

View File

@ -113,7 +113,7 @@ static struct scsi_host_template cxgb4i_host_template = {
.eh_device_reset_handler = iscsi_eh_device_reset, .eh_device_reset_handler = iscsi_eh_device_reset,
.eh_target_reset_handler = iscsi_eh_recover_target, .eh_target_reset_handler = iscsi_eh_recover_target,
.target_alloc = iscsi_target_alloc, .target_alloc = iscsi_target_alloc,
.use_clustering = DISABLE_CLUSTERING, .dma_boundary = PAGE_SIZE - 1,
.this_id = -1, .this_id = -1,
.track_queue_depth = 1, .track_queue_depth = 1,
}; };

View File

@ -3174,7 +3174,6 @@ static struct scsi_host_template driver_template = {
.this_id = -1, .this_id = -1,
.sg_tablesize = 1, /* No scatter gather support */ .sg_tablesize = 1, /* No scatter gather support */
.max_sectors = CXLFLASH_MAX_SECTORS, .max_sectors = CXLFLASH_MAX_SECTORS,
.use_clustering = ENABLE_CLUSTERING,
.shost_attrs = cxlflash_host_attrs, .shost_attrs = cxlflash_host_attrs,
.sdev_attrs = cxlflash_dev_attrs, .sdev_attrs = cxlflash_dev_attrs,
}; };

View File

@ -4631,7 +4631,7 @@ static struct scsi_host_template dc395x_driver_template = {
.cmd_per_lun = DC395x_MAX_CMD_PER_LUN, .cmd_per_lun = DC395x_MAX_CMD_PER_LUN,
.eh_abort_handler = dc395x_eh_abort, .eh_abort_handler = dc395x_eh_abort,
.eh_bus_reset_handler = dc395x_eh_bus_reset, .eh_bus_reset_handler = dc395x_eh_bus_reset,
.use_clustering = DISABLE_CLUSTERING, .dma_boundary = PAGE_SIZE - 1,
}; };

View File

@ -63,7 +63,7 @@ static struct scsi_host_template dmx3191d_driver_template = {
.this_id = 7, .this_id = 7,
.sg_tablesize = SG_ALL, .sg_tablesize = SG_ALL,
.cmd_per_lun = 2, .cmd_per_lun = 2,
.use_clustering = DISABLE_CLUSTERING, .dma_boundary = PAGE_SIZE - 1,
.cmd_size = NCR5380_CMD_SIZE, .cmd_size = NCR5380_CMD_SIZE,
}; };

View File

@ -934,15 +934,15 @@ static int adpt_install_hba(struct scsi_host_template* sht, struct pci_dev* pDev
* See if we should enable dma64 mode. * See if we should enable dma64 mode.
*/ */
if (sizeof(dma_addr_t) > 4 && if (sizeof(dma_addr_t) > 4 &&
pci_set_dma_mask(pDev, DMA_BIT_MASK(64)) == 0) { dma_get_required_mask(&pDev->dev) > DMA_BIT_MASK(32) &&
if (dma_get_required_mask(&pDev->dev) > DMA_BIT_MASK(32)) dma_set_mask(&pDev->dev, DMA_BIT_MASK(64)) == 0)
dma64 = 1; dma64 = 1;
}
if (!dma64 && pci_set_dma_mask(pDev, DMA_BIT_MASK(32)) != 0) if (!dma64 && dma_set_mask(&pDev->dev, DMA_BIT_MASK(32)) != 0)
return -EINVAL; return -EINVAL;
/* adapter only supports message blocks below 4GB */ /* adapter only supports message blocks below 4GB */
pci_set_consistent_dma_mask(pDev, DMA_BIT_MASK(32)); dma_set_coherent_mask(&pDev->dev, DMA_BIT_MASK(32));
base_addr0_phys = pci_resource_start(pDev,0); base_addr0_phys = pci_resource_start(pDev,0);
hba_map0_area_size = pci_resource_len(pDev,0); hba_map0_area_size = pci_resource_len(pDev,0);
@ -3569,7 +3569,6 @@ static struct scsi_host_template driver_template = {
.slave_configure = adpt_slave_configure, .slave_configure = adpt_slave_configure,
.can_queue = MAX_TO_IOP_MESSAGES, .can_queue = MAX_TO_IOP_MESSAGES,
.this_id = 7, .this_id = 7,
.use_clustering = ENABLE_CLUSTERING,
}; };
static int __init adpt_init(void) static int __init adpt_init(void)

View File

@ -266,6 +266,7 @@ int esas2r_init_adapter(struct Scsi_Host *host, struct pci_dev *pcid,
int i; int i;
void *next_uncached; void *next_uncached;
struct esas2r_request *first_request, *last_request; struct esas2r_request *first_request, *last_request;
bool dma64 = false;
if (index >= MAX_ADAPTERS) { if (index >= MAX_ADAPTERS) {
esas2r_log(ESAS2R_LOG_CRIT, esas2r_log(ESAS2R_LOG_CRIT,
@ -286,42 +287,20 @@ int esas2r_init_adapter(struct Scsi_Host *host, struct pci_dev *pcid,
a->pcid = pcid; a->pcid = pcid;
a->host = host; a->host = host;
if (sizeof(dma_addr_t) > 4) { if (sizeof(dma_addr_t) > 4 &&
const uint64_t required_mask = dma_get_required_mask dma_get_required_mask(&pcid->dev) > DMA_BIT_MASK(32) &&
(&pcid->dev); !dma_set_mask_and_coherent(&pcid->dev, DMA_BIT_MASK(64)))
if (required_mask > DMA_BIT_MASK(32) dma64 = true;
&& !pci_set_dma_mask(pcid, DMA_BIT_MASK(64))
&& !pci_set_consistent_dma_mask(pcid, if (!dma64 && dma_set_mask_and_coherent(&pcid->dev, DMA_BIT_MASK(32))) {
DMA_BIT_MASK(64))) { esas2r_log(ESAS2R_LOG_CRIT, "failed to set DMA mask");
esas2r_log_dev(ESAS2R_LOG_INFO, esas2r_kill_adapter(index);
&(a->pcid->dev), return 0;
"64-bit PCI addressing enabled\n");
} else if (!pci_set_dma_mask(pcid, DMA_BIT_MASK(32))
&& !pci_set_consistent_dma_mask(pcid,
DMA_BIT_MASK(32))) {
esas2r_log_dev(ESAS2R_LOG_INFO,
&(a->pcid->dev),
"32-bit PCI addressing enabled\n");
} else {
esas2r_log(ESAS2R_LOG_CRIT,
"failed to set DMA mask");
esas2r_kill_adapter(index);
return 0;
}
} else {
if (!pci_set_dma_mask(pcid, DMA_BIT_MASK(32))
&& !pci_set_consistent_dma_mask(pcid,
DMA_BIT_MASK(32))) {
esas2r_log_dev(ESAS2R_LOG_INFO,
&(a->pcid->dev),
"32-bit PCI addressing enabled\n");
} else {
esas2r_log(ESAS2R_LOG_CRIT,
"failed to set DMA mask");
esas2r_kill_adapter(index);
return 0;
}
} }
esas2r_log_dev(ESAS2R_LOG_INFO, &pcid->dev,
"%s-bit PCI addressing enabled\n", dma64 ? "64" : "32");
esas2r_adapters[index] = a; esas2r_adapters[index] = a;
sprintf(a->name, ESAS2R_DRVR_NAME "_%02d", index); sprintf(a->name, ESAS2R_DRVR_NAME "_%02d", index);
esas2r_debug("new adapter %p, name %s", a, a->name); esas2r_debug("new adapter %p, name %s", a, a->name);

View File

@ -250,7 +250,6 @@ static struct scsi_host_template driver_template = {
ESAS2R_DEFAULT_CMD_PER_LUN, ESAS2R_DEFAULT_CMD_PER_LUN,
.present = 0, .present = 0,
.unchecked_isa_dma = 0, .unchecked_isa_dma = 0,
.use_clustering = ENABLE_CLUSTERING,
.emulated = 0, .emulated = 0,
.proc_name = ESAS2R_DRVR_NAME, .proc_name = ESAS2R_DRVR_NAME,
.change_queue_depth = scsi_change_queue_depth, .change_queue_depth = scsi_change_queue_depth,

View File

@ -2676,7 +2676,6 @@ struct scsi_host_template scsi_esp_template = {
.can_queue = 7, .can_queue = 7,
.this_id = 7, .this_id = 7,
.sg_tablesize = SG_ALL, .sg_tablesize = SG_ALL,
.use_clustering = ENABLE_CLUSTERING,
.max_sectors = 0xffff, .max_sectors = 0xffff,
.skip_settle_delay = 1, .skip_settle_delay = 1,
}; };

View File

@ -286,7 +286,6 @@ static struct scsi_host_template fcoe_shost_template = {
.this_id = -1, .this_id = -1,
.cmd_per_lun = 3, .cmd_per_lun = 3,
.can_queue = FCOE_MAX_OUTSTANDING_COMMANDS, .can_queue = FCOE_MAX_OUTSTANDING_COMMANDS,
.use_clustering = ENABLE_CLUSTERING,
.sg_tablesize = SG_ALL, .sg_tablesize = SG_ALL,
.max_sectors = 0xffff, .max_sectors = 0xffff,
.track_queue_depth = 1, .track_queue_depth = 1,
@ -1670,7 +1669,6 @@ static void fcoe_recv_frame(struct sk_buff *skb)
struct fc_stats *stats; struct fc_stats *stats;
struct fcoe_crc_eof crc_eof; struct fcoe_crc_eof crc_eof;
struct fc_frame *fp; struct fc_frame *fp;
struct fcoe_port *port;
struct fcoe_hdr *hp; struct fcoe_hdr *hp;
fr = fcoe_dev_from_skb(skb); fr = fcoe_dev_from_skb(skb);
@ -1688,7 +1686,6 @@ static void fcoe_recv_frame(struct sk_buff *skb)
skb_end_pointer(skb), skb->csum, skb_end_pointer(skb), skb->csum,
skb->dev ? skb->dev->name : "<NULL>"); skb->dev ? skb->dev->name : "<NULL>");
port = lport_priv(lport);
skb_linearize(skb); /* check for skb_is_nonlinear is within skb_linearize */ skb_linearize(skb); /* check for skb_is_nonlinear is within skb_linearize */
/* /*
@ -1859,7 +1856,6 @@ static int fcoe_device_notification(struct notifier_block *notifier,
struct net_device *netdev = netdev_notifier_info_to_dev(ptr); struct net_device *netdev = netdev_notifier_info_to_dev(ptr);
struct fcoe_ctlr *ctlr; struct fcoe_ctlr *ctlr;
struct fcoe_interface *fcoe; struct fcoe_interface *fcoe;
struct fcoe_port *port;
struct fc_stats *stats; struct fc_stats *stats;
u32 link_possible = 1; u32 link_possible = 1;
u32 mfs; u32 mfs;
@ -1897,7 +1893,6 @@ static int fcoe_device_notification(struct notifier_block *notifier,
break; break;
case NETDEV_UNREGISTER: case NETDEV_UNREGISTER:
list_del(&fcoe->list); list_del(&fcoe->list);
port = lport_priv(ctlr->lp);
fcoe_vport_remove(lport); fcoe_vport_remove(lport);
mutex_lock(&fcoe_config_mutex); mutex_lock(&fcoe_config_mutex);
fcoe_if_destroy(lport); fcoe_if_destroy(lport);

View File

@ -115,7 +115,6 @@ static struct scsi_host_template fnic_host_template = {
.this_id = -1, .this_id = -1,
.cmd_per_lun = 3, .cmd_per_lun = 3,
.can_queue = FNIC_DFLT_IO_REQ, .can_queue = FNIC_DFLT_IO_REQ,
.use_clustering = ENABLE_CLUSTERING,
.sg_tablesize = FNIC_MAX_SG_DESC_CNT, .sg_tablesize = FNIC_MAX_SG_DESC_CNT,
.max_sectors = 0xffff, .max_sectors = 0xffff,
.shost_attrs = fnic_attrs, .shost_attrs = fnic_attrs,

View File

@ -468,14 +468,13 @@ int fnic_trace_buf_init(void)
fnic_max_trace_entries = (trace_max_pages * PAGE_SIZE)/ fnic_max_trace_entries = (trace_max_pages * PAGE_SIZE)/
FNIC_ENTRY_SIZE_BYTES; FNIC_ENTRY_SIZE_BYTES;
fnic_trace_buf_p = (unsigned long)vmalloc((trace_max_pages * PAGE_SIZE)); fnic_trace_buf_p = (unsigned long)vzalloc(trace_max_pages * PAGE_SIZE);
if (!fnic_trace_buf_p) { if (!fnic_trace_buf_p) {
printk(KERN_ERR PFX "Failed to allocate memory " printk(KERN_ERR PFX "Failed to allocate memory "
"for fnic_trace_buf_p\n"); "for fnic_trace_buf_p\n");
err = -ENOMEM; err = -ENOMEM;
goto err_fnic_trace_buf_init; goto err_fnic_trace_buf_init;
} }
memset((void *)fnic_trace_buf_p, 0, (trace_max_pages * PAGE_SIZE));
fnic_trace_entries.page_offset = fnic_trace_entries.page_offset =
vmalloc(array_size(fnic_max_trace_entries, vmalloc(array_size(fnic_max_trace_entries,

View File

@ -700,7 +700,7 @@ static struct scsi_host_template driver_template = {
.this_id = 7, .this_id = 7,
.sg_tablesize = SG_ALL, .sg_tablesize = SG_ALL,
.cmd_per_lun = 2, .cmd_per_lun = 2,
.use_clustering = DISABLE_CLUSTERING, .dma_boundary = PAGE_SIZE - 1,
.cmd_size = NCR5380_CMD_SIZE, .cmd_size = NCR5380_CMD_SIZE,
.max_sectors = 128, .max_sectors = 128,
}; };

View File

@ -4680,7 +4680,6 @@ static struct scsi_host_template gdth_template = {
.sg_tablesize = GDTH_MAXSG, .sg_tablesize = GDTH_MAXSG,
.cmd_per_lun = GDTH_MAXC_P_L, .cmd_per_lun = GDTH_MAXC_P_L,
.unchecked_isa_dma = 1, .unchecked_isa_dma = 1,
.use_clustering = ENABLE_CLUSTERING,
.no_write_same = 1, .no_write_same = 1,
}; };

View File

@ -184,7 +184,7 @@ static struct scsi_host_template gvp11_scsi_template = {
.this_id = 7, .this_id = 7,
.sg_tablesize = SG_ALL, .sg_tablesize = SG_ALL,
.cmd_per_lun = CMD_PER_LUN, .cmd_per_lun = CMD_PER_LUN,
.use_clustering = DISABLE_CLUSTERING .dma_boundary = PAGE_SIZE - 1,
}; };
static int check_wd33c93(struct gvp11_scsiregs *regs) static int check_wd33c93(struct gvp11_scsiregs *regs)

View File

@ -69,6 +69,12 @@
#define HISI_SAS_SATA_PROTOCOL_FPDMA 0x8 #define HISI_SAS_SATA_PROTOCOL_FPDMA 0x8
#define HISI_SAS_SATA_PROTOCOL_ATAPI 0x10 #define HISI_SAS_SATA_PROTOCOL_ATAPI 0x10
#define HISI_SAS_DIF_PROT_MASK (SHOST_DIF_TYPE1_PROTECTION | \
SHOST_DIF_TYPE2_PROTECTION | \
SHOST_DIF_TYPE3_PROTECTION)
#define HISI_SAS_PROT_MASK (HISI_SAS_DIF_PROT_MASK)
struct hisi_hba; struct hisi_hba;
enum { enum {
@ -211,7 +217,7 @@ struct hisi_sas_slot {
/* Do not reorder/change members after here */ /* Do not reorder/change members after here */
void *buf; void *buf;
dma_addr_t buf_dma; dma_addr_t buf_dma;
int idx; u16 idx;
}; };
struct hisi_sas_hw { struct hisi_sas_hw {
@ -268,6 +274,8 @@ struct hisi_hba {
struct pci_dev *pci_dev; struct pci_dev *pci_dev;
struct device *dev; struct device *dev;
int prot_mask;
void __iomem *regs; void __iomem *regs;
void __iomem *sgpio_regs; void __iomem *sgpio_regs;
struct regmap *ctrl; struct regmap *ctrl;
@ -322,6 +330,8 @@ struct hisi_hba {
unsigned long sata_dev_bitmap[BITS_TO_LONGS(HISI_SAS_MAX_DEVICES)]; unsigned long sata_dev_bitmap[BITS_TO_LONGS(HISI_SAS_MAX_DEVICES)];
struct work_struct rst_work; struct work_struct rst_work;
u32 phy_state; u32 phy_state;
u32 intr_coal_ticks; /* Time of interrupt coalesce in us */
u32 intr_coal_count; /* Interrupt count to coalesce */
}; };
/* Generic HW DMA host memory structures */ /* Generic HW DMA host memory structures */
@ -468,7 +478,6 @@ extern int hisi_sas_remove(struct platform_device *pdev);
extern int hisi_sas_slave_configure(struct scsi_device *sdev); extern int hisi_sas_slave_configure(struct scsi_device *sdev);
extern int hisi_sas_scan_finished(struct Scsi_Host *shost, unsigned long time); extern int hisi_sas_scan_finished(struct Scsi_Host *shost, unsigned long time);
extern void hisi_sas_scan_start(struct Scsi_Host *shost); extern void hisi_sas_scan_start(struct Scsi_Host *shost);
extern struct device_attribute *host_attrs[];
extern int hisi_sas_host_reset(struct Scsi_Host *shost, int reset_type); extern int hisi_sas_host_reset(struct Scsi_Host *shost, int reset_type);
extern void hisi_sas_phy_down(struct hisi_hba *hisi_hba, int phy_no, int rdy); extern void hisi_sas_phy_down(struct hisi_hba *hisi_hba, int phy_no, int rdy);
extern void hisi_sas_slot_task_free(struct hisi_hba *hisi_hba, extern void hisi_sas_slot_task_free(struct hisi_hba *hisi_hba,

View File

@ -296,42 +296,109 @@ static void hisi_sas_task_prep_abort(struct hisi_hba *hisi_hba,
device_id, abort_flag, tag_to_abort); device_id, abort_flag, tag_to_abort);
} }
static void hisi_sas_dma_unmap(struct hisi_hba *hisi_hba,
struct sas_task *task, int n_elem,
int n_elem_req, int n_elem_resp)
{
struct device *dev = hisi_hba->dev;
if (!sas_protocol_ata(task->task_proto)) {
if (task->num_scatter) {
if (n_elem)
dma_unmap_sg(dev, task->scatter,
task->num_scatter,
task->data_dir);
} else if (task->task_proto & SAS_PROTOCOL_SMP) {
if (n_elem_req)
dma_unmap_sg(dev, &task->smp_task.smp_req,
1, DMA_TO_DEVICE);
if (n_elem_resp)
dma_unmap_sg(dev, &task->smp_task.smp_resp,
1, DMA_FROM_DEVICE);
}
}
}
static int hisi_sas_dma_map(struct hisi_hba *hisi_hba,
struct sas_task *task, int *n_elem,
int *n_elem_req, int *n_elem_resp)
{
struct device *dev = hisi_hba->dev;
int rc;
if (sas_protocol_ata(task->task_proto)) {
*n_elem = task->num_scatter;
} else {
unsigned int req_len, resp_len;
if (task->num_scatter) {
*n_elem = dma_map_sg(dev, task->scatter,
task->num_scatter, task->data_dir);
if (!*n_elem) {
rc = -ENOMEM;
goto prep_out;
}
} else if (task->task_proto & SAS_PROTOCOL_SMP) {
*n_elem_req = dma_map_sg(dev, &task->smp_task.smp_req,
1, DMA_TO_DEVICE);
if (!*n_elem_req) {
rc = -ENOMEM;
goto prep_out;
}
req_len = sg_dma_len(&task->smp_task.smp_req);
if (req_len & 0x3) {
rc = -EINVAL;
goto err_out_dma_unmap;
}
*n_elem_resp = dma_map_sg(dev, &task->smp_task.smp_resp,
1, DMA_FROM_DEVICE);
if (!*n_elem_resp) {
rc = -ENOMEM;
goto err_out_dma_unmap;
}
resp_len = sg_dma_len(&task->smp_task.smp_resp);
if (resp_len & 0x3) {
rc = -EINVAL;
goto err_out_dma_unmap;
}
}
}
if (*n_elem > HISI_SAS_SGE_PAGE_CNT) {
dev_err(dev, "task prep: n_elem(%d) > HISI_SAS_SGE_PAGE_CNT",
*n_elem);
rc = -EINVAL;
goto err_out_dma_unmap;
}
return 0;
err_out_dma_unmap:
/* It would be better to call dma_unmap_sg() here, but it's messy */
hisi_sas_dma_unmap(hisi_hba, task, *n_elem,
*n_elem_req, *n_elem_resp);
prep_out:
return rc;
}
static int hisi_sas_task_prep(struct sas_task *task, static int hisi_sas_task_prep(struct sas_task *task,
struct hisi_sas_dq **dq_pointer, struct hisi_sas_dq **dq_pointer,
bool is_tmf, struct hisi_sas_tmf_task *tmf, bool is_tmf, struct hisi_sas_tmf_task *tmf,
int *pass) int *pass)
{ {
struct domain_device *device = task->dev; struct domain_device *device = task->dev;
struct hisi_hba *hisi_hba; struct hisi_hba *hisi_hba = dev_to_hisi_hba(device);
struct hisi_sas_device *sas_dev = device->lldd_dev; struct hisi_sas_device *sas_dev = device->lldd_dev;
struct hisi_sas_port *port; struct hisi_sas_port *port;
struct hisi_sas_slot *slot; struct hisi_sas_slot *slot;
struct hisi_sas_cmd_hdr *cmd_hdr_base; struct hisi_sas_cmd_hdr *cmd_hdr_base;
struct asd_sas_port *sas_port = device->port; struct asd_sas_port *sas_port = device->port;
struct device *dev; struct device *dev = hisi_hba->dev;
int dlvry_queue_slot, dlvry_queue, rc, slot_idx; int dlvry_queue_slot, dlvry_queue, rc, slot_idx;
int n_elem = 0, n_elem_req = 0, n_elem_resp = 0; int n_elem = 0, n_elem_req = 0, n_elem_resp = 0;
struct hisi_sas_dq *dq; struct hisi_sas_dq *dq;
unsigned long flags; unsigned long flags;
int wr_q_index; int wr_q_index;
if (!sas_port) {
struct task_status_struct *ts = &task->task_status;
ts->resp = SAS_TASK_UNDELIVERED;
ts->stat = SAS_PHY_DOWN;
/*
* libsas will use dev->port, should
* not call task_done for sata
*/
if (device->dev_type != SAS_SATA_DEV)
task->task_done(task);
return -ECOMM;
}
hisi_hba = dev_to_hisi_hba(device);
dev = hisi_hba->dev;
if (DEV_IS_GONE(sas_dev)) { if (DEV_IS_GONE(sas_dev)) {
if (sas_dev) if (sas_dev)
dev_info(dev, "task prep: device %d not ready\n", dev_info(dev, "task prep: device %d not ready\n",
@ -355,49 +422,10 @@ static int hisi_sas_task_prep(struct sas_task *task,
return -ECOMM; return -ECOMM;
} }
if (!sas_protocol_ata(task->task_proto)) { rc = hisi_sas_dma_map(hisi_hba, task, &n_elem,
unsigned int req_len, resp_len; &n_elem_req, &n_elem_resp);
if (rc < 0)
if (task->num_scatter) { goto prep_out;
n_elem = dma_map_sg(dev, task->scatter,
task->num_scatter, task->data_dir);
if (!n_elem) {
rc = -ENOMEM;
goto prep_out;
}
} else if (task->task_proto & SAS_PROTOCOL_SMP) {
n_elem_req = dma_map_sg(dev, &task->smp_task.smp_req,
1, DMA_TO_DEVICE);
if (!n_elem_req) {
rc = -ENOMEM;
goto prep_out;
}
req_len = sg_dma_len(&task->smp_task.smp_req);
if (req_len & 0x3) {
rc = -EINVAL;
goto err_out_dma_unmap;
}
n_elem_resp = dma_map_sg(dev, &task->smp_task.smp_resp,
1, DMA_FROM_DEVICE);
if (!n_elem_resp) {
rc = -ENOMEM;
goto err_out_dma_unmap;
}
resp_len = sg_dma_len(&task->smp_task.smp_resp);
if (resp_len & 0x3) {
rc = -EINVAL;
goto err_out_dma_unmap;
}
}
} else
n_elem = task->num_scatter;
if (n_elem > HISI_SAS_SGE_PAGE_CNT) {
dev_err(dev, "task prep: n_elem(%d) > HISI_SAS_SGE_PAGE_CNT",
n_elem);
rc = -EINVAL;
goto err_out_dma_unmap;
}
if (hisi_hba->hw->slot_index_alloc) if (hisi_hba->hw->slot_index_alloc)
rc = hisi_hba->hw->slot_index_alloc(hisi_hba, device); rc = hisi_hba->hw->slot_index_alloc(hisi_hba, device);
@ -482,19 +510,8 @@ static int hisi_sas_task_prep(struct sas_task *task,
err_out_tag: err_out_tag:
hisi_sas_slot_index_free(hisi_hba, slot_idx); hisi_sas_slot_index_free(hisi_hba, slot_idx);
err_out_dma_unmap: err_out_dma_unmap:
if (!sas_protocol_ata(task->task_proto)) { hisi_sas_dma_unmap(hisi_hba, task, n_elem,
if (task->num_scatter) { n_elem_req, n_elem_resp);
dma_unmap_sg(dev, task->scatter, task->num_scatter,
task->data_dir);
} else if (task->task_proto & SAS_PROTOCOL_SMP) {
if (n_elem_req)
dma_unmap_sg(dev, &task->smp_task.smp_req,
1, DMA_TO_DEVICE);
if (n_elem_resp)
dma_unmap_sg(dev, &task->smp_task.smp_resp,
1, DMA_FROM_DEVICE);
}
}
prep_out: prep_out:
dev_err(dev, "task prep: failed[%d]!\n", rc); dev_err(dev, "task prep: failed[%d]!\n", rc);
return rc; return rc;
@ -506,10 +523,29 @@ static int hisi_sas_task_exec(struct sas_task *task, gfp_t gfp_flags,
u32 rc; u32 rc;
u32 pass = 0; u32 pass = 0;
unsigned long flags; unsigned long flags;
struct hisi_hba *hisi_hba = dev_to_hisi_hba(task->dev); struct hisi_hba *hisi_hba;
struct device *dev = hisi_hba->dev; struct device *dev;
struct domain_device *device = task->dev;
struct asd_sas_port *sas_port = device->port;
struct hisi_sas_dq *dq = NULL; struct hisi_sas_dq *dq = NULL;
if (!sas_port) {
struct task_status_struct *ts = &task->task_status;
ts->resp = SAS_TASK_UNDELIVERED;
ts->stat = SAS_PHY_DOWN;
/*
* libsas will use dev->port, should
* not call task_done for sata
*/
if (device->dev_type != SAS_SATA_DEV)
task->task_done(task);
return -ECOMM;
}
hisi_hba = dev_to_hisi_hba(device);
dev = hisi_hba->dev;
if (unlikely(test_bit(HISI_SAS_REJECT_CMD_BIT, &hisi_hba->flags))) { if (unlikely(test_bit(HISI_SAS_REJECT_CMD_BIT, &hisi_hba->flags))) {
if (in_softirq()) if (in_softirq())
return -EINVAL; return -EINVAL;
@ -1459,12 +1495,12 @@ static int hisi_sas_abort_task(struct sas_task *task)
if (task->lldd_task && task->task_proto & SAS_PROTOCOL_SSP) { if (task->lldd_task && task->task_proto & SAS_PROTOCOL_SSP) {
struct scsi_cmnd *cmnd = task->uldd_task; struct scsi_cmnd *cmnd = task->uldd_task;
struct hisi_sas_slot *slot = task->lldd_task; struct hisi_sas_slot *slot = task->lldd_task;
u32 tag = slot->idx; u16 tag = slot->idx;
int rc2; int rc2;
int_to_scsilun(cmnd->device->lun, &lun); int_to_scsilun(cmnd->device->lun, &lun);
tmf_task.tmf = TMF_ABORT_TASK; tmf_task.tmf = TMF_ABORT_TASK;
tmf_task.tag_of_task_to_be_managed = cpu_to_le16(tag); tmf_task.tag_of_task_to_be_managed = tag;
rc = hisi_sas_debug_issue_ssp_tmf(task->dev, lun.scsi_lun, rc = hisi_sas_debug_issue_ssp_tmf(task->dev, lun.scsi_lun,
&tmf_task); &tmf_task);
@ -1718,7 +1754,7 @@ static int hisi_sas_query_task(struct sas_task *task)
int_to_scsilun(cmnd->device->lun, &lun); int_to_scsilun(cmnd->device->lun, &lun);
tmf_task.tmf = TMF_QUERY_TASK; tmf_task.tmf = TMF_QUERY_TASK;
tmf_task.tag_of_task_to_be_managed = cpu_to_le16(tag); tmf_task.tag_of_task_to_be_managed = tag;
rc = hisi_sas_debug_issue_ssp_tmf(device, rc = hisi_sas_debug_issue_ssp_tmf(device,
lun.scsi_lun, lun.scsi_lun,
@ -1994,12 +2030,6 @@ EXPORT_SYMBOL_GPL(hisi_sas_kill_tasklets);
struct scsi_transport_template *hisi_sas_stt; struct scsi_transport_template *hisi_sas_stt;
EXPORT_SYMBOL_GPL(hisi_sas_stt); EXPORT_SYMBOL_GPL(hisi_sas_stt);
struct device_attribute *host_attrs[] = {
&dev_attr_phy_event_threshold,
NULL,
};
EXPORT_SYMBOL_GPL(host_attrs);
static struct sas_domain_function_template hisi_sas_transport_ops = { static struct sas_domain_function_template hisi_sas_transport_ops = {
.lldd_dev_found = hisi_sas_dev_found, .lldd_dev_found = hisi_sas_dev_found,
.lldd_dev_gone = hisi_sas_dev_gone, .lldd_dev_gone = hisi_sas_dev_gone,
@ -2380,7 +2410,6 @@ int hisi_sas_probe(struct platform_device *pdev,
shost->max_lun = ~0; shost->max_lun = ~0;
shost->max_channel = 1; shost->max_channel = 1;
shost->max_cmd_len = 16; shost->max_cmd_len = 16;
shost->sg_tablesize = min_t(u16, SG_ALL, HISI_SAS_SGE_PAGE_CNT);
if (hisi_hba->hw->slot_index_alloc) { if (hisi_hba->hw->slot_index_alloc) {
shost->can_queue = hisi_hba->hw->max_command_entries; shost->can_queue = hisi_hba->hw->max_command_entries;
shost->cmd_per_lun = hisi_hba->hw->max_command_entries; shost->cmd_per_lun = hisi_hba->hw->max_command_entries;

View File

@ -510,6 +510,7 @@ static void setup_itct_v1_hw(struct hisi_hba *hisi_hba,
struct hisi_sas_itct *itct = &hisi_hba->itct[device_id]; struct hisi_sas_itct *itct = &hisi_hba->itct[device_id];
struct asd_sas_port *sas_port = device->port; struct asd_sas_port *sas_port = device->port;
struct hisi_sas_port *port = to_hisi_sas_port(sas_port); struct hisi_sas_port *port = to_hisi_sas_port(sas_port);
u64 sas_addr;
memset(itct, 0, sizeof(*itct)); memset(itct, 0, sizeof(*itct));
@ -534,8 +535,8 @@ static void setup_itct_v1_hw(struct hisi_hba *hisi_hba,
itct->qw0 = cpu_to_le64(qw0); itct->qw0 = cpu_to_le64(qw0);
/* qw1 */ /* qw1 */
memcpy(&itct->sas_addr, device->sas_addr, SAS_ADDR_SIZE); memcpy(&sas_addr, device->sas_addr, SAS_ADDR_SIZE);
itct->sas_addr = __swab64(itct->sas_addr); itct->sas_addr = cpu_to_le64(__swab64(sas_addr));
/* qw2 */ /* qw2 */
itct->qw2 = cpu_to_le64((500ULL << ITCT_HDR_IT_NEXUS_LOSS_TL_OFF) | itct->qw2 = cpu_to_le64((500ULL << ITCT_HDR_IT_NEXUS_LOSS_TL_OFF) |
@ -561,7 +562,7 @@ static void clear_itct_v1_hw(struct hisi_hba *hisi_hba,
reg_val &= ~CFG_AGING_TIME_ITCT_REL_MSK; reg_val &= ~CFG_AGING_TIME_ITCT_REL_MSK;
hisi_sas_write32(hisi_hba, CFG_AGING_TIME, reg_val); hisi_sas_write32(hisi_hba, CFG_AGING_TIME, reg_val);
qw0 = cpu_to_le64(itct->qw0); qw0 = le64_to_cpu(itct->qw0);
qw0 &= ~ITCT_HDR_VALID_MSK; qw0 &= ~ITCT_HDR_VALID_MSK;
itct->qw0 = cpu_to_le64(qw0); itct->qw0 = cpu_to_le64(qw0);
} }
@ -1100,7 +1101,7 @@ static void slot_err_v1_hw(struct hisi_hba *hisi_hba,
case SAS_PROTOCOL_SSP: case SAS_PROTOCOL_SSP:
{ {
int error = -1; int error = -1;
u32 dma_err_type = cpu_to_le32(err_record->dma_err_type); u32 dma_err_type = le32_to_cpu(err_record->dma_err_type);
u32 dma_tx_err_type = ((dma_err_type & u32 dma_tx_err_type = ((dma_err_type &
ERR_HDR_DMA_TX_ERR_TYPE_MSK)) >> ERR_HDR_DMA_TX_ERR_TYPE_MSK)) >>
ERR_HDR_DMA_TX_ERR_TYPE_OFF; ERR_HDR_DMA_TX_ERR_TYPE_OFF;
@ -1108,9 +1109,9 @@ static void slot_err_v1_hw(struct hisi_hba *hisi_hba,
ERR_HDR_DMA_RX_ERR_TYPE_MSK)) >> ERR_HDR_DMA_RX_ERR_TYPE_MSK)) >>
ERR_HDR_DMA_RX_ERR_TYPE_OFF; ERR_HDR_DMA_RX_ERR_TYPE_OFF;
u32 trans_tx_fail_type = u32 trans_tx_fail_type =
cpu_to_le32(err_record->trans_tx_fail_type); le32_to_cpu(err_record->trans_tx_fail_type);
u32 trans_rx_fail_type = u32 trans_rx_fail_type =
cpu_to_le32(err_record->trans_rx_fail_type); le32_to_cpu(err_record->trans_rx_fail_type);
if (dma_tx_err_type) { if (dma_tx_err_type) {
/* dma tx err */ /* dma tx err */
@ -1558,7 +1559,7 @@ static irqreturn_t cq_interrupt_v1_hw(int irq, void *p)
u32 cmplt_hdr_data; u32 cmplt_hdr_data;
complete_hdr = &complete_queue[rd_point]; complete_hdr = &complete_queue[rd_point];
cmplt_hdr_data = cpu_to_le32(complete_hdr->data); cmplt_hdr_data = le32_to_cpu(complete_hdr->data);
idx = (cmplt_hdr_data & CMPLT_HDR_IPTT_MSK) >> idx = (cmplt_hdr_data & CMPLT_HDR_IPTT_MSK) >>
CMPLT_HDR_IPTT_OFF; CMPLT_HDR_IPTT_OFF;
slot = &hisi_hba->slot_info[idx]; slot = &hisi_hba->slot_info[idx];
@ -1797,6 +1798,11 @@ static int hisi_sas_v1_init(struct hisi_hba *hisi_hba)
return 0; return 0;
} }
static struct device_attribute *host_attrs_v1_hw[] = {
&dev_attr_phy_event_threshold,
NULL
};
static struct scsi_host_template sht_v1_hw = { static struct scsi_host_template sht_v1_hw = {
.name = DRV_NAME, .name = DRV_NAME,
.module = THIS_MODULE, .module = THIS_MODULE,
@ -1808,14 +1814,13 @@ static struct scsi_host_template sht_v1_hw = {
.change_queue_depth = sas_change_queue_depth, .change_queue_depth = sas_change_queue_depth,
.bios_param = sas_bios_param, .bios_param = sas_bios_param,
.this_id = -1, .this_id = -1,
.sg_tablesize = SG_ALL, .sg_tablesize = HISI_SAS_SGE_PAGE_CNT,
.max_sectors = SCSI_DEFAULT_MAX_SECTORS, .max_sectors = SCSI_DEFAULT_MAX_SECTORS,
.use_clustering = ENABLE_CLUSTERING,
.eh_device_reset_handler = sas_eh_device_reset_handler, .eh_device_reset_handler = sas_eh_device_reset_handler,
.eh_target_reset_handler = sas_eh_target_reset_handler, .eh_target_reset_handler = sas_eh_target_reset_handler,
.target_destroy = sas_target_destroy, .target_destroy = sas_target_destroy,
.ioctl = sas_ioctl, .ioctl = sas_ioctl,
.shost_attrs = host_attrs, .shost_attrs = host_attrs_v1_hw,
}; };
static const struct hisi_sas_hw hisi_sas_v1_hw = { static const struct hisi_sas_hw hisi_sas_v1_hw = {

View File

@ -934,6 +934,7 @@ static void setup_itct_v2_hw(struct hisi_hba *hisi_hba,
struct domain_device *parent_dev = device->parent; struct domain_device *parent_dev = device->parent;
struct asd_sas_port *sas_port = device->port; struct asd_sas_port *sas_port = device->port;
struct hisi_sas_port *port = to_hisi_sas_port(sas_port); struct hisi_sas_port *port = to_hisi_sas_port(sas_port);
u64 sas_addr;
memset(itct, 0, sizeof(*itct)); memset(itct, 0, sizeof(*itct));
@ -966,8 +967,8 @@ static void setup_itct_v2_hw(struct hisi_hba *hisi_hba,
itct->qw0 = cpu_to_le64(qw0); itct->qw0 = cpu_to_le64(qw0);
/* qw1 */ /* qw1 */
memcpy(&itct->sas_addr, device->sas_addr, SAS_ADDR_SIZE); memcpy(&sas_addr, device->sas_addr, SAS_ADDR_SIZE);
itct->sas_addr = __swab64(itct->sas_addr); itct->sas_addr = cpu_to_le64(__swab64(sas_addr));
/* qw2 */ /* qw2 */
if (!dev_is_sata(device)) if (!dev_is_sata(device))
@ -2044,11 +2045,11 @@ static void slot_err_v2_hw(struct hisi_hba *hisi_hba,
struct task_status_struct *ts = &task->task_status; struct task_status_struct *ts = &task->task_status;
struct hisi_sas_err_record_v2 *err_record = struct hisi_sas_err_record_v2 *err_record =
hisi_sas_status_buf_addr_mem(slot); hisi_sas_status_buf_addr_mem(slot);
u32 trans_tx_fail_type = cpu_to_le32(err_record->trans_tx_fail_type); u32 trans_tx_fail_type = le32_to_cpu(err_record->trans_tx_fail_type);
u32 trans_rx_fail_type = cpu_to_le32(err_record->trans_rx_fail_type); u32 trans_rx_fail_type = le32_to_cpu(err_record->trans_rx_fail_type);
u16 dma_tx_err_type = cpu_to_le16(err_record->dma_tx_err_type); u16 dma_tx_err_type = le16_to_cpu(err_record->dma_tx_err_type);
u16 sipc_rx_err_type = cpu_to_le16(err_record->sipc_rx_err_type); u16 sipc_rx_err_type = le16_to_cpu(err_record->sipc_rx_err_type);
u32 dma_rx_err_type = cpu_to_le32(err_record->dma_rx_err_type); u32 dma_rx_err_type = le32_to_cpu(err_record->dma_rx_err_type);
int error = -1; int error = -1;
if (err_phase == 1) { if (err_phase == 1) {
@ -2059,8 +2060,7 @@ static void slot_err_v2_hw(struct hisi_hba *hisi_hba,
trans_tx_fail_type); trans_tx_fail_type);
} else if (err_phase == 2) { } else if (err_phase == 2) {
/* error in RX phase, the priority is: DW1 > DW3 > DW2 */ /* error in RX phase, the priority is: DW1 > DW3 > DW2 */
error = parse_trans_rx_err_code_v2_hw( error = parse_trans_rx_err_code_v2_hw(trans_rx_fail_type);
trans_rx_fail_type);
if (error == -1) { if (error == -1) {
error = parse_dma_rx_err_code_v2_hw( error = parse_dma_rx_err_code_v2_hw(
dma_rx_err_type); dma_rx_err_type);
@ -2358,6 +2358,7 @@ slot_complete_v2_hw(struct hisi_hba *hisi_hba, struct hisi_sas_slot *slot)
&complete_queue[slot->cmplt_queue_slot]; &complete_queue[slot->cmplt_queue_slot];
unsigned long flags; unsigned long flags;
bool is_internal = slot->is_internal; bool is_internal = slot->is_internal;
u32 dw0;
if (unlikely(!task || !task->lldd_task || !task->dev)) if (unlikely(!task || !task->lldd_task || !task->dev))
return -EINVAL; return -EINVAL;
@ -2382,8 +2383,9 @@ slot_complete_v2_hw(struct hisi_hba *hisi_hba, struct hisi_sas_slot *slot)
} }
/* Use SAS+TMF status codes */ /* Use SAS+TMF status codes */
switch ((complete_hdr->dw0 & CMPLT_HDR_ABORT_STAT_MSK) dw0 = le32_to_cpu(complete_hdr->dw0);
>> CMPLT_HDR_ABORT_STAT_OFF) { switch ((dw0 & CMPLT_HDR_ABORT_STAT_MSK) >>
CMPLT_HDR_ABORT_STAT_OFF) {
case STAT_IO_ABORTED: case STAT_IO_ABORTED:
/* this io has been aborted by abort command */ /* this io has been aborted by abort command */
ts->stat = SAS_ABORTED_TASK; ts->stat = SAS_ABORTED_TASK;
@ -2408,9 +2410,8 @@ slot_complete_v2_hw(struct hisi_hba *hisi_hba, struct hisi_sas_slot *slot)
break; break;
} }
if ((complete_hdr->dw0 & CMPLT_HDR_ERX_MSK) && if ((dw0 & CMPLT_HDR_ERX_MSK) && (!(dw0 & CMPLT_HDR_RSPNS_XFRD_MSK))) {
(!(complete_hdr->dw0 & CMPLT_HDR_RSPNS_XFRD_MSK))) { u32 err_phase = (dw0 & CMPLT_HDR_ERR_PHASE_MSK)
u32 err_phase = (complete_hdr->dw0 & CMPLT_HDR_ERR_PHASE_MSK)
>> CMPLT_HDR_ERR_PHASE_OFF; >> CMPLT_HDR_ERR_PHASE_OFF;
u32 *error_info = hisi_sas_status_buf_addr_mem(slot); u32 *error_info = hisi_sas_status_buf_addr_mem(slot);
@ -2526,22 +2527,23 @@ static void prep_ata_v2_hw(struct hisi_hba *hisi_hba,
struct hisi_sas_tmf_task *tmf = slot->tmf; struct hisi_sas_tmf_task *tmf = slot->tmf;
u8 *buf_cmd; u8 *buf_cmd;
int has_data = 0, hdr_tag = 0; int has_data = 0, hdr_tag = 0;
u32 dw1 = 0, dw2 = 0; u32 dw0, dw1 = 0, dw2 = 0;
/* create header */ /* create header */
/* dw0 */ /* dw0 */
hdr->dw0 = cpu_to_le32(port->id << CMD_HDR_PORT_OFF); dw0 = port->id << CMD_HDR_PORT_OFF;
if (parent_dev && DEV_IS_EXPANDER(parent_dev->dev_type)) if (parent_dev && DEV_IS_EXPANDER(parent_dev->dev_type))
hdr->dw0 |= cpu_to_le32(3 << CMD_HDR_CMD_OFF); dw0 |= 3 << CMD_HDR_CMD_OFF;
else else
hdr->dw0 |= cpu_to_le32(4 << CMD_HDR_CMD_OFF); dw0 |= 4 << CMD_HDR_CMD_OFF;
if (tmf && tmf->force_phy) { if (tmf && tmf->force_phy) {
hdr->dw0 |= CMD_HDR_FORCE_PHY_MSK; dw0 |= CMD_HDR_FORCE_PHY_MSK;
hdr->dw0 |= cpu_to_le32((1 << tmf->phy_id) dw0 |= (1 << tmf->phy_id) << CMD_HDR_PHY_ID_OFF;
<< CMD_HDR_PHY_ID_OFF);
} }
hdr->dw0 = cpu_to_le32(dw0);
/* dw1 */ /* dw1 */
switch (task->data_dir) { switch (task->data_dir) {
case DMA_TO_DEVICE: case DMA_TO_DEVICE:
@ -3152,20 +3154,24 @@ static void cq_tasklet_v2_hw(unsigned long val)
/* Check for NCQ completion */ /* Check for NCQ completion */
if (complete_hdr->act) { if (complete_hdr->act) {
u32 act_tmp = complete_hdr->act; u32 act_tmp = le32_to_cpu(complete_hdr->act);
int ncq_tag_count = ffs(act_tmp); int ncq_tag_count = ffs(act_tmp);
u32 dw1 = le32_to_cpu(complete_hdr->dw1);
dev_id = (complete_hdr->dw1 & CMPLT_HDR_DEV_ID_MSK) >> dev_id = (dw1 & CMPLT_HDR_DEV_ID_MSK) >>
CMPLT_HDR_DEV_ID_OFF; CMPLT_HDR_DEV_ID_OFF;
itct = &hisi_hba->itct[dev_id]; itct = &hisi_hba->itct[dev_id];
/* The NCQ tags are held in the itct header */ /* The NCQ tags are held in the itct header */
while (ncq_tag_count) { while (ncq_tag_count) {
__le64 *ncq_tag = &itct->qw4_15[0]; __le64 *_ncq_tag = &itct->qw4_15[0], __ncq_tag;
u64 ncq_tag;
ncq_tag_count -= 1; ncq_tag_count--;
iptt = (ncq_tag[ncq_tag_count / 5] __ncq_tag = _ncq_tag[ncq_tag_count / 5];
>> (ncq_tag_count % 5) * 12) & 0xfff; ncq_tag = le64_to_cpu(__ncq_tag);
iptt = (ncq_tag >> (ncq_tag_count % 5) * 12) &
0xfff;
slot = &hisi_hba->slot_info[iptt]; slot = &hisi_hba->slot_info[iptt];
slot->cmplt_queue_slot = rd_point; slot->cmplt_queue_slot = rd_point;
@ -3176,7 +3182,9 @@ static void cq_tasklet_v2_hw(unsigned long val)
ncq_tag_count = ffs(act_tmp); ncq_tag_count = ffs(act_tmp);
} }
} else { } else {
iptt = (complete_hdr->dw1) & CMPLT_HDR_IPTT_MSK; u32 dw1 = le32_to_cpu(complete_hdr->dw1);
iptt = dw1 & CMPLT_HDR_IPTT_MSK;
slot = &hisi_hba->slot_info[iptt]; slot = &hisi_hba->slot_info[iptt];
slot->cmplt_queue_slot = rd_point; slot->cmplt_queue_slot = rd_point;
slot->cmplt_queue = queue; slot->cmplt_queue = queue;
@ -3552,6 +3560,11 @@ static void wait_cmds_complete_timeout_v2_hw(struct hisi_hba *hisi_hba,
dev_dbg(dev, "wait commands complete %dms\n", time); dev_dbg(dev, "wait commands complete %dms\n", time);
} }
static struct device_attribute *host_attrs_v2_hw[] = {
&dev_attr_phy_event_threshold,
NULL
};
static struct scsi_host_template sht_v2_hw = { static struct scsi_host_template sht_v2_hw = {
.name = DRV_NAME, .name = DRV_NAME,
.module = THIS_MODULE, .module = THIS_MODULE,
@ -3563,14 +3576,13 @@ static struct scsi_host_template sht_v2_hw = {
.change_queue_depth = sas_change_queue_depth, .change_queue_depth = sas_change_queue_depth,
.bios_param = sas_bios_param, .bios_param = sas_bios_param,
.this_id = -1, .this_id = -1,
.sg_tablesize = SG_ALL, .sg_tablesize = HISI_SAS_SGE_PAGE_CNT,
.max_sectors = SCSI_DEFAULT_MAX_SECTORS, .max_sectors = SCSI_DEFAULT_MAX_SECTORS,
.use_clustering = ENABLE_CLUSTERING,
.eh_device_reset_handler = sas_eh_device_reset_handler, .eh_device_reset_handler = sas_eh_device_reset_handler,
.eh_target_reset_handler = sas_eh_target_reset_handler, .eh_target_reset_handler = sas_eh_target_reset_handler,
.target_destroy = sas_target_destroy, .target_destroy = sas_target_destroy,
.ioctl = sas_ioctl, .ioctl = sas_ioctl,
.shost_attrs = host_attrs, .shost_attrs = host_attrs_v2_hw,
}; };
static const struct hisi_sas_hw hisi_sas_v2_hw = { static const struct hisi_sas_hw hisi_sas_v2_hw = {

View File

@ -42,6 +42,7 @@
#define MAX_CON_TIME_LIMIT_TIME 0xa4 #define MAX_CON_TIME_LIMIT_TIME 0xa4
#define BUS_INACTIVE_LIMIT_TIME 0xa8 #define BUS_INACTIVE_LIMIT_TIME 0xa8
#define REJECT_TO_OPEN_LIMIT_TIME 0xac #define REJECT_TO_OPEN_LIMIT_TIME 0xac
#define CQ_INT_CONVERGE_EN 0xb0
#define CFG_AGING_TIME 0xbc #define CFG_AGING_TIME 0xbc
#define HGC_DFX_CFG2 0xc0 #define HGC_DFX_CFG2 0xc0
#define CFG_ABT_SET_QUERY_IPTT 0xd4 #define CFG_ABT_SET_QUERY_IPTT 0xd4
@ -126,6 +127,8 @@
#define PHY_CTRL (PORT_BASE + 0x14) #define PHY_CTRL (PORT_BASE + 0x14)
#define PHY_CTRL_RESET_OFF 0 #define PHY_CTRL_RESET_OFF 0
#define PHY_CTRL_RESET_MSK (0x1 << PHY_CTRL_RESET_OFF) #define PHY_CTRL_RESET_MSK (0x1 << PHY_CTRL_RESET_OFF)
#define CMD_HDR_PIR_OFF 8
#define CMD_HDR_PIR_MSK (0x1 << CMD_HDR_PIR_OFF)
#define SL_CFG (PORT_BASE + 0x84) #define SL_CFG (PORT_BASE + 0x84)
#define AIP_LIMIT (PORT_BASE + 0x90) #define AIP_LIMIT (PORT_BASE + 0x90)
#define SL_CONTROL (PORT_BASE + 0x94) #define SL_CONTROL (PORT_BASE + 0x94)
@ -332,6 +335,16 @@
#define ITCT_HDR_RTOLT_OFF 48 #define ITCT_HDR_RTOLT_OFF 48
#define ITCT_HDR_RTOLT_MSK (0xffffULL << ITCT_HDR_RTOLT_OFF) #define ITCT_HDR_RTOLT_MSK (0xffffULL << ITCT_HDR_RTOLT_OFF)
struct hisi_sas_protect_iu_v3_hw {
u32 dw0;
u32 lbrtcv;
u32 lbrtgv;
u32 dw3;
u32 dw4;
u32 dw5;
u32 rsv;
};
struct hisi_sas_complete_v3_hdr { struct hisi_sas_complete_v3_hdr {
__le32 dw0; __le32 dw0;
__le32 dw1; __le32 dw1;
@ -371,6 +384,28 @@ struct hisi_sas_err_record_v3 {
((fis.command == ATA_CMD_DEV_RESET) && \ ((fis.command == ATA_CMD_DEV_RESET) && \
((fis.control & ATA_SRST) != 0))) ((fis.control & ATA_SRST) != 0)))
#define T10_INSRT_EN_OFF 0
#define T10_INSRT_EN_MSK (1 << T10_INSRT_EN_OFF)
#define T10_RMV_EN_OFF 1
#define T10_RMV_EN_MSK (1 << T10_RMV_EN_OFF)
#define T10_RPLC_EN_OFF 2
#define T10_RPLC_EN_MSK (1 << T10_RPLC_EN_OFF)
#define T10_CHK_EN_OFF 3
#define T10_CHK_EN_MSK (1 << T10_CHK_EN_OFF)
#define INCR_LBRT_OFF 5
#define INCR_LBRT_MSK (1 << INCR_LBRT_OFF)
#define USR_DATA_BLOCK_SZ_OFF 20
#define USR_DATA_BLOCK_SZ_MSK (0x3 << USR_DATA_BLOCK_SZ_OFF)
#define T10_CHK_MSK_OFF 16
static bool hisi_sas_intr_conv;
MODULE_PARM_DESC(intr_conv, "interrupt converge enable (0-1)");
/* permit overriding the host protection capabilities mask (EEDP/T10 PI) */
static int prot_mask;
module_param(prot_mask, int, 0);
MODULE_PARM_DESC(prot_mask, " host protection capabilities mask, def=0x0 ");
static u32 hisi_sas_read32(struct hisi_hba *hisi_hba, u32 off) static u32 hisi_sas_read32(struct hisi_hba *hisi_hba, u32 off)
{ {
void __iomem *regs = hisi_hba->regs + off; void __iomem *regs = hisi_hba->regs + off;
@ -436,6 +471,8 @@ static void init_reg_v3_hw(struct hisi_hba *hisi_hba)
hisi_sas_write32(hisi_hba, INT_COAL_EN, 0x1); hisi_sas_write32(hisi_hba, INT_COAL_EN, 0x1);
hisi_sas_write32(hisi_hba, OQ_INT_COAL_TIME, 0x1); hisi_sas_write32(hisi_hba, OQ_INT_COAL_TIME, 0x1);
hisi_sas_write32(hisi_hba, OQ_INT_COAL_CNT, 0x1); hisi_sas_write32(hisi_hba, OQ_INT_COAL_CNT, 0x1);
hisi_sas_write32(hisi_hba, CQ_INT_CONVERGE_EN,
hisi_sas_intr_conv);
hisi_sas_write32(hisi_hba, OQ_INT_SRC, 0xffff); hisi_sas_write32(hisi_hba, OQ_INT_SRC, 0xffff);
hisi_sas_write32(hisi_hba, ENT_INT_SRC1, 0xffffffff); hisi_sas_write32(hisi_hba, ENT_INT_SRC1, 0xffffffff);
hisi_sas_write32(hisi_hba, ENT_INT_SRC2, 0xffffffff); hisi_sas_write32(hisi_hba, ENT_INT_SRC2, 0xffffffff);
@ -494,7 +531,7 @@ static void init_reg_v3_hw(struct hisi_hba *hisi_hba)
hisi_sas_phy_write32(hisi_hba, i, PHYCTRL_OOB_RESTART_MSK, 0x1); hisi_sas_phy_write32(hisi_hba, i, PHYCTRL_OOB_RESTART_MSK, 0x1);
hisi_sas_phy_write32(hisi_hba, i, STP_LINK_TIMER, 0x7f7a120); hisi_sas_phy_write32(hisi_hba, i, STP_LINK_TIMER, 0x7f7a120);
hisi_sas_phy_write32(hisi_hba, i, CON_CFG_DRIVER, 0x2a0a01); hisi_sas_phy_write32(hisi_hba, i, CON_CFG_DRIVER, 0x2a0a01);
hisi_sas_phy_write32(hisi_hba, i, SAS_SSP_CON_TIMER_CFG, 0x32);
/* used for 12G negotiate */ /* used for 12G negotiate */
hisi_sas_phy_write32(hisi_hba, i, COARSETUNE_TIME, 0x1e); hisi_sas_phy_write32(hisi_hba, i, COARSETUNE_TIME, 0x1e);
hisi_sas_phy_write32(hisi_hba, i, AIP_LIMIT, 0x2ffff); hisi_sas_phy_write32(hisi_hba, i, AIP_LIMIT, 0x2ffff);
@ -622,6 +659,7 @@ static void setup_itct_v3_hw(struct hisi_hba *hisi_hba,
struct domain_device *parent_dev = device->parent; struct domain_device *parent_dev = device->parent;
struct asd_sas_port *sas_port = device->port; struct asd_sas_port *sas_port = device->port;
struct hisi_sas_port *port = to_hisi_sas_port(sas_port); struct hisi_sas_port *port = to_hisi_sas_port(sas_port);
u64 sas_addr;
memset(itct, 0, sizeof(*itct)); memset(itct, 0, sizeof(*itct));
@ -654,8 +692,8 @@ static void setup_itct_v3_hw(struct hisi_hba *hisi_hba,
itct->qw0 = cpu_to_le64(qw0); itct->qw0 = cpu_to_le64(qw0);
/* qw1 */ /* qw1 */
memcpy(&itct->sas_addr, device->sas_addr, SAS_ADDR_SIZE); memcpy(&sas_addr, device->sas_addr, SAS_ADDR_SIZE);
itct->sas_addr = __swab64(itct->sas_addr); itct->sas_addr = cpu_to_le64(__swab64(sas_addr));
/* qw2 */ /* qw2 */
if (!dev_is_sata(device)) if (!dev_is_sata(device))
@ -932,6 +970,58 @@ static void prep_prd_sge_v3_hw(struct hisi_hba *hisi_hba,
hdr->sg_len = cpu_to_le32(n_elem << CMD_HDR_DATA_SGL_LEN_OFF); hdr->sg_len = cpu_to_le32(n_elem << CMD_HDR_DATA_SGL_LEN_OFF);
} }
static u32 get_prot_chk_msk_v3_hw(struct scsi_cmnd *scsi_cmnd)
{
unsigned char prot_flags = scsi_cmnd->prot_flags;
if (prot_flags & SCSI_PROT_TRANSFER_PI) {
if (prot_flags & SCSI_PROT_REF_CHECK)
return 0xc << 16;
return 0xfc << 16;
}
return 0;
}
static void fill_prot_v3_hw(struct scsi_cmnd *scsi_cmnd,
struct hisi_sas_protect_iu_v3_hw *prot)
{
unsigned char prot_op = scsi_get_prot_op(scsi_cmnd);
unsigned int interval = scsi_prot_interval(scsi_cmnd);
u32 lbrt_chk_val = t10_pi_ref_tag(scsi_cmnd->request);
switch (prot_op) {
case SCSI_PROT_READ_STRIP:
prot->dw0 |= (T10_RMV_EN_MSK | T10_CHK_EN_MSK);
prot->lbrtcv = lbrt_chk_val;
prot->dw4 |= get_prot_chk_msk_v3_hw(scsi_cmnd);
break;
case SCSI_PROT_WRITE_INSERT:
prot->dw0 |= T10_INSRT_EN_MSK;
prot->lbrtgv = lbrt_chk_val;
break;
default:
WARN(1, "prot_op(0x%x) is not valid\n", prot_op);
break;
}
switch (interval) {
case 512:
break;
case 4096:
prot->dw0 |= (0x1 << USR_DATA_BLOCK_SZ_OFF);
break;
case 520:
prot->dw0 |= (0x2 << USR_DATA_BLOCK_SZ_OFF);
break;
default:
WARN(1, "protection interval (0x%x) invalid\n",
interval);
break;
}
prot->dw0 |= INCR_LBRT_MSK;
}
static void prep_ssp_v3_hw(struct hisi_hba *hisi_hba, static void prep_ssp_v3_hw(struct hisi_hba *hisi_hba,
struct hisi_sas_slot *slot) struct hisi_sas_slot *slot)
{ {
@ -943,9 +1033,10 @@ static void prep_ssp_v3_hw(struct hisi_hba *hisi_hba,
struct sas_ssp_task *ssp_task = &task->ssp_task; struct sas_ssp_task *ssp_task = &task->ssp_task;
struct scsi_cmnd *scsi_cmnd = ssp_task->cmd; struct scsi_cmnd *scsi_cmnd = ssp_task->cmd;
struct hisi_sas_tmf_task *tmf = slot->tmf; struct hisi_sas_tmf_task *tmf = slot->tmf;
unsigned char prot_op = scsi_get_prot_op(scsi_cmnd);
int has_data = 0, priority = !!tmf; int has_data = 0, priority = !!tmf;
u8 *buf_cmd; u8 *buf_cmd;
u32 dw1 = 0, dw2 = 0; u32 dw1 = 0, dw2 = 0, len = 0;
hdr->dw0 = cpu_to_le32((1 << CMD_HDR_RESP_REPORT_OFF) | hdr->dw0 = cpu_to_le32((1 << CMD_HDR_RESP_REPORT_OFF) |
(2 << CMD_HDR_TLR_CTRL_OFF) | (2 << CMD_HDR_TLR_CTRL_OFF) |
@ -975,7 +1066,6 @@ static void prep_ssp_v3_hw(struct hisi_hba *hisi_hba,
/* map itct entry */ /* map itct entry */
dw1 |= sas_dev->device_id << CMD_HDR_DEV_ID_OFF; dw1 |= sas_dev->device_id << CMD_HDR_DEV_ID_OFF;
hdr->dw1 = cpu_to_le32(dw1);
dw2 = (((sizeof(struct ssp_command_iu) + sizeof(struct ssp_frame_hdr) dw2 = (((sizeof(struct ssp_command_iu) + sizeof(struct ssp_frame_hdr)
+ 3) / 4) << CMD_HDR_CFL_OFF) | + 3) / 4) << CMD_HDR_CFL_OFF) |
@ -988,7 +1078,6 @@ static void prep_ssp_v3_hw(struct hisi_hba *hisi_hba,
prep_prd_sge_v3_hw(hisi_hba, slot, hdr, task->scatter, prep_prd_sge_v3_hw(hisi_hba, slot, hdr, task->scatter,
slot->n_elem); slot->n_elem);
hdr->data_transfer_len = cpu_to_le32(task->total_xfer_len);
hdr->cmd_table_addr = cpu_to_le64(hisi_sas_cmd_hdr_addr_dma(slot)); hdr->cmd_table_addr = cpu_to_le64(hisi_sas_cmd_hdr_addr_dma(slot));
hdr->sts_buffer_addr = cpu_to_le64(hisi_sas_status_buf_addr_dma(slot)); hdr->sts_buffer_addr = cpu_to_le64(hisi_sas_status_buf_addr_dma(slot));
@ -1013,6 +1102,38 @@ static void prep_ssp_v3_hw(struct hisi_hba *hisi_hba,
break; break;
} }
} }
if (has_data && (prot_op != SCSI_PROT_NORMAL)) {
struct hisi_sas_protect_iu_v3_hw prot;
u8 *buf_cmd_prot;
hdr->dw7 |= cpu_to_le32(1 << CMD_HDR_ADDR_MODE_SEL_OFF);
dw1 |= CMD_HDR_PIR_MSK;
buf_cmd_prot = hisi_sas_cmd_hdr_addr_mem(slot) +
sizeof(struct ssp_frame_hdr) +
sizeof(struct ssp_command_iu);
memset(&prot, 0, sizeof(struct hisi_sas_protect_iu_v3_hw));
fill_prot_v3_hw(scsi_cmnd, &prot);
memcpy(buf_cmd_prot, &prot,
sizeof(struct hisi_sas_protect_iu_v3_hw));
/*
* For READ, we need length of info read to memory, while for
* WRITE we need length of data written to the disk.
*/
if (prot_op == SCSI_PROT_WRITE_INSERT) {
unsigned int interval = scsi_prot_interval(scsi_cmnd);
unsigned int ilog2_interval = ilog2(interval);
len = (task->total_xfer_len >> ilog2_interval) * 8;
}
}
hdr->dw1 = cpu_to_le32(dw1);
hdr->data_transfer_len = cpu_to_le32(task->total_xfer_len + len);
} }
static void prep_smp_v3_hw(struct hisi_hba *hisi_hba, static void prep_smp_v3_hw(struct hisi_hba *hisi_hba,
@ -1584,15 +1705,16 @@ slot_err_v3_hw(struct hisi_hba *hisi_hba, struct sas_task *task,
&complete_queue[slot->cmplt_queue_slot]; &complete_queue[slot->cmplt_queue_slot];
struct hisi_sas_err_record_v3 *record = struct hisi_sas_err_record_v3 *record =
hisi_sas_status_buf_addr_mem(slot); hisi_sas_status_buf_addr_mem(slot);
u32 dma_rx_err_type = record->dma_rx_err_type; u32 dma_rx_err_type = le32_to_cpu(record->dma_rx_err_type);
u32 trans_tx_fail_type = record->trans_tx_fail_type; u32 trans_tx_fail_type = le32_to_cpu(record->trans_tx_fail_type);
u32 dw3 = le32_to_cpu(complete_hdr->dw3);
switch (task->task_proto) { switch (task->task_proto) {
case SAS_PROTOCOL_SSP: case SAS_PROTOCOL_SSP:
if (dma_rx_err_type & RX_DATA_LEN_UNDERFLOW_MSK) { if (dma_rx_err_type & RX_DATA_LEN_UNDERFLOW_MSK) {
ts->residual = trans_tx_fail_type; ts->residual = trans_tx_fail_type;
ts->stat = SAS_DATA_UNDERRUN; ts->stat = SAS_DATA_UNDERRUN;
} else if (complete_hdr->dw3 & CMPLT_HDR_IO_IN_TARGET_MSK) { } else if (dw3 & CMPLT_HDR_IO_IN_TARGET_MSK) {
ts->stat = SAS_QUEUE_FULL; ts->stat = SAS_QUEUE_FULL;
slot->abort = 1; slot->abort = 1;
} else { } else {
@ -1606,7 +1728,7 @@ slot_err_v3_hw(struct hisi_hba *hisi_hba, struct sas_task *task,
if (dma_rx_err_type & RX_DATA_LEN_UNDERFLOW_MSK) { if (dma_rx_err_type & RX_DATA_LEN_UNDERFLOW_MSK) {
ts->residual = trans_tx_fail_type; ts->residual = trans_tx_fail_type;
ts->stat = SAS_DATA_UNDERRUN; ts->stat = SAS_DATA_UNDERRUN;
} else if (complete_hdr->dw3 & CMPLT_HDR_IO_IN_TARGET_MSK) { } else if (dw3 & CMPLT_HDR_IO_IN_TARGET_MSK) {
ts->stat = SAS_PHY_DOWN; ts->stat = SAS_PHY_DOWN;
slot->abort = 1; slot->abort = 1;
} else { } else {
@ -1639,6 +1761,7 @@ slot_complete_v3_hw(struct hisi_hba *hisi_hba, struct hisi_sas_slot *slot)
&complete_queue[slot->cmplt_queue_slot]; &complete_queue[slot->cmplt_queue_slot];
unsigned long flags; unsigned long flags;
bool is_internal = slot->is_internal; bool is_internal = slot->is_internal;
u32 dw0, dw1, dw3;
if (unlikely(!task || !task->lldd_task || !task->dev)) if (unlikely(!task || !task->lldd_task || !task->dev))
return -EINVAL; return -EINVAL;
@ -1662,11 +1785,14 @@ slot_complete_v3_hw(struct hisi_hba *hisi_hba, struct hisi_sas_slot *slot)
goto out; goto out;
} }
dw0 = le32_to_cpu(complete_hdr->dw0);
dw1 = le32_to_cpu(complete_hdr->dw1);
dw3 = le32_to_cpu(complete_hdr->dw3);
/* /*
* Use SAS+TMF status codes * Use SAS+TMF status codes
*/ */
switch ((complete_hdr->dw0 & CMPLT_HDR_ABORT_STAT_MSK) switch ((dw0 & CMPLT_HDR_ABORT_STAT_MSK) >> CMPLT_HDR_ABORT_STAT_OFF) {
>> CMPLT_HDR_ABORT_STAT_OFF) {
case STAT_IO_ABORTED: case STAT_IO_ABORTED:
/* this IO has been aborted by abort command */ /* this IO has been aborted by abort command */
ts->stat = SAS_ABORTED_TASK; ts->stat = SAS_ABORTED_TASK;
@ -1689,7 +1815,7 @@ slot_complete_v3_hw(struct hisi_hba *hisi_hba, struct hisi_sas_slot *slot)
} }
/* check for erroneous completion */ /* check for erroneous completion */
if ((complete_hdr->dw0 & CMPLT_HDR_CMPLT_MSK) == 0x3) { if ((dw0 & CMPLT_HDR_CMPLT_MSK) == 0x3) {
u32 *error_info = hisi_sas_status_buf_addr_mem(slot); u32 *error_info = hisi_sas_status_buf_addr_mem(slot);
slot_err_v3_hw(hisi_hba, task, slot); slot_err_v3_hw(hisi_hba, task, slot);
@ -1698,8 +1824,7 @@ slot_complete_v3_hw(struct hisi_hba *hisi_hba, struct hisi_sas_slot *slot)
"CQ hdr: 0x%x 0x%x 0x%x 0x%x " "CQ hdr: 0x%x 0x%x 0x%x 0x%x "
"Error info: 0x%x 0x%x 0x%x 0x%x\n", "Error info: 0x%x 0x%x 0x%x 0x%x\n",
slot->idx, task, sas_dev->device_id, slot->idx, task, sas_dev->device_id,
complete_hdr->dw0, complete_hdr->dw1, dw0, dw1, complete_hdr->act, dw3,
complete_hdr->act, complete_hdr->dw3,
error_info[0], error_info[1], error_info[0], error_info[1],
error_info[2], error_info[3]); error_info[2], error_info[3]);
if (unlikely(slot->abort)) if (unlikely(slot->abort))
@ -1797,11 +1922,13 @@ static void cq_tasklet_v3_hw(unsigned long val)
while (rd_point != wr_point) { while (rd_point != wr_point) {
struct hisi_sas_complete_v3_hdr *complete_hdr; struct hisi_sas_complete_v3_hdr *complete_hdr;
struct device *dev = hisi_hba->dev; struct device *dev = hisi_hba->dev;
u32 dw1;
int iptt; int iptt;
complete_hdr = &complete_queue[rd_point]; complete_hdr = &complete_queue[rd_point];
dw1 = le32_to_cpu(complete_hdr->dw1);
iptt = (complete_hdr->dw1) & CMPLT_HDR_IPTT_MSK; iptt = dw1 & CMPLT_HDR_IPTT_MSK;
if (likely(iptt < HISI_SAS_COMMAND_ENTRIES_V3_HW)) { if (likely(iptt < HISI_SAS_COMMAND_ENTRIES_V3_HW)) {
slot = &hisi_hba->slot_info[iptt]; slot = &hisi_hba->slot_info[iptt];
slot->cmplt_queue_slot = rd_point; slot->cmplt_queue_slot = rd_point;
@ -1878,10 +2005,12 @@ static int interrupt_init_v3_hw(struct hisi_hba *hisi_hba)
for (i = 0; i < hisi_hba->queue_count; i++) { for (i = 0; i < hisi_hba->queue_count; i++) {
struct hisi_sas_cq *cq = &hisi_hba->cq[i]; struct hisi_sas_cq *cq = &hisi_hba->cq[i];
struct tasklet_struct *t = &cq->tasklet; struct tasklet_struct *t = &cq->tasklet;
int nr = hisi_sas_intr_conv ? 16 : 16 + i;
unsigned long irqflags = hisi_sas_intr_conv ? IRQF_SHARED : 0;
rc = devm_request_irq(dev, pci_irq_vector(pdev, i+16), rc = devm_request_irq(dev, pci_irq_vector(pdev, nr),
cq_interrupt_v3_hw, 0, cq_interrupt_v3_hw, irqflags,
DRV_NAME " cq", cq); DRV_NAME " cq", cq);
if (rc) { if (rc) {
dev_err(dev, dev_err(dev,
"could not request cq%d interrupt, rc=%d\n", "could not request cq%d interrupt, rc=%d\n",
@ -1898,8 +2027,9 @@ static int interrupt_init_v3_hw(struct hisi_hba *hisi_hba)
free_cq_irqs: free_cq_irqs:
for (k = 0; k < i; k++) { for (k = 0; k < i; k++) {
struct hisi_sas_cq *cq = &hisi_hba->cq[k]; struct hisi_sas_cq *cq = &hisi_hba->cq[k];
int nr = hisi_sas_intr_conv ? 16 : 16 + k;
free_irq(pci_irq_vector(pdev, k+16), cq); free_irq(pci_irq_vector(pdev, nr), cq);
} }
free_irq(pci_irq_vector(pdev, 11), hisi_hba); free_irq(pci_irq_vector(pdev, 11), hisi_hba);
free_chnl_interrupt: free_chnl_interrupt:
@ -2089,6 +2219,119 @@ static void wait_cmds_complete_timeout_v3_hw(struct hisi_hba *hisi_hba,
dev_dbg(dev, "wait commands complete %dms\n", time); dev_dbg(dev, "wait commands complete %dms\n", time);
} }
static ssize_t intr_conv_v3_hw_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
return scnprintf(buf, PAGE_SIZE, "%u\n", hisi_sas_intr_conv);
}
static DEVICE_ATTR_RO(intr_conv_v3_hw);
static void config_intr_coal_v3_hw(struct hisi_hba *hisi_hba)
{
/* config those registers between enable and disable PHYs */
hisi_sas_stop_phys(hisi_hba);
if (hisi_hba->intr_coal_ticks == 0 ||
hisi_hba->intr_coal_count == 0) {
hisi_sas_write32(hisi_hba, INT_COAL_EN, 0x1);
hisi_sas_write32(hisi_hba, OQ_INT_COAL_TIME, 0x1);
hisi_sas_write32(hisi_hba, OQ_INT_COAL_CNT, 0x1);
} else {
hisi_sas_write32(hisi_hba, INT_COAL_EN, 0x3);
hisi_sas_write32(hisi_hba, OQ_INT_COAL_TIME,
hisi_hba->intr_coal_ticks);
hisi_sas_write32(hisi_hba, OQ_INT_COAL_CNT,
hisi_hba->intr_coal_count);
}
phys_init_v3_hw(hisi_hba);
}
static ssize_t intr_coal_ticks_v3_hw_show(struct device *dev,
struct device_attribute *attr,
char *buf)
{
struct Scsi_Host *shost = class_to_shost(dev);
struct hisi_hba *hisi_hba = shost_priv(shost);
return scnprintf(buf, PAGE_SIZE, "%u\n",
hisi_hba->intr_coal_ticks);
}
static ssize_t intr_coal_ticks_v3_hw_store(struct device *dev,
struct device_attribute *attr,
const char *buf, size_t count)
{
struct Scsi_Host *shost = class_to_shost(dev);
struct hisi_hba *hisi_hba = shost_priv(shost);
u32 intr_coal_ticks;
int ret;
ret = kstrtou32(buf, 10, &intr_coal_ticks);
if (ret) {
dev_err(dev, "Input data of interrupt coalesce unmatch\n");
return -EINVAL;
}
if (intr_coal_ticks >= BIT(24)) {
dev_err(dev, "intr_coal_ticks must be less than 2^24!\n");
return -EINVAL;
}
hisi_hba->intr_coal_ticks = intr_coal_ticks;
config_intr_coal_v3_hw(hisi_hba);
return count;
}
static DEVICE_ATTR_RW(intr_coal_ticks_v3_hw);
static ssize_t intr_coal_count_v3_hw_show(struct device *dev,
struct device_attribute
*attr, char *buf)
{
struct Scsi_Host *shost = class_to_shost(dev);
struct hisi_hba *hisi_hba = shost_priv(shost);
return scnprintf(buf, PAGE_SIZE, "%u\n",
hisi_hba->intr_coal_count);
}
static ssize_t intr_coal_count_v3_hw_store(struct device *dev,
struct device_attribute
*attr, const char *buf, size_t count)
{
struct Scsi_Host *shost = class_to_shost(dev);
struct hisi_hba *hisi_hba = shost_priv(shost);
u32 intr_coal_count;
int ret;
ret = kstrtou32(buf, 10, &intr_coal_count);
if (ret) {
dev_err(dev, "Input data of interrupt coalesce unmatch\n");
return -EINVAL;
}
if (intr_coal_count >= BIT(8)) {
dev_err(dev, "intr_coal_count must be less than 2^8!\n");
return -EINVAL;
}
hisi_hba->intr_coal_count = intr_coal_count;
config_intr_coal_v3_hw(hisi_hba);
return count;
}
static DEVICE_ATTR_RW(intr_coal_count_v3_hw);
static struct device_attribute *host_attrs_v3_hw[] = {
&dev_attr_phy_event_threshold,
&dev_attr_intr_conv_v3_hw,
&dev_attr_intr_coal_ticks_v3_hw,
&dev_attr_intr_coal_count_v3_hw,
NULL
};
static struct scsi_host_template sht_v3_hw = { static struct scsi_host_template sht_v3_hw = {
.name = DRV_NAME, .name = DRV_NAME,
.module = THIS_MODULE, .module = THIS_MODULE,
@ -2100,14 +2343,13 @@ static struct scsi_host_template sht_v3_hw = {
.change_queue_depth = sas_change_queue_depth, .change_queue_depth = sas_change_queue_depth,
.bios_param = sas_bios_param, .bios_param = sas_bios_param,
.this_id = -1, .this_id = -1,
.sg_tablesize = SG_ALL, .sg_tablesize = HISI_SAS_SGE_PAGE_CNT,
.max_sectors = SCSI_DEFAULT_MAX_SECTORS, .max_sectors = SCSI_DEFAULT_MAX_SECTORS,
.use_clustering = ENABLE_CLUSTERING,
.eh_device_reset_handler = sas_eh_device_reset_handler, .eh_device_reset_handler = sas_eh_device_reset_handler,
.eh_target_reset_handler = sas_eh_target_reset_handler, .eh_target_reset_handler = sas_eh_target_reset_handler,
.target_destroy = sas_target_destroy, .target_destroy = sas_target_destroy,
.ioctl = sas_ioctl, .ioctl = sas_ioctl,
.shost_attrs = host_attrs, .shost_attrs = host_attrs_v3_hw,
.tag_alloc_policy = BLK_TAG_ALLOC_RR, .tag_alloc_policy = BLK_TAG_ALLOC_RR,
}; };
@ -2161,6 +2403,12 @@ hisi_sas_shost_alloc_pci(struct pci_dev *pdev)
hisi_hba->shost = shost; hisi_hba->shost = shost;
SHOST_TO_SAS_HA(shost) = &hisi_hba->sha; SHOST_TO_SAS_HA(shost) = &hisi_hba->sha;
if (prot_mask & ~HISI_SAS_PROT_MASK)
dev_err(dev, "unsupported protection mask 0x%x, using default (0x0)\n",
prot_mask);
else
hisi_hba->prot_mask = prot_mask;
timer_setup(&hisi_hba->timer, NULL, 0); timer_setup(&hisi_hba->timer, NULL, 0);
if (hisi_sas_get_fw_info(hisi_hba) < 0) if (hisi_sas_get_fw_info(hisi_hba) < 0)
@ -2199,14 +2447,11 @@ hisi_sas_v3_probe(struct pci_dev *pdev, const struct pci_device_id *id)
if (rc) if (rc)
goto err_out_disable_device; goto err_out_disable_device;
if ((pci_set_dma_mask(pdev, DMA_BIT_MASK(64)) != 0) || if (dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(64)) ||
(pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(64)) != 0)) { dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32))) {
if ((pci_set_dma_mask(pdev, DMA_BIT_MASK(32)) != 0) || dev_err(dev, "No usable DMA addressing method\n");
(pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32)) != 0)) { rc = -EIO;
dev_err(dev, "No usable DMA addressing method\n"); goto err_out_regions;
rc = -EIO;
goto err_out_regions;
}
} }
shost = hisi_sas_shost_alloc_pci(pdev); shost = hisi_sas_shost_alloc_pci(pdev);
@ -2245,7 +2490,6 @@ hisi_sas_v3_probe(struct pci_dev *pdev, const struct pci_device_id *id)
shost->max_lun = ~0; shost->max_lun = ~0;
shost->max_channel = 1; shost->max_channel = 1;
shost->max_cmd_len = 16; shost->max_cmd_len = 16;
shost->sg_tablesize = min_t(u16, SG_ALL, HISI_SAS_SGE_PAGE_CNT);
shost->can_queue = hisi_hba->hw->max_command_entries - shost->can_queue = hisi_hba->hw->max_command_entries -
HISI_SAS_RESERVED_IPTT_CNT; HISI_SAS_RESERVED_IPTT_CNT;
shost->cmd_per_lun = hisi_hba->hw->max_command_entries - shost->cmd_per_lun = hisi_hba->hw->max_command_entries -
@ -2275,6 +2519,12 @@ hisi_sas_v3_probe(struct pci_dev *pdev, const struct pci_device_id *id)
if (rc) if (rc)
goto err_out_register_ha; goto err_out_register_ha;
if (hisi_hba->prot_mask) {
dev_info(dev, "Registering for DIF/DIX prot_mask=0x%x\n",
prot_mask);
scsi_host_set_prot(hisi_hba->shost, prot_mask);
}
scsi_scan_host(shost); scsi_scan_host(shost);
return 0; return 0;
@ -2301,8 +2551,9 @@ hisi_sas_v3_destroy_irqs(struct pci_dev *pdev, struct hisi_hba *hisi_hba)
free_irq(pci_irq_vector(pdev, 11), hisi_hba); free_irq(pci_irq_vector(pdev, 11), hisi_hba);
for (i = 0; i < hisi_hba->queue_count; i++) { for (i = 0; i < hisi_hba->queue_count; i++) {
struct hisi_sas_cq *cq = &hisi_hba->cq[i]; struct hisi_sas_cq *cq = &hisi_hba->cq[i];
int nr = hisi_sas_intr_conv ? 16 : 16 + i;
free_irq(pci_irq_vector(pdev, i+16), cq); free_irq(pci_irq_vector(pdev, nr), cq);
} }
pci_free_irq_vectors(pdev); pci_free_irq_vectors(pdev);
} }
@ -2529,7 +2780,7 @@ static int hisi_sas_v3_suspend(struct pci_dev *pdev, pm_message_t state)
struct hisi_hba *hisi_hba = sha->lldd_ha; struct hisi_hba *hisi_hba = sha->lldd_ha;
struct device *dev = hisi_hba->dev; struct device *dev = hisi_hba->dev;
struct Scsi_Host *shost = hisi_hba->shost; struct Scsi_Host *shost = hisi_hba->shost;
u32 device_state; pci_power_t device_state;
int rc; int rc;
if (!pdev->pm_cap) { if (!pdev->pm_cap) {
@ -2575,7 +2826,7 @@ static int hisi_sas_v3_resume(struct pci_dev *pdev)
struct Scsi_Host *shost = hisi_hba->shost; struct Scsi_Host *shost = hisi_hba->shost;
struct device *dev = hisi_hba->dev; struct device *dev = hisi_hba->dev;
unsigned int rc; unsigned int rc;
u32 device_state = pdev->current_state; pci_power_t device_state = pdev->current_state;
dev_warn(dev, "resuming from operating state [D%d]\n", dev_warn(dev, "resuming from operating state [D%d]\n",
device_state); device_state);
@ -2624,6 +2875,7 @@ static struct pci_driver sas_v3_pci_driver = {
}; };
module_pci_driver(sas_v3_pci_driver); module_pci_driver(sas_v3_pci_driver);
module_param_named(intr_conv, hisi_sas_intr_conv, bool, 0444);
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");
MODULE_AUTHOR("John Garry <john.garry@huawei.com>"); MODULE_AUTHOR("John Garry <john.garry@huawei.com>");

View File

@ -416,7 +416,6 @@ struct Scsi_Host *scsi_host_alloc(struct scsi_host_template *sht, int privsize)
shost->sg_prot_tablesize = sht->sg_prot_tablesize; shost->sg_prot_tablesize = sht->sg_prot_tablesize;
shost->cmd_per_lun = sht->cmd_per_lun; shost->cmd_per_lun = sht->cmd_per_lun;
shost->unchecked_isa_dma = sht->unchecked_isa_dma; shost->unchecked_isa_dma = sht->unchecked_isa_dma;
shost->use_clustering = sht->use_clustering;
shost->no_write_same = sht->no_write_same; shost->no_write_same = sht->no_write_same;
if (shost_eh_deadline == -1 || !sht->eh_host_reset_handler) if (shost_eh_deadline == -1 || !sht->eh_host_reset_handler)
@ -449,6 +448,11 @@ struct Scsi_Host *scsi_host_alloc(struct scsi_host_template *sht, int privsize)
else else
shost->max_sectors = SCSI_DEFAULT_MAX_SECTORS; shost->max_sectors = SCSI_DEFAULT_MAX_SECTORS;
if (sht->max_segment_size)
shost->max_segment_size = sht->max_segment_size;
else
shost->max_segment_size = BLK_MAX_SEGMENT_SIZE;
/* /*
* assume a 4GB boundary, if not set * assume a 4GB boundary, if not set
*/ */

View File

@ -965,7 +965,6 @@ static struct scsi_host_template hpsa_driver_template = {
.scan_finished = hpsa_scan_finished, .scan_finished = hpsa_scan_finished,
.change_queue_depth = hpsa_change_queue_depth, .change_queue_depth = hpsa_change_queue_depth,
.this_id = -1, .this_id = -1,
.use_clustering = ENABLE_CLUSTERING,
.eh_device_reset_handler = hpsa_eh_device_reset_handler, .eh_device_reset_handler = hpsa_eh_device_reset_handler,
.ioctl = hpsa_ioctl, .ioctl = hpsa_ioctl,
.slave_alloc = hpsa_slave_alloc, .slave_alloc = hpsa_slave_alloc,
@ -4663,6 +4662,7 @@ static int fixup_ioaccel_cdb(u8 *cdb, int *cdb_len)
case WRITE_6: case WRITE_6:
case WRITE_12: case WRITE_12:
is_write = 1; is_write = 1;
/* fall through */
case READ_6: case READ_6:
case READ_12: case READ_12:
if (*cdb_len == 6) { if (*cdb_len == 6) {
@ -5093,6 +5093,7 @@ static int hpsa_scsi_ioaccel_raid_map(struct ctlr_info *h,
switch (cmd->cmnd[0]) { switch (cmd->cmnd[0]) {
case WRITE_6: case WRITE_6:
is_write = 1; is_write = 1;
/* fall through */
case READ_6: case READ_6:
first_block = (((cmd->cmnd[1] & 0x1F) << 16) | first_block = (((cmd->cmnd[1] & 0x1F) << 16) |
(cmd->cmnd[2] << 8) | (cmd->cmnd[2] << 8) |
@ -5103,6 +5104,7 @@ static int hpsa_scsi_ioaccel_raid_map(struct ctlr_info *h,
break; break;
case WRITE_10: case WRITE_10:
is_write = 1; is_write = 1;
/* fall through */
case READ_10: case READ_10:
first_block = first_block =
(((u64) cmd->cmnd[2]) << 24) | (((u64) cmd->cmnd[2]) << 24) |
@ -5115,6 +5117,7 @@ static int hpsa_scsi_ioaccel_raid_map(struct ctlr_info *h,
break; break;
case WRITE_12: case WRITE_12:
is_write = 1; is_write = 1;
/* fall through */
case READ_12: case READ_12:
first_block = first_block =
(((u64) cmd->cmnd[2]) << 24) | (((u64) cmd->cmnd[2]) << 24) |
@ -5129,6 +5132,7 @@ static int hpsa_scsi_ioaccel_raid_map(struct ctlr_info *h,
break; break;
case WRITE_16: case WRITE_16:
is_write = 1; is_write = 1;
/* fall through */
case READ_16: case READ_16:
first_block = first_block =
(((u64) cmd->cmnd[2]) << 56) | (((u64) cmd->cmnd[2]) << 56) |

View File

@ -1180,7 +1180,6 @@ static struct scsi_host_template driver_template = {
.eh_host_reset_handler = hptiop_reset, .eh_host_reset_handler = hptiop_reset,
.info = hptiop_info, .info = hptiop_info,
.emulated = 0, .emulated = 0,
.use_clustering = ENABLE_CLUSTERING,
.proc_name = driver_name, .proc_name = driver_name,
.shost_attrs = hptiop_attrs, .shost_attrs = hptiop_attrs,
.slave_configure = hptiop_slave_config, .slave_configure = hptiop_slave_config,
@ -1309,11 +1308,11 @@ static int hptiop_probe(struct pci_dev *pcidev, const struct pci_device_id *id)
/* Enable 64bit DMA if possible */ /* Enable 64bit DMA if possible */
iop_ops = (struct hptiop_adapter_ops *)id->driver_data; iop_ops = (struct hptiop_adapter_ops *)id->driver_data;
if (pci_set_dma_mask(pcidev, DMA_BIT_MASK(iop_ops->hw_dma_bit_mask))) { if (dma_set_mask(&pcidev->dev,
if (pci_set_dma_mask(pcidev, DMA_BIT_MASK(32))) { DMA_BIT_MASK(iop_ops->hw_dma_bit_mask)) ||
printk(KERN_ERR "hptiop: fail to set dma_mask\n"); dma_set_mask(&pcidev->dev, DMA_BIT_MASK(32))) {
goto disable_pci_device; printk(KERN_ERR "hptiop: fail to set dma_mask\n");
} goto disable_pci_device;
} }
if (pci_request_regions(pcidev, driver_name)) { if (pci_request_regions(pcidev, driver_name)) {

View File

@ -3100,7 +3100,6 @@ static struct scsi_host_template driver_template = {
.this_id = -1, .this_id = -1,
.sg_tablesize = SG_ALL, .sg_tablesize = SG_ALL,
.max_sectors = IBMVFC_MAX_SECTORS, .max_sectors = IBMVFC_MAX_SECTORS,
.use_clustering = ENABLE_CLUSTERING,
.shost_attrs = ibmvfc_attrs, .shost_attrs = ibmvfc_attrs,
.track_queue_depth = 1, .track_queue_depth = 1,
}; };

View File

@ -2079,7 +2079,6 @@ static struct scsi_host_template driver_template = {
.can_queue = IBMVSCSI_MAX_REQUESTS_DEFAULT, .can_queue = IBMVSCSI_MAX_REQUESTS_DEFAULT,
.this_id = -1, .this_id = -1,
.sg_tablesize = SG_ALL, .sg_tablesize = SG_ALL,
.use_clustering = ENABLE_CLUSTERING,
.shost_attrs = ibmvscsi_attrs, .shost_attrs = ibmvscsi_attrs,
}; };

View File

@ -3695,11 +3695,6 @@ static int ibmvscsis_get_system_info(void)
return 0; return 0;
} }
static char *ibmvscsis_get_fabric_name(void)
{
return "ibmvscsis";
}
static char *ibmvscsis_get_fabric_wwn(struct se_portal_group *se_tpg) static char *ibmvscsis_get_fabric_wwn(struct se_portal_group *se_tpg)
{ {
struct ibmvscsis_tport *tport = struct ibmvscsis_tport *tport =
@ -4044,9 +4039,8 @@ static struct configfs_attribute *ibmvscsis_tpg_attrs[] = {
static const struct target_core_fabric_ops ibmvscsis_ops = { static const struct target_core_fabric_ops ibmvscsis_ops = {
.module = THIS_MODULE, .module = THIS_MODULE,
.name = "ibmvscsis", .fabric_name = "ibmvscsis",
.max_data_sg_nents = MAX_TXU / PAGE_SIZE, .max_data_sg_nents = MAX_TXU / PAGE_SIZE,
.get_fabric_name = ibmvscsis_get_fabric_name,
.tpg_get_wwn = ibmvscsis_get_fabric_wwn, .tpg_get_wwn = ibmvscsis_get_fabric_wwn,
.tpg_get_tag = ibmvscsis_get_tag, .tpg_get_tag = ibmvscsis_get_tag,
.tpg_get_default_depth = ibmvscsis_get_default_depth, .tpg_get_default_depth = ibmvscsis_get_default_depth,

View File

@ -1110,7 +1110,6 @@ static struct scsi_host_template imm_template = {
.bios_param = imm_biosparam, .bios_param = imm_biosparam,
.this_id = 7, .this_id = 7,
.sg_tablesize = SG_ALL, .sg_tablesize = SG_ALL,
.use_clustering = ENABLE_CLUSTERING,
.can_queue = 1, .can_queue = 1,
.slave_alloc = imm_adjust_queue, .slave_alloc = imm_adjust_queue,
}; };

View File

@ -2817,7 +2817,6 @@ static struct scsi_host_template initio_template = {
.can_queue = MAX_TARGETS * i91u_MAXQUEUE, .can_queue = MAX_TARGETS * i91u_MAXQUEUE,
.this_id = 1, .this_id = 1,
.sg_tablesize = SG_ALL, .sg_tablesize = SG_ALL,
.use_clustering = ENABLE_CLUSTERING,
}; };
static int initio_probe_one(struct pci_dev *pdev, static int initio_probe_one(struct pci_dev *pdev,
@ -2840,7 +2839,7 @@ static int initio_probe_one(struct pci_dev *pdev,
reg = 0; reg = 0;
bios_seg = (bios_seg << 8) + ((u16) ((reg & 0xFF00) >> 8)); bios_seg = (bios_seg << 8) + ((u16) ((reg & 0xFF00) >> 8));
if (pci_set_dma_mask(pdev, DMA_BIT_MASK(32))) { if (dma_set_mask(&pdev->dev, DMA_BIT_MASK(32))) {
printk(KERN_WARNING "i91u: Could not set 32 bit DMA mask\n"); printk(KERN_WARNING "i91u: Could not set 32 bit DMA mask\n");
error = -ENODEV; error = -ENODEV;
goto out_disable_device; goto out_disable_device;

View File

@ -6754,7 +6754,6 @@ static struct scsi_host_template driver_template = {
.sg_tablesize = IPR_MAX_SGLIST, .sg_tablesize = IPR_MAX_SGLIST,
.max_sectors = IPR_IOA_MAX_SECTORS, .max_sectors = IPR_IOA_MAX_SECTORS,
.cmd_per_lun = IPR_MAX_CMD_PER_LUN, .cmd_per_lun = IPR_MAX_CMD_PER_LUN,
.use_clustering = ENABLE_CLUSTERING,
.shost_attrs = ipr_ioa_attrs, .shost_attrs = ipr_ioa_attrs,
.sdev_attrs = ipr_dev_attrs, .sdev_attrs = ipr_dev_attrs,
.proc_name = IPR_NAME, .proc_name = IPR_NAME,

Some files were not shown because too many files have changed in this diff Show More