SCSI misc on 20220324

This series consists of the usual driver updates (qla2xxx, pm8001,
 libsas, smartpqi, scsi_debug, lpfc, iscsi, mpi3mr) plus minor updates
 and bug fixes.  The high blast radius core update is the removal of
 write same, which affects block and several non-SCSI devices.  The
 other big change, which is more local, is the removal of the SCSI
 pointer.
 
 Signed-off-by: James E.J. Bottomley <jejb@linux.ibm.com>
 -----BEGIN PGP SIGNATURE-----
 
 iJwEABMIAEQWIQTnYEDbdso9F2cI+arnQslM7pishQUCYjzDQyYcamFtZXMuYm90
 dG9tbGV5QGhhbnNlbnBhcnRuZXJzaGlwLmNvbQAKCRDnQslM7pishQMYAQDEWUGV
 6U0+736AHVtOfiMNfiRN79B1HfXVoHvemnPcTwD/UlndwFfy/3GGOtoZmqEpc73J
 Ec1HDuUCE18H1H2QAh0=
 =/Ty9
 -----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 series consists of the usual driver updates (qla2xxx, pm8001,
  libsas, smartpqi, scsi_debug, lpfc, iscsi, mpi3mr) plus minor updates
  and bug fixes.

  The high blast radius core update is the removal of write same, which
  affects block and several non-SCSI devices. The other big change,
  which is more local, is the removal of the SCSI pointer"

* tag 'scsi-misc' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi: (281 commits)
  scsi: scsi_ioctl: Drop needless assignment in sg_io()
  scsi: bsg: Drop needless assignment in scsi_bsg_sg_io_fn()
  scsi: lpfc: Copyright updates for 14.2.0.0 patches
  scsi: lpfc: Update lpfc version to 14.2.0.0
  scsi: lpfc: SLI path split: Refactor BSG paths
  scsi: lpfc: SLI path split: Refactor Abort paths
  scsi: lpfc: SLI path split: Refactor SCSI paths
  scsi: lpfc: SLI path split: Refactor CT paths
  scsi: lpfc: SLI path split: Refactor misc ELS paths
  scsi: lpfc: SLI path split: Refactor VMID paths
  scsi: lpfc: SLI path split: Refactor FDISC paths
  scsi: lpfc: SLI path split: Refactor LS_RJT paths
  scsi: lpfc: SLI path split: Refactor LS_ACC paths
  scsi: lpfc: SLI path split: Refactor the RSCN/SCR/RDF/EDC/FARPR paths
  scsi: lpfc: SLI path split: Refactor PLOGI/PRLI/ADISC/LOGO paths
  scsi: lpfc: SLI path split: Refactor base ELS paths and the FLOGI path
  scsi: lpfc: SLI path split: Introduce lpfc_prep_wqe
  scsi: lpfc: SLI path split: Refactor fast and slow paths to native SLI4
  scsi: lpfc: SLI path split: Refactor lpfc_iocbq
  scsi: lpfc: Use kcalloc()
  ...
This commit is contained in:
Linus Torvalds 2022-03-24 19:37:53 -07:00
commit 6f2689a766
298 changed files with 8546 additions and 8344 deletions

View File

@ -207,7 +207,6 @@ Management Functions (TMFs) described in SAM::
/* Task Management Functions. Must be called from process context. */ /* Task Management Functions. Must be called from process context. */
int (*lldd_abort_task)(struct sas_task *); int (*lldd_abort_task)(struct sas_task *);
int (*lldd_abort_task_set)(struct domain_device *, u8 *lun); int (*lldd_abort_task_set)(struct domain_device *, u8 *lun);
int (*lldd_clear_aca)(struct domain_device *, u8 *lun);
int (*lldd_clear_task_set)(struct domain_device *, u8 *lun); int (*lldd_clear_task_set)(struct domain_device *, u8 *lun);
int (*lldd_I_T_nexus_reset)(struct domain_device *); int (*lldd_I_T_nexus_reset)(struct domain_device *);
int (*lldd_lu_reset)(struct domain_device *, u8 *lun); int (*lldd_lu_reset)(struct domain_device *, u8 *lun);
@ -262,7 +261,6 @@ can look like this (called last thing from probe())
my_ha->sas_ha.lldd_abort_task = my_abort_task; my_ha->sas_ha.lldd_abort_task = my_abort_task;
my_ha->sas_ha.lldd_abort_task_set = my_abort_task_set; my_ha->sas_ha.lldd_abort_task_set = my_abort_task_set;
my_ha->sas_ha.lldd_clear_aca = my_clear_aca;
my_ha->sas_ha.lldd_clear_task_set = my_clear_task_set; my_ha->sas_ha.lldd_clear_task_set = my_clear_task_set;
my_ha->sas_ha.lldd_I_T_nexus_reset= NULL; (2) my_ha->sas_ha.lldd_I_T_nexus_reset= NULL; (2)
my_ha->sas_ha.lldd_lu_reset = my_lu_reset; my_ha->sas_ha.lldd_lu_reset = my_lu_reset;

View File

@ -95,19 +95,18 @@ function
- BLK_EH_RESET_TIMER - BLK_EH_RESET_TIMER
This indicates that more time is required to finish the This indicates that more time is required to finish the
command. Timer is restarted. This action is counted as a command. Timer is restarted.
retry and only allowed scmd->allowed + 1(!) times. Once the
limit is reached, action for BLK_EH_DONE is taken instead.
- BLK_EH_DONE - BLK_EH_DONE
eh_timed_out() callback did not handle the command. eh_timed_out() callback did not handle the command.
Step #2 is taken. Step #2 is taken.
2. scsi_abort_command() is invoked to schedule an asynchrous abort. 2. scsi_abort_command() is invoked to schedule an asynchronous abort which may
Asynchronous abort are not invoked for commands which the issue a retry scmd->allowed + 1 times. Asynchronous aborts are not invoked
SCSI_EH_ABORT_SCHEDULED flag is set (this indicates that the command for commands for which the SCSI_EH_ABORT_SCHEDULED flag is set (this
already had been aborted once, and this is a retry which failed), indicates that the command already had been aborted once, and this is a
or when the EH deadline is expired. In these case Step #3 is taken. retry which failed), when retries are exceeded, or when the EH deadline is
expired. In these cases Step #3 is taken.
3. scsi_eh_scmd_add(scmd, SCSI_EH_CANCEL_CMD) is invoked for the 3. scsi_eh_scmd_add(scmd, SCSI_EH_CANCEL_CMD) is invoked for the
command. See [1-4] for more information. command. See [1-4] for more information.

View File

@ -10,8 +10,8 @@ Universal Flash Storage
1. Overview 1. Overview
2. UFS Architecture Overview 2. UFS Architecture Overview
2.1 Application Layer 2.1 Application Layer
2.2 UFS Transport Protocol(UTP) layer 2.2 UFS Transport Protocol (UTP) layer
2.3 UFS Interconnect(UIC) Layer 2.3 UFS Interconnect (UIC) Layer
3. UFSHCD Overview 3. UFSHCD Overview
3.1 UFS controller initialization 3.1 UFS controller initialization
3.2 UTP Transfer requests 3.2 UTP Transfer requests
@ -22,15 +22,15 @@ Universal Flash Storage
1. Overview 1. Overview
=========== ===========
Universal Flash Storage(UFS) is a storage specification for flash devices. Universal Flash Storage (UFS) is a storage specification for flash devices.
It is aimed to provide a universal storage interface for both It aims to provide a universal storage interface for both
embedded and removable flash memory based storage in mobile embedded and removable flash memory-based storage in mobile
devices such as smart phones and tablet computers. The specification devices such as smart phones and tablet computers. The specification
is defined by JEDEC Solid State Technology Association. UFS is based is defined by JEDEC Solid State Technology Association. UFS is based
on MIPI M-PHY physical layer standard. UFS uses MIPI M-PHY as the on the MIPI M-PHY physical layer standard. UFS uses MIPI M-PHY as the
physical layer and MIPI Unipro as the link layer. physical layer and MIPI Unipro as the link layer.
The main goals of UFS is to provide: The main goals of UFS are to provide:
* Optimized performance: * Optimized performance:
@ -53,17 +53,17 @@ The main goals of UFS is to provide:
UFS has a layered communication architecture which is based on SCSI UFS has a layered communication architecture which is based on SCSI
SAM-5 architectural model. SAM-5 architectural model.
UFS communication architecture consists of following layers, UFS communication architecture consists of the following layers.
2.1 Application Layer 2.1 Application Layer
--------------------- ---------------------
The Application layer is composed of UFS command set layer(UCS), The Application layer is composed of the UFS command set layer (UCS),
Task Manager and Device manager. The UFS interface is designed to be Task Manager and Device manager. The UFS interface is designed to be
protocol agnostic, however SCSI has been selected as a baseline protocol agnostic, however SCSI has been selected as a baseline
protocol for versions 1.0 and 1.1 of UFS protocol layer. protocol for versions 1.0 and 1.1 of the UFS protocol layer.
UFS supports subset of SCSI commands defined by SPC-4 and SBC-3. UFS supports a subset of SCSI commands defined by SPC-4 and SBC-3.
* UCS: * UCS:
It handles SCSI commands supported by UFS specification. It handles SCSI commands supported by UFS specification.
@ -78,10 +78,10 @@ UFS communication architecture consists of following layers,
requests which are used to modify and retrieve configuration requests which are used to modify and retrieve configuration
information of the device. information of the device.
2.2 UFS Transport Protocol(UTP) layer 2.2 UFS Transport Protocol (UTP) layer
------------------------------------- --------------------------------------
UTP layer provides services for The UTP layer provides services for
the higher layers through Service Access Points. UTP defines 3 the higher layers through Service Access Points. UTP defines 3
service access points for higher layers. service access points for higher layers.
@ -89,19 +89,19 @@ UFS communication architecture consists of following layers,
manager for device level operations. These device level operations manager for device level operations. These device level operations
are done through query requests. are done through query requests.
* UTP_CMD_SAP: Command service access point is exposed to UFS command * UTP_CMD_SAP: Command service access point is exposed to UFS command
set layer(UCS) to transport commands. set layer (UCS) to transport commands.
* UTP_TM_SAP: Task management service access point is exposed to task * UTP_TM_SAP: Task management service access point is exposed to task
manager to transport task management functions. manager to transport task management functions.
UTP transports messages through UFS protocol information unit(UPIU). UTP transports messages through UFS protocol information unit (UPIU).
2.3 UFS Interconnect(UIC) Layer 2.3 UFS Interconnect (UIC) Layer
------------------------------- --------------------------------
UIC is the lowest layer of UFS layered architecture. It handles UIC is the lowest layer of the UFS layered architecture. It handles
connection between UFS host and UFS device. UIC consists of the connection between UFS host and UFS device. UIC consists of
MIPI UniPro and MIPI M-PHY. UIC provides 2 service access points MIPI UniPro and MIPI M-PHY. UIC provides 2 service access points
to upper layer, to upper layer:
* UIC_SAP: To transport UPIU between UFS host and UFS device. * UIC_SAP: To transport UPIU between UFS host and UFS device.
* UIO_SAP: To issue commands to Unipro layers. * UIO_SAP: To issue commands to Unipro layers.
@ -110,25 +110,25 @@ UFS communication architecture consists of following layers,
3. UFSHCD Overview 3. UFSHCD Overview
================== ==================
The UFS host controller driver is based on Linux SCSI Framework. The UFS host controller driver is based on the Linux SCSI Framework.
UFSHCD is a low level device driver which acts as an interface between UFSHCD is a low-level device driver which acts as an interface between
SCSI Midlayer and PCIe based UFS host controllers. the SCSI Midlayer and PCIe-based UFS host controllers.
The current UFSHCD implementation supports following functionality, The current UFSHCD implementation supports the following functionality:
3.1 UFS controller initialization 3.1 UFS controller initialization
--------------------------------- ---------------------------------
The initialization module brings UFS host controller to active state The initialization module brings the UFS host controller to active state
and prepares the controller to transfer commands/response between and prepares the controller to transfer commands/responses between
UFSHCD and UFS device. UFSHCD and UFS device.
3.2 UTP Transfer requests 3.2 UTP Transfer requests
------------------------- -------------------------
Transfer request handling module of UFSHCD receives SCSI commands Transfer request handling module of UFSHCD receives SCSI commands
from SCSI Midlayer, forms UPIUs and issues the UPIUs to UFS Host from the SCSI Midlayer, forms UPIUs and issues the UPIUs to the UFS Host
controller. Also, the module decodes, responses received from UFS controller. Also, the module decodes responses received from the UFS
host controller in the form of UPIUs and intimates the SCSI Midlayer host controller in the form of UPIUs and intimates the SCSI Midlayer
of the status of the command. of the status of the command.
@ -136,19 +136,19 @@ The current UFSHCD implementation supports following functionality,
---------------------- ----------------------
Error handling module handles Host controller fatal errors, Error handling module handles Host controller fatal errors,
Device fatal errors and UIC interconnect layer related errors. Device fatal errors and UIC interconnect layer-related errors.
3.4 SCSI Error handling 3.4 SCSI Error handling
----------------------- -----------------------
This is done through UFSHCD SCSI error handling routines registered This is done through UFSHCD SCSI error handling routines registered
with SCSI Midlayer. Examples of some of the error handling commands with the SCSI Midlayer. Examples of some of the error handling commands
issues by SCSI Midlayer are Abort task, Lun reset and host reset. issues by the SCSI Midlayer are Abort task, LUN reset and host reset.
UFSHCD Routines to perform these tasks are registered with UFSHCD Routines to perform these tasks are registered with
SCSI Midlayer through .eh_abort_handler, .eh_device_reset_handler and SCSI Midlayer through .eh_abort_handler, .eh_device_reset_handler and
.eh_host_reset_handler. .eh_host_reset_handler.
In this version of UFSHCD Query requests and power management In this version of UFSHCD, Query requests and power management
functionality are not implemented. functionality are not implemented.
4. BSG Support 4. BSG Support
@ -182,14 +182,14 @@ If you wish to read or write a descriptor, use the appropriate xferp of
sg_io_v4. sg_io_v4.
The userspace tool that interacts with the ufs-bsg endpoint and uses its The userspace tool that interacts with the ufs-bsg endpoint and uses its
upiu-based protocol is available at: UPIU-based protocol is available at:
https://github.com/westerndigitalcorporation/ufs-tool https://github.com/westerndigitalcorporation/ufs-tool
For more detailed information about the tool and its supported For more detailed information about the tool and its supported
features, please see the tool's README. features, please see the tool's README.
UFS Specifications can be found at: UFS specifications can be found at:
- UFS - http://www.jedec.org/sites/default/files/docs/JESD220.pdf - UFS - http://www.jedec.org/sites/default/files/docs/JESD220.pdf
- UFSHCI - http://www.jedec.org/sites/default/files/docs/JESD223.pdf - UFSHCI - http://www.jedec.org/sites/default/files/docs/JESD223.pdf

View File

@ -123,7 +123,6 @@ static const char *const blk_op_name[] = {
REQ_OP_NAME(ZONE_CLOSE), REQ_OP_NAME(ZONE_CLOSE),
REQ_OP_NAME(ZONE_FINISH), REQ_OP_NAME(ZONE_FINISH),
REQ_OP_NAME(ZONE_APPEND), REQ_OP_NAME(ZONE_APPEND),
REQ_OP_NAME(WRITE_SAME),
REQ_OP_NAME(WRITE_ZEROES), REQ_OP_NAME(WRITE_ZEROES),
REQ_OP_NAME(DRV_IN), REQ_OP_NAME(DRV_IN),
REQ_OP_NAME(DRV_OUT), REQ_OP_NAME(DRV_OUT),
@ -828,10 +827,6 @@ void submit_bio_noacct(struct bio *bio)
if (!blk_queue_secure_erase(q)) if (!blk_queue_secure_erase(q))
goto not_supported; goto not_supported;
break; break;
case REQ_OP_WRITE_SAME:
if (!q->limits.max_write_same_sectors)
goto not_supported;
break;
case REQ_OP_ZONE_APPEND: case REQ_OP_ZONE_APPEND:
status = blk_check_zone_append(q, bio); status = blk_check_zone_append(q, bio);
if (status != BLK_STS_OK) if (status != BLK_STS_OK)
@ -903,13 +898,7 @@ void submit_bio(struct bio *bio)
* go through the normal accounting stuff before submission. * go through the normal accounting stuff before submission.
*/ */
if (bio_has_data(bio)) { if (bio_has_data(bio)) {
unsigned int count; unsigned int count = bio_sectors(bio);
if (unlikely(bio_op(bio) == REQ_OP_WRITE_SAME))
count = queue_logical_block_size(
bdev_get_queue(bio->bi_bdev)) >> 9;
else
count = bio_sectors(bio);
if (op_is_write(bio_op(bio))) { if (op_is_write(bio_op(bio))) {
count_vm_events(PGPGOUT, count); count_vm_events(PGPGOUT, count);

View File

@ -132,94 +132,6 @@ int blkdev_issue_discard(struct block_device *bdev, sector_t sector,
} }
EXPORT_SYMBOL(blkdev_issue_discard); EXPORT_SYMBOL(blkdev_issue_discard);
/**
* __blkdev_issue_write_same - generate number of bios with same page
* @bdev: target blockdev
* @sector: start sector
* @nr_sects: number of sectors to write
* @gfp_mask: memory allocation flags (for bio_alloc)
* @page: page containing data to write
* @biop: pointer to anchor bio
*
* Description:
* Generate and issue number of bios(REQ_OP_WRITE_SAME) with same page.
*/
static int __blkdev_issue_write_same(struct block_device *bdev, sector_t sector,
sector_t nr_sects, gfp_t gfp_mask, struct page *page,
struct bio **biop)
{
struct request_queue *q = bdev_get_queue(bdev);
unsigned int max_write_same_sectors;
struct bio *bio = *biop;
sector_t bs_mask;
if (bdev_read_only(bdev))
return -EPERM;
bs_mask = (bdev_logical_block_size(bdev) >> 9) - 1;
if ((sector | nr_sects) & bs_mask)
return -EINVAL;
if (!bdev_write_same(bdev))
return -EOPNOTSUPP;
/* Ensure that max_write_same_sectors doesn't overflow bi_size */
max_write_same_sectors = bio_allowed_max_sectors(q);
while (nr_sects) {
bio = blk_next_bio(bio, bdev, 1, REQ_OP_WRITE_SAME, gfp_mask);
bio->bi_iter.bi_sector = sector;
bio->bi_vcnt = 1;
bio->bi_io_vec->bv_page = page;
bio->bi_io_vec->bv_offset = 0;
bio->bi_io_vec->bv_len = bdev_logical_block_size(bdev);
if (nr_sects > max_write_same_sectors) {
bio->bi_iter.bi_size = max_write_same_sectors << 9;
nr_sects -= max_write_same_sectors;
sector += max_write_same_sectors;
} else {
bio->bi_iter.bi_size = nr_sects << 9;
nr_sects = 0;
}
cond_resched();
}
*biop = bio;
return 0;
}
/**
* blkdev_issue_write_same - queue a write same operation
* @bdev: target blockdev
* @sector: start sector
* @nr_sects: number of sectors to write
* @gfp_mask: memory allocation flags (for bio_alloc)
* @page: page containing data
*
* Description:
* Issue a write same request for the sectors in question.
*/
int blkdev_issue_write_same(struct block_device *bdev, sector_t sector,
sector_t nr_sects, gfp_t gfp_mask,
struct page *page)
{
struct bio *bio = NULL;
struct blk_plug plug;
int ret;
blk_start_plug(&plug);
ret = __blkdev_issue_write_same(bdev, sector, nr_sects, gfp_mask, page,
&bio);
if (ret == 0 && bio) {
ret = submit_bio_wait(bio);
bio_put(bio);
}
blk_finish_plug(&plug);
return ret;
}
EXPORT_SYMBOL(blkdev_issue_write_same);
static int __blkdev_issue_write_zeroes(struct block_device *bdev, static int __blkdev_issue_write_zeroes(struct block_device *bdev,
sector_t sector, sector_t nr_sects, gfp_t gfp_mask, sector_t sector, sector_t nr_sects, gfp_t gfp_mask,
struct bio **biop, unsigned flags) struct bio **biop, unsigned flags)

View File

@ -153,22 +153,6 @@ static struct bio *blk_bio_write_zeroes_split(struct request_queue *q,
return bio_split(bio, q->limits.max_write_zeroes_sectors, GFP_NOIO, bs); return bio_split(bio, q->limits.max_write_zeroes_sectors, GFP_NOIO, bs);
} }
static struct bio *blk_bio_write_same_split(struct request_queue *q,
struct bio *bio,
struct bio_set *bs,
unsigned *nsegs)
{
*nsegs = 1;
if (!q->limits.max_write_same_sectors)
return NULL;
if (bio_sectors(bio) <= q->limits.max_write_same_sectors)
return NULL;
return bio_split(bio, q->limits.max_write_same_sectors, GFP_NOIO, bs);
}
/* /*
* Return the maximum number of sectors from the start of a bio that may be * Return the maximum number of sectors from the start of a bio that may be
* submitted as a single request to a block device. If enough sectors remain, * submitted as a single request to a block device. If enough sectors remain,
@ -352,10 +336,6 @@ void __blk_queue_split(struct request_queue *q, struct bio **bio,
split = blk_bio_write_zeroes_split(q, *bio, &q->bio_split, split = blk_bio_write_zeroes_split(q, *bio, &q->bio_split,
nr_segs); nr_segs);
break; break;
case REQ_OP_WRITE_SAME:
split = blk_bio_write_same_split(q, *bio, &q->bio_split,
nr_segs);
break;
default: default:
split = blk_bio_segment_split(q, *bio, &q->bio_split, nr_segs); split = blk_bio_segment_split(q, *bio, &q->bio_split, nr_segs);
break; break;
@ -415,8 +395,6 @@ unsigned int blk_recalc_rq_segments(struct request *rq)
return 1; return 1;
case REQ_OP_WRITE_ZEROES: case REQ_OP_WRITE_ZEROES:
return 0; return 0;
case REQ_OP_WRITE_SAME:
return 1;
} }
rq_for_each_bvec(bv, rq, iter) rq_for_each_bvec(bv, rq, iter)
@ -554,8 +532,6 @@ int __blk_rq_map_sg(struct request_queue *q, struct request *rq,
if (rq->rq_flags & RQF_SPECIAL_PAYLOAD) if (rq->rq_flags & RQF_SPECIAL_PAYLOAD)
nsegs = __blk_bvec_map_sg(rq->special_vec, sglist, last_sg); nsegs = __blk_bvec_map_sg(rq->special_vec, sglist, last_sg);
else if (rq->bio && bio_op(rq->bio) == REQ_OP_WRITE_SAME)
nsegs = __blk_bvec_map_sg(bio_iovec(rq->bio), sglist, last_sg);
else if (rq->bio) else if (rq->bio)
nsegs = __blk_bios_map_sg(q, rq->bio, sglist, last_sg); nsegs = __blk_bios_map_sg(q, rq->bio, sglist, last_sg);
@ -762,13 +738,6 @@ static enum elv_merge blk_try_req_merge(struct request *req,
return ELEVATOR_NO_MERGE; return ELEVATOR_NO_MERGE;
} }
static inline bool blk_write_same_mergeable(struct bio *a, struct bio *b)
{
if (bio_page(a) == bio_page(b) && bio_offset(a) == bio_offset(b))
return true;
return false;
}
/* /*
* For non-mq, this has to be called with the request spinlock acquired. * For non-mq, this has to be called with the request spinlock acquired.
* For mq with scheduling, the appropriate queue wide lock should be held. * For mq with scheduling, the appropriate queue wide lock should be held.
@ -785,10 +754,6 @@ static struct request *attempt_merge(struct request_queue *q,
if (rq_data_dir(req) != rq_data_dir(next)) if (rq_data_dir(req) != rq_data_dir(next))
return NULL; return NULL;
if (req_op(req) == REQ_OP_WRITE_SAME &&
!blk_write_same_mergeable(req->bio, next->bio))
return NULL;
/* /*
* Don't allow merge of different write hints, or for a hint with * Don't allow merge of different write hints, or for a hint with
* non-hint IO. * non-hint IO.
@ -921,11 +886,6 @@ bool blk_rq_merge_ok(struct request *rq, struct bio *bio)
if (!bio_crypt_rq_ctx_compatible(rq, bio)) if (!bio_crypt_rq_ctx_compatible(rq, bio))
return false; return false;
/* must be using the same buffer */
if (req_op(rq) == REQ_OP_WRITE_SAME &&
!blk_write_same_mergeable(rq->bio, bio))
return false;
/* /*
* Don't allow merge of different write hints, or for a hint with * Don't allow merge of different write hints, or for a hint with
* non-hint IO. * non-hint IO.

View File

@ -42,7 +42,6 @@ void blk_set_default_limits(struct queue_limits *lim)
lim->max_sectors = lim->max_hw_sectors = BLK_SAFE_MAX_SECTORS; lim->max_sectors = lim->max_hw_sectors = BLK_SAFE_MAX_SECTORS;
lim->max_dev_sectors = 0; lim->max_dev_sectors = 0;
lim->chunk_sectors = 0; lim->chunk_sectors = 0;
lim->max_write_same_sectors = 0;
lim->max_write_zeroes_sectors = 0; lim->max_write_zeroes_sectors = 0;
lim->max_zone_append_sectors = 0; lim->max_zone_append_sectors = 0;
lim->max_discard_sectors = 0; lim->max_discard_sectors = 0;
@ -79,7 +78,6 @@ void blk_set_stacking_limits(struct queue_limits *lim)
lim->max_segment_size = UINT_MAX; lim->max_segment_size = UINT_MAX;
lim->max_sectors = UINT_MAX; lim->max_sectors = UINT_MAX;
lim->max_dev_sectors = UINT_MAX; lim->max_dev_sectors = UINT_MAX;
lim->max_write_same_sectors = UINT_MAX;
lim->max_write_zeroes_sectors = UINT_MAX; lim->max_write_zeroes_sectors = UINT_MAX;
lim->max_zone_append_sectors = UINT_MAX; lim->max_zone_append_sectors = UINT_MAX;
} }
@ -178,18 +176,6 @@ void blk_queue_max_discard_sectors(struct request_queue *q,
} }
EXPORT_SYMBOL(blk_queue_max_discard_sectors); EXPORT_SYMBOL(blk_queue_max_discard_sectors);
/**
* blk_queue_max_write_same_sectors - set max sectors for a single write same
* @q: the request queue for the device
* @max_write_same_sectors: maximum number of sectors to write per command
**/
void blk_queue_max_write_same_sectors(struct request_queue *q,
unsigned int max_write_same_sectors)
{
q->limits.max_write_same_sectors = max_write_same_sectors;
}
EXPORT_SYMBOL(blk_queue_max_write_same_sectors);
/** /**
* blk_queue_max_write_zeroes_sectors - set max sectors for a single * blk_queue_max_write_zeroes_sectors - set max sectors for a single
* write zeroes * write zeroes
@ -519,8 +505,6 @@ int blk_stack_limits(struct queue_limits *t, struct queue_limits *b,
t->max_sectors = min_not_zero(t->max_sectors, b->max_sectors); t->max_sectors = min_not_zero(t->max_sectors, b->max_sectors);
t->max_hw_sectors = min_not_zero(t->max_hw_sectors, b->max_hw_sectors); t->max_hw_sectors = min_not_zero(t->max_hw_sectors, b->max_hw_sectors);
t->max_dev_sectors = min_not_zero(t->max_dev_sectors, b->max_dev_sectors); t->max_dev_sectors = min_not_zero(t->max_dev_sectors, b->max_dev_sectors);
t->max_write_same_sectors = min(t->max_write_same_sectors,
b->max_write_same_sectors);
t->max_write_zeroes_sectors = min(t->max_write_zeroes_sectors, t->max_write_zeroes_sectors = min(t->max_write_zeroes_sectors,
b->max_write_zeroes_sectors); b->max_write_zeroes_sectors);
t->max_zone_append_sectors = min(t->max_zone_append_sectors, t->max_zone_append_sectors = min(t->max_zone_append_sectors,

View File

@ -214,8 +214,7 @@ static ssize_t queue_discard_zeroes_data_show(struct request_queue *q, char *pag
static ssize_t queue_write_same_max_show(struct request_queue *q, char *page) static ssize_t queue_write_same_max_show(struct request_queue *q, char *page)
{ {
return sprintf(page, "%llu\n", return queue_var_show(0, page);
(unsigned long long)q->limits.max_write_same_sectors << 9);
} }
static ssize_t queue_write_zeroes_max_show(struct request_queue *q, char *page) static ssize_t queue_write_zeroes_max_show(struct request_queue *q, char *page)

View File

@ -65,7 +65,6 @@ bool blk_req_needs_zone_write_lock(struct request *rq)
switch (req_op(rq)) { switch (req_op(rq)) {
case REQ_OP_WRITE_ZEROES: case REQ_OP_WRITE_ZEROES:
case REQ_OP_WRITE_SAME:
case REQ_OP_WRITE: case REQ_OP_WRITE:
return blk_rq_zone_is_seq(rq); return blk_rq_zone_is_seq(rq);
default: default:

View File

@ -286,7 +286,6 @@ static inline bool blk_may_split(struct request_queue *q, struct bio *bio)
case REQ_OP_DISCARD: case REQ_OP_DISCARD:
case REQ_OP_SECURE_ERASE: case REQ_OP_SECURE_ERASE:
case REQ_OP_WRITE_ZEROES: case REQ_OP_WRITE_ZEROES:
case REQ_OP_WRITE_SAME:
return true; /* non-trivial splitting decisions */ return true; /* non-trivial splitting decisions */
default: default:
break; break;

View File

@ -178,9 +178,6 @@ static struct bio *bounce_clone_bio(struct bio *bio_src)
case REQ_OP_SECURE_ERASE: case REQ_OP_SECURE_ERASE:
case REQ_OP_WRITE_ZEROES: case REQ_OP_WRITE_ZEROES:
break; break;
case REQ_OP_WRITE_SAME:
bio->bi_io_vec[bio->bi_vcnt++] = bio_src->bi_io_vec[0];
break;
default: default:
bio_for_each_segment(bv, bio_src, iter) bio_for_each_segment(bv, bio_src, iter)
bio->bi_io_vec[bio->bi_vcnt++] = bv; bio->bi_io_vec[bio->bi_vcnt++] = bv;

View File

@ -1022,7 +1022,9 @@ void ata_scsi_sdev_config(struct scsi_device *sdev)
*/ */
bool ata_scsi_dma_need_drain(struct request *rq) bool ata_scsi_dma_need_drain(struct request *rq)
{ {
return atapi_cmd_type(scsi_req(rq)->cmd[0]) == ATAPI_MISC; struct scsi_cmnd *scmd = blk_mq_rq_to_pdu(rq);
return atapi_cmd_type(scmd->cmnd[0]) == ATAPI_MISC;
} }
EXPORT_SYMBOL_GPL(ata_scsi_dma_need_drain); EXPORT_SYMBOL_GPL(ata_scsi_dma_need_drain);

View File

@ -912,7 +912,7 @@ assign_p_sizes_qlim(struct drbd_device *device, struct p_sizes *p,
p->qlim->io_min = cpu_to_be32(queue_io_min(q)); p->qlim->io_min = cpu_to_be32(queue_io_min(q));
p->qlim->io_opt = cpu_to_be32(queue_io_opt(q)); p->qlim->io_opt = cpu_to_be32(queue_io_opt(q));
p->qlim->discard_enabled = blk_queue_discard(q); p->qlim->discard_enabled = blk_queue_discard(q);
p->qlim->write_same_capable = !!q->limits.max_write_same_sectors; p->qlim->write_same_capable = 0;
} else { } else {
q = device->rq_queue; q = device->rq_queue;
p->qlim->physical_block_size = cpu_to_be32(queue_physical_block_size(q)); p->qlim->physical_block_size = cpu_to_be32(queue_physical_block_size(q));
@ -1591,9 +1591,6 @@ static int _drbd_send_bio(struct drbd_peer_device *peer_device, struct bio *bio)
? 0 : MSG_MORE); ? 0 : MSG_MORE);
if (err) if (err)
return err; return err;
/* REQ_OP_WRITE_SAME has only one segment */
if (bio_op(bio) == REQ_OP_WRITE_SAME)
break;
} }
return 0; return 0;
} }
@ -1612,9 +1609,6 @@ static int _drbd_send_zc_bio(struct drbd_peer_device *peer_device, struct bio *b
bio_iter_last(bvec, iter) ? 0 : MSG_MORE); bio_iter_last(bvec, iter) ? 0 : MSG_MORE);
if (err) if (err)
return err; return err;
/* REQ_OP_WRITE_SAME has only one segment */
if (bio_op(bio) == REQ_OP_WRITE_SAME)
break;
} }
return 0; return 0;
} }
@ -1646,7 +1640,6 @@ static u32 bio_flags_to_wire(struct drbd_connection *connection,
return (bio->bi_opf & REQ_SYNC ? DP_RW_SYNC : 0) | return (bio->bi_opf & REQ_SYNC ? DP_RW_SYNC : 0) |
(bio->bi_opf & REQ_FUA ? DP_FUA : 0) | (bio->bi_opf & REQ_FUA ? DP_FUA : 0) |
(bio->bi_opf & REQ_PREFLUSH ? DP_FLUSH : 0) | (bio->bi_opf & REQ_PREFLUSH ? DP_FLUSH : 0) |
(bio_op(bio) == REQ_OP_WRITE_SAME ? DP_WSAME : 0) |
(bio_op(bio) == REQ_OP_DISCARD ? DP_DISCARD : 0) | (bio_op(bio) == REQ_OP_DISCARD ? DP_DISCARD : 0) |
(bio_op(bio) == REQ_OP_WRITE_ZEROES ? (bio_op(bio) == REQ_OP_WRITE_ZEROES ?
((connection->agreed_features & DRBD_FF_WZEROES) ? ((connection->agreed_features & DRBD_FF_WZEROES) ?
@ -1665,7 +1658,6 @@ int drbd_send_dblock(struct drbd_peer_device *peer_device, struct drbd_request *
struct drbd_device *device = peer_device->device; struct drbd_device *device = peer_device->device;
struct drbd_socket *sock; struct drbd_socket *sock;
struct p_data *p; struct p_data *p;
struct p_wsame *wsame = NULL;
void *digest_out; void *digest_out;
unsigned int dp_flags = 0; unsigned int dp_flags = 0;
int digest_size; int digest_size;
@ -1703,29 +1695,14 @@ int drbd_send_dblock(struct drbd_peer_device *peer_device, struct drbd_request *
err = __send_command(peer_device->connection, device->vnr, sock, cmd, sizeof(*t), NULL, 0); err = __send_command(peer_device->connection, device->vnr, sock, cmd, sizeof(*t), NULL, 0);
goto out; goto out;
} }
if (dp_flags & DP_WSAME) { digest_out = p + 1;
/* this will only work if DRBD_FF_WSAME is set AND the
* handshake agreed that all nodes and backend devices are
* WRITE_SAME capable and agree on logical_block_size */
wsame = (struct p_wsame*)p;
digest_out = wsame + 1;
wsame->size = cpu_to_be32(req->i.size);
} else
digest_out = p + 1;
/* our digest is still only over the payload. /* our digest is still only over the payload.
* TRIM does not carry any payload. */ * TRIM does not carry any payload. */
if (digest_size) if (digest_size)
drbd_csum_bio(peer_device->connection->integrity_tfm, req->master_bio, digest_out); drbd_csum_bio(peer_device->connection->integrity_tfm, req->master_bio, digest_out);
if (wsame) { err = __send_command(peer_device->connection, device->vnr, sock, P_DATA,
err = sizeof(*p) + digest_size, NULL, req->i.size);
__send_command(peer_device->connection, device->vnr, sock, P_WSAME,
sizeof(*wsame) + digest_size, NULL,
bio_iovec(req->master_bio).bv_len);
} else
err =
__send_command(peer_device->connection, device->vnr, sock, P_DATA,
sizeof(*p) + digest_size, NULL, req->i.size);
if (!err) { if (!err) {
/* For protocol A, we have to memcpy the payload into /* For protocol A, we have to memcpy the payload into
* socket buffers, as we may complete right away * socket buffers, as we may complete right away

View File

@ -1265,71 +1265,6 @@ static void fixup_write_zeroes(struct drbd_device *device, struct request_queue
q->limits.max_write_zeroes_sectors = 0; q->limits.max_write_zeroes_sectors = 0;
} }
static void decide_on_write_same_support(struct drbd_device *device,
struct request_queue *q,
struct request_queue *b, struct o_qlim *o,
bool disable_write_same)
{
struct drbd_peer_device *peer_device = first_peer_device(device);
struct drbd_connection *connection = peer_device->connection;
bool can_do = b ? b->limits.max_write_same_sectors : true;
if (can_do && disable_write_same) {
can_do = false;
drbd_info(peer_device, "WRITE_SAME disabled by config\n");
}
if (can_do && connection->cstate >= C_CONNECTED && !(connection->agreed_features & DRBD_FF_WSAME)) {
can_do = false;
drbd_info(peer_device, "peer does not support WRITE_SAME\n");
}
if (o) {
/* logical block size; queue_logical_block_size(NULL) is 512 */
unsigned int peer_lbs = be32_to_cpu(o->logical_block_size);
unsigned int me_lbs_b = queue_logical_block_size(b);
unsigned int me_lbs = queue_logical_block_size(q);
if (me_lbs_b != me_lbs) {
drbd_warn(device,
"logical block size of local backend does not match (drbd:%u, backend:%u); was this a late attach?\n",
me_lbs, me_lbs_b);
/* rather disable write same than trigger some BUG_ON later in the scsi layer. */
can_do = false;
}
if (me_lbs_b != peer_lbs) {
drbd_warn(peer_device, "logical block sizes do not match (me:%u, peer:%u); this may cause problems.\n",
me_lbs, peer_lbs);
if (can_do) {
drbd_dbg(peer_device, "logical block size mismatch: WRITE_SAME disabled.\n");
can_do = false;
}
me_lbs = max(me_lbs, me_lbs_b);
/* We cannot change the logical block size of an in-use queue.
* We can only hope that access happens to be properly aligned.
* If not, the peer will likely produce an IO error, and detach. */
if (peer_lbs > me_lbs) {
if (device->state.role != R_PRIMARY) {
blk_queue_logical_block_size(q, peer_lbs);
drbd_warn(peer_device, "logical block size set to %u\n", peer_lbs);
} else {
drbd_warn(peer_device,
"current Primary must NOT adjust logical block size (%u -> %u); hope for the best.\n",
me_lbs, peer_lbs);
}
}
}
if (can_do && !o->write_same_capable) {
/* If we introduce an open-coded write-same loop on the receiving side,
* the peer would present itself as "capable". */
drbd_dbg(peer_device, "WRITE_SAME disabled (peer device not capable)\n");
can_do = false;
}
}
blk_queue_max_write_same_sectors(q, can_do ? DRBD_MAX_BBIO_SECTORS : 0);
}
static void drbd_setup_queue_param(struct drbd_device *device, struct drbd_backing_dev *bdev, static void drbd_setup_queue_param(struct drbd_device *device, struct drbd_backing_dev *bdev,
unsigned int max_bio_size, struct o_qlim *o) unsigned int max_bio_size, struct o_qlim *o)
{ {
@ -1339,7 +1274,6 @@ static void drbd_setup_queue_param(struct drbd_device *device, struct drbd_backi
struct request_queue *b = NULL; struct request_queue *b = NULL;
struct disk_conf *dc; struct disk_conf *dc;
bool discard_zeroes_if_aligned = true; bool discard_zeroes_if_aligned = true;
bool disable_write_same = false;
if (bdev) { if (bdev) {
b = bdev->backing_bdev->bd_disk->queue; b = bdev->backing_bdev->bd_disk->queue;
@ -1349,7 +1283,6 @@ static void drbd_setup_queue_param(struct drbd_device *device, struct drbd_backi
dc = rcu_dereference(device->ldev->disk_conf); dc = rcu_dereference(device->ldev->disk_conf);
max_segments = dc->max_bio_bvecs; max_segments = dc->max_bio_bvecs;
discard_zeroes_if_aligned = dc->discard_zeroes_if_aligned; discard_zeroes_if_aligned = dc->discard_zeroes_if_aligned;
disable_write_same = dc->disable_write_same;
rcu_read_unlock(); rcu_read_unlock();
blk_set_stacking_limits(&q->limits); blk_set_stacking_limits(&q->limits);
@ -1360,7 +1293,6 @@ static void drbd_setup_queue_param(struct drbd_device *device, struct drbd_backi
blk_queue_max_segments(q, max_segments ? max_segments : BLK_MAX_SEGMENTS); blk_queue_max_segments(q, max_segments ? max_segments : BLK_MAX_SEGMENTS);
blk_queue_segment_boundary(q, PAGE_SIZE-1); blk_queue_segment_boundary(q, PAGE_SIZE-1);
decide_on_discard_support(device, q, b, discard_zeroes_if_aligned); decide_on_discard_support(device, q, b, discard_zeroes_if_aligned);
decide_on_write_same_support(device, q, b, o, disable_write_same);
if (b) { if (b) {
blk_stack_limits(&q->limits, &b->limits, 0); blk_stack_limits(&q->limits, &b->limits, 0);
@ -1666,8 +1598,8 @@ int drbd_adm_disk_opts(struct sk_buff *skb, struct genl_info *info)
if (write_ordering_changed(old_disk_conf, new_disk_conf)) if (write_ordering_changed(old_disk_conf, new_disk_conf))
drbd_bump_write_ordering(device->resource, NULL, WO_BDEV_FLUSH); drbd_bump_write_ordering(device->resource, NULL, WO_BDEV_FLUSH);
if (old_disk_conf->discard_zeroes_if_aligned != new_disk_conf->discard_zeroes_if_aligned if (old_disk_conf->discard_zeroes_if_aligned !=
|| old_disk_conf->disable_write_same != new_disk_conf->disable_write_same) new_disk_conf->discard_zeroes_if_aligned)
drbd_reconsider_queue_parameters(device, device->ldev, NULL); drbd_reconsider_queue_parameters(device, device->ldev, NULL);
drbd_md_sync(device); drbd_md_sync(device);

View File

@ -1604,19 +1604,7 @@ static void drbd_issue_peer_discard_or_zero_out(struct drbd_device *device, stru
drbd_endio_write_sec_final(peer_req); drbd_endio_write_sec_final(peer_req);
} }
static void drbd_issue_peer_wsame(struct drbd_device *device, /**
struct drbd_peer_request *peer_req)
{
struct block_device *bdev = device->ldev->backing_bdev;
sector_t s = peer_req->i.sector;
sector_t nr = peer_req->i.size >> 9;
if (blkdev_issue_write_same(bdev, s, nr, GFP_NOIO, peer_req->pages))
peer_req->flags |= EE_WAS_ERROR;
drbd_endio_write_sec_final(peer_req);
}
/*
* drbd_submit_peer_request() * drbd_submit_peer_request()
* @device: DRBD device. * @device: DRBD device.
* @peer_req: peer request * @peer_req: peer request
@ -1651,7 +1639,7 @@ int drbd_submit_peer_request(struct drbd_device *device,
* Correctness first, performance later. Next step is to code an * Correctness first, performance later. Next step is to code an
* asynchronous variant of the same. * asynchronous variant of the same.
*/ */
if (peer_req->flags & (EE_TRIM|EE_WRITE_SAME|EE_ZEROOUT)) { if (peer_req->flags & (EE_TRIM | EE_ZEROOUT)) {
/* wait for all pending IO completions, before we start /* wait for all pending IO completions, before we start
* zeroing things out. */ * zeroing things out. */
conn_wait_active_ee_empty(peer_req->peer_device->connection); conn_wait_active_ee_empty(peer_req->peer_device->connection);
@ -1668,10 +1656,7 @@ int drbd_submit_peer_request(struct drbd_device *device,
spin_unlock_irq(&device->resource->req_lock); spin_unlock_irq(&device->resource->req_lock);
} }
if (peer_req->flags & (EE_TRIM|EE_ZEROOUT)) drbd_issue_peer_discard_or_zero_out(device, peer_req);
drbd_issue_peer_discard_or_zero_out(device, peer_req);
else /* EE_WRITE_SAME */
drbd_issue_peer_wsame(device, peer_req);
return 0; return 0;
} }
@ -1854,7 +1839,6 @@ read_in_block(struct drbd_peer_device *peer_device, u64 id, sector_t sector,
unsigned long *data; unsigned long *data;
struct p_trim *trim = (pi->cmd == P_TRIM) ? pi->data : NULL; struct p_trim *trim = (pi->cmd == P_TRIM) ? pi->data : NULL;
struct p_trim *zeroes = (pi->cmd == P_ZEROES) ? pi->data : NULL; struct p_trim *zeroes = (pi->cmd == P_ZEROES) ? pi->data : NULL;
struct p_trim *wsame = (pi->cmd == P_WSAME) ? pi->data : NULL;
digest_size = 0; digest_size = 0;
if (!trim && peer_device->connection->peer_integrity_tfm) { if (!trim && peer_device->connection->peer_integrity_tfm) {
@ -1869,7 +1853,7 @@ read_in_block(struct drbd_peer_device *peer_device, u64 id, sector_t sector,
data_size -= digest_size; data_size -= digest_size;
} }
/* assume request_size == data_size, but special case trim and wsame. */ /* assume request_size == data_size, but special case trim. */
ds = data_size; ds = data_size;
if (trim) { if (trim) {
if (!expect(data_size == 0)) if (!expect(data_size == 0))
@ -1879,23 +1863,11 @@ read_in_block(struct drbd_peer_device *peer_device, u64 id, sector_t sector,
if (!expect(data_size == 0)) if (!expect(data_size == 0))
return NULL; return NULL;
ds = be32_to_cpu(zeroes->size); ds = be32_to_cpu(zeroes->size);
} else if (wsame) {
if (data_size != queue_logical_block_size(device->rq_queue)) {
drbd_err(peer_device, "data size (%u) != drbd logical block size (%u)\n",
data_size, queue_logical_block_size(device->rq_queue));
return NULL;
}
if (data_size != bdev_logical_block_size(device->ldev->backing_bdev)) {
drbd_err(peer_device, "data size (%u) != backend logical block size (%u)\n",
data_size, bdev_logical_block_size(device->ldev->backing_bdev));
return NULL;
}
ds = be32_to_cpu(wsame->size);
} }
if (!expect(IS_ALIGNED(ds, 512))) if (!expect(IS_ALIGNED(ds, 512)))
return NULL; return NULL;
if (trim || wsame || zeroes) { if (trim || zeroes) {
if (!expect(ds <= (DRBD_MAX_BBIO_SECTORS << 9))) if (!expect(ds <= (DRBD_MAX_BBIO_SECTORS << 9)))
return NULL; return NULL;
} else if (!expect(ds <= DRBD_MAX_BIO_SIZE)) } else if (!expect(ds <= DRBD_MAX_BIO_SIZE))
@ -1927,8 +1899,6 @@ read_in_block(struct drbd_peer_device *peer_device, u64 id, sector_t sector,
peer_req->flags |= EE_ZEROOUT; peer_req->flags |= EE_ZEROOUT;
return peer_req; return peer_req;
} }
if (wsame)
peer_req->flags |= EE_WRITE_SAME;
/* receive payload size bytes into page chain */ /* receive payload size bytes into page chain */
ds = data_size; ds = data_size;
@ -2427,8 +2397,6 @@ static unsigned long wire_flags_to_bio_op(u32 dpf)
return REQ_OP_WRITE_ZEROES; return REQ_OP_WRITE_ZEROES;
if (dpf & DP_DISCARD) if (dpf & DP_DISCARD)
return REQ_OP_DISCARD; return REQ_OP_DISCARD;
if (dpf & DP_WSAME)
return REQ_OP_WRITE_SAME;
else else
return REQ_OP_WRITE; return REQ_OP_WRITE;
} }
@ -2695,11 +2663,11 @@ static int receive_Data(struct drbd_connection *connection, struct packet_info *
update_peer_seq(peer_device, peer_seq); update_peer_seq(peer_device, peer_seq);
spin_lock_irq(&device->resource->req_lock); spin_lock_irq(&device->resource->req_lock);
} }
/* TRIM and WRITE_SAME are processed synchronously, /* TRIM and is processed synchronously,
* we wait for all pending requests, respectively wait for * we wait for all pending requests, respectively wait for
* active_ee to become empty in drbd_submit_peer_request(); * active_ee to become empty in drbd_submit_peer_request();
* better not add ourselves here. */ * better not add ourselves here. */
if ((peer_req->flags & (EE_TRIM|EE_WRITE_SAME|EE_ZEROOUT)) == 0) if ((peer_req->flags & (EE_TRIM | EE_ZEROOUT)) == 0)
list_add_tail(&peer_req->w.list, &device->active_ee); list_add_tail(&peer_req->w.list, &device->active_ee);
spin_unlock_irq(&device->resource->req_lock); spin_unlock_irq(&device->resource->req_lock);
@ -5068,7 +5036,6 @@ static struct data_cmd drbd_cmd_handler[] = {
[P_TRIM] = { 0, sizeof(struct p_trim), receive_Data }, [P_TRIM] = { 0, sizeof(struct p_trim), receive_Data },
[P_ZEROES] = { 0, sizeof(struct p_trim), receive_Data }, [P_ZEROES] = { 0, sizeof(struct p_trim), receive_Data },
[P_RS_DEALLOCATED] = { 0, sizeof(struct p_block_desc), receive_rs_deallocated }, [P_RS_DEALLOCATED] = { 0, sizeof(struct p_block_desc), receive_rs_deallocated },
[P_WSAME] = { 1, sizeof(struct p_wsame), receive_Data },
}; };
static void drbdd(struct drbd_connection *connection) static void drbdd(struct drbd_connection *connection)

View File

@ -36,7 +36,6 @@ static struct drbd_request *drbd_req_new(struct drbd_device *device, struct bio
req->private_bio->bi_end_io = drbd_request_endio; req->private_bio->bi_end_io = drbd_request_endio;
req->rq_state = (bio_data_dir(bio_src) == WRITE ? RQ_WRITE : 0) req->rq_state = (bio_data_dir(bio_src) == WRITE ? RQ_WRITE : 0)
| (bio_op(bio_src) == REQ_OP_WRITE_SAME ? RQ_WSAME : 0)
| (bio_op(bio_src) == REQ_OP_WRITE_ZEROES ? RQ_ZEROES : 0) | (bio_op(bio_src) == REQ_OP_WRITE_ZEROES ? RQ_ZEROES : 0)
| (bio_op(bio_src) == REQ_OP_DISCARD ? RQ_UNMAP : 0); | (bio_op(bio_src) == REQ_OP_DISCARD ? RQ_UNMAP : 0);
req->device = device; req->device = device;

View File

@ -329,11 +329,6 @@ void drbd_csum_bio(struct crypto_shash *tfm, struct bio *bio, void *digest)
src = bvec_kmap_local(&bvec); src = bvec_kmap_local(&bvec);
crypto_shash_update(desc, src, bvec.bv_len); crypto_shash_update(desc, src, bvec.bv_len);
kunmap_local(src); kunmap_local(src);
/* REQ_OP_WRITE_SAME has only one segment,
* checksum the payload only once. */
if (bio_op(bio) == REQ_OP_WRITE_SAME)
break;
} }
crypto_shash_final(desc, digest); crypto_shash_final(desc, digest);
shash_desc_zero(desc); shash_desc_zero(desc);

View File

@ -693,6 +693,7 @@ static void pkt_rbtree_insert(struct pktcdvd_device *pd, struct pkt_rb_node *nod
static int pkt_generic_packet(struct pktcdvd_device *pd, struct packet_command *cgc) static int pkt_generic_packet(struct pktcdvd_device *pd, struct packet_command *cgc)
{ {
struct request_queue *q = bdev_get_queue(pd->bdev); struct request_queue *q = bdev_get_queue(pd->bdev);
struct scsi_cmnd *scmd;
struct request *rq; struct request *rq;
int ret = 0; int ret = 0;
@ -700,6 +701,7 @@ static int pkt_generic_packet(struct pktcdvd_device *pd, struct packet_command *
REQ_OP_DRV_OUT : REQ_OP_DRV_IN, 0); REQ_OP_DRV_OUT : REQ_OP_DRV_IN, 0);
if (IS_ERR(rq)) if (IS_ERR(rq))
return PTR_ERR(rq); return PTR_ERR(rq);
scmd = blk_mq_rq_to_pdu(rq);
if (cgc->buflen) { if (cgc->buflen) {
ret = blk_rq_map_kern(q, rq, cgc->buffer, cgc->buflen, ret = blk_rq_map_kern(q, rq, cgc->buffer, cgc->buflen,
@ -708,15 +710,15 @@ static int pkt_generic_packet(struct pktcdvd_device *pd, struct packet_command *
goto out; goto out;
} }
scsi_req(rq)->cmd_len = COMMAND_SIZE(cgc->cmd[0]); scmd->cmd_len = COMMAND_SIZE(cgc->cmd[0]);
memcpy(scsi_req(rq)->cmd, cgc->cmd, CDROM_PACKET_SIZE); memcpy(scmd->cmnd, cgc->cmd, CDROM_PACKET_SIZE);
rq->timeout = 60*HZ; rq->timeout = 60*HZ;
if (cgc->quiet) if (cgc->quiet)
rq->rq_flags |= RQF_QUIET; rq->rq_flags |= RQF_QUIET;
blk_execute_rq(rq, false); blk_execute_rq(rq, false);
if (scsi_req(rq)->result) if (scmd->result)
ret = -EIO; ret = -EIO;
out: out:
blk_mq_free_request(rq); blk_mq_free_request(rq);

View File

@ -79,7 +79,6 @@ static int rnbd_clt_set_dev_attr(struct rnbd_clt_dev *dev,
dev->nsectors = le64_to_cpu(rsp->nsectors); dev->nsectors = le64_to_cpu(rsp->nsectors);
dev->logical_block_size = le16_to_cpu(rsp->logical_block_size); dev->logical_block_size = le16_to_cpu(rsp->logical_block_size);
dev->physical_block_size = le16_to_cpu(rsp->physical_block_size); dev->physical_block_size = le16_to_cpu(rsp->physical_block_size);
dev->max_write_same_sectors = le32_to_cpu(rsp->max_write_same_sectors);
dev->max_discard_sectors = le32_to_cpu(rsp->max_discard_sectors); dev->max_discard_sectors = le32_to_cpu(rsp->max_discard_sectors);
dev->discard_granularity = le32_to_cpu(rsp->discard_granularity); dev->discard_granularity = le32_to_cpu(rsp->discard_granularity);
dev->discard_alignment = le32_to_cpu(rsp->discard_alignment); dev->discard_alignment = le32_to_cpu(rsp->discard_alignment);
@ -1355,8 +1354,6 @@ static void setup_request_queue(struct rnbd_clt_dev *dev)
blk_queue_logical_block_size(dev->queue, dev->logical_block_size); blk_queue_logical_block_size(dev->queue, dev->logical_block_size);
blk_queue_physical_block_size(dev->queue, dev->physical_block_size); blk_queue_physical_block_size(dev->queue, dev->physical_block_size);
blk_queue_max_hw_sectors(dev->queue, dev->max_hw_sectors); blk_queue_max_hw_sectors(dev->queue, dev->max_hw_sectors);
blk_queue_max_write_same_sectors(dev->queue,
dev->max_write_same_sectors);
/* /*
* we don't support discards to "discontiguous" segments * we don't support discards to "discontiguous" segments
@ -1606,10 +1603,10 @@ struct rnbd_clt_dev *rnbd_clt_map_device(const char *sessname,
} }
rnbd_clt_info(dev, rnbd_clt_info(dev,
"map_device: Device mapped as %s (nsectors: %zu, logical_block_size: %d, physical_block_size: %d, max_write_same_sectors: %d, max_discard_sectors: %d, discard_granularity: %d, discard_alignment: %d, secure_discard: %d, max_segments: %d, max_hw_sectors: %d, wc: %d, fua: %d)\n", "map_device: Device mapped as %s (nsectors: %zu, logical_block_size: %d, physical_block_size: %d, max_discard_sectors: %d, discard_granularity: %d, discard_alignment: %d, secure_discard: %d, max_segments: %d, max_hw_sectors: %d, wc: %d, fua: %d)\n",
dev->gd->disk_name, dev->nsectors, dev->gd->disk_name, dev->nsectors,
dev->logical_block_size, dev->physical_block_size, dev->logical_block_size, dev->physical_block_size,
dev->max_write_same_sectors, dev->max_discard_sectors, dev->max_discard_sectors,
dev->discard_granularity, dev->discard_alignment, dev->discard_granularity, dev->discard_alignment,
dev->secure_discard, dev->max_segments, dev->secure_discard, dev->max_segments,
dev->max_hw_sectors, dev->wc, dev->fua); dev->max_hw_sectors, dev->wc, dev->fua);

View File

@ -121,7 +121,6 @@ struct rnbd_clt_dev {
bool wc; bool wc;
bool fua; bool fua;
u32 max_hw_sectors; u32 max_hw_sectors;
u32 max_write_same_sectors;
u32 max_discard_sectors; u32 max_discard_sectors;
u32 discard_granularity; u32 discard_granularity;
u32 discard_alignment; u32 discard_alignment;

View File

@ -249,9 +249,6 @@ static inline u32 rnbd_to_bio_flags(u32 rnbd_opf)
case RNBD_OP_SECURE_ERASE: case RNBD_OP_SECURE_ERASE:
bio_opf = REQ_OP_SECURE_ERASE; bio_opf = REQ_OP_SECURE_ERASE;
break; break;
case RNBD_OP_WRITE_SAME:
bio_opf = REQ_OP_WRITE_SAME;
break;
default: default:
WARN(1, "Unknown RNBD type: %d (flags %d)\n", WARN(1, "Unknown RNBD type: %d (flags %d)\n",
rnbd_op(rnbd_opf), rnbd_opf); rnbd_op(rnbd_opf), rnbd_opf);
@ -284,9 +281,6 @@ static inline u32 rq_to_rnbd_flags(struct request *rq)
case REQ_OP_SECURE_ERASE: case REQ_OP_SECURE_ERASE:
rnbd_opf = RNBD_OP_SECURE_ERASE; rnbd_opf = RNBD_OP_SECURE_ERASE;
break; break;
case REQ_OP_WRITE_SAME:
rnbd_opf = RNBD_OP_WRITE_SAME;
break;
case REQ_OP_FLUSH: case REQ_OP_FLUSH:
rnbd_opf = RNBD_OP_FLUSH; rnbd_opf = RNBD_OP_FLUSH;
break; break;

View File

@ -548,8 +548,7 @@ static void rnbd_srv_fill_msg_open_rsp(struct rnbd_msg_open_rsp *rsp,
cpu_to_le16(rnbd_dev_get_max_segs(rnbd_dev)); cpu_to_le16(rnbd_dev_get_max_segs(rnbd_dev));
rsp->max_hw_sectors = rsp->max_hw_sectors =
cpu_to_le32(rnbd_dev_get_max_hw_sects(rnbd_dev)); cpu_to_le32(rnbd_dev_get_max_hw_sects(rnbd_dev));
rsp->max_write_same_sectors = rsp->max_write_same_sectors = 0;
cpu_to_le32(bdev_write_same(rnbd_dev->bdev));
rsp->max_discard_sectors = rsp->max_discard_sectors =
cpu_to_le32(rnbd_dev_get_max_discard_sects(rnbd_dev)); cpu_to_le32(rnbd_dev_get_max_discard_sects(rnbd_dev));
rsp->discard_granularity = rsp->discard_granularity =

View File

@ -284,7 +284,6 @@
#include <linux/times.h> #include <linux/times.h>
#include <linux/uaccess.h> #include <linux/uaccess.h>
#include <scsi/scsi_common.h> #include <scsi/scsi_common.h>
#include <scsi/scsi_request.h>
/* used to tell the module to turn on full debugging messages */ /* used to tell the module to turn on full debugging messages */
static bool debug; static bool debug;

View File

@ -971,6 +971,7 @@ static struct scsi_host_template iscsi_iser_sht = {
.proc_name = "iscsi_iser", .proc_name = "iscsi_iser",
.this_id = -1, .this_id = -1,
.track_queue_depth = 1, .track_queue_depth = 1,
.cmd_size = sizeof(struct iscsi_cmd),
}; };
static struct iscsi_transport iscsi_iser_transport = { static struct iscsi_transport iscsi_iser_transport = {

View File

@ -142,7 +142,6 @@ struct mapped_device {
#define DMF_EMULATE_ZONE_APPEND 9 #define DMF_EMULATE_ZONE_APPEND 9
void disable_discard(struct mapped_device *md); void disable_discard(struct mapped_device *md);
void disable_write_same(struct mapped_device *md);
void disable_write_zeroes(struct mapped_device *md); void disable_write_zeroes(struct mapped_device *md);
static inline sector_t dm_get_size(struct mapped_device *md) static inline sector_t dm_get_size(struct mapped_device *md)

View File

@ -1997,7 +1997,6 @@ static bool kcryptd_crypt_write_inline(struct crypt_config *cc,
*/ */
switch (bio_op(ctx->bio_in)) { switch (bio_op(ctx->bio_in)) {
case REQ_OP_WRITE: case REQ_OP_WRITE:
case REQ_OP_WRITE_SAME:
case REQ_OP_WRITE_ZEROES: case REQ_OP_WRITE_ZEROES:
return true; return true;
default: default:

View File

@ -335,7 +335,6 @@ static int ebs_ctr(struct dm_target *ti, unsigned int argc, char **argv)
ti->num_flush_bios = 1; ti->num_flush_bios = 1;
ti->num_discard_bios = 1; ti->num_discard_bios = 1;
ti->num_secure_erase_bios = 0; ti->num_secure_erase_bios = 0;
ti->num_write_same_bios = 0;
ti->num_write_zeroes_bios = 0; ti->num_write_zeroes_bios = 0;
return 0; return 0;
bad: bad:

View File

@ -304,7 +304,6 @@ static void do_region(int op, int op_flags, unsigned region,
unsigned num_bvecs; unsigned num_bvecs;
sector_t remaining = where->count; sector_t remaining = where->count;
struct request_queue *q = bdev_get_queue(where->bdev); struct request_queue *q = bdev_get_queue(where->bdev);
unsigned short logical_block_size = queue_logical_block_size(q);
sector_t num_sectors; sector_t num_sectors;
unsigned int special_cmd_max_sectors; unsigned int special_cmd_max_sectors;
@ -315,10 +314,8 @@ static void do_region(int op, int op_flags, unsigned region,
special_cmd_max_sectors = q->limits.max_discard_sectors; special_cmd_max_sectors = q->limits.max_discard_sectors;
else if (op == REQ_OP_WRITE_ZEROES) else if (op == REQ_OP_WRITE_ZEROES)
special_cmd_max_sectors = q->limits.max_write_zeroes_sectors; special_cmd_max_sectors = q->limits.max_write_zeroes_sectors;
else if (op == REQ_OP_WRITE_SAME) if ((op == REQ_OP_DISCARD || op == REQ_OP_WRITE_ZEROES) &&
special_cmd_max_sectors = q->limits.max_write_same_sectors; special_cmd_max_sectors == 0) {
if ((op == REQ_OP_DISCARD || op == REQ_OP_WRITE_ZEROES ||
op == REQ_OP_WRITE_SAME) && special_cmd_max_sectors == 0) {
atomic_inc(&io->count); atomic_inc(&io->count);
dec_count(io, region, BLK_STS_NOTSUPP); dec_count(io, region, BLK_STS_NOTSUPP);
return; return;
@ -337,9 +334,6 @@ static void do_region(int op, int op_flags, unsigned region,
case REQ_OP_WRITE_ZEROES: case REQ_OP_WRITE_ZEROES:
num_bvecs = 0; num_bvecs = 0;
break; break;
case REQ_OP_WRITE_SAME:
num_bvecs = 1;
break;
default: default:
num_bvecs = bio_max_segs(dm_sector_div_up(remaining, num_bvecs = bio_max_segs(dm_sector_div_up(remaining,
(PAGE_SIZE >> SECTOR_SHIFT))); (PAGE_SIZE >> SECTOR_SHIFT)));
@ -355,18 +349,6 @@ static void do_region(int op, int op_flags, unsigned region,
num_sectors = min_t(sector_t, special_cmd_max_sectors, remaining); num_sectors = min_t(sector_t, special_cmd_max_sectors, remaining);
bio->bi_iter.bi_size = num_sectors << SECTOR_SHIFT; bio->bi_iter.bi_size = num_sectors << SECTOR_SHIFT;
remaining -= num_sectors; remaining -= num_sectors;
} else if (op == REQ_OP_WRITE_SAME) {
/*
* WRITE SAME only uses a single page.
*/
dp->get_page(dp, &page, &len, &offset);
bio_add_page(bio, page, logical_block_size, offset);
num_sectors = min_t(sector_t, special_cmd_max_sectors, remaining);
bio->bi_iter.bi_size = num_sectors << SECTOR_SHIFT;
offset = 0;
remaining -= num_sectors;
dp->next_page(dp);
} else while (remaining) { } else while (remaining) {
/* /*
* Try and add as many pages as possible. * Try and add as many pages as possible.

View File

@ -60,7 +60,6 @@ static int linear_ctr(struct dm_target *ti, unsigned int argc, char **argv)
ti->num_flush_bios = 1; ti->num_flush_bios = 1;
ti->num_discard_bios = 1; ti->num_discard_bios = 1;
ti->num_secure_erase_bios = 1; ti->num_secure_erase_bios = 1;
ti->num_write_same_bios = 1;
ti->num_write_zeroes_bios = 1; ti->num_write_zeroes_bios = 1;
ti->private = lc; ti->private = lc;
return 0; return 0;

View File

@ -1249,7 +1249,6 @@ static int multipath_ctr(struct dm_target *ti, unsigned argc, char **argv)
ti->num_flush_bios = 1; ti->num_flush_bios = 1;
ti->num_discard_bios = 1; ti->num_discard_bios = 1;
ti->num_write_same_bios = 1;
ti->num_write_zeroes_bios = 1; ti->num_write_zeroes_bios = 1;
if (m->queue_mode == DM_TYPE_BIO_BASED) if (m->queue_mode == DM_TYPE_BIO_BASED)
ti->per_io_data_size = multipath_per_bio_data_size(); ti->per_io_data_size = multipath_per_bio_data_size();

View File

@ -217,9 +217,6 @@ static void dm_done(struct request *clone, blk_status_t error, bool mapped)
if (req_op(clone) == REQ_OP_DISCARD && if (req_op(clone) == REQ_OP_DISCARD &&
!clone->q->limits.max_discard_sectors) !clone->q->limits.max_discard_sectors)
disable_discard(tio->md); disable_discard(tio->md);
else if (req_op(clone) == REQ_OP_WRITE_SAME &&
!clone->q->limits.max_write_same_sectors)
disable_write_same(tio->md);
else if (req_op(clone) == REQ_OP_WRITE_ZEROES && else if (req_op(clone) == REQ_OP_WRITE_ZEROES &&
!clone->q->limits.max_write_zeroes_sectors) !clone->q->limits.max_write_zeroes_sectors)
disable_write_zeroes(tio->md); disable_write_zeroes(tio->md);

View File

@ -157,7 +157,6 @@ static int stripe_ctr(struct dm_target *ti, unsigned int argc, char **argv)
ti->num_flush_bios = stripes; ti->num_flush_bios = stripes;
ti->num_discard_bios = stripes; ti->num_discard_bios = stripes;
ti->num_secure_erase_bios = stripes; ti->num_secure_erase_bios = stripes;
ti->num_write_same_bios = stripes;
ti->num_write_zeroes_bios = stripes; ti->num_write_zeroes_bios = stripes;
sc->chunk_size = chunk_size; sc->chunk_size = chunk_size;
@ -284,8 +283,7 @@ static int stripe_map(struct dm_target *ti, struct bio *bio)
} }
if (unlikely(bio_op(bio) == REQ_OP_DISCARD) || if (unlikely(bio_op(bio) == REQ_OP_DISCARD) ||
unlikely(bio_op(bio) == REQ_OP_SECURE_ERASE) || unlikely(bio_op(bio) == REQ_OP_SECURE_ERASE) ||
unlikely(bio_op(bio) == REQ_OP_WRITE_ZEROES) || unlikely(bio_op(bio) == REQ_OP_WRITE_ZEROES)) {
unlikely(bio_op(bio) == REQ_OP_WRITE_SAME)) {
target_bio_nr = dm_bio_get_target_bio_nr(bio); target_bio_nr = dm_bio_get_target_bio_nr(bio);
BUG_ON(target_bio_nr >= sc->stripes); BUG_ON(target_bio_nr >= sc->stripes);
return stripe_map_range(sc, bio, target_bio_nr); return stripe_map_range(sc, bio, target_bio_nr);

View File

@ -1833,33 +1833,6 @@ static int device_is_not_random(struct dm_target *ti, struct dm_dev *dev,
return !blk_queue_add_random(q); return !blk_queue_add_random(q);
} }
static int device_not_write_same_capable(struct dm_target *ti, struct dm_dev *dev,
sector_t start, sector_t len, void *data)
{
struct request_queue *q = bdev_get_queue(dev->bdev);
return !q->limits.max_write_same_sectors;
}
static bool dm_table_supports_write_same(struct dm_table *t)
{
struct dm_target *ti;
unsigned i;
for (i = 0; i < dm_table_get_num_targets(t); i++) {
ti = dm_table_get_target(t, i);
if (!ti->num_write_same_bios)
return false;
if (!ti->type->iterate_devices ||
ti->type->iterate_devices(ti, device_not_write_same_capable, NULL))
return false;
}
return true;
}
static int device_not_write_zeroes_capable(struct dm_target *ti, struct dm_dev *dev, static int device_not_write_zeroes_capable(struct dm_target *ti, struct dm_dev *dev,
sector_t start, sector_t len, void *data) sector_t start, sector_t len, void *data)
{ {
@ -2038,8 +2011,6 @@ int dm_table_set_restrictions(struct dm_table *t, struct request_queue *q,
else else
blk_queue_flag_set(QUEUE_FLAG_NONROT, q); blk_queue_flag_set(QUEUE_FLAG_NONROT, q);
if (!dm_table_supports_write_same(t))
q->limits.max_write_same_sectors = 0;
if (!dm_table_supports_write_zeroes(t)) if (!dm_table_supports_write_zeroes(t))
q->limits.max_write_zeroes_sectors = 0; q->limits.max_write_zeroes_sectors = 0;

View File

@ -130,7 +130,6 @@ bool dm_is_zone_write(struct mapped_device *md, struct bio *bio)
switch (bio_op(bio)) { switch (bio_op(bio)) {
case REQ_OP_WRITE_ZEROES: case REQ_OP_WRITE_ZEROES:
case REQ_OP_WRITE_SAME:
case REQ_OP_WRITE: case REQ_OP_WRITE:
return !op_is_flush(bio->bi_opf) && bio_sectors(bio); return !op_is_flush(bio->bi_opf) && bio_sectors(bio);
default: default:
@ -390,7 +389,6 @@ static bool dm_zone_map_bio_begin(struct mapped_device *md,
case REQ_OP_ZONE_FINISH: case REQ_OP_ZONE_FINISH:
return true; return true;
case REQ_OP_WRITE_ZEROES: case REQ_OP_WRITE_ZEROES:
case REQ_OP_WRITE_SAME:
case REQ_OP_WRITE: case REQ_OP_WRITE:
/* Writes must be aligned to the zone write pointer */ /* Writes must be aligned to the zone write pointer */
if ((clone->bi_iter.bi_sector & (zsectors - 1)) != zwp_offset) if ((clone->bi_iter.bi_sector & (zsectors - 1)) != zwp_offset)
@ -446,7 +444,6 @@ static blk_status_t dm_zone_map_bio_end(struct mapped_device *md,
blk_queue_zone_sectors(md->queue)); blk_queue_zone_sectors(md->queue));
return BLK_STS_OK; return BLK_STS_OK;
case REQ_OP_WRITE_ZEROES: case REQ_OP_WRITE_ZEROES:
case REQ_OP_WRITE_SAME:
case REQ_OP_WRITE: case REQ_OP_WRITE:
WRITE_ONCE(md->zwp_offset[zno], zwp_offset + nr_sectors); WRITE_ONCE(md->zwp_offset[zno], zwp_offset + nr_sectors);
return BLK_STS_OK; return BLK_STS_OK;
@ -503,7 +500,6 @@ static bool dm_need_zone_wp_tracking(struct bio *orig_bio)
return false; return false;
switch (bio_op(orig_bio)) { switch (bio_op(orig_bio)) {
case REQ_OP_WRITE_ZEROES: case REQ_OP_WRITE_ZEROES:
case REQ_OP_WRITE_SAME:
case REQ_OP_WRITE: case REQ_OP_WRITE:
case REQ_OP_ZONE_RESET: case REQ_OP_ZONE_RESET:
case REQ_OP_ZONE_FINISH: case REQ_OP_ZONE_FINISH:

View File

@ -952,14 +952,6 @@ void disable_discard(struct mapped_device *md)
blk_queue_flag_clear(QUEUE_FLAG_DISCARD, md->queue); blk_queue_flag_clear(QUEUE_FLAG_DISCARD, md->queue);
} }
void disable_write_same(struct mapped_device *md)
{
struct queue_limits *limits = dm_get_queue_limits(md);
/* device doesn't really support WRITE SAME, disable it */
limits->max_write_same_sectors = 0;
}
void disable_write_zeroes(struct mapped_device *md) void disable_write_zeroes(struct mapped_device *md)
{ {
struct queue_limits *limits = dm_get_queue_limits(md); struct queue_limits *limits = dm_get_queue_limits(md);
@ -986,9 +978,6 @@ static void clone_endio(struct bio *bio)
if (bio_op(bio) == REQ_OP_DISCARD && if (bio_op(bio) == REQ_OP_DISCARD &&
!q->limits.max_discard_sectors) !q->limits.max_discard_sectors)
disable_discard(md); disable_discard(md);
else if (bio_op(bio) == REQ_OP_WRITE_SAME &&
!q->limits.max_write_same_sectors)
disable_write_same(md);
else if (bio_op(bio) == REQ_OP_WRITE_ZEROES && else if (bio_op(bio) == REQ_OP_WRITE_ZEROES &&
!q->limits.max_write_zeroes_sectors) !q->limits.max_write_zeroes_sectors)
disable_write_zeroes(md); disable_write_zeroes(md);
@ -1429,7 +1418,6 @@ static bool is_abnormal_io(struct bio *bio)
switch (bio_op(bio)) { switch (bio_op(bio)) {
case REQ_OP_DISCARD: case REQ_OP_DISCARD:
case REQ_OP_SECURE_ERASE: case REQ_OP_SECURE_ERASE:
case REQ_OP_WRITE_SAME:
case REQ_OP_WRITE_ZEROES: case REQ_OP_WRITE_ZEROES:
r = true; r = true;
break; break;
@ -1450,9 +1438,6 @@ static bool __process_abnormal_io(struct clone_info *ci, struct dm_target *ti,
case REQ_OP_SECURE_ERASE: case REQ_OP_SECURE_ERASE:
num_bios = ti->num_secure_erase_bios; num_bios = ti->num_secure_erase_bios;
break; break;
case REQ_OP_WRITE_SAME:
num_bios = ti->num_write_same_bios;
break;
case REQ_OP_WRITE_ZEROES: case REQ_OP_WRITE_ZEROES:
num_bios = ti->num_write_zeroes_bios; num_bios = ti->num_write_zeroes_bios;
break; break;

View File

@ -259,7 +259,6 @@ static bool linear_make_request(struct mddev *mddev, struct bio *bio)
if (mddev->gendisk) if (mddev->gendisk)
trace_block_bio_remap(bio, disk_devt(mddev->gendisk), trace_block_bio_remap(bio, disk_devt(mddev->gendisk),
bio_sector); bio_sector);
mddev_check_writesame(mddev, bio);
mddev_check_write_zeroes(mddev, bio); mddev_check_write_zeroes(mddev, bio);
submit_bio_noacct(bio); submit_bio_noacct(bio);
} }

View File

@ -127,7 +127,6 @@ static bool multipath_make_request(struct mddev *mddev, struct bio * bio)
mp_bh->bio.bi_opf |= REQ_FAILFAST_TRANSPORT; mp_bh->bio.bi_opf |= REQ_FAILFAST_TRANSPORT;
mp_bh->bio.bi_end_io = multipath_end_request; mp_bh->bio.bi_end_io = multipath_end_request;
mp_bh->bio.bi_private = mp_bh; mp_bh->bio.bi_private = mp_bh;
mddev_check_writesame(mddev, &mp_bh->bio);
mddev_check_write_zeroes(mddev, &mp_bh->bio); mddev_check_write_zeroes(mddev, &mp_bh->bio);
submit_bio_noacct(&mp_bh->bio); submit_bio_noacct(&mp_bh->bio);
return true; return true;

View File

@ -797,13 +797,6 @@ static inline void mddev_clear_unsupported_flags(struct mddev *mddev,
mddev->flags &= ~unsupported_flags; mddev->flags &= ~unsupported_flags;
} }
static inline void mddev_check_writesame(struct mddev *mddev, struct bio *bio)
{
if (bio_op(bio) == REQ_OP_WRITE_SAME &&
!bio->bi_bdev->bd_disk->queue->limits.max_write_same_sectors)
mddev->queue->limits.max_write_same_sectors = 0;
}
static inline void mddev_check_write_zeroes(struct mddev *mddev, struct bio *bio) static inline void mddev_check_write_zeroes(struct mddev *mddev, struct bio *bio)
{ {
if (bio_op(bio) == REQ_OP_WRITE_ZEROES && if (bio_op(bio) == REQ_OP_WRITE_ZEROES &&

View File

@ -402,7 +402,6 @@ static int raid0_run(struct mddev *mddev)
bool discard_supported = false; bool discard_supported = false;
blk_queue_max_hw_sectors(mddev->queue, mddev->chunk_sectors); blk_queue_max_hw_sectors(mddev->queue, mddev->chunk_sectors);
blk_queue_max_write_same_sectors(mddev->queue, mddev->chunk_sectors);
blk_queue_max_write_zeroes_sectors(mddev->queue, mddev->chunk_sectors); blk_queue_max_write_zeroes_sectors(mddev->queue, mddev->chunk_sectors);
blk_queue_max_discard_sectors(mddev->queue, UINT_MAX); blk_queue_max_discard_sectors(mddev->queue, UINT_MAX);
@ -594,7 +593,6 @@ static bool raid0_make_request(struct mddev *mddev, struct bio *bio)
if (mddev->gendisk) if (mddev->gendisk)
trace_block_bio_remap(bio, disk_devt(mddev->gendisk), trace_block_bio_remap(bio, disk_devt(mddev->gendisk),
bio_sector); bio_sector);
mddev_check_writesame(mddev, bio);
mddev_check_write_zeroes(mddev, bio); mddev_check_write_zeroes(mddev, bio);
submit_bio_noacct(bio); submit_bio_noacct(bio);
return true; return true;

View File

@ -3135,10 +3135,8 @@ static int raid1_run(struct mddev *mddev)
if (IS_ERR(conf)) if (IS_ERR(conf))
return PTR_ERR(conf); return PTR_ERR(conf);
if (mddev->queue) { if (mddev->queue)
blk_queue_max_write_same_sectors(mddev->queue, 0);
blk_queue_max_write_zeroes_sectors(mddev->queue, 0); blk_queue_max_write_zeroes_sectors(mddev->queue, 0);
}
rdev_for_each(rdev, mddev) { rdev_for_each(rdev, mddev) {
if (!mddev->gendisk) if (!mddev->gendisk)

View File

@ -4102,7 +4102,6 @@ static int raid10_run(struct mddev *mddev)
if (mddev->queue) { if (mddev->queue) {
blk_queue_max_discard_sectors(mddev->queue, blk_queue_max_discard_sectors(mddev->queue,
UINT_MAX); UINT_MAX);
blk_queue_max_write_same_sectors(mddev->queue, 0);
blk_queue_max_write_zeroes_sectors(mddev->queue, 0); blk_queue_max_write_zeroes_sectors(mddev->queue, 0);
blk_queue_io_min(mddev->queue, mddev->chunk_sectors << 9); blk_queue_io_min(mddev->queue, mddev->chunk_sectors << 9);
raid10_set_io_opt(conf); raid10_set_io_opt(conf);

View File

@ -7758,7 +7758,6 @@ static int raid5_run(struct mddev *mddev)
mddev->queue->limits.discard_alignment = stripe; mddev->queue->limits.discard_alignment = stripe;
mddev->queue->limits.discard_granularity = stripe; mddev->queue->limits.discard_granularity = stripe;
blk_queue_max_write_same_sectors(mddev->queue, 0);
blk_queue_max_write_zeroes_sectors(mddev->queue, 0); blk_queue_max_write_zeroes_sectors(mddev->queue, 0);
rdev_for_each(rdev, mddev) { rdev_for_each(rdev, mddev) {

View File

@ -3680,7 +3680,7 @@ mptsas_expander_add(MPT_ADAPTER *ioc, u16 handle)
MPI_SAS_EXPAND_PGAD_FORM_SHIFT), handle))) MPI_SAS_EXPAND_PGAD_FORM_SHIFT), handle)))
return NULL; return NULL;
port_info = kzalloc(sizeof(struct mptsas_portinfo), GFP_ATOMIC); port_info = kzalloc(sizeof(struct mptsas_portinfo), GFP_KERNEL);
if (!port_info) { if (!port_info) {
dfailprintk(ioc, printk(MYIOC_s_ERR_FMT dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
"%s: exit at line=%d\n", ioc->name, "%s: exit at line=%d\n", ioc->name,

View File

@ -1493,7 +1493,7 @@ mptspi_probe(struct pci_dev *pdev, const struct pci_device_id *id)
/* SCSI needs scsi_cmnd lookup table! /* SCSI needs scsi_cmnd lookup table!
* (with size equal to req_depth*PtrSz!) * (with size equal to req_depth*PtrSz!)
*/ */
ioc->ScsiLookup = kcalloc(ioc->req_depth, sizeof(void *), GFP_ATOMIC); ioc->ScsiLookup = kcalloc(ioc->req_depth, sizeof(void *), GFP_KERNEL);
if (!ioc->ScsiLookup) { if (!ioc->ScsiLookup) {
error = -ENOMEM; error = -ENOMEM;
goto out_mptspi_probe; goto out_mptspi_probe;

View File

@ -1791,8 +1791,6 @@ static int NCR_700_queuecommand_lck(struct scsi_cmnd *SCp)
slot->cmnd = SCp; slot->cmnd = SCp;
SCp->host_scribble = (unsigned char *)slot; SCp->host_scribble = (unsigned char *)slot;
SCp->SCp.ptr = NULL;
SCp->SCp.buffer = NULL;
#ifdef NCR_700_DEBUG #ifdef NCR_700_DEBUG
printk("53c700: scsi%d, command ", SCp->device->host->host_no); printk("53c700: scsi%d, command ", SCp->device->host->host_no);

View File

@ -84,8 +84,7 @@
* On command termination, the done function will be called as * On command termination, the done function will be called as
* appropriate. * appropriate.
* *
* SCSI pointers are maintained in the SCp field of SCSI command * The command data pointer is initialized after the command is connected
* structures, being initialized after the command is connected
* in NCR5380_select, and set as appropriate in NCR5380_information_transfer. * in NCR5380_select, and set as appropriate in NCR5380_information_transfer.
* Note that in violation of the standard, an implicit SAVE POINTERS operation * Note that in violation of the standard, an implicit SAVE POINTERS operation
* is done, since some BROKEN disks fail to issue an explicit SAVE POINTERS. * is done, since some BROKEN disks fail to issue an explicit SAVE POINTERS.
@ -145,40 +144,38 @@ static void bus_reset_cleanup(struct Scsi_Host *);
static inline void initialize_SCp(struct scsi_cmnd *cmd) static inline void initialize_SCp(struct scsi_cmnd *cmd)
{ {
/* struct NCR5380_cmd *ncmd = NCR5380_to_ncmd(cmd);
* Initialize the Scsi Pointer field so that all of the commands in the
* various queues are valid.
*/
if (scsi_bufflen(cmd)) { if (scsi_bufflen(cmd)) {
cmd->SCp.buffer = scsi_sglist(cmd); ncmd->buffer = scsi_sglist(cmd);
cmd->SCp.ptr = sg_virt(cmd->SCp.buffer); ncmd->ptr = sg_virt(ncmd->buffer);
cmd->SCp.this_residual = cmd->SCp.buffer->length; ncmd->this_residual = ncmd->buffer->length;
} else { } else {
cmd->SCp.buffer = NULL; ncmd->buffer = NULL;
cmd->SCp.ptr = NULL; ncmd->ptr = NULL;
cmd->SCp.this_residual = 0; ncmd->this_residual = 0;
} }
cmd->SCp.Status = 0; ncmd->status = 0;
cmd->SCp.Message = 0; ncmd->message = 0;
} }
static inline void advance_sg_buffer(struct scsi_cmnd *cmd) static inline void advance_sg_buffer(struct NCR5380_cmd *ncmd)
{ {
struct scatterlist *s = cmd->SCp.buffer; struct scatterlist *s = ncmd->buffer;
if (!cmd->SCp.this_residual && s && !sg_is_last(s)) { if (!ncmd->this_residual && s && !sg_is_last(s)) {
cmd->SCp.buffer = sg_next(s); ncmd->buffer = sg_next(s);
cmd->SCp.ptr = sg_virt(cmd->SCp.buffer); ncmd->ptr = sg_virt(ncmd->buffer);
cmd->SCp.this_residual = cmd->SCp.buffer->length; ncmd->this_residual = ncmd->buffer->length;
} }
} }
static inline void set_resid_from_SCp(struct scsi_cmnd *cmd) static inline void set_resid_from_SCp(struct scsi_cmnd *cmd)
{ {
int resid = cmd->SCp.this_residual; struct NCR5380_cmd *ncmd = NCR5380_to_ncmd(cmd);
struct scatterlist *s = cmd->SCp.buffer; int resid = ncmd->this_residual;
struct scatterlist *s = ncmd->buffer;
if (s) if (s)
while (!sg_is_last(s)) { while (!sg_is_last(s)) {
@ -564,7 +561,7 @@ static int NCR5380_queue_command(struct Scsi_Host *instance,
struct scsi_cmnd *cmd) struct scsi_cmnd *cmd)
{ {
struct NCR5380_hostdata *hostdata = shost_priv(instance); struct NCR5380_hostdata *hostdata = shost_priv(instance);
struct NCR5380_cmd *ncmd = scsi_cmd_priv(cmd); struct NCR5380_cmd *ncmd = NCR5380_to_ncmd(cmd);
unsigned long flags; unsigned long flags;
#if (NDEBUG & NDEBUG_NO_WRITE) #if (NDEBUG & NDEBUG_NO_WRITE)
@ -672,7 +669,7 @@ static struct scsi_cmnd *dequeue_next_cmd(struct Scsi_Host *instance)
static void requeue_cmd(struct Scsi_Host *instance, struct scsi_cmnd *cmd) static void requeue_cmd(struct Scsi_Host *instance, struct scsi_cmnd *cmd)
{ {
struct NCR5380_hostdata *hostdata = shost_priv(instance); struct NCR5380_hostdata *hostdata = shost_priv(instance);
struct NCR5380_cmd *ncmd = scsi_cmd_priv(cmd); struct NCR5380_cmd *ncmd = NCR5380_to_ncmd(cmd);
if (hostdata->sensing == cmd) { if (hostdata->sensing == cmd) {
scsi_eh_restore_cmnd(cmd, &hostdata->ses); scsi_eh_restore_cmnd(cmd, &hostdata->ses);
@ -757,6 +754,7 @@ static void NCR5380_main(struct work_struct *work)
static void NCR5380_dma_complete(struct Scsi_Host *instance) static void NCR5380_dma_complete(struct Scsi_Host *instance)
{ {
struct NCR5380_hostdata *hostdata = shost_priv(instance); struct NCR5380_hostdata *hostdata = shost_priv(instance);
struct NCR5380_cmd *ncmd = NCR5380_to_ncmd(hostdata->connected);
int transferred; int transferred;
unsigned char **data; unsigned char **data;
int *count; int *count;
@ -764,7 +762,7 @@ static void NCR5380_dma_complete(struct Scsi_Host *instance)
unsigned char p; unsigned char p;
if (hostdata->read_overruns) { if (hostdata->read_overruns) {
p = hostdata->connected->SCp.phase; p = ncmd->phase;
if (p & SR_IO) { if (p & SR_IO) {
udelay(10); udelay(10);
if ((NCR5380_read(BUS_AND_STATUS_REG) & if ((NCR5380_read(BUS_AND_STATUS_REG) &
@ -801,8 +799,8 @@ static void NCR5380_dma_complete(struct Scsi_Host *instance)
transferred = hostdata->dma_len - NCR5380_dma_residual(hostdata); transferred = hostdata->dma_len - NCR5380_dma_residual(hostdata);
hostdata->dma_len = 0; hostdata->dma_len = 0;
data = (unsigned char **)&hostdata->connected->SCp.ptr; data = (unsigned char **)&ncmd->ptr;
count = &hostdata->connected->SCp.this_residual; count = &ncmd->this_residual;
*data += transferred; *data += transferred;
*count -= transferred; *count -= transferred;
@ -1498,7 +1496,7 @@ static int NCR5380_transfer_dma(struct Scsi_Host *instance,
return -1; return -1;
} }
hostdata->connected->SCp.phase = p; NCR5380_to_ncmd(hostdata->connected)->phase = p;
if (p & SR_IO) { if (p & SR_IO) {
if (hostdata->read_overruns) if (hostdata->read_overruns)
@ -1690,7 +1688,7 @@ static void NCR5380_information_transfer(struct Scsi_Host *instance)
#endif #endif
while ((cmd = hostdata->connected)) { while ((cmd = hostdata->connected)) {
struct NCR5380_cmd *ncmd = scsi_cmd_priv(cmd); struct NCR5380_cmd *ncmd = NCR5380_to_ncmd(cmd);
tmp = NCR5380_read(STATUS_REG); tmp = NCR5380_read(STATUS_REG);
/* We only have a valid SCSI phase when REQ is asserted */ /* We only have a valid SCSI phase when REQ is asserted */
@ -1705,17 +1703,17 @@ static void NCR5380_information_transfer(struct Scsi_Host *instance)
sun3_dma_setup_done != cmd) { sun3_dma_setup_done != cmd) {
int count; int count;
advance_sg_buffer(cmd); advance_sg_buffer(ncmd);
count = sun3scsi_dma_xfer_len(hostdata, cmd); count = sun3scsi_dma_xfer_len(hostdata, cmd);
if (count > 0) { if (count > 0) {
if (cmd->sc_data_direction == DMA_TO_DEVICE) if (cmd->sc_data_direction == DMA_TO_DEVICE)
sun3scsi_dma_send_setup(hostdata, sun3scsi_dma_send_setup(hostdata,
cmd->SCp.ptr, count); ncmd->ptr, count);
else else
sun3scsi_dma_recv_setup(hostdata, sun3scsi_dma_recv_setup(hostdata,
cmd->SCp.ptr, count); ncmd->ptr, count);
sun3_dma_setup_done = cmd; sun3_dma_setup_done = cmd;
} }
#ifdef SUN3_SCSI_VME #ifdef SUN3_SCSI_VME
@ -1755,11 +1753,11 @@ static void NCR5380_information_transfer(struct Scsi_Host *instance)
* scatter-gather list, move onto the next one. * scatter-gather list, move onto the next one.
*/ */
advance_sg_buffer(cmd); advance_sg_buffer(ncmd);
dsprintk(NDEBUG_INFORMATION, instance, dsprintk(NDEBUG_INFORMATION, instance,
"this residual %d, sg ents %d\n", "this residual %d, sg ents %d\n",
cmd->SCp.this_residual, ncmd->this_residual,
sg_nents(cmd->SCp.buffer)); sg_nents(ncmd->buffer));
/* /*
* The preferred transfer method is going to be * The preferred transfer method is going to be
@ -1778,7 +1776,7 @@ static void NCR5380_information_transfer(struct Scsi_Host *instance)
if (transfersize > 0) { if (transfersize > 0) {
len = transfersize; len = transfersize;
if (NCR5380_transfer_dma(instance, &phase, if (NCR5380_transfer_dma(instance, &phase,
&len, (unsigned char **)&cmd->SCp.ptr)) { &len, (unsigned char **)&ncmd->ptr)) {
/* /*
* If the watchdog timer fires, all future * If the watchdog timer fires, all future
* accesses to this device will use the * accesses to this device will use the
@ -1794,13 +1792,13 @@ static void NCR5380_information_transfer(struct Scsi_Host *instance)
/* Transfer a small chunk so that the /* Transfer a small chunk so that the
* irq mode lock is not held too long. * irq mode lock is not held too long.
*/ */
transfersize = min(cmd->SCp.this_residual, transfersize = min(ncmd->this_residual,
NCR5380_PIO_CHUNK_SIZE); NCR5380_PIO_CHUNK_SIZE);
len = transfersize; len = transfersize;
NCR5380_transfer_pio(instance, &phase, &len, NCR5380_transfer_pio(instance, &phase, &len,
(unsigned char **)&cmd->SCp.ptr, (unsigned char **)&ncmd->ptr,
0); 0);
cmd->SCp.this_residual -= transfersize - len; ncmd->this_residual -= transfersize - len;
} }
#ifdef CONFIG_SUN3 #ifdef CONFIG_SUN3
if (sun3_dma_setup_done == cmd) if (sun3_dma_setup_done == cmd)
@ -1811,7 +1809,7 @@ static void NCR5380_information_transfer(struct Scsi_Host *instance)
len = 1; len = 1;
data = &tmp; data = &tmp;
NCR5380_transfer_pio(instance, &phase, &len, &data, 0); NCR5380_transfer_pio(instance, &phase, &len, &data, 0);
cmd->SCp.Message = tmp; ncmd->message = tmp;
switch (tmp) { switch (tmp) {
case ABORT: case ABORT:
@ -1828,15 +1826,15 @@ static void NCR5380_information_transfer(struct Scsi_Host *instance)
hostdata->connected = NULL; hostdata->connected = NULL;
hostdata->busy[scmd_id(cmd)] &= ~(1 << cmd->device->lun); hostdata->busy[scmd_id(cmd)] &= ~(1 << cmd->device->lun);
set_status_byte(cmd, cmd->SCp.Status); set_status_byte(cmd, ncmd->status);
set_resid_from_SCp(cmd); set_resid_from_SCp(cmd);
if (cmd->cmnd[0] == REQUEST_SENSE) if (cmd->cmnd[0] == REQUEST_SENSE)
complete_cmd(instance, cmd); complete_cmd(instance, cmd);
else { else {
if (cmd->SCp.Status == SAM_STAT_CHECK_CONDITION || if (ncmd->status == SAM_STAT_CHECK_CONDITION ||
cmd->SCp.Status == SAM_STAT_COMMAND_TERMINATED) { ncmd->status == SAM_STAT_COMMAND_TERMINATED) {
dsprintk(NDEBUG_QUEUES, instance, "autosense: adding cmd %p to tail of autosense queue\n", dsprintk(NDEBUG_QUEUES, instance, "autosense: adding cmd %p to tail of autosense queue\n",
cmd); cmd);
list_add_tail(&ncmd->list, list_add_tail(&ncmd->list,
@ -2000,7 +1998,7 @@ static void NCR5380_information_transfer(struct Scsi_Host *instance)
len = 1; len = 1;
data = &tmp; data = &tmp;
NCR5380_transfer_pio(instance, &phase, &len, &data, 0); NCR5380_transfer_pio(instance, &phase, &len, &data, 0);
cmd->SCp.Status = tmp; ncmd->status = tmp;
break; break;
default: default:
shost_printk(KERN_ERR, instance, "unknown phase\n"); shost_printk(KERN_ERR, instance, "unknown phase\n");
@ -2153,17 +2151,17 @@ static void NCR5380_reselect(struct Scsi_Host *instance)
if (sun3_dma_setup_done != tmp) { if (sun3_dma_setup_done != tmp) {
int count; int count;
advance_sg_buffer(tmp); advance_sg_buffer(ncmd);
count = sun3scsi_dma_xfer_len(hostdata, tmp); count = sun3scsi_dma_xfer_len(hostdata, tmp);
if (count > 0) { if (count > 0) {
if (tmp->sc_data_direction == DMA_TO_DEVICE) if (tmp->sc_data_direction == DMA_TO_DEVICE)
sun3scsi_dma_send_setup(hostdata, sun3scsi_dma_send_setup(hostdata,
tmp->SCp.ptr, count); ncmd->ptr, count);
else else
sun3scsi_dma_recv_setup(hostdata, sun3scsi_dma_recv_setup(hostdata,
tmp->SCp.ptr, count); ncmd->ptr, count);
sun3_dma_setup_done = tmp; sun3_dma_setup_done = tmp;
} }
} }
@ -2206,7 +2204,7 @@ static bool list_del_cmd(struct list_head *haystack,
struct scsi_cmnd *needle) struct scsi_cmnd *needle)
{ {
if (list_find_cmd(haystack, needle)) { if (list_find_cmd(haystack, needle)) {
struct NCR5380_cmd *ncmd = scsi_cmd_priv(needle); struct NCR5380_cmd *ncmd = NCR5380_to_ncmd(needle);
list_del(&ncmd->list); list_del(&ncmd->list);
return true; return true;

View File

@ -227,11 +227,15 @@ struct NCR5380_hostdata {
}; };
struct NCR5380_cmd { struct NCR5380_cmd {
char *ptr;
int this_residual;
struct scatterlist *buffer;
int status;
int message;
int phase;
struct list_head list; struct list_head list;
}; };
#define NCR5380_CMD_SIZE (sizeof(struct NCR5380_cmd))
#define NCR5380_PIO_CHUNK_SIZE 256 #define NCR5380_PIO_CHUNK_SIZE 256
/* Time limit (ms) to poll registers when IRQs are disabled, e.g. during PDMA */ /* Time limit (ms) to poll registers when IRQs are disabled, e.g. during PDMA */
@ -242,6 +246,11 @@ static inline struct scsi_cmnd *NCR5380_to_scmd(struct NCR5380_cmd *ncmd_ptr)
return ((struct scsi_cmnd *)ncmd_ptr) - 1; return ((struct scsi_cmnd *)ncmd_ptr) - 1;
} }
static inline struct NCR5380_cmd *NCR5380_to_ncmd(struct scsi_cmnd *cmd)
{
return scsi_cmd_priv(cmd);
}
#ifndef NDEBUG #ifndef NDEBUG
#define NDEBUG (0) #define NDEBUG (0)
#endif #endif

View File

@ -12,7 +12,11 @@
#include <asm/amigaints.h> #include <asm/amigaints.h>
#include <asm/amigahw.h> #include <asm/amigahw.h>
#include "scsi.h" #include <scsi/scsi.h>
#include <scsi/scsi_cmnd.h>
#include <scsi/scsi_device.h>
#include <scsi/scsi_eh.h>
#include <scsi/scsi_tcq.h>
#include "wd33c93.h" #include "wd33c93.h"
#include "a2091.h" #include "a2091.h"
@ -40,16 +44,17 @@ static irqreturn_t a2091_intr(int irq, void *data)
static int dma_setup(struct scsi_cmnd *cmd, int dir_in) static int dma_setup(struct scsi_cmnd *cmd, int dir_in)
{ {
struct scsi_pointer *scsi_pointer = WD33C93_scsi_pointer(cmd);
struct Scsi_Host *instance = cmd->device->host; struct Scsi_Host *instance = cmd->device->host;
struct a2091_hostdata *hdata = shost_priv(instance); struct a2091_hostdata *hdata = shost_priv(instance);
struct WD33C93_hostdata *wh = &hdata->wh; struct WD33C93_hostdata *wh = &hdata->wh;
struct a2091_scsiregs *regs = hdata->regs; struct a2091_scsiregs *regs = hdata->regs;
unsigned short cntr = CNTR_PDMD | CNTR_INTEN; unsigned short cntr = CNTR_PDMD | CNTR_INTEN;
unsigned long addr = virt_to_bus(cmd->SCp.ptr); unsigned long addr = virt_to_bus(scsi_pointer->ptr);
/* don't allow DMA if the physical address is bad */ /* don't allow DMA if the physical address is bad */
if (addr & A2091_XFER_MASK) { if (addr & A2091_XFER_MASK) {
wh->dma_bounce_len = (cmd->SCp.this_residual + 511) & ~0x1ff; wh->dma_bounce_len = (scsi_pointer->this_residual + 511) & ~0x1ff;
wh->dma_bounce_buffer = kmalloc(wh->dma_bounce_len, wh->dma_bounce_buffer = kmalloc(wh->dma_bounce_len,
GFP_KERNEL); GFP_KERNEL);
@ -73,8 +78,8 @@ static int dma_setup(struct scsi_cmnd *cmd, int dir_in)
if (!dir_in) { if (!dir_in) {
/* copy to bounce buffer for a write */ /* copy to bounce buffer for a write */
memcpy(wh->dma_bounce_buffer, cmd->SCp.ptr, memcpy(wh->dma_bounce_buffer, scsi_pointer->ptr,
cmd->SCp.this_residual); scsi_pointer->this_residual);
} }
} }
@ -92,10 +97,10 @@ static int dma_setup(struct scsi_cmnd *cmd, int dir_in)
if (dir_in) { if (dir_in) {
/* invalidate any cache */ /* invalidate any cache */
cache_clear(addr, cmd->SCp.this_residual); cache_clear(addr, scsi_pointer->this_residual);
} else { } else {
/* push any dirty cache */ /* push any dirty cache */
cache_push(addr, cmd->SCp.this_residual); cache_push(addr, scsi_pointer->this_residual);
} }
/* start DMA */ /* start DMA */
regs->ST_DMA = 1; regs->ST_DMA = 1;
@ -107,6 +112,7 @@ static int dma_setup(struct scsi_cmnd *cmd, int dir_in)
static void dma_stop(struct Scsi_Host *instance, struct scsi_cmnd *SCpnt, static void dma_stop(struct Scsi_Host *instance, struct scsi_cmnd *SCpnt,
int status) int status)
{ {
struct scsi_pointer *scsi_pointer = WD33C93_scsi_pointer(SCpnt);
struct a2091_hostdata *hdata = shost_priv(instance); struct a2091_hostdata *hdata = shost_priv(instance);
struct WD33C93_hostdata *wh = &hdata->wh; struct WD33C93_hostdata *wh = &hdata->wh;
struct a2091_scsiregs *regs = hdata->regs; struct a2091_scsiregs *regs = hdata->regs;
@ -139,8 +145,8 @@ static void dma_stop(struct Scsi_Host *instance, struct scsi_cmnd *SCpnt,
/* copy from a bounce buffer, if necessary */ /* copy from a bounce buffer, if necessary */
if (status && wh->dma_bounce_buffer) { if (status && wh->dma_bounce_buffer) {
if (wh->dma_dir) if (wh->dma_dir)
memcpy(SCpnt->SCp.ptr, wh->dma_bounce_buffer, memcpy(scsi_pointer->ptr, wh->dma_bounce_buffer,
SCpnt->SCp.this_residual); scsi_pointer->this_residual);
kfree(wh->dma_bounce_buffer); kfree(wh->dma_bounce_buffer);
wh->dma_bounce_buffer = NULL; wh->dma_bounce_buffer = NULL;
wh->dma_bounce_len = 0; wh->dma_bounce_len = 0;
@ -161,6 +167,7 @@ static struct scsi_host_template a2091_scsi_template = {
.sg_tablesize = SG_ALL, .sg_tablesize = SG_ALL,
.cmd_per_lun = CMD_PER_LUN, .cmd_per_lun = CMD_PER_LUN,
.dma_boundary = PAGE_SIZE - 1, .dma_boundary = PAGE_SIZE - 1,
.cmd_size = sizeof(struct scsi_pointer),
}; };
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

@ -13,7 +13,11 @@
#include <asm/amigaints.h> #include <asm/amigaints.h>
#include <asm/amigahw.h> #include <asm/amigahw.h>
#include "scsi.h" #include <scsi/scsi.h>
#include <scsi/scsi_cmnd.h>
#include <scsi/scsi_device.h>
#include <scsi/scsi_eh.h>
#include <scsi/scsi_tcq.h>
#include "wd33c93.h" #include "wd33c93.h"
#include "a3000.h" #include "a3000.h"
@ -44,12 +48,13 @@ static irqreturn_t a3000_intr(int irq, void *data)
static int dma_setup(struct scsi_cmnd *cmd, int dir_in) static int dma_setup(struct scsi_cmnd *cmd, int dir_in)
{ {
struct scsi_pointer *scsi_pointer = WD33C93_scsi_pointer(cmd);
struct Scsi_Host *instance = cmd->device->host; struct Scsi_Host *instance = cmd->device->host;
struct a3000_hostdata *hdata = shost_priv(instance); struct a3000_hostdata *hdata = shost_priv(instance);
struct WD33C93_hostdata *wh = &hdata->wh; struct WD33C93_hostdata *wh = &hdata->wh;
struct a3000_scsiregs *regs = hdata->regs; struct a3000_scsiregs *regs = hdata->regs;
unsigned short cntr = CNTR_PDMD | CNTR_INTEN; unsigned short cntr = CNTR_PDMD | CNTR_INTEN;
unsigned long addr = virt_to_bus(cmd->SCp.ptr); unsigned long addr = virt_to_bus(scsi_pointer->ptr);
/* /*
* if the physical address has the wrong alignment, or if * if the physical address has the wrong alignment, or if
@ -58,7 +63,7 @@ static int dma_setup(struct scsi_cmnd *cmd, int dir_in)
* buffer * buffer
*/ */
if (addr & A3000_XFER_MASK) { if (addr & A3000_XFER_MASK) {
wh->dma_bounce_len = (cmd->SCp.this_residual + 511) & ~0x1ff; wh->dma_bounce_len = (scsi_pointer->this_residual + 511) & ~0x1ff;
wh->dma_bounce_buffer = kmalloc(wh->dma_bounce_len, wh->dma_bounce_buffer = kmalloc(wh->dma_bounce_len,
GFP_KERNEL); GFP_KERNEL);
@ -70,8 +75,8 @@ static int dma_setup(struct scsi_cmnd *cmd, int dir_in)
if (!dir_in) { if (!dir_in) {
/* copy to bounce buffer for a write */ /* copy to bounce buffer for a write */
memcpy(wh->dma_bounce_buffer, cmd->SCp.ptr, memcpy(wh->dma_bounce_buffer, scsi_pointer->ptr,
cmd->SCp.this_residual); scsi_pointer->this_residual);
} }
addr = virt_to_bus(wh->dma_bounce_buffer); addr = virt_to_bus(wh->dma_bounce_buffer);
@ -91,10 +96,10 @@ static int dma_setup(struct scsi_cmnd *cmd, int dir_in)
if (dir_in) { if (dir_in) {
/* invalidate any cache */ /* invalidate any cache */
cache_clear(addr, cmd->SCp.this_residual); cache_clear(addr, scsi_pointer->this_residual);
} else { } else {
/* push any dirty cache */ /* push any dirty cache */
cache_push(addr, cmd->SCp.this_residual); cache_push(addr, scsi_pointer->this_residual);
} }
/* start DMA */ /* start DMA */
@ -109,6 +114,7 @@ static int dma_setup(struct scsi_cmnd *cmd, int dir_in)
static void dma_stop(struct Scsi_Host *instance, struct scsi_cmnd *SCpnt, static void dma_stop(struct Scsi_Host *instance, struct scsi_cmnd *SCpnt,
int status) int status)
{ {
struct scsi_pointer *scsi_pointer = WD33C93_scsi_pointer(SCpnt);
struct a3000_hostdata *hdata = shost_priv(instance); struct a3000_hostdata *hdata = shost_priv(instance);
struct WD33C93_hostdata *wh = &hdata->wh; struct WD33C93_hostdata *wh = &hdata->wh;
struct a3000_scsiregs *regs = hdata->regs; struct a3000_scsiregs *regs = hdata->regs;
@ -149,8 +155,8 @@ static void dma_stop(struct Scsi_Host *instance, struct scsi_cmnd *SCpnt,
if (status && wh->dma_bounce_buffer) { if (status && wh->dma_bounce_buffer) {
if (SCpnt) { if (SCpnt) {
if (wh->dma_dir && SCpnt) if (wh->dma_dir && SCpnt)
memcpy(SCpnt->SCp.ptr, wh->dma_bounce_buffer, memcpy(scsi_pointer->ptr, wh->dma_bounce_buffer,
SCpnt->SCp.this_residual); scsi_pointer->this_residual);
kfree(wh->dma_bounce_buffer); kfree(wh->dma_bounce_buffer);
wh->dma_bounce_buffer = NULL; wh->dma_bounce_buffer = NULL;
wh->dma_bounce_len = 0; wh->dma_bounce_len = 0;
@ -175,6 +181,7 @@ 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,
.cmd_size = sizeof(struct scsi_pointer),
}; };
static int __init amiga_a3000_scsi_probe(struct platform_device *pdev) static int __init amiga_a3000_scsi_probe(struct platform_device *pdev)

View File

@ -338,7 +338,7 @@ static inline int aac_valid_context(struct scsi_cmnd *scsicmd,
aac_fib_complete(fibptr); aac_fib_complete(fibptr);
return 0; return 0;
} }
scsicmd->SCp.phase = AAC_OWNER_MIDLEVEL; aac_priv(scsicmd)->owner = AAC_OWNER_MIDLEVEL;
device = scsicmd->device; device = scsicmd->device;
if (unlikely(!device)) { if (unlikely(!device)) {
dprintk((KERN_WARNING "aac_valid_context: scsi device corrupt\n")); dprintk((KERN_WARNING "aac_valid_context: scsi device corrupt\n"));
@ -592,7 +592,7 @@ static int aac_get_container_name(struct scsi_cmnd * scsicmd)
aac_fib_init(cmd_fibcontext); aac_fib_init(cmd_fibcontext);
dinfo = (struct aac_get_name *) fib_data(cmd_fibcontext); dinfo = (struct aac_get_name *) fib_data(cmd_fibcontext);
scsicmd->SCp.phase = AAC_OWNER_FIRMWARE; aac_priv(scsicmd)->owner = AAC_OWNER_FIRMWARE;
dinfo->command = cpu_to_le32(VM_ContainerConfig); dinfo->command = cpu_to_le32(VM_ContainerConfig);
dinfo->type = cpu_to_le32(CT_READ_NAME); dinfo->type = cpu_to_le32(CT_READ_NAME);
@ -634,14 +634,15 @@ static void _aac_probe_container2(void * context, struct fib * fibptr)
{ {
struct fsa_dev_info *fsa_dev_ptr; struct fsa_dev_info *fsa_dev_ptr;
int (*callback)(struct scsi_cmnd *); int (*callback)(struct scsi_cmnd *);
struct scsi_cmnd * scsicmd = (struct scsi_cmnd *)context; struct scsi_cmnd *scsicmd = context;
struct aac_cmd_priv *cmd_priv = aac_priv(scsicmd);
int i; int i;
if (!aac_valid_context(scsicmd, fibptr)) if (!aac_valid_context(scsicmd, fibptr))
return; return;
scsicmd->SCp.Status = 0; cmd_priv->status = 0;
fsa_dev_ptr = fibptr->dev->fsa_dev; fsa_dev_ptr = fibptr->dev->fsa_dev;
if (fsa_dev_ptr) { if (fsa_dev_ptr) {
struct aac_mount * dresp = (struct aac_mount *) fib_data(fibptr); struct aac_mount * dresp = (struct aac_mount *) fib_data(fibptr);
@ -679,12 +680,12 @@ static void _aac_probe_container2(void * context, struct fib * fibptr)
} }
if ((fsa_dev_ptr->valid & 1) == 0) if ((fsa_dev_ptr->valid & 1) == 0)
fsa_dev_ptr->valid = 0; fsa_dev_ptr->valid = 0;
scsicmd->SCp.Status = le32_to_cpu(dresp->count); cmd_priv->status = le32_to_cpu(dresp->count);
} }
aac_fib_complete(fibptr); aac_fib_complete(fibptr);
aac_fib_free(fibptr); aac_fib_free(fibptr);
callback = (int (*)(struct scsi_cmnd *))(scsicmd->SCp.ptr); callback = cmd_priv->callback;
scsicmd->SCp.ptr = NULL; cmd_priv->callback = NULL;
(*callback)(scsicmd); (*callback)(scsicmd);
return; return;
} }
@ -722,7 +723,7 @@ static void _aac_probe_container1(void * context, struct fib * fibptr)
dinfo->count = cpu_to_le32(scmd_id(scsicmd)); dinfo->count = cpu_to_le32(scmd_id(scsicmd));
dinfo->type = cpu_to_le32(FT_FILESYS); dinfo->type = cpu_to_le32(FT_FILESYS);
scsicmd->SCp.phase = AAC_OWNER_FIRMWARE; aac_priv(scsicmd)->owner = AAC_OWNER_FIRMWARE;
status = aac_fib_send(ContainerCommand, status = aac_fib_send(ContainerCommand,
fibptr, fibptr,
@ -743,6 +744,7 @@ static void _aac_probe_container1(void * context, struct fib * fibptr)
static int _aac_probe_container(struct scsi_cmnd * scsicmd, int (*callback)(struct scsi_cmnd *)) static int _aac_probe_container(struct scsi_cmnd * scsicmd, int (*callback)(struct scsi_cmnd *))
{ {
struct aac_cmd_priv *cmd_priv = aac_priv(scsicmd);
struct fib * fibptr; struct fib * fibptr;
int status = -ENOMEM; int status = -ENOMEM;
@ -761,8 +763,8 @@ static int _aac_probe_container(struct scsi_cmnd * scsicmd, int (*callback)(stru
dinfo->count = cpu_to_le32(scmd_id(scsicmd)); dinfo->count = cpu_to_le32(scmd_id(scsicmd));
dinfo->type = cpu_to_le32(FT_FILESYS); dinfo->type = cpu_to_le32(FT_FILESYS);
scsicmd->SCp.ptr = (char *)callback; cmd_priv->callback = callback;
scsicmd->SCp.phase = AAC_OWNER_FIRMWARE; cmd_priv->owner = AAC_OWNER_FIRMWARE;
status = aac_fib_send(ContainerCommand, status = aac_fib_send(ContainerCommand,
fibptr, fibptr,
@ -778,7 +780,7 @@ static int _aac_probe_container(struct scsi_cmnd * scsicmd, int (*callback)(stru
return 0; return 0;
if (status < 0) { if (status < 0) {
scsicmd->SCp.ptr = NULL; cmd_priv->callback = NULL;
aac_fib_complete(fibptr); aac_fib_complete(fibptr);
aac_fib_free(fibptr); aac_fib_free(fibptr);
} }
@ -817,6 +819,7 @@ static void aac_probe_container_scsi_done(struct scsi_cmnd *scsi_cmnd)
int aac_probe_container(struct aac_dev *dev, int cid) int aac_probe_container(struct aac_dev *dev, int cid)
{ {
struct scsi_cmnd *scsicmd = kzalloc(sizeof(*scsicmd), GFP_KERNEL); struct scsi_cmnd *scsicmd = kzalloc(sizeof(*scsicmd), GFP_KERNEL);
struct aac_cmd_priv *cmd_priv = aac_priv(scsicmd);
struct scsi_device *scsidev = kzalloc(sizeof(*scsidev), GFP_KERNEL); struct scsi_device *scsidev = kzalloc(sizeof(*scsidev), GFP_KERNEL);
int status; int status;
@ -835,7 +838,7 @@ int aac_probe_container(struct aac_dev *dev, int cid)
while (scsicmd->device == scsidev) while (scsicmd->device == scsidev)
schedule(); schedule();
kfree(scsidev); kfree(scsidev);
status = scsicmd->SCp.Status; status = cmd_priv->status;
kfree(scsicmd); kfree(scsicmd);
return status; return status;
} }
@ -1128,7 +1131,7 @@ static int aac_get_container_serial(struct scsi_cmnd * scsicmd)
dinfo->command = cpu_to_le32(VM_ContainerConfig); dinfo->command = cpu_to_le32(VM_ContainerConfig);
dinfo->type = cpu_to_le32(CT_CID_TO_32BITS_UID); dinfo->type = cpu_to_le32(CT_CID_TO_32BITS_UID);
dinfo->cid = cpu_to_le32(scmd_id(scsicmd)); dinfo->cid = cpu_to_le32(scmd_id(scsicmd));
scsicmd->SCp.phase = AAC_OWNER_FIRMWARE; aac_priv(scsicmd)->owner = AAC_OWNER_FIRMWARE;
status = aac_fib_send(ContainerCommand, status = aac_fib_send(ContainerCommand,
cmd_fibcontext, cmd_fibcontext,
@ -2486,7 +2489,7 @@ static int aac_read(struct scsi_cmnd * scsicmd)
* Alocate and initialize a Fib * Alocate and initialize a Fib
*/ */
cmd_fibcontext = aac_fib_alloc_tag(dev, scsicmd); cmd_fibcontext = aac_fib_alloc_tag(dev, scsicmd);
scsicmd->SCp.phase = AAC_OWNER_FIRMWARE; aac_priv(scsicmd)->owner = AAC_OWNER_FIRMWARE;
status = aac_adapter_read(cmd_fibcontext, scsicmd, lba, count); status = aac_adapter_read(cmd_fibcontext, scsicmd, lba, count);
/* /*
@ -2577,7 +2580,7 @@ static int aac_write(struct scsi_cmnd * scsicmd)
* Allocate and initialize a Fib then setup a BlockWrite command * Allocate and initialize a Fib then setup a BlockWrite command
*/ */
cmd_fibcontext = aac_fib_alloc_tag(dev, scsicmd); cmd_fibcontext = aac_fib_alloc_tag(dev, scsicmd);
scsicmd->SCp.phase = AAC_OWNER_FIRMWARE; aac_priv(scsicmd)->owner = AAC_OWNER_FIRMWARE;
status = aac_adapter_write(cmd_fibcontext, scsicmd, lba, count, fua); status = aac_adapter_write(cmd_fibcontext, scsicmd, lba, count, fua);
/* /*
@ -2660,7 +2663,7 @@ static int aac_synchronize(struct scsi_cmnd *scsicmd)
synchronizecmd->cid = cpu_to_le32(scmd_id(scsicmd)); synchronizecmd->cid = cpu_to_le32(scmd_id(scsicmd));
synchronizecmd->count = synchronizecmd->count =
cpu_to_le32(sizeof(((struct aac_synchronize_reply *)NULL)->data)); cpu_to_le32(sizeof(((struct aac_synchronize_reply *)NULL)->data));
scsicmd->SCp.phase = AAC_OWNER_FIRMWARE; aac_priv(scsicmd)->owner = AAC_OWNER_FIRMWARE;
/* /*
* Now send the Fib to the adapter * Now send the Fib to the adapter
@ -2736,7 +2739,7 @@ static int aac_start_stop(struct scsi_cmnd *scsicmd)
pmcmd->cid = cpu_to_le32(sdev_id(sdev)); pmcmd->cid = cpu_to_le32(sdev_id(sdev));
pmcmd->parm = (scsicmd->cmnd[1] & 1) ? pmcmd->parm = (scsicmd->cmnd[1] & 1) ?
cpu_to_le32(CT_PM_UNIT_IMMEDIATE) : 0; cpu_to_le32(CT_PM_UNIT_IMMEDIATE) : 0;
scsicmd->SCp.phase = AAC_OWNER_FIRMWARE; aac_priv(scsicmd)->owner = AAC_OWNER_FIRMWARE;
/* /*
* Now send the Fib to the adapter * Now send the Fib to the adapter
@ -3695,7 +3698,7 @@ out:
aac_fib_complete(fibptr); aac_fib_complete(fibptr);
if (fibptr->flags & FIB_CONTEXT_FLAG_NATIVE_HBA_TMF) if (fibptr->flags & FIB_CONTEXT_FLAG_NATIVE_HBA_TMF)
scsicmd->SCp.sent_command = 1; aac_priv(scsicmd)->sent_command = 1;
else else
aac_scsi_done(scsicmd); aac_scsi_done(scsicmd);
} }
@ -3725,7 +3728,7 @@ static int aac_send_srb_fib(struct scsi_cmnd* scsicmd)
* Allocate and initialize a Fib then setup a BlockWrite command * Allocate and initialize a Fib then setup a BlockWrite command
*/ */
cmd_fibcontext = aac_fib_alloc_tag(dev, scsicmd); cmd_fibcontext = aac_fib_alloc_tag(dev, scsicmd);
scsicmd->SCp.phase = AAC_OWNER_FIRMWARE; aac_priv(scsicmd)->owner = AAC_OWNER_FIRMWARE;
status = aac_adapter_scsi(cmd_fibcontext, scsicmd); status = aac_adapter_scsi(cmd_fibcontext, scsicmd);
/* /*
@ -3769,7 +3772,7 @@ static int aac_send_hba_fib(struct scsi_cmnd *scsicmd)
if (!cmd_fibcontext) if (!cmd_fibcontext)
return -1; return -1;
scsicmd->SCp.phase = AAC_OWNER_FIRMWARE; aac_priv(scsicmd)->owner = AAC_OWNER_FIRMWARE;
status = aac_adapter_hba(cmd_fibcontext, scsicmd); status = aac_adapter_hba(cmd_fibcontext, scsicmd);
/* /*

View File

@ -29,6 +29,7 @@
#include <linux/completion.h> #include <linux/completion.h>
#include <linux/pci.h> #include <linux/pci.h>
#include <scsi/scsi_host.h> #include <scsi/scsi_host.h>
#include <scsi/scsi_cmnd.h>
/*------------------------------------------------------------------------------ /*------------------------------------------------------------------------------
* D E F I N E S * D E F I N E S
@ -2673,11 +2674,24 @@ static inline void aac_cancel_rescan_worker(struct aac_dev *dev)
cancel_delayed_work_sync(&dev->src_reinit_aif_worker); cancel_delayed_work_sync(&dev->src_reinit_aif_worker);
} }
/* SCp.phase values */ enum aac_cmd_owner {
#define AAC_OWNER_MIDLEVEL 0x101 AAC_OWNER_MIDLEVEL = 0x101,
#define AAC_OWNER_LOWLEVEL 0x102 AAC_OWNER_LOWLEVEL = 0x102,
#define AAC_OWNER_ERROR_HANDLER 0x103 AAC_OWNER_ERROR_HANDLER = 0x103,
#define AAC_OWNER_FIRMWARE 0x106 AAC_OWNER_FIRMWARE = 0x106,
};
struct aac_cmd_priv {
int (*callback)(struct scsi_cmnd *);
int status;
enum aac_cmd_owner owner;
bool sent_command;
};
static inline struct aac_cmd_priv *aac_priv(struct scsi_cmnd *cmd)
{
return scsi_cmd_priv(cmd);
}
void aac_safw_rescan_worker(struct work_struct *work); void aac_safw_rescan_worker(struct work_struct *work);
void aac_src_reinit_aif_worker(struct work_struct *work); void aac_src_reinit_aif_worker(struct work_struct *work);

View File

@ -276,7 +276,7 @@ static bool wait_for_io_iter(struct scsi_cmnd *cmd, void *data, bool rsvd)
{ {
int *active = data; int *active = data;
if (cmd->SCp.phase == AAC_OWNER_FIRMWARE) if (aac_priv(cmd)->owner == AAC_OWNER_FIRMWARE)
*active = *active + 1; *active = *active + 1;
return true; return true;
} }

View File

@ -241,10 +241,9 @@ static struct aac_driver_ident aac_drivers[] = {
static int aac_queuecommand(struct Scsi_Host *shost, static int aac_queuecommand(struct Scsi_Host *shost,
struct scsi_cmnd *cmd) struct scsi_cmnd *cmd)
{ {
int r = 0; aac_priv(cmd)->owner = AAC_OWNER_LOWLEVEL;
cmd->SCp.phase = AAC_OWNER_LOWLEVEL;
r = (aac_scsi_cmd(cmd) ? FAILED : 0); return aac_scsi_cmd(cmd) ? FAILED : 0;
return r;
} }
/** /**
@ -638,7 +637,7 @@ static bool fib_count_iter(struct scsi_cmnd *scmnd, void *data, bool reserved)
{ {
struct fib_count_data *fib_count = data; struct fib_count_data *fib_count = data;
switch (scmnd->SCp.phase) { switch (aac_priv(scmnd)->owner) {
case AAC_OWNER_FIRMWARE: case AAC_OWNER_FIRMWARE:
fib_count->fwcnt++; fib_count->fwcnt++;
break; break;
@ -680,6 +679,7 @@ static int get_num_of_incomplete_fibs(struct aac_dev *aac)
static int aac_eh_abort(struct scsi_cmnd* cmd) static int aac_eh_abort(struct scsi_cmnd* cmd)
{ {
struct aac_cmd_priv *cmd_priv = aac_priv(cmd);
struct scsi_device * dev = cmd->device; struct scsi_device * dev = cmd->device;
struct Scsi_Host * host = dev->host; struct Scsi_Host * host = dev->host;
struct aac_dev * aac = (struct aac_dev *)host->hostdata; struct aac_dev * aac = (struct aac_dev *)host->hostdata;
@ -732,7 +732,7 @@ static int aac_eh_abort(struct scsi_cmnd* cmd)
tmf->error_length = cpu_to_le32(FW_ERROR_BUFFER_SIZE); tmf->error_length = cpu_to_le32(FW_ERROR_BUFFER_SIZE);
fib->hbacmd_size = sizeof(*tmf); fib->hbacmd_size = sizeof(*tmf);
cmd->SCp.sent_command = 0; cmd_priv->sent_command = 0;
status = aac_hba_send(HBA_IU_TYPE_SCSI_TM_REQ, fib, status = aac_hba_send(HBA_IU_TYPE_SCSI_TM_REQ, fib,
(fib_callback) aac_hba_callback, (fib_callback) aac_hba_callback,
@ -744,7 +744,7 @@ static int aac_eh_abort(struct scsi_cmnd* cmd)
} }
/* Wait up to 15 secs for completion */ /* Wait up to 15 secs for completion */
for (count = 0; count < 15; ++count) { for (count = 0; count < 15; ++count) {
if (cmd->SCp.sent_command) { if (cmd_priv->sent_command) {
ret = SUCCESS; ret = SUCCESS;
break; break;
} }
@ -784,7 +784,7 @@ static int aac_eh_abort(struct scsi_cmnd* cmd)
(fib->callback_data == cmd)) { (fib->callback_data == cmd)) {
fib->flags |= fib->flags |=
FIB_CONTEXT_FLAG_TIMED_OUT; FIB_CONTEXT_FLAG_TIMED_OUT;
cmd->SCp.phase = cmd_priv->owner =
AAC_OWNER_ERROR_HANDLER; AAC_OWNER_ERROR_HANDLER;
ret = SUCCESS; ret = SUCCESS;
} }
@ -811,7 +811,7 @@ static int aac_eh_abort(struct scsi_cmnd* cmd)
(command->device == cmd->device)) { (command->device == cmd->device)) {
fib->flags |= fib->flags |=
FIB_CONTEXT_FLAG_TIMED_OUT; FIB_CONTEXT_FLAG_TIMED_OUT;
command->SCp.phase = aac_priv(command)->owner =
AAC_OWNER_ERROR_HANDLER; AAC_OWNER_ERROR_HANDLER;
if (command == cmd) if (command == cmd)
ret = SUCCESS; ret = SUCCESS;
@ -864,7 +864,7 @@ static u8 aac_eh_tmf_hard_reset_fib(struct aac_hba_map_info *info,
rst->error_length = cpu_to_le32(FW_ERROR_BUFFER_SIZE); rst->error_length = cpu_to_le32(FW_ERROR_BUFFER_SIZE);
fib->hbacmd_size = sizeof(*rst); fib->hbacmd_size = sizeof(*rst);
return HBA_IU_TYPE_SATA_REQ; return HBA_IU_TYPE_SATA_REQ;
} }
static void aac_tmf_callback(void *context, struct fib *fibptr) static void aac_tmf_callback(void *context, struct fib *fibptr)
@ -1058,7 +1058,7 @@ static int aac_eh_bus_reset(struct scsi_cmnd* cmd)
if (bus >= AAC_MAX_BUSES || cid >= AAC_MAX_TARGETS || if (bus >= AAC_MAX_BUSES || cid >= AAC_MAX_TARGETS ||
info->devtype != AAC_DEVTYPE_NATIVE_RAW) { info->devtype != AAC_DEVTYPE_NATIVE_RAW) {
fib->flags |= FIB_CONTEXT_FLAG_EH_RESET; fib->flags |= FIB_CONTEXT_FLAG_EH_RESET;
cmd->SCp.phase = AAC_OWNER_ERROR_HANDLER; aac_priv(cmd)->owner = AAC_OWNER_ERROR_HANDLER;
} }
} }
} }
@ -1507,6 +1507,7 @@ static struct scsi_host_template aac_driver_template = {
#endif #endif
.emulated = 1, .emulated = 1,
.no_write_same = 1, .no_write_same = 1,
.cmd_size = sizeof(struct aac_cmd_priv),
}; };
static void __aac_shutdown(struct aac_dev * aac) static void __aac_shutdown(struct aac_dev * aac)

View File

@ -2277,6 +2277,15 @@ struct asc_board {
dvc_var.adv_dvc_var) dvc_var.adv_dvc_var)
#define adv_dvc_to_pdev(adv_dvc) to_pci_dev(adv_dvc_to_board(adv_dvc)->dev) #define adv_dvc_to_pdev(adv_dvc) to_pci_dev(adv_dvc_to_board(adv_dvc)->dev)
struct advansys_cmd {
dma_addr_t dma_handle;
};
static struct advansys_cmd *advansys_cmd(struct scsi_cmnd *cmd)
{
return scsi_cmd_priv(cmd);
}
#ifdef ADVANSYS_DEBUG #ifdef ADVANSYS_DEBUG
static int asc_dbglvl = 3; static int asc_dbglvl = 3;
@ -6681,7 +6690,7 @@ static void asc_isr_callback(ASC_DVC_VAR *asc_dvc_varp, ASC_QDONE_INFO *qdonep)
ASC_STATS(boardp->shost, callback); ASC_STATS(boardp->shost, callback);
dma_unmap_single(boardp->dev, scp->SCp.dma_handle, dma_unmap_single(boardp->dev, advansys_cmd(scp)->dma_handle,
SCSI_SENSE_BUFFERSIZE, DMA_FROM_DEVICE); SCSI_SENSE_BUFFERSIZE, DMA_FROM_DEVICE);
/* /*
* 'qdonep' contains the command's ending status. * 'qdonep' contains the command's ending status.
@ -7399,15 +7408,15 @@ static int advansys_slave_configure(struct scsi_device *sdev)
static __le32 asc_get_sense_buffer_dma(struct scsi_cmnd *scp) static __le32 asc_get_sense_buffer_dma(struct scsi_cmnd *scp)
{ {
struct asc_board *board = shost_priv(scp->device->host); struct asc_board *board = shost_priv(scp->device->host);
struct advansys_cmd *acmd = advansys_cmd(scp);
scp->SCp.dma_handle = dma_map_single(board->dev, scp->sense_buffer, acmd->dma_handle = dma_map_single(board->dev, scp->sense_buffer,
SCSI_SENSE_BUFFERSIZE, SCSI_SENSE_BUFFERSIZE, DMA_FROM_DEVICE);
DMA_FROM_DEVICE); if (dma_mapping_error(board->dev, acmd->dma_handle)) {
if (dma_mapping_error(board->dev, scp->SCp.dma_handle)) {
ASC_DBG(1, "failed to map sense buffer\n"); ASC_DBG(1, "failed to map sense buffer\n");
return 0; return 0;
} }
return cpu_to_le32(scp->SCp.dma_handle); return cpu_to_le32(acmd->dma_handle);
} }
static int asc_build_req(struct asc_board *boardp, struct scsi_cmnd *scp, static int asc_build_req(struct asc_board *boardp, struct scsi_cmnd *scp,
@ -10604,6 +10613,7 @@ static struct scsi_host_template advansys_template = {
.eh_host_reset_handler = advansys_reset, .eh_host_reset_handler = advansys_reset,
.bios_param = advansys_biosparam, .bios_param = advansys_biosparam,
.slave_configure = advansys_slave_configure, .slave_configure = advansys_slave_configure,
.cmd_size = sizeof(struct advansys_cmd),
}; };
static int advansys_wide_init_chip(struct Scsi_Host *shost) static int advansys_wide_init_chip(struct Scsi_Host *shost)

View File

@ -243,13 +243,16 @@
#include <linux/workqueue.h> #include <linux/workqueue.h>
#include <linux/list.h> #include <linux/list.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <scsi/scsicam.h>
#include "scsi.h" #include <scsi/scsi.h>
#include <scsi/scsi_cmnd.h>
#include <scsi/scsi_dbg.h> #include <scsi/scsi_dbg.h>
#include <scsi/scsi_host.h> #include <scsi/scsi_device.h>
#include <scsi/scsi_transport_spi.h>
#include <scsi/scsi_eh.h> #include <scsi/scsi_eh.h>
#include <scsi/scsi_host.h>
#include <scsi/scsi_tcq.h>
#include <scsi/scsi_transport_spi.h>
#include <scsi/scsicam.h>
#include "aha152x.h" #include "aha152x.h"
static LIST_HEAD(aha152x_host_list); static LIST_HEAD(aha152x_host_list);
@ -313,6 +316,17 @@ enum {
check_condition = 0x0800, /* requesting sense after CHECK CONDITION */ check_condition = 0x0800, /* requesting sense after CHECK CONDITION */
}; };
struct aha152x_cmd_priv {
struct scsi_pointer scsi_pointer;
};
static struct scsi_pointer *aha152x_scsi_pointer(struct scsi_cmnd *cmd)
{
struct aha152x_cmd_priv *acmd = scsi_cmd_priv(cmd);
return &acmd->scsi_pointer;
}
MODULE_AUTHOR("Jürgen Fischer"); MODULE_AUTHOR("Jürgen Fischer");
MODULE_DESCRIPTION(AHA152X_REVID); MODULE_DESCRIPTION(AHA152X_REVID);
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");
@ -876,14 +890,17 @@ void aha152x_release(struct Scsi_Host *shpnt)
static int setup_expected_interrupts(struct Scsi_Host *shpnt) static int setup_expected_interrupts(struct Scsi_Host *shpnt)
{ {
if(CURRENT_SC) { if(CURRENT_SC) {
CURRENT_SC->SCp.phase |= 1 << 16; struct scsi_pointer *scsi_pointer =
aha152x_scsi_pointer(CURRENT_SC);
if(CURRENT_SC->SCp.phase & selecting) { scsi_pointer->phase |= 1 << 16;
if (scsi_pointer->phase & selecting) {
SETPORT(SSTAT1, SELTO); SETPORT(SSTAT1, SELTO);
SETPORT(SIMODE0, ENSELDO | (DISCONNECTED_SC ? ENSELDI : 0)); SETPORT(SIMODE0, ENSELDO | (DISCONNECTED_SC ? ENSELDI : 0));
SETPORT(SIMODE1, ENSELTIMO); SETPORT(SIMODE1, ENSELTIMO);
} else { } else {
SETPORT(SIMODE0, (CURRENT_SC->SCp.phase & spiordy) ? ENSPIORDY : 0); SETPORT(SIMODE0, (scsi_pointer->phase & spiordy) ? ENSPIORDY : 0);
SETPORT(SIMODE1, ENPHASEMIS | ENSCSIRST | ENSCSIPERR | ENBUSFREE); SETPORT(SIMODE1, ENPHASEMIS | ENSCSIRST | ENSCSIPERR | ENBUSFREE);
} }
} else if(STATE==seldi) { } else if(STATE==seldi) {
@ -907,16 +924,17 @@ static int setup_expected_interrupts(struct Scsi_Host *shpnt)
static int aha152x_internal_queue(struct scsi_cmnd *SCpnt, static int aha152x_internal_queue(struct scsi_cmnd *SCpnt,
struct completion *complete, int phase) struct completion *complete, int phase)
{ {
struct scsi_pointer *scsi_pointer = aha152x_scsi_pointer(SCpnt);
struct Scsi_Host *shpnt = SCpnt->device->host; struct Scsi_Host *shpnt = SCpnt->device->host;
unsigned long flags; unsigned long flags;
SCpnt->SCp.phase = not_issued | phase; scsi_pointer->phase = not_issued | phase;
SCpnt->SCp.Status = 0x1; /* Ilegal status by SCSI standard */ scsi_pointer->Status = 0x1; /* Ilegal status by SCSI standard */
SCpnt->SCp.Message = 0; scsi_pointer->Message = 0;
SCpnt->SCp.have_data_in = 0; scsi_pointer->have_data_in = 0;
SCpnt->SCp.sent_command = 0; scsi_pointer->sent_command = 0;
if(SCpnt->SCp.phase & (resetting|check_condition)) { if (scsi_pointer->phase & (resetting | check_condition)) {
if (!SCpnt->host_scribble || SCSEM(SCpnt) || SCNEXT(SCpnt)) { if (!SCpnt->host_scribble || SCSEM(SCpnt) || SCNEXT(SCpnt)) {
scmd_printk(KERN_ERR, SCpnt, "cannot reuse command\n"); scmd_printk(KERN_ERR, SCpnt, "cannot reuse command\n");
return FAILED; return FAILED;
@ -939,15 +957,15 @@ static int aha152x_internal_queue(struct scsi_cmnd *SCpnt,
SCp.phase : current state of the command */ SCp.phase : current state of the command */
if ((phase & resetting) || !scsi_sglist(SCpnt)) { if ((phase & resetting) || !scsi_sglist(SCpnt)) {
SCpnt->SCp.ptr = NULL; scsi_pointer->ptr = NULL;
SCpnt->SCp.this_residual = 0; scsi_pointer->this_residual = 0;
scsi_set_resid(SCpnt, 0); scsi_set_resid(SCpnt, 0);
SCpnt->SCp.buffer = NULL; scsi_pointer->buffer = NULL;
} else { } else {
scsi_set_resid(SCpnt, scsi_bufflen(SCpnt)); scsi_set_resid(SCpnt, scsi_bufflen(SCpnt));
SCpnt->SCp.buffer = scsi_sglist(SCpnt); scsi_pointer->buffer = scsi_sglist(SCpnt);
SCpnt->SCp.ptr = SG_ADDRESS(SCpnt->SCp.buffer); scsi_pointer->ptr = SG_ADDRESS(scsi_pointer->buffer);
SCpnt->SCp.this_residual = SCpnt->SCp.buffer->length; scsi_pointer->this_residual = scsi_pointer->buffer->length;
} }
DO_LOCK(flags); DO_LOCK(flags);
@ -997,7 +1015,7 @@ static void reset_done(struct scsi_cmnd *SCpnt)
static void aha152x_scsi_done(struct scsi_cmnd *SCpnt) static void aha152x_scsi_done(struct scsi_cmnd *SCpnt)
{ {
if (SCpnt->SCp.phase & resetting) if (aha152x_scsi_pointer(SCpnt)->phase & resetting)
reset_done(SCpnt); reset_done(SCpnt);
else else
scsi_done(SCpnt); scsi_done(SCpnt);
@ -1083,7 +1101,7 @@ static int aha152x_device_reset(struct scsi_cmnd * SCpnt)
DO_LOCK(flags); DO_LOCK(flags);
if(SCpnt->SCp.phase & resetted) { if (aha152x_scsi_pointer(SCpnt)->phase & resetted) {
HOSTDATA(shpnt)->commands--; HOSTDATA(shpnt)->commands--;
if (!HOSTDATA(shpnt)->commands) if (!HOSTDATA(shpnt)->commands)
SETPORT(PORTA, 0); SETPORT(PORTA, 0);
@ -1377,28 +1395,31 @@ static void busfree_run(struct Scsi_Host *shpnt)
SETPORT(SSTAT1, CLRBUSFREE); SETPORT(SSTAT1, CLRBUSFREE);
if(CURRENT_SC) { if(CURRENT_SC) {
struct scsi_pointer *scsi_pointer =
aha152x_scsi_pointer(CURRENT_SC);
#if defined(AHA152X_STAT) #if defined(AHA152X_STAT)
action++; action++;
#endif #endif
CURRENT_SC->SCp.phase &= ~syncneg; scsi_pointer->phase &= ~syncneg;
if(CURRENT_SC->SCp.phase & completed) { if (scsi_pointer->phase & completed) {
/* target sent COMMAND COMPLETE */ /* target sent COMMAND COMPLETE */
done(shpnt, CURRENT_SC->SCp.Status, DID_OK); done(shpnt, scsi_pointer->Status, DID_OK);
} else if(CURRENT_SC->SCp.phase & aborted) { } else if (scsi_pointer->phase & aborted) {
done(shpnt, CURRENT_SC->SCp.Status, DID_ABORT); done(shpnt, scsi_pointer->Status, DID_ABORT);
} else if(CURRENT_SC->SCp.phase & resetted) { } else if (scsi_pointer->phase & resetted) {
done(shpnt, CURRENT_SC->SCp.Status, DID_RESET); done(shpnt, scsi_pointer->Status, DID_RESET);
} else if(CURRENT_SC->SCp.phase & disconnected) { } else if (scsi_pointer->phase & disconnected) {
/* target sent DISCONNECT */ /* target sent DISCONNECT */
#if defined(AHA152X_STAT) #if defined(AHA152X_STAT)
HOSTDATA(shpnt)->disconnections++; HOSTDATA(shpnt)->disconnections++;
#endif #endif
append_SC(&DISCONNECTED_SC, CURRENT_SC); append_SC(&DISCONNECTED_SC, CURRENT_SC);
CURRENT_SC->SCp.phase |= 1 << 16; scsi_pointer->phase |= 1 << 16;
CURRENT_SC = NULL; CURRENT_SC = NULL;
} else { } else {
@ -1417,23 +1438,24 @@ static void busfree_run(struct Scsi_Host *shpnt)
action++; action++;
#endif #endif
if(DONE_SC->SCp.phase & check_condition) { if (aha152x_scsi_pointer(DONE_SC)->phase & check_condition) {
struct scsi_cmnd *cmd = HOSTDATA(shpnt)->done_SC; struct scsi_cmnd *cmd = HOSTDATA(shpnt)->done_SC;
struct aha152x_scdata *sc = SCDATA(cmd); struct aha152x_scdata *sc = SCDATA(cmd);
scsi_eh_restore_cmnd(cmd, &sc->ses); scsi_eh_restore_cmnd(cmd, &sc->ses);
cmd->SCp.Status = SAM_STAT_CHECK_CONDITION; aha152x_scsi_pointer(cmd)->Status = SAM_STAT_CHECK_CONDITION;
HOSTDATA(shpnt)->commands--; HOSTDATA(shpnt)->commands--;
if (!HOSTDATA(shpnt)->commands) if (!HOSTDATA(shpnt)->commands)
SETPORT(PORTA, 0); /* turn led off */ SETPORT(PORTA, 0); /* turn led off */
} else if(DONE_SC->SCp.Status==SAM_STAT_CHECK_CONDITION) { } else if (aha152x_scsi_pointer(DONE_SC)->Status ==
SAM_STAT_CHECK_CONDITION) {
#if defined(AHA152X_STAT) #if defined(AHA152X_STAT)
HOSTDATA(shpnt)->busfree_with_check_condition++; HOSTDATA(shpnt)->busfree_with_check_condition++;
#endif #endif
if(!(DONE_SC->SCp.phase & not_issued)) { if(!(aha152x_scsi_pointer(DONE_SC)->phase & not_issued)) {
struct aha152x_scdata *sc; struct aha152x_scdata *sc;
struct scsi_cmnd *ptr = DONE_SC; struct scsi_cmnd *ptr = DONE_SC;
DONE_SC=NULL; DONE_SC=NULL;
@ -1458,7 +1480,7 @@ static void busfree_run(struct Scsi_Host *shpnt)
if (!HOSTDATA(shpnt)->commands) if (!HOSTDATA(shpnt)->commands)
SETPORT(PORTA, 0); /* turn led off */ SETPORT(PORTA, 0); /* turn led off */
if (!(ptr->SCp.phase & resetting)) { if (!(aha152x_scsi_pointer(ptr)->phase & resetting)) {
kfree(ptr->host_scribble); kfree(ptr->host_scribble);
ptr->host_scribble=NULL; ptr->host_scribble=NULL;
} }
@ -1481,10 +1503,13 @@ static void busfree_run(struct Scsi_Host *shpnt)
DO_UNLOCK(flags); DO_UNLOCK(flags);
if(CURRENT_SC) { if(CURRENT_SC) {
struct scsi_pointer *scsi_pointer =
aha152x_scsi_pointer(CURRENT_SC);
#if defined(AHA152X_STAT) #if defined(AHA152X_STAT)
action++; action++;
#endif #endif
CURRENT_SC->SCp.phase |= selecting; scsi_pointer->phase |= selecting;
/* clear selection timeout */ /* clear selection timeout */
SETPORT(SSTAT1, SELTO); SETPORT(SSTAT1, SELTO);
@ -1512,11 +1537,13 @@ static void busfree_run(struct Scsi_Host *shpnt)
*/ */
static void seldo_run(struct Scsi_Host *shpnt) static void seldo_run(struct Scsi_Host *shpnt)
{ {
struct scsi_pointer *scsi_pointer = aha152x_scsi_pointer(CURRENT_SC);
SETPORT(SCSISIG, 0); SETPORT(SCSISIG, 0);
SETPORT(SSTAT1, CLRBUSFREE); SETPORT(SSTAT1, CLRBUSFREE);
SETPORT(SSTAT1, CLRPHASECHG); SETPORT(SSTAT1, CLRPHASECHG);
CURRENT_SC->SCp.phase &= ~(selecting|not_issued); scsi_pointer->phase &= ~(selecting | not_issued);
SETPORT(SCSISEQ, 0); SETPORT(SCSISEQ, 0);
@ -1531,12 +1558,12 @@ static void seldo_run(struct Scsi_Host *shpnt)
ADDMSGO(IDENTIFY(RECONNECT, CURRENT_SC->device->lun)); ADDMSGO(IDENTIFY(RECONNECT, CURRENT_SC->device->lun));
if (CURRENT_SC->SCp.phase & aborting) { if (scsi_pointer->phase & aborting) {
ADDMSGO(ABORT); ADDMSGO(ABORT);
} else if (CURRENT_SC->SCp.phase & resetting) { } else if (scsi_pointer->phase & resetting) {
ADDMSGO(BUS_DEVICE_RESET); ADDMSGO(BUS_DEVICE_RESET);
} else if (SYNCNEG==0 && SYNCHRONOUS) { } else if (SYNCNEG==0 && SYNCHRONOUS) {
CURRENT_SC->SCp.phase |= syncneg; scsi_pointer->phase |= syncneg;
MSGOLEN += spi_populate_sync_msg(&MSGO(MSGOLEN), 50, 8); MSGOLEN += spi_populate_sync_msg(&MSGO(MSGOLEN), 50, 8);
SYNCNEG=1; /* negotiation in progress */ SYNCNEG=1; /* negotiation in progress */
} }
@ -1551,15 +1578,17 @@ static void seldo_run(struct Scsi_Host *shpnt)
*/ */
static void selto_run(struct Scsi_Host *shpnt) static void selto_run(struct Scsi_Host *shpnt)
{ {
struct scsi_pointer *scsi_pointer = aha152x_scsi_pointer(CURRENT_SC);
SETPORT(SCSISEQ, 0); SETPORT(SCSISEQ, 0);
SETPORT(SSTAT1, CLRSELTIMO); SETPORT(SSTAT1, CLRSELTIMO);
if (!CURRENT_SC) if (!CURRENT_SC)
return; return;
CURRENT_SC->SCp.phase &= ~selecting; scsi_pointer->phase &= ~selecting;
if (CURRENT_SC->SCp.phase & aborted) if (scsi_pointer->phase & aborted)
done(shpnt, SAM_STAT_GOOD, DID_ABORT); done(shpnt, SAM_STAT_GOOD, DID_ABORT);
else if (TESTLO(SSTAT0, SELINGO)) else if (TESTLO(SSTAT0, SELINGO))
done(shpnt, SAM_STAT_GOOD, DID_BUS_BUSY); done(shpnt, SAM_STAT_GOOD, DID_BUS_BUSY);
@ -1587,7 +1616,10 @@ static void seldi_run(struct Scsi_Host *shpnt)
SETPORT(SSTAT1, CLRPHASECHG); SETPORT(SSTAT1, CLRPHASECHG);
if(CURRENT_SC) { if(CURRENT_SC) {
if(!(CURRENT_SC->SCp.phase & not_issued)) struct scsi_pointer *scsi_pointer =
aha152x_scsi_pointer(CURRENT_SC);
if (!(scsi_pointer->phase & not_issued))
scmd_printk(KERN_ERR, CURRENT_SC, scmd_printk(KERN_ERR, CURRENT_SC,
"command should not have been issued yet\n"); "command should not have been issued yet\n");
@ -1644,6 +1676,7 @@ static void seldi_run(struct Scsi_Host *shpnt)
static void msgi_run(struct Scsi_Host *shpnt) static void msgi_run(struct Scsi_Host *shpnt)
{ {
for(;;) { for(;;) {
struct scsi_pointer *scsi_pointer;
int sstat1 = GETPORT(SSTAT1); int sstat1 = GETPORT(SSTAT1);
if(sstat1 & (PHASECHG|PHASEMIS|BUSFREE) || !(sstat1 & REQINIT)) if(sstat1 & (PHASECHG|PHASEMIS|BUSFREE) || !(sstat1 & REQINIT))
@ -1681,8 +1714,9 @@ static void msgi_run(struct Scsi_Host *shpnt)
continue; continue;
} }
CURRENT_SC->SCp.Message = MSGI(0); scsi_pointer = aha152x_scsi_pointer(CURRENT_SC);
CURRENT_SC->SCp.phase &= ~disconnected; scsi_pointer->Message = MSGI(0);
scsi_pointer->phase &= ~disconnected;
MSGILEN=0; MSGILEN=0;
@ -1690,7 +1724,8 @@ static void msgi_run(struct Scsi_Host *shpnt)
continue; continue;
} }
CURRENT_SC->SCp.Message = MSGI(0); scsi_pointer = aha152x_scsi_pointer(CURRENT_SC);
scsi_pointer->Message = MSGI(0);
switch (MSGI(0)) { switch (MSGI(0)) {
case DISCONNECT: case DISCONNECT:
@ -1698,11 +1733,11 @@ static void msgi_run(struct Scsi_Host *shpnt)
scmd_printk(KERN_WARNING, CURRENT_SC, scmd_printk(KERN_WARNING, CURRENT_SC,
"target was not allowed to disconnect\n"); "target was not allowed to disconnect\n");
CURRENT_SC->SCp.phase |= disconnected; scsi_pointer->phase |= disconnected;
break; break;
case COMMAND_COMPLETE: case COMMAND_COMPLETE:
CURRENT_SC->SCp.phase |= completed; scsi_pointer->phase |= completed;
break; break;
case MESSAGE_REJECT: case MESSAGE_REJECT:
@ -1832,8 +1867,11 @@ static void msgi_end(struct Scsi_Host *shpnt)
*/ */
static void msgo_init(struct Scsi_Host *shpnt) static void msgo_init(struct Scsi_Host *shpnt)
{ {
struct scsi_pointer *scsi_pointer = aha152x_scsi_pointer(CURRENT_SC);
if(MSGOLEN==0) { if(MSGOLEN==0) {
if((CURRENT_SC->SCp.phase & syncneg) && SYNCNEG==2 && SYNCRATE==0) { if ((scsi_pointer->phase & syncneg) && SYNCNEG==2 &&
SYNCRATE==0) {
ADDMSGO(IDENTIFY(RECONNECT, CURRENT_SC->device->lun)); ADDMSGO(IDENTIFY(RECONNECT, CURRENT_SC->device->lun));
} else { } else {
scmd_printk(KERN_INFO, CURRENT_SC, scmd_printk(KERN_INFO, CURRENT_SC,
@ -1850,6 +1888,8 @@ static void msgo_init(struct Scsi_Host *shpnt)
*/ */
static void msgo_run(struct Scsi_Host *shpnt) static void msgo_run(struct Scsi_Host *shpnt)
{ {
struct scsi_pointer *scsi_pointer = aha152x_scsi_pointer(CURRENT_SC);
while(MSGO_I<MSGOLEN) { while(MSGO_I<MSGOLEN) {
if (TESTLO(SSTAT0, SPIORDY)) if (TESTLO(SSTAT0, SPIORDY))
return; return;
@ -1861,13 +1901,13 @@ static void msgo_run(struct Scsi_Host *shpnt)
if (MSGO(MSGO_I) & IDENTIFY_BASE) if (MSGO(MSGO_I) & IDENTIFY_BASE)
CURRENT_SC->SCp.phase |= identified; scsi_pointer->phase |= identified;
if (MSGO(MSGO_I)==ABORT) if (MSGO(MSGO_I)==ABORT)
CURRENT_SC->SCp.phase |= aborted; scsi_pointer->phase |= aborted;
if (MSGO(MSGO_I)==BUS_DEVICE_RESET) if (MSGO(MSGO_I)==BUS_DEVICE_RESET)
CURRENT_SC->SCp.phase |= resetted; scsi_pointer->phase |= resetted;
SETPORT(SCSIDAT, MSGO(MSGO_I++)); SETPORT(SCSIDAT, MSGO(MSGO_I++));
} }
@ -1896,7 +1936,7 @@ static void msgo_end(struct Scsi_Host *shpnt)
*/ */
static void cmd_init(struct Scsi_Host *shpnt) static void cmd_init(struct Scsi_Host *shpnt)
{ {
if (CURRENT_SC->SCp.sent_command) { if (aha152x_scsi_pointer(CURRENT_SC)->sent_command) {
scmd_printk(KERN_ERR, CURRENT_SC, scmd_printk(KERN_ERR, CURRENT_SC,
"command already sent\n"); "command already sent\n");
done(shpnt, SAM_STAT_GOOD, DID_ERROR); done(shpnt, SAM_STAT_GOOD, DID_ERROR);
@ -1927,7 +1967,7 @@ static void cmd_end(struct Scsi_Host *shpnt)
"command sent incompletely (%d/%d)\n", "command sent incompletely (%d/%d)\n",
CMD_I, CURRENT_SC->cmd_len); CMD_I, CURRENT_SC->cmd_len);
else else
CURRENT_SC->SCp.sent_command++; aha152x_scsi_pointer(CURRENT_SC)->sent_command++;
} }
/* /*
@ -1939,7 +1979,7 @@ static void status_run(struct Scsi_Host *shpnt)
if (TESTLO(SSTAT0, SPIORDY)) if (TESTLO(SSTAT0, SPIORDY))
return; return;
CURRENT_SC->SCp.Status = GETPORT(SCSIDAT); aha152x_scsi_pointer(CURRENT_SC)->Status = GETPORT(SCSIDAT);
} }
@ -1963,6 +2003,7 @@ static void datai_init(struct Scsi_Host *shpnt)
static void datai_run(struct Scsi_Host *shpnt) static void datai_run(struct Scsi_Host *shpnt)
{ {
struct scsi_pointer *scsi_pointer;
unsigned long the_time; unsigned long the_time;
int fifodata, data_count; int fifodata, data_count;
@ -2000,35 +2041,36 @@ static void datai_run(struct Scsi_Host *shpnt)
fifodata = GETPORT(FIFOSTAT); fifodata = GETPORT(FIFOSTAT);
} }
if(CURRENT_SC->SCp.this_residual>0) { scsi_pointer = aha152x_scsi_pointer(CURRENT_SC);
while(fifodata>0 && CURRENT_SC->SCp.this_residual>0) { if (scsi_pointer->this_residual > 0) {
data_count = fifodata > CURRENT_SC->SCp.this_residual ? while (fifodata > 0 && scsi_pointer->this_residual > 0) {
CURRENT_SC->SCp.this_residual : data_count = fifodata > scsi_pointer->this_residual ?
scsi_pointer->this_residual :
fifodata; fifodata;
fifodata -= data_count; fifodata -= data_count;
if (data_count & 1) { if (data_count & 1) {
SETPORT(DMACNTRL0, ENDMA|_8BIT); SETPORT(DMACNTRL0, ENDMA|_8BIT);
*CURRENT_SC->SCp.ptr++ = GETPORT(DATAPORT); *scsi_pointer->ptr++ = GETPORT(DATAPORT);
CURRENT_SC->SCp.this_residual--; scsi_pointer->this_residual--;
DATA_LEN++; DATA_LEN++;
SETPORT(DMACNTRL0, ENDMA); SETPORT(DMACNTRL0, ENDMA);
} }
if (data_count > 1) { if (data_count > 1) {
data_count >>= 1; data_count >>= 1;
insw(DATAPORT, CURRENT_SC->SCp.ptr, data_count); insw(DATAPORT, scsi_pointer->ptr, data_count);
CURRENT_SC->SCp.ptr += 2 * data_count; scsi_pointer->ptr += 2 * data_count;
CURRENT_SC->SCp.this_residual -= 2 * data_count; scsi_pointer->this_residual -= 2 * data_count;
DATA_LEN += 2 * data_count; DATA_LEN += 2 * data_count;
} }
if (CURRENT_SC->SCp.this_residual == 0 && if (scsi_pointer->this_residual == 0 &&
!sg_is_last(CURRENT_SC->SCp.buffer)) { !sg_is_last(scsi_pointer->buffer)) {
/* advance to next buffer */ /* advance to next buffer */
CURRENT_SC->SCp.buffer = sg_next(CURRENT_SC->SCp.buffer); scsi_pointer->buffer = sg_next(scsi_pointer->buffer);
CURRENT_SC->SCp.ptr = SG_ADDRESS(CURRENT_SC->SCp.buffer); scsi_pointer->ptr = SG_ADDRESS(scsi_pointer->buffer);
CURRENT_SC->SCp.this_residual = CURRENT_SC->SCp.buffer->length; scsi_pointer->this_residual = scsi_pointer->buffer->length;
} }
} }
} else if (fifodata > 0) { } else if (fifodata > 0) {
@ -2096,14 +2138,15 @@ static void datao_init(struct Scsi_Host *shpnt)
static void datao_run(struct Scsi_Host *shpnt) static void datao_run(struct Scsi_Host *shpnt)
{ {
struct scsi_pointer *scsi_pointer = aha152x_scsi_pointer(CURRENT_SC);
unsigned long the_time; unsigned long the_time;
int data_count; int data_count;
/* until phase changes or all data sent */ /* until phase changes or all data sent */
while(TESTLO(DMASTAT, INTSTAT) && CURRENT_SC->SCp.this_residual>0) { while (TESTLO(DMASTAT, INTSTAT) && scsi_pointer->this_residual > 0) {
data_count = 128; data_count = 128;
if(data_count > CURRENT_SC->SCp.this_residual) if (data_count > scsi_pointer->this_residual)
data_count=CURRENT_SC->SCp.this_residual; data_count = scsi_pointer->this_residual;
if(TESTLO(DMASTAT, DFIFOEMP)) { if(TESTLO(DMASTAT, DFIFOEMP)) {
scmd_printk(KERN_ERR, CURRENT_SC, scmd_printk(KERN_ERR, CURRENT_SC,
@ -2114,26 +2157,26 @@ static void datao_run(struct Scsi_Host *shpnt)
if(data_count & 1) { if(data_count & 1) {
SETPORT(DMACNTRL0,WRITE_READ|ENDMA|_8BIT); SETPORT(DMACNTRL0,WRITE_READ|ENDMA|_8BIT);
SETPORT(DATAPORT, *CURRENT_SC->SCp.ptr++); SETPORT(DATAPORT, *scsi_pointer->ptr++);
CURRENT_SC->SCp.this_residual--; scsi_pointer->this_residual--;
CMD_INC_RESID(CURRENT_SC, -1); CMD_INC_RESID(CURRENT_SC, -1);
SETPORT(DMACNTRL0,WRITE_READ|ENDMA); SETPORT(DMACNTRL0,WRITE_READ|ENDMA);
} }
if(data_count > 1) { if(data_count > 1) {
data_count >>= 1; data_count >>= 1;
outsw(DATAPORT, CURRENT_SC->SCp.ptr, data_count); outsw(DATAPORT, scsi_pointer->ptr, data_count);
CURRENT_SC->SCp.ptr += 2 * data_count; scsi_pointer->ptr += 2 * data_count;
CURRENT_SC->SCp.this_residual -= 2 * data_count; scsi_pointer->this_residual -= 2 * data_count;
CMD_INC_RESID(CURRENT_SC, -2 * data_count); CMD_INC_RESID(CURRENT_SC, -2 * data_count);
} }
if (CURRENT_SC->SCp.this_residual == 0 && if (scsi_pointer->this_residual == 0 &&
!sg_is_last(CURRENT_SC->SCp.buffer)) { !sg_is_last(scsi_pointer->buffer)) {
/* advance to next buffer */ /* advance to next buffer */
CURRENT_SC->SCp.buffer = sg_next(CURRENT_SC->SCp.buffer); scsi_pointer->buffer = sg_next(scsi_pointer->buffer);
CURRENT_SC->SCp.ptr = SG_ADDRESS(CURRENT_SC->SCp.buffer); scsi_pointer->ptr = SG_ADDRESS(scsi_pointer->buffer);
CURRENT_SC->SCp.this_residual = CURRENT_SC->SCp.buffer->length; scsi_pointer->this_residual = scsi_pointer->buffer->length;
} }
the_time=jiffies + 100*HZ; the_time=jiffies + 100*HZ;
@ -2149,6 +2192,8 @@ static void datao_run(struct Scsi_Host *shpnt)
static void datao_end(struct Scsi_Host *shpnt) static void datao_end(struct Scsi_Host *shpnt)
{ {
struct scsi_pointer *scsi_pointer = aha152x_scsi_pointer(CURRENT_SC);
if(TESTLO(DMASTAT, DFIFOEMP)) { if(TESTLO(DMASTAT, DFIFOEMP)) {
u32 datao_cnt = GETSTCNT(); u32 datao_cnt = GETSTCNT();
int datao_out = DATA_LEN - scsi_get_resid(CURRENT_SC); int datao_out = DATA_LEN - scsi_get_resid(CURRENT_SC);
@ -2166,9 +2211,9 @@ static void datao_end(struct Scsi_Host *shpnt)
sg = sg_next(sg); sg = sg_next(sg);
} }
CURRENT_SC->SCp.buffer = sg; scsi_pointer->buffer = sg;
CURRENT_SC->SCp.ptr = SG_ADDRESS(CURRENT_SC->SCp.buffer) + done; scsi_pointer->ptr = SG_ADDRESS(scsi_pointer->buffer) + done;
CURRENT_SC->SCp.this_residual = CURRENT_SC->SCp.buffer->length - scsi_pointer->this_residual = scsi_pointer->buffer->length -
done; done;
} }
@ -2184,6 +2229,7 @@ static void datao_end(struct Scsi_Host *shpnt)
*/ */
static int update_state(struct Scsi_Host *shpnt) static int update_state(struct Scsi_Host *shpnt)
{ {
struct scsi_pointer *scsi_pointer = aha152x_scsi_pointer(CURRENT_SC);
int dataphase=0; int dataphase=0;
unsigned int stat0 = GETPORT(SSTAT0); unsigned int stat0 = GETPORT(SSTAT0);
unsigned int stat1 = GETPORT(SSTAT1); unsigned int stat1 = GETPORT(SSTAT1);
@ -2197,7 +2243,8 @@ static int update_state(struct Scsi_Host *shpnt)
SETPORT(SSTAT1,SCSIRSTI); SETPORT(SSTAT1,SCSIRSTI);
} else if (stat0 & SELDI && PREVSTATE == busfree) { } else if (stat0 & SELDI && PREVSTATE == busfree) {
STATE=seldi; STATE=seldi;
} else if(stat0 & SELDO && CURRENT_SC && (CURRENT_SC->SCp.phase & selecting)) { } else if (stat0 & SELDO && CURRENT_SC &&
(scsi_pointer->phase & selecting)) {
STATE=seldo; STATE=seldo;
} else if(stat1 & SELTO) { } else if(stat1 & SELTO) {
STATE=selto; STATE=selto;
@ -2329,7 +2376,8 @@ static void is_complete(struct Scsi_Host *shpnt)
SETPORT(SXFRCTL0, CH1); SETPORT(SXFRCTL0, CH1);
SETPORT(DMACNTRL0, 0); SETPORT(DMACNTRL0, 0);
if(CURRENT_SC) if(CURRENT_SC)
CURRENT_SC->SCp.phase &= ~spiordy; aha152x_scsi_pointer(CURRENT_SC)->phase &=
~spiordy;
} }
/* /*
@ -2351,7 +2399,8 @@ static void is_complete(struct Scsi_Host *shpnt)
SETPORT(DMACNTRL0, 0); SETPORT(DMACNTRL0, 0);
SETPORT(SXFRCTL0, CH1|SPIOEN); SETPORT(SXFRCTL0, CH1|SPIOEN);
if(CURRENT_SC) if(CURRENT_SC)
CURRENT_SC->SCp.phase |= spiordy; aha152x_scsi_pointer(CURRENT_SC)->phase |=
spiordy;
} }
/* /*
@ -2441,21 +2490,23 @@ static void disp_enintr(struct Scsi_Host *shpnt)
*/ */
static void show_command(struct scsi_cmnd *ptr) static void show_command(struct scsi_cmnd *ptr)
{ {
const int phase = aha152x_scsi_pointer(ptr)->phase;
scsi_print_command(ptr); scsi_print_command(ptr);
scmd_printk(KERN_DEBUG, ptr, scmd_printk(KERN_DEBUG, ptr,
"request_bufflen=%d; resid=%d; " "request_bufflen=%d; resid=%d; "
"phase |%s%s%s%s%s%s%s%s%s; next=0x%p", "phase |%s%s%s%s%s%s%s%s%s; next=0x%p",
scsi_bufflen(ptr), scsi_get_resid(ptr), scsi_bufflen(ptr), scsi_get_resid(ptr),
(ptr->SCp.phase & not_issued) ? "not issued|" : "", phase & not_issued ? "not issued|" : "",
(ptr->SCp.phase & selecting) ? "selecting|" : "", phase & selecting ? "selecting|" : "",
(ptr->SCp.phase & identified) ? "identified|" : "", phase & identified ? "identified|" : "",
(ptr->SCp.phase & disconnected) ? "disconnected|" : "", phase & disconnected ? "disconnected|" : "",
(ptr->SCp.phase & completed) ? "completed|" : "", phase & completed ? "completed|" : "",
(ptr->SCp.phase & spiordy) ? "spiordy|" : "", phase & spiordy ? "spiordy|" : "",
(ptr->SCp.phase & syncneg) ? "syncneg|" : "", phase & syncneg ? "syncneg|" : "",
(ptr->SCp.phase & aborted) ? "aborted|" : "", phase & aborted ? "aborted|" : "",
(ptr->SCp.phase & resetted) ? "resetted|" : "", phase & resetted ? "resetted|" : "",
(SCDATA(ptr)) ? SCNEXT(ptr) : NULL); SCDATA(ptr) ? SCNEXT(ptr) : NULL);
} }
/* /*
@ -2487,6 +2538,8 @@ static void show_queues(struct Scsi_Host *shpnt)
static void get_command(struct seq_file *m, struct scsi_cmnd * ptr) static void get_command(struct seq_file *m, struct scsi_cmnd * ptr)
{ {
struct scsi_pointer *scsi_pointer = aha152x_scsi_pointer(ptr);
const int phase = scsi_pointer->phase;
int i; int i;
seq_printf(m, "%p: target=%d; lun=%d; cmnd=( ", seq_printf(m, "%p: target=%d; lun=%d; cmnd=( ",
@ -2496,24 +2549,24 @@ static void get_command(struct seq_file *m, struct scsi_cmnd * ptr)
seq_printf(m, "0x%02x ", ptr->cmnd[i]); seq_printf(m, "0x%02x ", ptr->cmnd[i]);
seq_printf(m, "); resid=%d; residual=%d; buffers=%d; phase |", seq_printf(m, "); resid=%d; residual=%d; buffers=%d; phase |",
scsi_get_resid(ptr), ptr->SCp.this_residual, scsi_get_resid(ptr), scsi_pointer->this_residual,
sg_nents(ptr->SCp.buffer) - 1); sg_nents(scsi_pointer->buffer) - 1);
if (ptr->SCp.phase & not_issued) if (phase & not_issued)
seq_puts(m, "not issued|"); seq_puts(m, "not issued|");
if (ptr->SCp.phase & selecting) if (phase & selecting)
seq_puts(m, "selecting|"); seq_puts(m, "selecting|");
if (ptr->SCp.phase & disconnected) if (phase & disconnected)
seq_puts(m, "disconnected|"); seq_puts(m, "disconnected|");
if (ptr->SCp.phase & aborted) if (phase & aborted)
seq_puts(m, "aborted|"); seq_puts(m, "aborted|");
if (ptr->SCp.phase & identified) if (phase & identified)
seq_puts(m, "identified|"); seq_puts(m, "identified|");
if (ptr->SCp.phase & completed) if (phase & completed)
seq_puts(m, "completed|"); seq_puts(m, "completed|");
if (ptr->SCp.phase & spiordy) if (phase & spiordy)
seq_puts(m, "spiordy|"); seq_puts(m, "spiordy|");
if (ptr->SCp.phase & syncneg) if (phase & syncneg)
seq_puts(m, "syncneg|"); seq_puts(m, "syncneg|");
seq_printf(m, "; next=0x%p\n", SCNEXT(ptr)); seq_printf(m, "; next=0x%p\n", SCNEXT(ptr));
} }
@ -2918,6 +2971,7 @@ static struct scsi_host_template aha152x_driver_template = {
.sg_tablesize = SG_ALL, .sg_tablesize = SG_ALL,
.dma_boundary = PAGE_SIZE - 1, .dma_boundary = PAGE_SIZE - 1,
.slave_alloc = aha152x_adjust_queue, .slave_alloc = aha152x_adjust_queue,
.cmd_size = sizeof(struct aha152x_cmd_priv),
}; };
#if !defined(AHA152X_PCMCIA) #if !defined(AHA152X_PCMCIA)
@ -3375,13 +3429,11 @@ static int __init aha152x_setup(char *str)
setup[setup_count].synchronous = ints[0] >= 6 ? ints[6] : 1; setup[setup_count].synchronous = ints[0] >= 6 ? ints[6] : 1;
setup[setup_count].delay = ints[0] >= 7 ? ints[7] : DELAY_DEFAULT; setup[setup_count].delay = ints[0] >= 7 ? ints[7] : DELAY_DEFAULT;
setup[setup_count].ext_trans = ints[0] >= 8 ? ints[8] : 0; setup[setup_count].ext_trans = ints[0] >= 8 ? ints[8] : 0;
if (ints[0] > 8) { /*}*/ if (ints[0] > 8)
printk(KERN_NOTICE "aha152x: usage: aha152x=<IOBASE>[,<IRQ>[,<SCSI ID>" printk(KERN_NOTICE "aha152x: usage: aha152x=<IOBASE>[,<IRQ>[,<SCSI ID>"
"[,<RECONNECT>[,<PARITY>[,<SYNCHRONOUS>[,<DELAY>[,<EXT_TRANS>]]]]]]]\n"); "[,<RECONNECT>[,<PARITY>[,<SYNCHRONOUS>[,<DELAY>[,<EXT_TRANS>]]]]]]]\n");
} else { else
setup_count++; setup_count++;
return 0;
}
return 1; return 1;
} }

View File

@ -206,7 +206,6 @@ static int makecode(unsigned hosterr, unsigned scsierr)
static int aha1542_test_port(struct Scsi_Host *sh) static int aha1542_test_port(struct Scsi_Host *sh)
{ {
u8 inquiry_result[4];
int i; int i;
/* Quick and dirty test for presence of the card. */ /* Quick and dirty test for presence of the card. */
@ -240,7 +239,7 @@ static int aha1542_test_port(struct Scsi_Host *sh)
for (i = 0; i < 4; i++) { for (i = 0; i < 4; i++) {
if (!wait_mask(STATUS(sh->io_port), DF, DF, 0, 0)) if (!wait_mask(STATUS(sh->io_port), DF, DF, 0, 0))
return 0; return 0;
inquiry_result[i] = inb(DATA(sh->io_port)); (void)inb(DATA(sh->io_port));
} }
/* Reading port should reset DF */ /* Reading port should reset DF */

View File

@ -55,8 +55,12 @@
#include <asm/dma.h> #include <asm/dma.h>
#include <asm/io.h> #include <asm/io.h>
#include "scsi.h" #include <scsi/scsi.h>
#include <scsi/scsi_cmnd.h>
#include <scsi/scsi_device.h>
#include <scsi/scsi_eh.h>
#include <scsi/scsi_host.h> #include <scsi/scsi_host.h>
#include <scsi/scsi_tcq.h>
#include "aha1740.h" #include "aha1740.h"
/* IF YOU ARE HAVING PROBLEMS WITH THIS DRIVER, AND WANT TO WATCH /* IF YOU ARE HAVING PROBLEMS WITH THIS DRIVER, AND WANT TO WATCH

View File

@ -283,7 +283,7 @@ main(int argc, char *argv[])
/* /*
* Decend the tree of scopes and insert/emit * Decend the tree of scopes and insert/emit
* patches as appropriate. We perform a depth first * patches as appropriate. We perform a depth first
* tranversal, recursively handling each scope. * traversal, recursively handling each scope.
*/ */
/* start at the root scope */ /* start at the root scope */
dump_scope(SLIST_FIRST(&scope_stack)); dump_scope(SLIST_FIRST(&scope_stack));

View File

@ -60,7 +60,6 @@ void asd_set_dmamode(struct domain_device *dev);
/* ---------- TMFs ---------- */ /* ---------- TMFs ---------- */
int asd_abort_task(struct sas_task *); int asd_abort_task(struct sas_task *);
int asd_abort_task_set(struct domain_device *, u8 *lun); int asd_abort_task_set(struct domain_device *, u8 *lun);
int asd_clear_aca(struct domain_device *, u8 *lun);
int asd_clear_task_set(struct domain_device *, u8 *lun); int asd_clear_task_set(struct domain_device *, u8 *lun);
int asd_lu_reset(struct domain_device *, u8 *lun); int asd_lu_reset(struct domain_device *, u8 *lun);
int asd_I_T_nexus_reset(struct domain_device *dev); int asd_I_T_nexus_reset(struct domain_device *dev);

View File

@ -960,7 +960,6 @@ static struct sas_domain_function_template aic94xx_transport_functions = {
.lldd_abort_task = asd_abort_task, .lldd_abort_task = asd_abort_task,
.lldd_abort_task_set = asd_abort_task_set, .lldd_abort_task_set = asd_abort_task_set,
.lldd_clear_aca = asd_clear_aca,
.lldd_clear_task_set = asd_clear_task_set, .lldd_clear_task_set = asd_clear_task_set,
.lldd_I_T_nexus_reset = asd_I_T_nexus_reset, .lldd_I_T_nexus_reset = asd_I_T_nexus_reset,
.lldd_lu_reset = asd_lu_reset, .lldd_lu_reset = asd_lu_reset,

View File

@ -322,7 +322,6 @@ Again:
spin_lock_irqsave(&task->task_state_lock, flags); spin_lock_irqsave(&task->task_state_lock, flags);
task->task_state_flags &= ~SAS_TASK_STATE_PENDING; task->task_state_flags &= ~SAS_TASK_STATE_PENDING;
task->task_state_flags &= ~SAS_TASK_AT_INITIATOR;
task->task_state_flags |= SAS_TASK_STATE_DONE; task->task_state_flags |= SAS_TASK_STATE_DONE;
if (unlikely((task->task_state_flags & SAS_TASK_STATE_ABORTED))) { if (unlikely((task->task_state_flags & SAS_TASK_STATE_ABORTED))) {
struct completion *completion = ascb->completion; struct completion *completion = ascb->completion;
@ -532,7 +531,6 @@ int asd_execute_task(struct sas_task *task, gfp_t gfp_flags)
struct sas_task *t = task; struct sas_task *t = task;
struct asd_ascb *ascb = NULL, *a; struct asd_ascb *ascb = NULL, *a;
struct asd_ha_struct *asd_ha = task->dev->port->ha->lldd_ha; struct asd_ha_struct *asd_ha = task->dev->port->ha->lldd_ha;
unsigned long flags;
res = asd_can_queue(asd_ha, 1); res = asd_can_queue(asd_ha, 1);
if (res) if (res)
@ -575,10 +573,6 @@ int asd_execute_task(struct sas_task *task, gfp_t gfp_flags)
} }
if (res) if (res)
goto out_err_unmap; goto out_err_unmap;
spin_lock_irqsave(&t->task_state_lock, flags);
t->task_state_flags |= SAS_TASK_AT_INITIATOR;
spin_unlock_irqrestore(&t->task_state_lock, flags);
} }
list_del_init(&alist); list_del_init(&alist);
@ -597,9 +591,6 @@ out_err_unmap:
if (a == b) if (a == b)
break; break;
t = a->uldd_task; t = a->uldd_task;
spin_lock_irqsave(&t->task_state_lock, flags);
t->task_state_flags &= ~SAS_TASK_AT_INITIATOR;
spin_unlock_irqrestore(&t->task_state_lock, flags);
switch (t->task_proto) { switch (t->task_proto) {
case SAS_PROTOCOL_SATA: case SAS_PROTOCOL_SATA:
case SAS_PROTOCOL_STP: case SAS_PROTOCOL_STP:

View File

@ -287,7 +287,7 @@ static int asd_get_tmf_resp_tasklet(struct asd_ascb *ascb,
fh = edb->vaddr + 16; fh = edb->vaddr + 16;
ru = edb->vaddr + 16 + sizeof(*fh); ru = edb->vaddr + 16 + sizeof(*fh);
res = ru->status; res = ru->status;
if (ru->datapres == 1) /* Response data present */ if (ru->datapres == SAS_DATAPRES_RESPONSE_DATA)
res = ru->resp_data[3]; res = ru->resp_data[3];
#if 0 #if 0
ascb->tag = fh->tag; ascb->tag = fh->tag;
@ -644,15 +644,6 @@ int asd_abort_task_set(struct domain_device *dev, u8 *lun)
return res; return res;
} }
int asd_clear_aca(struct domain_device *dev, u8 *lun)
{
int res = asd_initiate_ssp_tmf(dev, lun, TMF_CLEAR_ACA, 0);
if (res == TMF_RESP_FUNC_COMPLETE)
asd_clear_nexus_I_T_L(dev, lun);
return res;
}
int asd_clear_task_set(struct domain_device *dev, u8 *lun) int asd_clear_task_set(struct domain_device *dev, u8 *lun)
{ {
int res = asd_initiate_ssp_tmf(dev, lun, TMF_CLEAR_TASK_SET, 0); int res = asd_initiate_ssp_tmf(dev, lun, TMF_CLEAR_TASK_SET, 0);

View File

@ -126,13 +126,17 @@
#include <asm/ecard.h> #include <asm/ecard.h>
#include "../scsi.h" #include <scsi/scsi.h>
#include <scsi/scsi_cmnd.h>
#include <scsi/scsi_dbg.h> #include <scsi/scsi_dbg.h>
#include <scsi/scsi_device.h>
#include <scsi/scsi_eh.h>
#include <scsi/scsi_host.h> #include <scsi/scsi_host.h>
#include <scsi/scsi_tcq.h>
#include <scsi/scsi_transport_spi.h> #include <scsi/scsi_transport_spi.h>
#include "acornscsi.h" #include "acornscsi.h"
#include "msgqueue.h" #include "msgqueue.h"
#include "scsi.h" #include "arm_scsi.h"
#include <scsi/scsicam.h> #include <scsi/scsicam.h>
@ -725,7 +729,7 @@ intr_ret_t acornscsi_kick(AS_Host *host)
*/ */
host->scsi.phase = PHASE_CONNECTING; host->scsi.phase = PHASE_CONNECTING;
host->SCpnt = SCpnt; host->SCpnt = SCpnt;
host->scsi.SCp = SCpnt->SCp; host->scsi.SCp = *arm_scsi_pointer(SCpnt);
host->dma.xfer_setup = 0; host->dma.xfer_setup = 0;
host->dma.xfer_required = 0; host->dma.xfer_required = 0;
host->dma.xfer_done = 0; host->dma.xfer_done = 0;
@ -1420,6 +1424,7 @@ unsigned char acornscsi_readmessagebyte(AS_Host *host)
static static
void acornscsi_message(AS_Host *host) void acornscsi_message(AS_Host *host)
{ {
struct scsi_pointer *scsi_pointer;
unsigned char message[16]; unsigned char message[16];
unsigned int msgidx = 0, msglen = 1; unsigned int msgidx = 0, msglen = 1;
@ -1489,8 +1494,9 @@ void acornscsi_message(AS_Host *host)
* the saved data pointer for the current I/O process. * the saved data pointer for the current I/O process.
*/ */
acornscsi_dma_cleanup(host); acornscsi_dma_cleanup(host);
host->SCpnt->SCp = host->scsi.SCp; scsi_pointer = arm_scsi_pointer(host->SCpnt);
host->SCpnt->SCp.sent_command = 0; *scsi_pointer = host->scsi.SCp;
scsi_pointer->sent_command = 0;
host->scsi.phase = PHASE_MSGIN; host->scsi.phase = PHASE_MSGIN;
break; break;
@ -1505,7 +1511,7 @@ void acornscsi_message(AS_Host *host)
* the present command and status areas.' * the present command and status areas.'
*/ */
acornscsi_dma_cleanup(host); acornscsi_dma_cleanup(host);
host->scsi.SCp = host->SCpnt->SCp; host->scsi.SCp = *arm_scsi_pointer(host->SCpnt);
host->scsi.phase = PHASE_MSGIN; host->scsi.phase = PHASE_MSGIN;
break; break;
@ -1805,7 +1811,7 @@ int acornscsi_reconnect_finish(AS_Host *host)
/* /*
* Restore data pointer from SAVED pointers. * Restore data pointer from SAVED pointers.
*/ */
host->scsi.SCp = host->SCpnt->SCp; host->scsi.SCp = *arm_scsi_pointer(host->SCpnt);
#if (DEBUG & (DEBUG_QUEUES|DEBUG_DISCON)) #if (DEBUG & (DEBUG_QUEUES|DEBUG_DISCON))
printk(", data pointers: [%p, %X]", printk(", data pointers: [%p, %X]",
host->scsi.SCp.ptr, host->scsi.SCp.this_residual); host->scsi.SCp.ptr, host->scsi.SCp.this_residual);
@ -2404,6 +2410,7 @@ acornscsi_intr(int irq, void *dev_id)
*/ */
static int acornscsi_queuecmd_lck(struct scsi_cmnd *SCpnt) static int acornscsi_queuecmd_lck(struct scsi_cmnd *SCpnt)
{ {
struct scsi_pointer *scsi_pointer = arm_scsi_pointer(SCpnt);
void (*done)(struct scsi_cmnd *) = scsi_done; void (*done)(struct scsi_cmnd *) = scsi_done;
AS_Host *host = (AS_Host *)SCpnt->device->host->hostdata; AS_Host *host = (AS_Host *)SCpnt->device->host->hostdata;
@ -2419,9 +2426,9 @@ static int acornscsi_queuecmd_lck(struct scsi_cmnd *SCpnt)
SCpnt->host_scribble = NULL; SCpnt->host_scribble = NULL;
SCpnt->result = 0; SCpnt->result = 0;
SCpnt->SCp.phase = (int)acornscsi_datadirection(SCpnt->cmnd[0]); scsi_pointer->phase = (int)acornscsi_datadirection(SCpnt->cmnd[0]);
SCpnt->SCp.sent_command = 0; scsi_pointer->sent_command = 0;
SCpnt->SCp.scsi_xferred = 0; scsi_pointer->scsi_xferred = 0;
init_SCp(SCpnt); init_SCp(SCpnt);
@ -2787,6 +2794,7 @@ static struct scsi_host_template acornscsi_template = {
.cmd_per_lun = 2, .cmd_per_lun = 2,
.dma_boundary = PAGE_SIZE - 1, .dma_boundary = PAGE_SIZE - 1,
.proc_name = "acornscsi", .proc_name = "acornscsi",
.cmd_size = sizeof(struct arm_cmd_priv),
}; };
static int acornscsi_probe(struct expansion_card *ec, const struct ecard_id *id) static int acornscsi_probe(struct expansion_card *ec, const struct ecard_id *id)

View File

@ -1,16 +1,25 @@
/* SPDX-License-Identifier: GPL-2.0-only */ /* SPDX-License-Identifier: GPL-2.0-only */
/* /*
* linux/drivers/acorn/scsi/scsi.h
*
* Copyright (C) 2002 Russell King * Copyright (C) 2002 Russell King
* *
* Commonly used scsi driver functions. * Commonly used functions by the ARM SCSI-II drivers.
*/ */
#include <linux/scatterlist.h> #include <linux/scatterlist.h>
#define BELT_AND_BRACES #define BELT_AND_BRACES
struct arm_cmd_priv {
struct scsi_pointer scsi_pointer;
};
static inline struct scsi_pointer *arm_scsi_pointer(struct scsi_cmnd *cmd)
{
struct arm_cmd_priv *acmd = scsi_cmd_priv(cmd);
return &acmd->scsi_pointer;
}
/* /*
* The scatter-gather list handling. This contains all * The scatter-gather list handling. This contains all
* the yucky stuff that needs to be fixed properly. * the yucky stuff that needs to be fixed properly.
@ -78,16 +87,18 @@ static inline void put_next_SCp_byte(struct scsi_pointer *SCp, unsigned char c)
static inline void init_SCp(struct scsi_cmnd *SCpnt) static inline void init_SCp(struct scsi_cmnd *SCpnt)
{ {
memset(&SCpnt->SCp, 0, sizeof(struct scsi_pointer)); struct scsi_pointer *scsi_pointer = arm_scsi_pointer(SCpnt);
memset(scsi_pointer, 0, sizeof(struct scsi_pointer));
if (scsi_bufflen(SCpnt)) { if (scsi_bufflen(SCpnt)) {
unsigned long len = 0; unsigned long len = 0;
SCpnt->SCp.buffer = scsi_sglist(SCpnt); scsi_pointer->buffer = scsi_sglist(SCpnt);
SCpnt->SCp.buffers_residual = scsi_sg_count(SCpnt) - 1; scsi_pointer->buffers_residual = scsi_sg_count(SCpnt) - 1;
SCpnt->SCp.ptr = sg_virt(SCpnt->SCp.buffer); scsi_pointer->ptr = sg_virt(scsi_pointer->buffer);
SCpnt->SCp.this_residual = SCpnt->SCp.buffer->length; scsi_pointer->this_residual = scsi_pointer->buffer->length;
SCpnt->SCp.phase = scsi_bufflen(SCpnt); scsi_pointer->phase = scsi_bufflen(SCpnt);
#ifdef BELT_AND_BRACES #ifdef BELT_AND_BRACES
{ /* { /*
@ -111,15 +122,15 @@ static inline void init_SCp(struct scsi_cmnd *SCpnt)
* FIXME: Totaly naive fixup. We should abort * FIXME: Totaly naive fixup. We should abort
* with error * with error
*/ */
SCpnt->SCp.phase = scsi_pointer->phase =
min_t(unsigned long, len, min_t(unsigned long, len,
scsi_bufflen(SCpnt)); scsi_bufflen(SCpnt));
} }
} }
#endif #endif
} else { } else {
SCpnt->SCp.ptr = NULL; scsi_pointer->ptr = NULL;
SCpnt->SCp.this_residual = 0; scsi_pointer->this_residual = 0;
SCpnt->SCp.phase = 0; scsi_pointer->phase = 0;
} }
} }

View File

@ -35,8 +35,12 @@
#include <asm/io.h> #include <asm/io.h>
#include <asm/ecard.h> #include <asm/ecard.h>
#include "../scsi.h" #include <scsi/scsi.h>
#include <scsi/scsi_cmnd.h>
#include <scsi/scsi_device.h>
#include <scsi/scsi_eh.h>
#include <scsi/scsi_host.h> #include <scsi/scsi_host.h>
#include <scsi/scsi_tcq.h>
#include "fas216.h" #include "fas216.h"
struct arxescsi_info { struct arxescsi_info {

View File

@ -223,7 +223,7 @@ static struct scsi_host_template cumanascsi_template = {
.sg_tablesize = SG_ALL, .sg_tablesize = SG_ALL,
.cmd_per_lun = 2, .cmd_per_lun = 2,
.proc_name = "CumanaSCSI-1", .proc_name = "CumanaSCSI-1",
.cmd_size = NCR5380_CMD_SIZE, .cmd_size = sizeof(struct NCR5380_cmd),
.max_sectors = 128, .max_sectors = 128,
.dma_boundary = PAGE_SIZE - 1, .dma_boundary = PAGE_SIZE - 1,
}; };

View File

@ -29,10 +29,14 @@
#include <asm/ecard.h> #include <asm/ecard.h>
#include <asm/io.h> #include <asm/io.h>
#include "../scsi.h" #include <scsi/scsi.h>
#include <scsi/scsi_cmnd.h>
#include <scsi/scsi_device.h>
#include <scsi/scsi_eh.h>
#include <scsi/scsi_host.h> #include <scsi/scsi_host.h>
#include <scsi/scsi_tcq.h>
#include "fas216.h" #include "fas216.h"
#include "scsi.h" #include "arm_scsi.h"
#include <scsi/scsicam.h> #include <scsi/scsicam.h>

View File

@ -35,10 +35,14 @@
#include <asm/dma.h> #include <asm/dma.h>
#include <asm/ecard.h> #include <asm/ecard.h>
#include "../scsi.h" #include <scsi/scsi.h>
#include <scsi/scsi_cmnd.h>
#include <scsi/scsi_device.h>
#include <scsi/scsi_eh.h>
#include <scsi/scsi_host.h> #include <scsi/scsi_host.h>
#include <scsi/scsi_tcq.h>
#include "fas216.h" #include "fas216.h"
#include "scsi.h" #include "arm_scsi.h"
#include <scsi/scsicam.h> #include <scsi/scsicam.h>

View File

@ -47,11 +47,15 @@
#include <asm/irq.h> #include <asm/irq.h>
#include <asm/ecard.h> #include <asm/ecard.h>
#include "../scsi.h" #include <scsi/scsi.h>
#include <scsi/scsi_cmnd.h>
#include <scsi/scsi_dbg.h> #include <scsi/scsi_dbg.h>
#include <scsi/scsi_device.h>
#include <scsi/scsi_eh.h>
#include <scsi/scsi_host.h> #include <scsi/scsi_host.h>
#include <scsi/scsi_tcq.h>
#include "fas216.h" #include "fas216.h"
#include "scsi.h" #include "arm_scsi.h"
/* NOTE: SCSI2 Synchronous transfers *require* DMA according to /* NOTE: SCSI2 Synchronous transfers *require* DMA according to
* the data sheet. This restriction is crazy, especially when * the data sheet. This restriction is crazy, especially when
@ -757,7 +761,7 @@ static void fas216_transfer(FAS216_Info *info)
fas216_log(info, LOG_ERROR, "null buffer passed to " fas216_log(info, LOG_ERROR, "null buffer passed to "
"fas216_starttransfer"); "fas216_starttransfer");
print_SCp(&info->scsi.SCp, "SCp: ", "\n"); print_SCp(&info->scsi.SCp, "SCp: ", "\n");
print_SCp(&info->SCpnt->SCp, "Cmnd SCp: ", "\n"); print_SCp(arm_scsi_pointer(info->SCpnt), "Cmnd SCp: ", "\n");
return; return;
} }
@ -1007,7 +1011,7 @@ fas216_reselected_intr(FAS216_Info *info)
/* /*
* Restore data pointer from SAVED data pointer * Restore data pointer from SAVED data pointer
*/ */
info->scsi.SCp = info->SCpnt->SCp; info->scsi.SCp = *arm_scsi_pointer(info->SCpnt);
fas216_log(info, LOG_CONNECT, "data pointers: [%p, %X]", fas216_log(info, LOG_CONNECT, "data pointers: [%p, %X]",
info->scsi.SCp.ptr, info->scsi.SCp.this_residual); info->scsi.SCp.ptr, info->scsi.SCp.this_residual);
@ -1050,6 +1054,7 @@ fas216_reselected_intr(FAS216_Info *info)
static void fas216_parse_message(FAS216_Info *info, unsigned char *message, int msglen) static void fas216_parse_message(FAS216_Info *info, unsigned char *message, int msglen)
{ {
struct scsi_pointer *scsi_pointer;
int i; int i;
switch (message[0]) { switch (message[0]) {
@ -1074,8 +1079,9 @@ static void fas216_parse_message(FAS216_Info *info, unsigned char *message, int
* as required by the SCSI II standard. These always * as required by the SCSI II standard. These always
* point to the start of their respective areas. * point to the start of their respective areas.
*/ */
info->SCpnt->SCp = info->scsi.SCp; scsi_pointer = arm_scsi_pointer(info->SCpnt);
info->SCpnt->SCp.sent_command = 0; *scsi_pointer = info->scsi.SCp;
scsi_pointer->sent_command = 0;
fas216_log(info, LOG_CONNECT | LOG_MESSAGES | LOG_BUFFER, fas216_log(info, LOG_CONNECT | LOG_MESSAGES | LOG_BUFFER,
"save data pointers: [%p, %X]", "save data pointers: [%p, %X]",
info->scsi.SCp.ptr, info->scsi.SCp.this_residual); info->scsi.SCp.ptr, info->scsi.SCp.this_residual);
@ -1088,7 +1094,7 @@ static void fas216_parse_message(FAS216_Info *info, unsigned char *message, int
/* /*
* Restore current data pointer from SAVED data pointer * Restore current data pointer from SAVED data pointer
*/ */
info->scsi.SCp = info->SCpnt->SCp; info->scsi.SCp = *arm_scsi_pointer(info->SCpnt);
fas216_log(info, LOG_CONNECT | LOG_MESSAGES | LOG_BUFFER, fas216_log(info, LOG_CONNECT | LOG_MESSAGES | LOG_BUFFER,
"restore data pointers: [%p, 0x%x]", "restore data pointers: [%p, 0x%x]",
info->scsi.SCp.ptr, info->scsi.SCp.this_residual); info->scsi.SCp.ptr, info->scsi.SCp.this_residual);
@ -1766,7 +1772,7 @@ static void fas216_start_command(FAS216_Info *info, struct scsi_cmnd *SCpnt)
* claim host busy * claim host busy
*/ */
info->scsi.phase = PHASE_SELECTION; info->scsi.phase = PHASE_SELECTION;
info->scsi.SCp = SCpnt->SCp; info->scsi.SCp = *arm_scsi_pointer(SCpnt);
info->SCpnt = SCpnt; info->SCpnt = SCpnt;
info->dma.transfer_type = fasdma_none; info->dma.transfer_type = fasdma_none;
@ -1845,7 +1851,7 @@ static void fas216_do_bus_device_reset(FAS216_Info *info,
* claim host busy * claim host busy
*/ */
info->scsi.phase = PHASE_SELECTION; info->scsi.phase = PHASE_SELECTION;
info->scsi.SCp = SCpnt->SCp; info->scsi.SCp = *arm_scsi_pointer(SCpnt);
info->SCpnt = SCpnt; info->SCpnt = SCpnt;
info->dma.transfer_type = fasdma_none; info->dma.transfer_type = fasdma_none;
@ -1995,11 +2001,13 @@ static void fas216_devicereset_done(FAS216_Info *info, struct scsi_cmnd *SCpnt,
static void fas216_rq_sns_done(FAS216_Info *info, struct scsi_cmnd *SCpnt, static void fas216_rq_sns_done(FAS216_Info *info, struct scsi_cmnd *SCpnt,
unsigned int result) unsigned int result)
{ {
struct scsi_pointer *scsi_pointer = arm_scsi_pointer(SCpnt);
fas216_log_target(info, LOG_CONNECT, SCpnt->device->id, fas216_log_target(info, LOG_CONNECT, SCpnt->device->id,
"request sense complete, result=0x%04x%02x%02x", "request sense complete, result=0x%04x%02x%02x",
result, SCpnt->SCp.Message, SCpnt->SCp.Status); result, scsi_pointer->Message, scsi_pointer->Status);
if (result != DID_OK || SCpnt->SCp.Status != SAM_STAT_GOOD) if (result != DID_OK || scsi_pointer->Status != SAM_STAT_GOOD)
/* /*
* Something went wrong. Make sure that we don't * Something went wrong. Make sure that we don't
* have valid data in the sense buffer that could * have valid data in the sense buffer that could
@ -2029,6 +2037,8 @@ static void fas216_rq_sns_done(FAS216_Info *info, struct scsi_cmnd *SCpnt,
static void static void
fas216_std_done(FAS216_Info *info, struct scsi_cmnd *SCpnt, unsigned int result) fas216_std_done(FAS216_Info *info, struct scsi_cmnd *SCpnt, unsigned int result)
{ {
struct scsi_pointer *scsi_pointer = arm_scsi_pointer(SCpnt);
info->stats.fins += 1; info->stats.fins += 1;
set_host_byte(SCpnt, result); set_host_byte(SCpnt, result);
@ -2103,8 +2113,8 @@ request_sense:
fas216_log_target(info, LOG_CONNECT, SCpnt->device->id, fas216_log_target(info, LOG_CONNECT, SCpnt->device->id,
"requesting sense"); "requesting sense");
init_SCp(SCpnt); init_SCp(SCpnt);
SCpnt->SCp.Message = 0; scsi_pointer->Message = 0;
SCpnt->SCp.Status = 0; scsi_pointer->Status = 0;
SCpnt->host_scribble = (void *)fas216_rq_sns_done; SCpnt->host_scribble = (void *)fas216_rq_sns_done;
/* /*

View File

@ -312,6 +312,10 @@ typedef struct {
/* driver-private data per SCSI command. */ /* driver-private data per SCSI command. */
struct fas216_cmd_priv { struct fas216_cmd_priv {
/*
* @scsi_pointer must be the first member. See also arm_scsi_pointer().
*/
struct scsi_pointer scsi_pointer;
void (*scsi_done)(struct scsi_cmnd *cmd); void (*scsi_done)(struct scsi_cmnd *cmd);
}; };

View File

@ -113,7 +113,7 @@ static struct scsi_host_template oakscsi_template = {
.cmd_per_lun = 2, .cmd_per_lun = 2,
.dma_boundary = PAGE_SIZE - 1, .dma_boundary = PAGE_SIZE - 1,
.proc_name = "oakscsi", .proc_name = "oakscsi",
.cmd_size = NCR5380_CMD_SIZE, .cmd_size = sizeof(struct NCR5380_cmd),
.max_sectors = 128, .max_sectors = 128,
}; };

View File

@ -20,10 +20,14 @@
#include <asm/ecard.h> #include <asm/ecard.h>
#include <asm/io.h> #include <asm/io.h>
#include "../scsi.h" #include <scsi/scsi.h>
#include <scsi/scsi_cmnd.h>
#include <scsi/scsi_device.h>
#include <scsi/scsi_eh.h>
#include <scsi/scsi_host.h> #include <scsi/scsi_host.h>
#include <scsi/scsi_tcq.h>
#include "fas216.h" #include "fas216.h"
#include "scsi.h" #include "arm_scsi.h"
#include <scsi/scsicam.h> #include <scsi/scsicam.h>

View File

@ -20,7 +20,11 @@
#include <linux/list.h> #include <linux/list.h>
#include <linux/init.h> #include <linux/init.h>
#include "../scsi.h" #include <scsi/scsi.h>
#include <scsi/scsi_cmnd.h>
#include <scsi/scsi_device.h>
#include <scsi/scsi_eh.h>
#include <scsi/scsi_tcq.h>
#define DEBUG #define DEBUG

View File

@ -538,7 +538,7 @@ static int falcon_classify_cmd(struct scsi_cmnd *cmd)
static int atari_scsi_dma_xfer_len(struct NCR5380_hostdata *hostdata, static int atari_scsi_dma_xfer_len(struct NCR5380_hostdata *hostdata,
struct scsi_cmnd *cmd) struct scsi_cmnd *cmd)
{ {
int wanted_len = cmd->SCp.this_residual; int wanted_len = NCR5380_to_ncmd(cmd)->this_residual;
int possible_len, limit; int possible_len, limit;
if (wanted_len < DMA_MIN_SIZE) if (wanted_len < DMA_MIN_SIZE)
@ -610,7 +610,7 @@ static int atari_scsi_dma_xfer_len(struct NCR5380_hostdata *hostdata,
} }
/* Last step: apply the hard limit on DMA transfers */ /* Last step: apply the hard limit on DMA transfers */
limit = (atari_dma_buffer && !STRAM_ADDR(virt_to_phys(cmd->SCp.ptr))) ? limit = (atari_dma_buffer && !STRAM_ADDR(virt_to_phys(NCR5380_to_ncmd(cmd)->ptr))) ?
STRAM_BUFFER_SIZE : 255*512; STRAM_BUFFER_SIZE : 255*512;
if (possible_len > limit) if (possible_len > limit)
possible_len = limit; possible_len = limit;
@ -711,7 +711,7 @@ static struct scsi_host_template atari_scsi_template = {
.this_id = 7, .this_id = 7,
.cmd_per_lun = 2, .cmd_per_lun = 2,
.dma_boundary = PAGE_SIZE - 1, .dma_boundary = PAGE_SIZE - 1,
.cmd_size = NCR5380_CMD_SIZE, .cmd_size = sizeof(struct NCR5380_cmd),
}; };
static int __init atari_scsi_probe(struct platform_device *pdev) static int __init atari_scsi_probe(struct platform_device *pdev)

View File

@ -218,7 +218,7 @@ static char const *cqe_desc[] = {
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 = iscsi_cmd(sc)->task;
struct iscsi_cls_session *cls_session; struct iscsi_cls_session *cls_session;
struct beiscsi_io_task *abrt_io_task; struct beiscsi_io_task *abrt_io_task;
struct beiscsi_conn *beiscsi_conn; struct beiscsi_conn *beiscsi_conn;
@ -403,6 +403,7 @@ static struct scsi_host_template beiscsi_sht = {
.cmd_per_lun = BEISCSI_CMD_PER_LUN, .cmd_per_lun = BEISCSI_CMD_PER_LUN,
.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,
.cmd_size = sizeof(struct iscsi_cmd),
}; };
static struct scsi_transport_template *beiscsi_scsi_transport; static struct scsi_transport_template *beiscsi_scsi_transport;

View File

@ -711,7 +711,7 @@ bfad_im_serial_num_show(struct device *dev, struct device_attribute *attr,
char serial_num[BFA_ADAPTER_SERIAL_NUM_LEN]; char serial_num[BFA_ADAPTER_SERIAL_NUM_LEN];
bfa_get_adapter_serial_num(&bfad->bfa, serial_num); bfa_get_adapter_serial_num(&bfad->bfa, serial_num);
return snprintf(buf, PAGE_SIZE, "%s\n", serial_num); return sysfs_emit(buf, "%s\n", serial_num);
} }
static ssize_t static ssize_t
@ -725,7 +725,7 @@ bfad_im_model_show(struct device *dev, struct device_attribute *attr,
char model[BFA_ADAPTER_MODEL_NAME_LEN]; char model[BFA_ADAPTER_MODEL_NAME_LEN];
bfa_get_adapter_model(&bfad->bfa, model); bfa_get_adapter_model(&bfad->bfa, model);
return snprintf(buf, PAGE_SIZE, "%s\n", model); return sysfs_emit(buf, "%s\n", model);
} }
static ssize_t static ssize_t
@ -805,7 +805,7 @@ bfad_im_model_desc_show(struct device *dev, struct device_attribute *attr,
snprintf(model_descr, BFA_ADAPTER_MODEL_DESCR_LEN, snprintf(model_descr, BFA_ADAPTER_MODEL_DESCR_LEN,
"Invalid Model"); "Invalid Model");
return snprintf(buf, PAGE_SIZE, "%s\n", model_descr); return sysfs_emit(buf, "%s\n", model_descr);
} }
static ssize_t static ssize_t
@ -819,7 +819,7 @@ bfad_im_node_name_show(struct device *dev, struct device_attribute *attr,
u64 nwwn; u64 nwwn;
nwwn = bfa_fcs_lport_get_nwwn(port->fcs_port); nwwn = bfa_fcs_lport_get_nwwn(port->fcs_port);
return snprintf(buf, PAGE_SIZE, "0x%llx\n", cpu_to_be64(nwwn)); return sysfs_emit(buf, "0x%llx\n", cpu_to_be64(nwwn));
} }
static ssize_t static ssize_t
@ -836,7 +836,7 @@ bfad_im_symbolic_name_show(struct device *dev, struct device_attribute *attr,
bfa_fcs_lport_get_attr(&bfad->bfa_fcs.fabric.bport, &port_attr); bfa_fcs_lport_get_attr(&bfad->bfa_fcs.fabric.bport, &port_attr);
strlcpy(symname, port_attr.port_cfg.sym_name.symname, strlcpy(symname, port_attr.port_cfg.sym_name.symname,
BFA_SYMNAME_MAXLEN); BFA_SYMNAME_MAXLEN);
return snprintf(buf, PAGE_SIZE, "%s\n", symname); return sysfs_emit(buf, "%s\n", symname);
} }
static ssize_t static ssize_t
@ -850,14 +850,14 @@ bfad_im_hw_version_show(struct device *dev, struct device_attribute *attr,
char hw_ver[BFA_VERSION_LEN]; char hw_ver[BFA_VERSION_LEN];
bfa_get_pci_chip_rev(&bfad->bfa, hw_ver); bfa_get_pci_chip_rev(&bfad->bfa, hw_ver);
return snprintf(buf, PAGE_SIZE, "%s\n", hw_ver); return sysfs_emit(buf, "%s\n", hw_ver);
} }
static ssize_t static ssize_t
bfad_im_drv_version_show(struct device *dev, struct device_attribute *attr, bfad_im_drv_version_show(struct device *dev, struct device_attribute *attr,
char *buf) char *buf)
{ {
return snprintf(buf, PAGE_SIZE, "%s\n", BFAD_DRIVER_VERSION); return sysfs_emit(buf, "%s\n", BFAD_DRIVER_VERSION);
} }
static ssize_t static ssize_t
@ -871,7 +871,7 @@ bfad_im_optionrom_version_show(struct device *dev,
char optrom_ver[BFA_VERSION_LEN]; char optrom_ver[BFA_VERSION_LEN];
bfa_get_adapter_optrom_ver(&bfad->bfa, optrom_ver); bfa_get_adapter_optrom_ver(&bfad->bfa, optrom_ver);
return snprintf(buf, PAGE_SIZE, "%s\n", optrom_ver); return sysfs_emit(buf, "%s\n", optrom_ver);
} }
static ssize_t static ssize_t
@ -885,7 +885,7 @@ bfad_im_fw_version_show(struct device *dev, struct device_attribute *attr,
char fw_ver[BFA_VERSION_LEN]; char fw_ver[BFA_VERSION_LEN];
bfa_get_adapter_fw_ver(&bfad->bfa, fw_ver); bfa_get_adapter_fw_ver(&bfad->bfa, fw_ver);
return snprintf(buf, PAGE_SIZE, "%s\n", fw_ver); return sysfs_emit(buf, "%s\n", fw_ver);
} }
static ssize_t static ssize_t
@ -897,7 +897,7 @@ bfad_im_num_of_ports_show(struct device *dev, struct device_attribute *attr,
(struct bfad_im_port_s *) shost->hostdata[0]; (struct bfad_im_port_s *) shost->hostdata[0];
struct bfad_s *bfad = im_port->bfad; struct bfad_s *bfad = im_port->bfad;
return snprintf(buf, PAGE_SIZE, "%d\n", return sysfs_emit(buf, "%d\n",
bfa_get_nports(&bfad->bfa)); bfa_get_nports(&bfad->bfa));
} }
@ -905,7 +905,7 @@ static ssize_t
bfad_im_drv_name_show(struct device *dev, struct device_attribute *attr, bfad_im_drv_name_show(struct device *dev, struct device_attribute *attr,
char *buf) char *buf)
{ {
return snprintf(buf, PAGE_SIZE, "%s\n", BFAD_DRIVER_NAME); return sysfs_emit(buf, "%s\n", BFAD_DRIVER_NAME);
} }
static ssize_t static ssize_t
@ -924,14 +924,14 @@ bfad_im_num_of_discovered_ports_show(struct device *dev,
rports = kcalloc(nrports, sizeof(struct bfa_rport_qualifier_s), rports = kcalloc(nrports, sizeof(struct bfa_rport_qualifier_s),
GFP_ATOMIC); GFP_ATOMIC);
if (rports == NULL) if (rports == NULL)
return snprintf(buf, PAGE_SIZE, "Failed\n"); return sysfs_emit(buf, "Failed\n");
spin_lock_irqsave(&bfad->bfad_lock, flags); spin_lock_irqsave(&bfad->bfad_lock, flags);
bfa_fcs_lport_get_rport_quals(port->fcs_port, rports, &nrports); bfa_fcs_lport_get_rport_quals(port->fcs_port, rports, &nrports);
spin_unlock_irqrestore(&bfad->bfad_lock, flags); spin_unlock_irqrestore(&bfad->bfad_lock, flags);
kfree(rports); kfree(rports);
return snprintf(buf, PAGE_SIZE, "%d\n", nrports); return sysfs_emit(buf, "%d\n", nrports);
} }
static DEVICE_ATTR(serial_number, S_IRUGO, static DEVICE_ATTR(serial_number, S_IRUGO,

View File

@ -150,10 +150,10 @@ bfa_cb_tskim_done(void *bfad, struct bfad_tskim_s *dtsk,
struct scsi_cmnd *cmnd = (struct scsi_cmnd *)dtsk; struct scsi_cmnd *cmnd = (struct scsi_cmnd *)dtsk;
wait_queue_head_t *wq; wait_queue_head_t *wq;
cmnd->SCp.Status |= tsk_status << 1; bfad_priv(cmnd)->status |= tsk_status << 1;
set_bit(IO_DONE_BIT, (unsigned long *)&cmnd->SCp.Status); set_bit(IO_DONE_BIT, &bfad_priv(cmnd)->status);
wq = (wait_queue_head_t *) cmnd->SCp.ptr; wq = bfad_priv(cmnd)->wq;
cmnd->SCp.ptr = NULL; bfad_priv(cmnd)->wq = NULL;
if (wq) if (wq)
wake_up(wq); wake_up(wq);
@ -259,7 +259,7 @@ bfad_im_target_reset_send(struct bfad_s *bfad, struct scsi_cmnd *cmnd,
* happens. * happens.
*/ */
cmnd->host_scribble = NULL; cmnd->host_scribble = NULL;
cmnd->SCp.Status = 0; bfad_priv(cmnd)->status = 0;
bfa_itnim = bfa_fcs_itnim_get_halitn(&itnim->fcs_itnim); bfa_itnim = bfa_fcs_itnim_get_halitn(&itnim->fcs_itnim);
/* /*
* bfa_itnim can be NULL if the port gets disconnected and the bfa * bfa_itnim can be NULL if the port gets disconnected and the bfa
@ -326,8 +326,8 @@ bfad_im_reset_lun_handler(struct scsi_cmnd *cmnd)
* if happens. * if happens.
*/ */
cmnd->host_scribble = NULL; cmnd->host_scribble = NULL;
cmnd->SCp.ptr = (char *)&wq; bfad_priv(cmnd)->wq = &wq;
cmnd->SCp.Status = 0; bfad_priv(cmnd)->status = 0;
bfa_itnim = bfa_fcs_itnim_get_halitn(&itnim->fcs_itnim); bfa_itnim = bfa_fcs_itnim_get_halitn(&itnim->fcs_itnim);
/* /*
* bfa_itnim can be NULL if the port gets disconnected and the bfa * bfa_itnim can be NULL if the port gets disconnected and the bfa
@ -347,10 +347,9 @@ bfad_im_reset_lun_handler(struct scsi_cmnd *cmnd)
FCP_TM_LUN_RESET, BFAD_LUN_RESET_TMO); FCP_TM_LUN_RESET, BFAD_LUN_RESET_TMO);
spin_unlock_irqrestore(&bfad->bfad_lock, flags); spin_unlock_irqrestore(&bfad->bfad_lock, flags);
wait_event(wq, test_bit(IO_DONE_BIT, wait_event(wq, test_bit(IO_DONE_BIT, &bfad_priv(cmnd)->status));
(unsigned long *)&cmnd->SCp.Status));
task_status = cmnd->SCp.Status >> 1; task_status = bfad_priv(cmnd)->status >> 1;
if (task_status != BFI_TSKIM_STS_OK) { if (task_status != BFI_TSKIM_STS_OK) {
BFA_LOG(KERN_ERR, bfad, bfa_log_level, BFA_LOG(KERN_ERR, bfad, bfa_log_level,
"LUN reset failure, status: %d\n", task_status); "LUN reset failure, status: %d\n", task_status);
@ -381,16 +380,16 @@ bfad_im_reset_target_handler(struct scsi_cmnd *cmnd)
spin_lock_irqsave(&bfad->bfad_lock, flags); spin_lock_irqsave(&bfad->bfad_lock, flags);
itnim = bfad_get_itnim(im_port, starget->id); itnim = bfad_get_itnim(im_port, starget->id);
if (itnim) { if (itnim) {
cmnd->SCp.ptr = (char *)&wq; bfad_priv(cmnd)->wq = &wq;
rc = bfad_im_target_reset_send(bfad, cmnd, itnim); rc = bfad_im_target_reset_send(bfad, cmnd, itnim);
if (rc == BFA_STATUS_OK) { if (rc == BFA_STATUS_OK) {
/* wait target reset to complete */ /* wait target reset to complete */
spin_unlock_irqrestore(&bfad->bfad_lock, flags); spin_unlock_irqrestore(&bfad->bfad_lock, flags);
wait_event(wq, test_bit(IO_DONE_BIT, wait_event(wq, test_bit(IO_DONE_BIT,
(unsigned long *)&cmnd->SCp.Status)); &bfad_priv(cmnd)->status));
spin_lock_irqsave(&bfad->bfad_lock, flags); spin_lock_irqsave(&bfad->bfad_lock, flags);
task_status = cmnd->SCp.Status >> 1; task_status = bfad_priv(cmnd)->status >> 1;
if (task_status != BFI_TSKIM_STS_OK) if (task_status != BFI_TSKIM_STS_OK)
BFA_LOG(KERN_ERR, bfad, bfa_log_level, BFA_LOG(KERN_ERR, bfad, bfa_log_level,
"target reset failure," "target reset failure,"
@ -797,6 +796,7 @@ struct scsi_host_template bfad_im_scsi_host_template = {
.name = BFAD_DRIVER_NAME, .name = BFAD_DRIVER_NAME,
.info = bfad_im_info, .info = bfad_im_info,
.queuecommand = bfad_im_queuecommand, .queuecommand = bfad_im_queuecommand,
.cmd_size = sizeof(struct bfad_cmd_priv),
.eh_timed_out = fc_eh_timed_out, .eh_timed_out = fc_eh_timed_out,
.eh_abort_handler = bfad_im_abort_handler, .eh_abort_handler = bfad_im_abort_handler,
.eh_device_reset_handler = bfad_im_reset_lun_handler, .eh_device_reset_handler = bfad_im_reset_lun_handler,
@ -819,6 +819,7 @@ struct scsi_host_template bfad_im_vport_template = {
.name = BFAD_DRIVER_NAME, .name = BFAD_DRIVER_NAME,
.info = bfad_im_info, .info = bfad_im_info,
.queuecommand = bfad_im_queuecommand, .queuecommand = bfad_im_queuecommand,
.cmd_size = sizeof(struct bfad_cmd_priv),
.eh_timed_out = fc_eh_timed_out, .eh_timed_out = fc_eh_timed_out,
.eh_abort_handler = bfad_im_abort_handler, .eh_abort_handler = bfad_im_abort_handler,
.eh_device_reset_handler = bfad_im_reset_lun_handler, .eh_device_reset_handler = bfad_im_reset_lun_handler,

View File

@ -43,6 +43,22 @@ u32 bfad_im_supported_speeds(struct bfa_s *bfa);
*/ */
#define IO_DONE_BIT 0 #define IO_DONE_BIT 0
/**
* struct bfad_cmd_priv - private data per SCSI command.
* @status: Lowest bit represents IO_DONE. The next seven bits hold a value of
* type enum bfi_tskim_status.
* @wq: Wait queue used to wait for completion of an operation.
*/
struct bfad_cmd_priv {
unsigned long status;
wait_queue_head_t *wq;
};
static inline struct bfad_cmd_priv *bfad_priv(struct scsi_cmnd *cmd)
{
return scsi_cmd_priv(cmd);
}
struct bfad_itnim_data_s { struct bfad_itnim_data_s {
struct bfad_itnim_s *itnim; struct bfad_itnim_s *itnim;
}; };

View File

@ -137,8 +137,6 @@
#define BNX2FC_FW_TIMEOUT (3 * HZ) #define BNX2FC_FW_TIMEOUT (3 * HZ)
#define PORT_MAX 2 #define PORT_MAX 2
#define CMD_SCSI_STATUS(Cmnd) ((Cmnd)->SCp.Status)
/* FC FCP Status */ /* FC FCP Status */
#define FC_GOOD 0 #define FC_GOOD 0
@ -493,7 +491,14 @@ struct bnx2fc_unsol_els {
struct work_struct unsol_els_work; struct work_struct unsol_els_work;
}; };
struct bnx2fc_priv {
struct bnx2fc_cmd *io_req;
};
static inline struct bnx2fc_priv *bnx2fc_priv(struct scsi_cmnd *cmd)
{
return scsi_cmd_priv(cmd);
}
struct bnx2fc_cmd *bnx2fc_cmd_alloc(struct bnx2fc_rport *tgt); struct bnx2fc_cmd *bnx2fc_cmd_alloc(struct bnx2fc_rport *tgt);
struct bnx2fc_cmd *bnx2fc_elstm_alloc(struct bnx2fc_rport *tgt, int type); struct bnx2fc_cmd *bnx2fc_elstm_alloc(struct bnx2fc_rport *tgt, int type);

View File

@ -2718,14 +2718,13 @@ static int __init bnx2fc_mod_init(void)
bg = &bnx2fc_global; bg = &bnx2fc_global;
skb_queue_head_init(&bg->fcoe_rx_list); skb_queue_head_init(&bg->fcoe_rx_list);
l2_thread = kthread_create(bnx2fc_l2_rcv_thread, l2_thread = kthread_run(bnx2fc_l2_rcv_thread,
(void *)bg, (void *)bg,
"bnx2fc_l2_thread"); "bnx2fc_l2_thread");
if (IS_ERR(l2_thread)) { if (IS_ERR(l2_thread)) {
rc = PTR_ERR(l2_thread); rc = PTR_ERR(l2_thread);
goto free_wq; goto free_wq;
} }
wake_up_process(l2_thread);
spin_lock_bh(&bg->fcoe_rx_list.lock); spin_lock_bh(&bg->fcoe_rx_list.lock);
bg->kthread = l2_thread; bg->kthread = l2_thread;
spin_unlock_bh(&bg->fcoe_rx_list.lock); spin_unlock_bh(&bg->fcoe_rx_list.lock);
@ -2975,6 +2974,7 @@ static struct scsi_host_template bnx2fc_shost_template = {
.track_queue_depth = 1, .track_queue_depth = 1,
.slave_configure = bnx2fc_slave_configure, .slave_configure = bnx2fc_slave_configure,
.shost_groups = bnx2fc_host_groups, .shost_groups = bnx2fc_host_groups,
.cmd_size = sizeof(struct bnx2fc_priv),
}; };
static struct libfc_function_template bnx2fc_libfc_fcn_templ = { static struct libfc_function_template bnx2fc_libfc_fcn_templ = {

View File

@ -204,7 +204,7 @@ static void bnx2fc_scsi_done(struct bnx2fc_cmd *io_req, int err_code)
sc_cmd, host_byte(sc_cmd->result), sc_cmd->retries, sc_cmd, host_byte(sc_cmd->result), sc_cmd->retries,
sc_cmd->allowed); sc_cmd->allowed);
scsi_set_resid(sc_cmd, scsi_bufflen(sc_cmd)); scsi_set_resid(sc_cmd, scsi_bufflen(sc_cmd));
sc_cmd->SCp.ptr = NULL; bnx2fc_priv(sc_cmd)->io_req = NULL;
scsi_done(sc_cmd); scsi_done(sc_cmd);
} }
@ -765,7 +765,7 @@ retry_tmf:
task = &(task_page[index]); task = &(task_page[index]);
bnx2fc_init_mp_task(io_req, task); bnx2fc_init_mp_task(io_req, task);
sc_cmd->SCp.ptr = (char *)io_req; bnx2fc_priv(sc_cmd)->io_req = io_req;
/* Obtain free SQ entry */ /* Obtain free SQ entry */
spin_lock_bh(&tgt->tgt_lock); spin_lock_bh(&tgt->tgt_lock);
@ -1147,7 +1147,7 @@ int bnx2fc_eh_abort(struct scsi_cmnd *sc_cmd)
BNX2FC_TGT_DBG(tgt, "Entered bnx2fc_eh_abort\n"); BNX2FC_TGT_DBG(tgt, "Entered bnx2fc_eh_abort\n");
spin_lock_bh(&tgt->tgt_lock); spin_lock_bh(&tgt->tgt_lock);
io_req = (struct bnx2fc_cmd *)sc_cmd->SCp.ptr; io_req = bnx2fc_priv(sc_cmd)->io_req;
if (!io_req) { if (!io_req) {
/* Command might have just completed */ /* Command might have just completed */
printk(KERN_ERR PFX "eh_abort: io_req is NULL\n"); printk(KERN_ERR PFX "eh_abort: io_req is NULL\n");
@ -1572,8 +1572,8 @@ void bnx2fc_process_tm_compl(struct bnx2fc_cmd *io_req,
printk(KERN_ERR PFX "tmf's fc_hdr r_ctl = 0x%x\n", printk(KERN_ERR PFX "tmf's fc_hdr r_ctl = 0x%x\n",
fc_hdr->fh_r_ctl); fc_hdr->fh_r_ctl);
} }
if (!sc_cmd->SCp.ptr) { if (!bnx2fc_priv(sc_cmd)->io_req) {
printk(KERN_ERR PFX "tm_compl: SCp.ptr is NULL\n"); printk(KERN_ERR PFX "tm_compl: io_req is NULL\n");
return; return;
} }
switch (io_req->fcp_status) { switch (io_req->fcp_status) {
@ -1609,7 +1609,7 @@ void bnx2fc_process_tm_compl(struct bnx2fc_cmd *io_req,
return; return;
} }
sc_cmd->SCp.ptr = NULL; bnx2fc_priv(sc_cmd)->io_req = NULL;
scsi_done(sc_cmd); scsi_done(sc_cmd);
kref_put(&io_req->refcount, bnx2fc_cmd_release); kref_put(&io_req->refcount, bnx2fc_cmd_release);
@ -1773,8 +1773,7 @@ static void bnx2fc_parse_fcp_rsp(struct bnx2fc_cmd *io_req,
io_req->fcp_resid = fcp_rsp->fcp_resid; io_req->fcp_resid = fcp_rsp->fcp_resid;
io_req->scsi_comp_flags = rsp_flags; io_req->scsi_comp_flags = rsp_flags;
CMD_SCSI_STATUS(sc_cmd) = io_req->cdb_status = io_req->cdb_status = fcp_rsp->scsi_status_code;
fcp_rsp->scsi_status_code;
/* Fetch fcp_rsp_info and fcp_sns_info if available */ /* Fetch fcp_rsp_info and fcp_sns_info if available */
if (num_rq) { if (num_rq) {
@ -1946,8 +1945,8 @@ void bnx2fc_process_scsi_cmd_compl(struct bnx2fc_cmd *io_req,
/* parse fcp_rsp and obtain sense data from RQ if available */ /* parse fcp_rsp and obtain sense data from RQ if available */
bnx2fc_parse_fcp_rsp(io_req, fcp_rsp, num_rq, rq_data); bnx2fc_parse_fcp_rsp(io_req, fcp_rsp, num_rq, rq_data);
if (!sc_cmd->SCp.ptr) { if (!bnx2fc_priv(sc_cmd)->io_req) {
printk(KERN_ERR PFX "SCp.ptr is NULL\n"); printk(KERN_ERR PFX "io_req is NULL\n");
return; return;
} }
@ -2018,7 +2017,7 @@ void bnx2fc_process_scsi_cmd_compl(struct bnx2fc_cmd *io_req,
io_req->fcp_status); io_req->fcp_status);
break; break;
} }
sc_cmd->SCp.ptr = NULL; bnx2fc_priv(sc_cmd)->io_req = NULL;
scsi_done(sc_cmd); scsi_done(sc_cmd);
kref_put(&io_req->refcount, bnx2fc_cmd_release); kref_put(&io_req->refcount, bnx2fc_cmd_release);
} }
@ -2044,7 +2043,7 @@ int bnx2fc_post_io_req(struct bnx2fc_rport *tgt,
io_req->port = port; io_req->port = port;
io_req->tgt = tgt; io_req->tgt = tgt;
io_req->data_xfer_len = scsi_bufflen(sc_cmd); io_req->data_xfer_len = scsi_bufflen(sc_cmd);
sc_cmd->SCp.ptr = (char *)io_req; bnx2fc_priv(sc_cmd)->io_req = io_req;
stats = per_cpu_ptr(lport->stats, get_cpu()); stats = per_cpu_ptr(lport->stats, get_cpu());
if (sc_cmd->sc_data_direction == DMA_FROM_DEVICE) { if (sc_cmd->sc_data_direction == DMA_FROM_DEVICE) {

View File

@ -482,7 +482,7 @@ void bnx2fc_rport_event_handler(struct fc_lport *lport,
} }
/* /*
* Offlaod process is protected with hba mutex. * Offload process is protected with hba mutex.
* Use the same mutex_lock for upload process too * Use the same mutex_lock for upload process too
*/ */
mutex_lock(&hba->hba_mutex); mutex_lock(&hba->hba_mutex);

View File

@ -2268,6 +2268,7 @@ static struct scsi_host_template bnx2i_host_template = {
.sg_tablesize = ISCSI_MAX_BDS_PER_CMD, .sg_tablesize = ISCSI_MAX_BDS_PER_CMD,
.shost_groups = bnx2i_dev_groups, .shost_groups = bnx2i_dev_groups,
.track_queue_depth = 1, .track_queue_depth = 1,
.cmd_size = sizeof(struct iscsi_cmd),
}; };
struct iscsi_transport bnx2i_iscsi_transport = { struct iscsi_transport bnx2i_iscsi_transport = {

View File

@ -166,7 +166,7 @@ csio_scsi_fcp_cmnd(struct csio_ioreq *req, void *addr)
struct scsi_cmnd *scmnd = csio_scsi_cmnd(req); struct scsi_cmnd *scmnd = csio_scsi_cmnd(req);
/* Check for Task Management */ /* Check for Task Management */
if (likely(scmnd->SCp.Message == 0)) { if (likely(csio_priv(scmnd)->fc_tm_flags == 0)) {
int_to_scsilun(scmnd->device->lun, &fcp_cmnd->fc_lun); int_to_scsilun(scmnd->device->lun, &fcp_cmnd->fc_lun);
fcp_cmnd->fc_tm_flags = 0; fcp_cmnd->fc_tm_flags = 0;
fcp_cmnd->fc_cmdref = 0; fcp_cmnd->fc_cmdref = 0;
@ -185,7 +185,7 @@ csio_scsi_fcp_cmnd(struct csio_ioreq *req, void *addr)
} else { } else {
memset(fcp_cmnd, 0, sizeof(*fcp_cmnd)); memset(fcp_cmnd, 0, sizeof(*fcp_cmnd));
int_to_scsilun(scmnd->device->lun, &fcp_cmnd->fc_lun); int_to_scsilun(scmnd->device->lun, &fcp_cmnd->fc_lun);
fcp_cmnd->fc_tm_flags = (uint8_t)scmnd->SCp.Message; fcp_cmnd->fc_tm_flags = csio_priv(scmnd)->fc_tm_flags;
} }
} }
@ -1855,7 +1855,7 @@ csio_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *cmnd)
/* Needed during abort */ /* Needed during abort */
cmnd->host_scribble = (unsigned char *)ioreq; cmnd->host_scribble = (unsigned char *)ioreq;
cmnd->SCp.Message = 0; csio_priv(cmnd)->fc_tm_flags = 0;
/* Kick off SCSI IO SM on the ioreq */ /* Kick off SCSI IO SM on the ioreq */
spin_lock_irqsave(&hw->lock, flags); spin_lock_irqsave(&hw->lock, flags);
@ -2026,7 +2026,7 @@ csio_tm_cbfn(struct csio_hw *hw, struct csio_ioreq *req)
req, req->wr_status); req, req->wr_status);
/* Cache FW return status */ /* Cache FW return status */
cmnd->SCp.Status = req->wr_status; csio_priv(cmnd)->wr_status = req->wr_status;
/* Special handling based on FCP response */ /* Special handling based on FCP response */
@ -2049,7 +2049,7 @@ csio_tm_cbfn(struct csio_hw *hw, struct csio_ioreq *req)
/* Modify return status if flags indicate success */ /* Modify return status if flags indicate success */
if (flags & FCP_RSP_LEN_VAL) if (flags & FCP_RSP_LEN_VAL)
if (rsp_info->rsp_code == FCP_TMF_CMPL) if (rsp_info->rsp_code == FCP_TMF_CMPL)
cmnd->SCp.Status = FW_SUCCESS; csio_priv(cmnd)->wr_status = FW_SUCCESS;
csio_dbg(hw, "TM FCP rsp code: %d\n", rsp_info->rsp_code); csio_dbg(hw, "TM FCP rsp code: %d\n", rsp_info->rsp_code);
} }
@ -2125,9 +2125,9 @@ csio_eh_lun_reset_handler(struct scsi_cmnd *cmnd)
csio_scsi_cmnd(ioreq) = cmnd; csio_scsi_cmnd(ioreq) = cmnd;
cmnd->host_scribble = (unsigned char *)ioreq; cmnd->host_scribble = (unsigned char *)ioreq;
cmnd->SCp.Status = 0; csio_priv(cmnd)->wr_status = 0;
cmnd->SCp.Message = FCP_TMF_LUN_RESET; csio_priv(cmnd)->fc_tm_flags = FCP_TMF_LUN_RESET;
ioreq->tmo = CSIO_SCSI_LUNRST_TMO_MS / 1000; ioreq->tmo = CSIO_SCSI_LUNRST_TMO_MS / 1000;
/* /*
@ -2178,9 +2178,10 @@ csio_eh_lun_reset_handler(struct scsi_cmnd *cmnd)
} }
/* LUN reset returned, check cached status */ /* LUN reset returned, check cached status */
if (cmnd->SCp.Status != FW_SUCCESS) { if (csio_priv(cmnd)->wr_status != FW_SUCCESS) {
csio_err(hw, "LUN reset failed (%d:%llu), status: %d\n", csio_err(hw, "LUN reset failed (%d:%llu), status: %d\n",
cmnd->device->id, cmnd->device->lun, cmnd->SCp.Status); cmnd->device->id, cmnd->device->lun,
csio_priv(cmnd)->wr_status);
goto fail; goto fail;
} }
@ -2271,6 +2272,7 @@ struct scsi_host_template csio_fcoe_shost_template = {
.name = CSIO_DRV_DESC, .name = CSIO_DRV_DESC,
.proc_name = KBUILD_MODNAME, .proc_name = KBUILD_MODNAME,
.queuecommand = csio_queuecommand, .queuecommand = csio_queuecommand,
.cmd_size = sizeof(struct csio_cmd_priv),
.eh_timed_out = fc_eh_timed_out, .eh_timed_out = fc_eh_timed_out,
.eh_abort_handler = csio_eh_abort_handler, .eh_abort_handler = csio_eh_abort_handler,
.eh_device_reset_handler = csio_eh_lun_reset_handler, .eh_device_reset_handler = csio_eh_lun_reset_handler,

View File

@ -188,6 +188,16 @@ struct csio_scsi_level_data {
uint64_t oslun; uint64_t oslun;
}; };
struct csio_cmd_priv {
uint8_t fc_tm_flags; /* task management flags */
uint16_t wr_status;
};
static inline struct csio_cmd_priv *csio_priv(struct scsi_cmnd *cmd)
{
return scsi_cmd_priv(cmd);
}
static inline struct csio_ioreq * static inline struct csio_ioreq *
csio_get_scsi_ioreq(struct csio_scsim *scm) csio_get_scsi_ioreq(struct csio_scsim *scm)
{ {

View File

@ -98,6 +98,7 @@ static struct scsi_host_template cxgb3i_host_template = {
.dma_boundary = PAGE_SIZE - 1, .dma_boundary = PAGE_SIZE - 1,
.this_id = -1, .this_id = -1,
.track_queue_depth = 1, .track_queue_depth = 1,
.cmd_size = sizeof(struct iscsi_cmd),
}; };
static struct iscsi_transport cxgb3i_iscsi_transport = { static struct iscsi_transport cxgb3i_iscsi_transport = {

View File

@ -116,6 +116,7 @@ static struct scsi_host_template cxgb4i_host_template = {
.dma_boundary = PAGE_SIZE - 1, .dma_boundary = PAGE_SIZE - 1,
.this_id = -1, .this_id = -1,
.track_queue_depth = 1, .track_queue_depth = 1,
.cmd_size = sizeof(struct iscsi_cmd),
}; };
static struct iscsi_transport cxgb4i_iscsi_transport = { static struct iscsi_transport cxgb4i_iscsi_transport = {

View File

@ -430,8 +430,8 @@ static int write_same16(struct scsi_device *sdev,
struct device *dev = &cfg->dev->dev; struct device *dev = &cfg->dev->dev;
const u32 s = ilog2(sdev->sector_size) - 9; const u32 s = ilog2(sdev->sector_size) - 9;
const u32 to = sdev->request_queue->rq_timeout; const u32 to = sdev->request_queue->rq_timeout;
const u32 ws_limit = blk_queue_get_max_sectors(sdev->request_queue, const u32 ws_limit =
REQ_OP_WRITE_SAME) >> s; sdev->request_queue->limits.max_write_zeroes_sectors >> s;
cmd_buf = kzalloc(CMD_BUFSIZE, GFP_KERNEL); cmd_buf = kzalloc(CMD_BUFSIZE, GFP_KERNEL);
scsi_cmd = kzalloc(MAX_COMMAND_SIZE, GFP_KERNEL); scsi_cmd = kzalloc(MAX_COMMAND_SIZE, GFP_KERNEL);

View File

@ -3314,9 +3314,6 @@ static void srb_done(struct AdapterCtlBlk *acb, struct DeviceCtlBlk *dcb,
/* Here is the info for Doug Gilbert's sg3 ... */ /* Here is the info for Doug Gilbert's sg3 ... */
scsi_set_resid(cmd, srb->total_xfer_length); scsi_set_resid(cmd, srb->total_xfer_length);
/* This may be interpreted by sb. or not ... */
cmd->SCp.this_residual = srb->total_xfer_length;
cmd->SCp.buffers_residual = 0;
if (debug_enabled(DBG_KG)) { if (debug_enabled(DBG_KG)) {
if (srb->total_xfer_length) if (srb->total_xfer_length)
dprintkdbg(DBG_KG, "srb_done: (0x%p) <%02i-%i> " dprintkdbg(DBG_KG, "srb_done: (0x%p) <%02i-%i> "

View File

@ -52,7 +52,7 @@ static struct scsi_host_template dmx3191d_driver_template = {
.sg_tablesize = SG_ALL, .sg_tablesize = SG_ALL,
.cmd_per_lun = 2, .cmd_per_lun = 2,
.dma_boundary = PAGE_SIZE - 1, .dma_boundary = PAGE_SIZE - 1,
.cmd_size = NCR5380_CMD_SIZE, .cmd_size = sizeof(struct NCR5380_cmd),
}; };
static int dmx3191d_probe_one(struct pci_dev *pdev, static int dmx3191d_probe_one(struct pci_dev *pdev,

View File

@ -4127,7 +4127,7 @@ sli_calc_max_qentries(struct sli4 *sli4)
sli4->qinfo.count_mask[q]); sli4->qinfo.count_mask[q]);
} }
/* single, continguous DMA allocations will be called for each queue /* single, contiguous DMA allocations will be called for each queue
* of size (max_qentries * queue entry size); since these can be large, * of size (max_qentries * queue entry size); since these can be large,
* check against the OS max DMA allocation size * check against the OS max DMA allocation size
*/ */

View File

@ -2678,6 +2678,7 @@ struct scsi_host_template scsi_esp_template = {
.sg_tablesize = SG_ALL, .sg_tablesize = SG_ALL,
.max_sectors = 0xffff, .max_sectors = 0xffff,
.skip_settle_delay = 1, .skip_settle_delay = 1,
.cmd_size = sizeof(struct esp_cmd_priv),
}; };
EXPORT_SYMBOL(scsi_esp_template); EXPORT_SYMBOL(scsi_esp_template);
@ -2739,9 +2740,6 @@ static struct spi_function_template esp_transport_ops = {
static int __init esp_init(void) static int __init esp_init(void)
{ {
BUILD_BUG_ON(sizeof(struct scsi_pointer) <
sizeof(struct esp_cmd_priv));
esp_transport_template = spi_attach_transport(&esp_transport_ops); esp_transport_template = spi_attach_transport(&esp_transport_ops);
if (!esp_transport_template) if (!esp_transport_template)
return -ENODEV; return -ENODEV;

View File

@ -262,7 +262,8 @@ struct esp_cmd_priv {
struct scatterlist *cur_sg; struct scatterlist *cur_sg;
int tot_residue; int tot_residue;
}; };
#define ESP_CMD_PRIV(CMD) ((struct esp_cmd_priv *)(&(CMD)->SCp))
#define ESP_CMD_PRIV(cmd) ((struct esp_cmd_priv *)scsi_cmd_priv(cmd))
/* NOTE: this enum is ordered based on chip features! */ /* NOTE: this enum is ordered based on chip features! */
enum esp_rev { enum esp_rev {

View File

@ -277,6 +277,7 @@ static struct scsi_host_template fcoe_shost_template = {
.sg_tablesize = SG_ALL, .sg_tablesize = SG_ALL,
.max_sectors = 0xffff, .max_sectors = 0xffff,
.track_queue_depth = 1, .track_queue_depth = 1,
.cmd_size = sizeof(struct libfc_cmd_priv),
}; };
/** /**

View File

@ -115,6 +115,11 @@ struct fdomain {
struct work_struct work; struct work_struct work;
}; };
static struct scsi_pointer *fdomain_scsi_pointer(struct scsi_cmnd *cmd)
{
return scsi_cmd_priv(cmd);
}
static inline void fdomain_make_bus_idle(struct fdomain *fd) static inline void fdomain_make_bus_idle(struct fdomain *fd)
{ {
outb(0, fd->base + REG_BCTL); outb(0, fd->base + REG_BCTL);
@ -263,20 +268,21 @@ static void fdomain_work(struct work_struct *work)
struct Scsi_Host *sh = container_of((void *)fd, struct Scsi_Host, struct Scsi_Host *sh = container_of((void *)fd, struct Scsi_Host,
hostdata); hostdata);
struct scsi_cmnd *cmd = fd->cur_cmd; struct scsi_cmnd *cmd = fd->cur_cmd;
struct scsi_pointer *scsi_pointer = fdomain_scsi_pointer(cmd);
unsigned long flags; unsigned long flags;
int status; int status;
int done = 0; int done = 0;
spin_lock_irqsave(sh->host_lock, flags); spin_lock_irqsave(sh->host_lock, flags);
if (cmd->SCp.phase & in_arbitration) { if (scsi_pointer->phase & in_arbitration) {
status = inb(fd->base + REG_ASTAT); status = inb(fd->base + REG_ASTAT);
if (!(status & ASTAT_ARB)) { if (!(status & ASTAT_ARB)) {
set_host_byte(cmd, DID_BUS_BUSY); set_host_byte(cmd, DID_BUS_BUSY);
fdomain_finish_cmd(fd); fdomain_finish_cmd(fd);
goto out; goto out;
} }
cmd->SCp.phase = in_selection; scsi_pointer->phase = in_selection;
outb(ICTL_SEL | FIFO_COUNT, fd->base + REG_ICTL); outb(ICTL_SEL | FIFO_COUNT, fd->base + REG_ICTL);
outb(BCTL_BUSEN | BCTL_SEL, fd->base + REG_BCTL); outb(BCTL_BUSEN | BCTL_SEL, fd->base + REG_BCTL);
@ -285,7 +291,7 @@ static void fdomain_work(struct work_struct *work)
/* Stop arbitration and enable parity */ /* Stop arbitration and enable parity */
outb(ACTL_IRQEN | PARITY_MASK, fd->base + REG_ACTL); outb(ACTL_IRQEN | PARITY_MASK, fd->base + REG_ACTL);
goto out; goto out;
} else if (cmd->SCp.phase & in_selection) { } else if (scsi_pointer->phase & in_selection) {
status = inb(fd->base + REG_BSTAT); status = inb(fd->base + REG_BSTAT);
if (!(status & BSTAT_BSY)) { if (!(status & BSTAT_BSY)) {
/* Try again, for slow devices */ /* Try again, for slow devices */
@ -297,75 +303,75 @@ static void fdomain_work(struct work_struct *work)
/* Stop arbitration and enable parity */ /* Stop arbitration and enable parity */
outb(ACTL_IRQEN | PARITY_MASK, fd->base + REG_ACTL); outb(ACTL_IRQEN | PARITY_MASK, fd->base + REG_ACTL);
} }
cmd->SCp.phase = in_other; scsi_pointer->phase = in_other;
outb(ICTL_FIFO | ICTL_REQ | FIFO_COUNT, fd->base + REG_ICTL); outb(ICTL_FIFO | ICTL_REQ | FIFO_COUNT, fd->base + REG_ICTL);
outb(BCTL_BUSEN, fd->base + REG_BCTL); outb(BCTL_BUSEN, fd->base + REG_BCTL);
goto out; goto out;
} }
/* cur_cmd->SCp.phase == in_other: this is the body of the routine */ /* fdomain_scsi_pointer(cur_cmd)->phase == in_other: this is the body of the routine */
status = inb(fd->base + REG_BSTAT); status = inb(fd->base + REG_BSTAT);
if (status & BSTAT_REQ) { if (status & BSTAT_REQ) {
switch (status & (BSTAT_MSG | BSTAT_CMD | BSTAT_IO)) { switch (status & (BSTAT_MSG | BSTAT_CMD | BSTAT_IO)) {
case BSTAT_CMD: /* COMMAND OUT */ case BSTAT_CMD: /* COMMAND OUT */
outb(cmd->cmnd[cmd->SCp.sent_command++], outb(cmd->cmnd[scsi_pointer->sent_command++],
fd->base + REG_SCSI_DATA); fd->base + REG_SCSI_DATA);
break; break;
case 0: /* DATA OUT -- tmc18c50/tmc18c30 only */ case 0: /* DATA OUT -- tmc18c50/tmc18c30 only */
if (fd->chip != tmc1800 && !cmd->SCp.have_data_in) { if (fd->chip != tmc1800 && !scsi_pointer->have_data_in) {
cmd->SCp.have_data_in = -1; scsi_pointer->have_data_in = -1;
outb(ACTL_IRQEN | ACTL_FIFOWR | ACTL_FIFOEN | outb(ACTL_IRQEN | ACTL_FIFOWR | ACTL_FIFOEN |
PARITY_MASK, fd->base + REG_ACTL); PARITY_MASK, fd->base + REG_ACTL);
} }
break; break;
case BSTAT_IO: /* DATA IN -- tmc18c50/tmc18c30 only */ case BSTAT_IO: /* DATA IN -- tmc18c50/tmc18c30 only */
if (fd->chip != tmc1800 && !cmd->SCp.have_data_in) { if (fd->chip != tmc1800 && !scsi_pointer->have_data_in) {
cmd->SCp.have_data_in = 1; scsi_pointer->have_data_in = 1;
outb(ACTL_IRQEN | ACTL_FIFOEN | PARITY_MASK, outb(ACTL_IRQEN | ACTL_FIFOEN | PARITY_MASK,
fd->base + REG_ACTL); fd->base + REG_ACTL);
} }
break; break;
case BSTAT_CMD | BSTAT_IO: /* STATUS IN */ case BSTAT_CMD | BSTAT_IO: /* STATUS IN */
cmd->SCp.Status = inb(fd->base + REG_SCSI_DATA); scsi_pointer->Status = inb(fd->base + REG_SCSI_DATA);
break; break;
case BSTAT_MSG | BSTAT_CMD: /* MESSAGE OUT */ case BSTAT_MSG | BSTAT_CMD: /* MESSAGE OUT */
outb(MESSAGE_REJECT, fd->base + REG_SCSI_DATA); outb(MESSAGE_REJECT, fd->base + REG_SCSI_DATA);
break; break;
case BSTAT_MSG | BSTAT_CMD | BSTAT_IO: /* MESSAGE IN */ case BSTAT_MSG | BSTAT_CMD | BSTAT_IO: /* MESSAGE IN */
cmd->SCp.Message = inb(fd->base + REG_SCSI_DATA); scsi_pointer->Message = inb(fd->base + REG_SCSI_DATA);
if (cmd->SCp.Message == COMMAND_COMPLETE) if (scsi_pointer->Message == COMMAND_COMPLETE)
++done; ++done;
break; break;
} }
} }
if (fd->chip == tmc1800 && !cmd->SCp.have_data_in && if (fd->chip == tmc1800 && !scsi_pointer->have_data_in &&
cmd->SCp.sent_command >= cmd->cmd_len) { scsi_pointer->sent_command >= cmd->cmd_len) {
if (cmd->sc_data_direction == DMA_TO_DEVICE) { if (cmd->sc_data_direction == DMA_TO_DEVICE) {
cmd->SCp.have_data_in = -1; scsi_pointer->have_data_in = -1;
outb(ACTL_IRQEN | ACTL_FIFOWR | ACTL_FIFOEN | outb(ACTL_IRQEN | ACTL_FIFOWR | ACTL_FIFOEN |
PARITY_MASK, fd->base + REG_ACTL); PARITY_MASK, fd->base + REG_ACTL);
} else { } else {
cmd->SCp.have_data_in = 1; scsi_pointer->have_data_in = 1;
outb(ACTL_IRQEN | ACTL_FIFOEN | PARITY_MASK, outb(ACTL_IRQEN | ACTL_FIFOEN | PARITY_MASK,
fd->base + REG_ACTL); fd->base + REG_ACTL);
} }
} }
if (cmd->SCp.have_data_in == -1) /* DATA OUT */ if (scsi_pointer->have_data_in == -1) /* DATA OUT */
fdomain_write_data(cmd); fdomain_write_data(cmd);
if (cmd->SCp.have_data_in == 1) /* DATA IN */ if (scsi_pointer->have_data_in == 1) /* DATA IN */
fdomain_read_data(cmd); fdomain_read_data(cmd);
if (done) { if (done) {
set_status_byte(cmd, cmd->SCp.Status); set_status_byte(cmd, scsi_pointer->Status);
set_host_byte(cmd, DID_OK); set_host_byte(cmd, DID_OK);
scsi_msg_to_host_byte(cmd, cmd->SCp.Message); scsi_msg_to_host_byte(cmd, scsi_pointer->Message);
fdomain_finish_cmd(fd); fdomain_finish_cmd(fd);
} else { } else {
if (cmd->SCp.phase & disconnect) { if (scsi_pointer->phase & disconnect) {
outb(ICTL_FIFO | ICTL_SEL | ICTL_REQ | FIFO_COUNT, outb(ICTL_FIFO | ICTL_SEL | ICTL_REQ | FIFO_COUNT,
fd->base + REG_ICTL); fd->base + REG_ICTL);
outb(0, fd->base + REG_BCTL); outb(0, fd->base + REG_BCTL);
@ -398,14 +404,15 @@ static irqreturn_t fdomain_irq(int irq, void *dev_id)
static int fdomain_queue(struct Scsi_Host *sh, struct scsi_cmnd *cmd) static int fdomain_queue(struct Scsi_Host *sh, struct scsi_cmnd *cmd)
{ {
struct scsi_pointer *scsi_pointer = fdomain_scsi_pointer(cmd);
struct fdomain *fd = shost_priv(cmd->device->host); struct fdomain *fd = shost_priv(cmd->device->host);
unsigned long flags; unsigned long flags;
cmd->SCp.Status = 0; scsi_pointer->Status = 0;
cmd->SCp.Message = 0; scsi_pointer->Message = 0;
cmd->SCp.have_data_in = 0; scsi_pointer->have_data_in = 0;
cmd->SCp.sent_command = 0; scsi_pointer->sent_command = 0;
cmd->SCp.phase = in_arbitration; scsi_pointer->phase = in_arbitration;
scsi_set_resid(cmd, scsi_bufflen(cmd)); scsi_set_resid(cmd, scsi_bufflen(cmd));
spin_lock_irqsave(sh->host_lock, flags); spin_lock_irqsave(sh->host_lock, flags);
@ -440,7 +447,7 @@ static int fdomain_abort(struct scsi_cmnd *cmd)
spin_lock_irqsave(sh->host_lock, flags); spin_lock_irqsave(sh->host_lock, flags);
fdomain_make_bus_idle(fd); fdomain_make_bus_idle(fd);
fd->cur_cmd->SCp.phase |= aborted; fdomain_scsi_pointer(fd->cur_cmd)->phase |= aborted;
/* Aborts are not done well. . . */ /* Aborts are not done well. . . */
set_host_byte(fd->cur_cmd, DID_ABORT); set_host_byte(fd->cur_cmd, DID_ABORT);
@ -501,6 +508,7 @@ static struct scsi_host_template fdomain_template = {
.this_id = 7, .this_id = 7,
.sg_tablesize = 64, .sg_tablesize = 64,
.dma_boundary = PAGE_SIZE - 1, .dma_boundary = PAGE_SIZE - 1,
.cmd_size = sizeof(struct scsi_pointer),
}; };
struct Scsi_Host *fdomain_create(int base, int irq, int this_id, struct Scsi_Host *fdomain_create(int base, int irq, int this_id,

View File

@ -89,15 +89,28 @@
#define FNIC_DEV_RST_ABTS_PENDING BIT(21) #define FNIC_DEV_RST_ABTS_PENDING BIT(21)
/* /*
* Usage of the scsi_cmnd scratchpad. * fnic private data per SCSI command.
* These fields are locked by the hashed io_req_lock. * These fields are locked by the hashed io_req_lock.
*/ */
#define CMD_SP(Cmnd) ((Cmnd)->SCp.ptr) struct fnic_cmd_priv {
#define CMD_STATE(Cmnd) ((Cmnd)->SCp.phase) struct fnic_io_req *io_req;
#define CMD_ABTS_STATUS(Cmnd) ((Cmnd)->SCp.Message) enum fnic_ioreq_state state;
#define CMD_LR_STATUS(Cmnd) ((Cmnd)->SCp.have_data_in) u32 flags;
#define CMD_TAG(Cmnd) ((Cmnd)->SCp.sent_command) u16 abts_status;
#define CMD_FLAGS(Cmnd) ((Cmnd)->SCp.Status) u16 lr_status;
};
static inline struct fnic_cmd_priv *fnic_priv(struct scsi_cmnd *cmd)
{
return scsi_cmd_priv(cmd);
}
static inline u64 fnic_flags_and_state(struct scsi_cmnd *cmd)
{
struct fnic_cmd_priv *fcmd = fnic_priv(cmd);
return ((u64)fcmd->flags << 32) | fcmd->state;
}
#define FCPIO_INVALID_CODE 0x100 /* hdr_status value unused by firmware */ #define FCPIO_INVALID_CODE 0x100 /* hdr_status value unused by firmware */

View File

@ -124,6 +124,7 @@ static struct scsi_host_template fnic_host_template = {
.max_sectors = 0xffff, .max_sectors = 0xffff,
.shost_groups = fnic_host_groups, .shost_groups = fnic_host_groups,
.track_queue_depth = 1, .track_queue_depth = 1,
.cmd_size = sizeof(struct fnic_cmd_priv),
}; };
static void static void

View File

@ -497,8 +497,8 @@ static int fnic_queuecommand_lck(struct scsi_cmnd *sc)
* caller disabling them. * caller disabling them.
*/ */
spin_unlock(lp->host->host_lock); spin_unlock(lp->host->host_lock);
CMD_STATE(sc) = FNIC_IOREQ_NOT_INITED; fnic_priv(sc)->state = FNIC_IOREQ_NOT_INITED;
CMD_FLAGS(sc) = FNIC_NO_FLAGS; fnic_priv(sc)->flags = FNIC_NO_FLAGS;
/* Get a new io_req for this SCSI IO */ /* Get a new io_req for this SCSI IO */
io_req = mempool_alloc(fnic->io_req_pool, GFP_ATOMIC); io_req = mempool_alloc(fnic->io_req_pool, GFP_ATOMIC);
@ -513,7 +513,7 @@ static int fnic_queuecommand_lck(struct scsi_cmnd *sc)
sg_count = scsi_dma_map(sc); sg_count = scsi_dma_map(sc);
if (sg_count < 0) { if (sg_count < 0) {
FNIC_TRACE(fnic_queuecommand, sc->device->host->host_no, FNIC_TRACE(fnic_queuecommand, sc->device->host->host_no,
tag, sc, 0, sc->cmnd[0], sg_count, CMD_STATE(sc)); tag, sc, 0, sc->cmnd[0], sg_count, fnic_priv(sc)->state);
mempool_free(io_req, fnic->io_req_pool); mempool_free(io_req, fnic->io_req_pool);
goto out; goto out;
} }
@ -558,9 +558,9 @@ static int fnic_queuecommand_lck(struct scsi_cmnd *sc)
io_lock_acquired = 1; io_lock_acquired = 1;
io_req->port_id = rport->port_id; io_req->port_id = rport->port_id;
io_req->start_time = jiffies; io_req->start_time = jiffies;
CMD_STATE(sc) = FNIC_IOREQ_CMD_PENDING; fnic_priv(sc)->state = FNIC_IOREQ_CMD_PENDING;
CMD_SP(sc) = (char *)io_req; fnic_priv(sc)->io_req = io_req;
CMD_FLAGS(sc) |= FNIC_IO_INITIALIZED; fnic_priv(sc)->flags |= FNIC_IO_INITIALIZED;
/* create copy wq desc and enqueue it */ /* create copy wq desc and enqueue it */
wq = &fnic->wq_copy[0]; wq = &fnic->wq_copy[0];
@ -571,11 +571,10 @@ static int fnic_queuecommand_lck(struct scsi_cmnd *sc)
* refetch the pointer under the lock. * refetch the pointer under the lock.
*/ */
FNIC_TRACE(fnic_queuecommand, sc->device->host->host_no, FNIC_TRACE(fnic_queuecommand, sc->device->host->host_no,
tag, sc, 0, 0, 0, tag, sc, 0, 0, 0, fnic_flags_and_state(sc));
(((u64)CMD_FLAGS(sc) << 32) | CMD_STATE(sc))); io_req = fnic_priv(sc)->io_req;
io_req = (struct fnic_io_req *)CMD_SP(sc); fnic_priv(sc)->io_req = NULL;
CMD_SP(sc) = NULL; fnic_priv(sc)->state = FNIC_IOREQ_CMD_COMPLETE;
CMD_STATE(sc) = FNIC_IOREQ_CMD_COMPLETE;
spin_unlock_irqrestore(io_lock, flags); spin_unlock_irqrestore(io_lock, flags);
if (io_req) { if (io_req) {
fnic_release_ioreq_buf(fnic, io_req, sc); fnic_release_ioreq_buf(fnic, io_req, sc);
@ -594,7 +593,7 @@ static int fnic_queuecommand_lck(struct scsi_cmnd *sc)
atomic64_read(&fnic_stats->io_stats.active_ios)); atomic64_read(&fnic_stats->io_stats.active_ios));
/* REVISIT: Use per IO lock in the final code */ /* REVISIT: Use per IO lock in the final code */
CMD_FLAGS(sc) |= FNIC_IO_ISSUED; fnic_priv(sc)->flags |= FNIC_IO_ISSUED;
} }
out: out:
cmd_trace = ((u64)sc->cmnd[0] << 56 | (u64)sc->cmnd[7] << 40 | cmd_trace = ((u64)sc->cmnd[0] << 56 | (u64)sc->cmnd[7] << 40 |
@ -603,8 +602,8 @@ out:
sc->cmnd[5]); sc->cmnd[5]);
FNIC_TRACE(fnic_queuecommand, sc->device->host->host_no, FNIC_TRACE(fnic_queuecommand, sc->device->host->host_no,
tag, sc, io_req, sg_count, cmd_trace, tag, sc, io_req, sg_count, cmd_trace,
(((u64)CMD_FLAGS(sc) >> 32) | CMD_STATE(sc))); fnic_flags_and_state(sc));
/* if only we issued IO, will we have the io lock */ /* if only we issued IO, will we have the io lock */
if (io_lock_acquired) if (io_lock_acquired)
@ -867,11 +866,11 @@ static void fnic_fcpio_icmnd_cmpl_handler(struct fnic *fnic,
io_lock = fnic_io_lock_hash(fnic, sc); io_lock = fnic_io_lock_hash(fnic, sc);
spin_lock_irqsave(io_lock, flags); spin_lock_irqsave(io_lock, flags);
io_req = (struct fnic_io_req *)CMD_SP(sc); io_req = fnic_priv(sc)->io_req;
WARN_ON_ONCE(!io_req); WARN_ON_ONCE(!io_req);
if (!io_req) { if (!io_req) {
atomic64_inc(&fnic_stats->io_stats.ioreq_null); atomic64_inc(&fnic_stats->io_stats.ioreq_null);
CMD_FLAGS(sc) |= FNIC_IO_REQ_NULL; fnic_priv(sc)->flags |= FNIC_IO_REQ_NULL;
spin_unlock_irqrestore(io_lock, flags); spin_unlock_irqrestore(io_lock, flags);
shost_printk(KERN_ERR, fnic->lport->host, shost_printk(KERN_ERR, fnic->lport->host,
"icmnd_cmpl io_req is null - " "icmnd_cmpl io_req is null - "
@ -888,17 +887,17 @@ static void fnic_fcpio_icmnd_cmpl_handler(struct fnic *fnic,
* if SCSI-ML has already issued abort on this command, * if SCSI-ML has already issued abort on this command,
* set completion of the IO. The abts path will clean it up * set completion of the IO. The abts path will clean it up
*/ */
if (CMD_STATE(sc) == FNIC_IOREQ_ABTS_PENDING) { if (fnic_priv(sc)->state == FNIC_IOREQ_ABTS_PENDING) {
/* /*
* set the FNIC_IO_DONE so that this doesn't get * set the FNIC_IO_DONE so that this doesn't get
* flagged as 'out of order' if it was not aborted * flagged as 'out of order' if it was not aborted
*/ */
CMD_FLAGS(sc) |= FNIC_IO_DONE; fnic_priv(sc)->flags |= FNIC_IO_DONE;
CMD_FLAGS(sc) |= FNIC_IO_ABTS_PENDING; fnic_priv(sc)->flags |= FNIC_IO_ABTS_PENDING;
spin_unlock_irqrestore(io_lock, flags); spin_unlock_irqrestore(io_lock, flags);
if(FCPIO_ABORTED == hdr_status) if(FCPIO_ABORTED == hdr_status)
CMD_FLAGS(sc) |= FNIC_IO_ABORTED; fnic_priv(sc)->flags |= FNIC_IO_ABORTED;
FNIC_SCSI_DBG(KERN_INFO, fnic->lport->host, FNIC_SCSI_DBG(KERN_INFO, fnic->lport->host,
"icmnd_cmpl abts pending " "icmnd_cmpl abts pending "
@ -912,7 +911,7 @@ static void fnic_fcpio_icmnd_cmpl_handler(struct fnic *fnic,
} }
/* Mark the IO as complete */ /* Mark the IO as complete */
CMD_STATE(sc) = FNIC_IOREQ_CMD_COMPLETE; fnic_priv(sc)->state = FNIC_IOREQ_CMD_COMPLETE;
icmnd_cmpl = &desc->u.icmnd_cmpl; icmnd_cmpl = &desc->u.icmnd_cmpl;
@ -983,8 +982,8 @@ static void fnic_fcpio_icmnd_cmpl_handler(struct fnic *fnic,
} }
/* Break link with the SCSI command */ /* Break link with the SCSI command */
CMD_SP(sc) = NULL; fnic_priv(sc)->io_req = NULL;
CMD_FLAGS(sc) |= FNIC_IO_DONE; fnic_priv(sc)->flags |= FNIC_IO_DONE;
if (hdr_status != FCPIO_SUCCESS) { if (hdr_status != FCPIO_SUCCESS) {
atomic64_inc(&fnic_stats->io_stats.io_failures); atomic64_inc(&fnic_stats->io_stats.io_failures);
@ -1005,8 +1004,7 @@ static void fnic_fcpio_icmnd_cmpl_handler(struct fnic *fnic,
((u64)icmnd_cmpl->_resvd0[1] << 56 | ((u64)icmnd_cmpl->_resvd0[1] << 56 |
(u64)icmnd_cmpl->_resvd0[0] << 48 | (u64)icmnd_cmpl->_resvd0[0] << 48 |
jiffies_to_msecs(jiffies - start_time)), jiffies_to_msecs(jiffies - start_time)),
desc, cmd_trace, desc, cmd_trace, fnic_flags_and_state(sc));
(((u64)CMD_FLAGS(sc) << 32) | CMD_STATE(sc)));
if (sc->sc_data_direction == DMA_FROM_DEVICE) { if (sc->sc_data_direction == DMA_FROM_DEVICE) {
fnic->lport->host_stats.fcp_input_requests++; fnic->lport->host_stats.fcp_input_requests++;
@ -1094,12 +1092,12 @@ static void fnic_fcpio_itmf_cmpl_handler(struct fnic *fnic,
} }
io_lock = fnic_io_lock_hash(fnic, sc); io_lock = fnic_io_lock_hash(fnic, sc);
spin_lock_irqsave(io_lock, flags); spin_lock_irqsave(io_lock, flags);
io_req = (struct fnic_io_req *)CMD_SP(sc); io_req = fnic_priv(sc)->io_req;
WARN_ON_ONCE(!io_req); WARN_ON_ONCE(!io_req);
if (!io_req) { if (!io_req) {
atomic64_inc(&fnic_stats->io_stats.ioreq_null); atomic64_inc(&fnic_stats->io_stats.ioreq_null);
spin_unlock_irqrestore(io_lock, flags); spin_unlock_irqrestore(io_lock, flags);
CMD_FLAGS(sc) |= FNIC_IO_ABT_TERM_REQ_NULL; fnic_priv(sc)->flags |= FNIC_IO_ABT_TERM_REQ_NULL;
shost_printk(KERN_ERR, fnic->lport->host, shost_printk(KERN_ERR, fnic->lport->host,
"itmf_cmpl io_req is null - " "itmf_cmpl io_req is null - "
"hdr status = %s tag = 0x%x sc 0x%p\n", "hdr status = %s tag = 0x%x sc 0x%p\n",
@ -1114,9 +1112,9 @@ static void fnic_fcpio_itmf_cmpl_handler(struct fnic *fnic,
FNIC_SCSI_DBG(KERN_DEBUG, fnic->lport->host, FNIC_SCSI_DBG(KERN_DEBUG, fnic->lport->host,
"dev reset abts cmpl recd. id %x status %s\n", "dev reset abts cmpl recd. id %x status %s\n",
id, fnic_fcpio_status_to_str(hdr_status)); id, fnic_fcpio_status_to_str(hdr_status));
CMD_STATE(sc) = FNIC_IOREQ_ABTS_COMPLETE; fnic_priv(sc)->state = FNIC_IOREQ_ABTS_COMPLETE;
CMD_ABTS_STATUS(sc) = hdr_status; fnic_priv(sc)->abts_status = hdr_status;
CMD_FLAGS(sc) |= FNIC_DEV_RST_DONE; fnic_priv(sc)->flags |= FNIC_DEV_RST_DONE;
if (io_req->abts_done) if (io_req->abts_done)
complete(io_req->abts_done); complete(io_req->abts_done);
spin_unlock_irqrestore(io_lock, flags); spin_unlock_irqrestore(io_lock, flags);
@ -1126,7 +1124,7 @@ static void fnic_fcpio_itmf_cmpl_handler(struct fnic *fnic,
case FCPIO_SUCCESS: case FCPIO_SUCCESS:
break; break;
case FCPIO_TIMEOUT: case FCPIO_TIMEOUT:
if (CMD_FLAGS(sc) & FNIC_IO_ABTS_ISSUED) if (fnic_priv(sc)->flags & FNIC_IO_ABTS_ISSUED)
atomic64_inc(&abts_stats->abort_fw_timeouts); atomic64_inc(&abts_stats->abort_fw_timeouts);
else else
atomic64_inc( atomic64_inc(
@ -1138,34 +1136,34 @@ static void fnic_fcpio_itmf_cmpl_handler(struct fnic *fnic,
(int)(id & FNIC_TAG_MASK)); (int)(id & FNIC_TAG_MASK));
break; break;
case FCPIO_IO_NOT_FOUND: case FCPIO_IO_NOT_FOUND:
if (CMD_FLAGS(sc) & FNIC_IO_ABTS_ISSUED) if (fnic_priv(sc)->flags & FNIC_IO_ABTS_ISSUED)
atomic64_inc(&abts_stats->abort_io_not_found); atomic64_inc(&abts_stats->abort_io_not_found);
else else
atomic64_inc( atomic64_inc(
&term_stats->terminate_io_not_found); &term_stats->terminate_io_not_found);
break; break;
default: default:
if (CMD_FLAGS(sc) & FNIC_IO_ABTS_ISSUED) if (fnic_priv(sc)->flags & FNIC_IO_ABTS_ISSUED)
atomic64_inc(&abts_stats->abort_failures); atomic64_inc(&abts_stats->abort_failures);
else else
atomic64_inc( atomic64_inc(
&term_stats->terminate_failures); &term_stats->terminate_failures);
break; break;
} }
if (CMD_STATE(sc) != FNIC_IOREQ_ABTS_PENDING) { if (fnic_priv(sc)->state != FNIC_IOREQ_ABTS_PENDING) {
/* This is a late completion. Ignore it */ /* This is a late completion. Ignore it */
spin_unlock_irqrestore(io_lock, flags); spin_unlock_irqrestore(io_lock, flags);
return; return;
} }
CMD_FLAGS(sc) |= FNIC_IO_ABT_TERM_DONE; fnic_priv(sc)->flags |= FNIC_IO_ABT_TERM_DONE;
CMD_ABTS_STATUS(sc) = hdr_status; fnic_priv(sc)->abts_status = hdr_status;
/* If the status is IO not found consider it as success */ /* If the status is IO not found consider it as success */
if (hdr_status == FCPIO_IO_NOT_FOUND) if (hdr_status == FCPIO_IO_NOT_FOUND)
CMD_ABTS_STATUS(sc) = FCPIO_SUCCESS; fnic_priv(sc)->abts_status = FCPIO_SUCCESS;
if (!(CMD_FLAGS(sc) & (FNIC_IO_ABORTED | FNIC_IO_DONE))) if (!(fnic_priv(sc)->flags & (FNIC_IO_ABORTED | FNIC_IO_DONE)))
atomic64_inc(&misc_stats->no_icmnd_itmf_cmpls); atomic64_inc(&misc_stats->no_icmnd_itmf_cmpls);
FNIC_SCSI_DBG(KERN_DEBUG, fnic->lport->host, FNIC_SCSI_DBG(KERN_DEBUG, fnic->lport->host,
@ -1184,7 +1182,7 @@ static void fnic_fcpio_itmf_cmpl_handler(struct fnic *fnic,
} else { } else {
FNIC_SCSI_DBG(KERN_DEBUG, fnic->lport->host, FNIC_SCSI_DBG(KERN_DEBUG, fnic->lport->host,
"abts cmpl, completing IO\n"); "abts cmpl, completing IO\n");
CMD_SP(sc) = NULL; fnic_priv(sc)->io_req = NULL;
sc->result = (DID_ERROR << 16); sc->result = (DID_ERROR << 16);
spin_unlock_irqrestore(io_lock, flags); spin_unlock_irqrestore(io_lock, flags);
@ -1201,8 +1199,7 @@ static void fnic_fcpio_itmf_cmpl_handler(struct fnic *fnic,
(u64)sc->cmnd[2] << 24 | (u64)sc->cmnd[2] << 24 |
(u64)sc->cmnd[3] << 16 | (u64)sc->cmnd[3] << 16 |
(u64)sc->cmnd[4] << 8 | sc->cmnd[5]), (u64)sc->cmnd[4] << 8 | sc->cmnd[5]),
(((u64)CMD_FLAGS(sc) << 32) | fnic_flags_and_state(sc));
CMD_STATE(sc)));
scsi_done(sc); scsi_done(sc);
atomic64_dec(&fnic_stats->io_stats.active_ios); atomic64_dec(&fnic_stats->io_stats.active_ios);
if (atomic64_read(&fnic->io_cmpl_skip)) if (atomic64_read(&fnic->io_cmpl_skip))
@ -1212,15 +1209,14 @@ static void fnic_fcpio_itmf_cmpl_handler(struct fnic *fnic,
} }
} else if (id & FNIC_TAG_DEV_RST) { } else if (id & FNIC_TAG_DEV_RST) {
/* Completion of device reset */ /* Completion of device reset */
CMD_LR_STATUS(sc) = hdr_status; fnic_priv(sc)->lr_status = hdr_status;
if (CMD_STATE(sc) == FNIC_IOREQ_ABTS_PENDING) { if (fnic_priv(sc)->state == FNIC_IOREQ_ABTS_PENDING) {
spin_unlock_irqrestore(io_lock, flags); spin_unlock_irqrestore(io_lock, flags);
CMD_FLAGS(sc) |= FNIC_DEV_RST_ABTS_PENDING; fnic_priv(sc)->flags |= FNIC_DEV_RST_ABTS_PENDING;
FNIC_TRACE(fnic_fcpio_itmf_cmpl_handler, FNIC_TRACE(fnic_fcpio_itmf_cmpl_handler,
sc->device->host->host_no, id, sc, sc->device->host->host_no, id, sc,
jiffies_to_msecs(jiffies - start_time), jiffies_to_msecs(jiffies - start_time),
desc, 0, desc, 0, fnic_flags_and_state(sc));
(((u64)CMD_FLAGS(sc) << 32) | CMD_STATE(sc)));
FNIC_SCSI_DBG(KERN_DEBUG, fnic->lport->host, FNIC_SCSI_DBG(KERN_DEBUG, fnic->lport->host,
"Terminate pending " "Terminate pending "
"dev reset cmpl recd. id %d status %s\n", "dev reset cmpl recd. id %d status %s\n",
@ -1228,14 +1224,13 @@ static void fnic_fcpio_itmf_cmpl_handler(struct fnic *fnic,
fnic_fcpio_status_to_str(hdr_status)); fnic_fcpio_status_to_str(hdr_status));
return; return;
} }
if (CMD_FLAGS(sc) & FNIC_DEV_RST_TIMED_OUT) { if (fnic_priv(sc)->flags & FNIC_DEV_RST_TIMED_OUT) {
/* Need to wait for terminate completion */ /* Need to wait for terminate completion */
spin_unlock_irqrestore(io_lock, flags); spin_unlock_irqrestore(io_lock, flags);
FNIC_TRACE(fnic_fcpio_itmf_cmpl_handler, FNIC_TRACE(fnic_fcpio_itmf_cmpl_handler,
sc->device->host->host_no, id, sc, sc->device->host->host_no, id, sc,
jiffies_to_msecs(jiffies - start_time), jiffies_to_msecs(jiffies - start_time),
desc, 0, desc, 0, fnic_flags_and_state(sc));
(((u64)CMD_FLAGS(sc) << 32) | CMD_STATE(sc)));
FNIC_SCSI_DBG(KERN_DEBUG, fnic->lport->host, FNIC_SCSI_DBG(KERN_DEBUG, fnic->lport->host,
"dev reset cmpl recd after time out. " "dev reset cmpl recd after time out. "
"id %d status %s\n", "id %d status %s\n",
@ -1243,8 +1238,8 @@ static void fnic_fcpio_itmf_cmpl_handler(struct fnic *fnic,
fnic_fcpio_status_to_str(hdr_status)); fnic_fcpio_status_to_str(hdr_status));
return; return;
} }
CMD_STATE(sc) = FNIC_IOREQ_CMD_COMPLETE; fnic_priv(sc)->state = FNIC_IOREQ_CMD_COMPLETE;
CMD_FLAGS(sc) |= FNIC_DEV_RST_DONE; fnic_priv(sc)->flags |= FNIC_DEV_RST_DONE;
FNIC_SCSI_DBG(KERN_DEBUG, fnic->lport->host, FNIC_SCSI_DBG(KERN_DEBUG, fnic->lport->host,
"dev reset cmpl recd. id %d status %s\n", "dev reset cmpl recd. id %d status %s\n",
(int)(id & FNIC_TAG_MASK), (int)(id & FNIC_TAG_MASK),
@ -1256,7 +1251,7 @@ static void fnic_fcpio_itmf_cmpl_handler(struct fnic *fnic,
} else { } else {
shost_printk(KERN_ERR, fnic->lport->host, shost_printk(KERN_ERR, fnic->lport->host,
"Unexpected itmf io state %s tag %x\n", "Unexpected itmf io state %s tag %x\n",
fnic_ioreq_state_to_str(CMD_STATE(sc)), id); fnic_ioreq_state_to_str(fnic_priv(sc)->state), id);
spin_unlock_irqrestore(io_lock, flags); spin_unlock_irqrestore(io_lock, flags);
} }
@ -1369,21 +1364,21 @@ static bool fnic_cleanup_io_iter(struct scsi_cmnd *sc, void *data,
io_lock = fnic_io_lock_tag(fnic, tag); io_lock = fnic_io_lock_tag(fnic, tag);
spin_lock_irqsave(io_lock, flags); spin_lock_irqsave(io_lock, flags);
io_req = (struct fnic_io_req *)CMD_SP(sc); io_req = fnic_priv(sc)->io_req;
if ((CMD_FLAGS(sc) & FNIC_DEVICE_RESET) && if ((fnic_priv(sc)->flags & FNIC_DEVICE_RESET) &&
!(CMD_FLAGS(sc) & FNIC_DEV_RST_DONE)) { !(fnic_priv(sc)->flags & FNIC_DEV_RST_DONE)) {
/* /*
* We will be here only when FW completes reset * We will be here only when FW completes reset
* without sending completions for outstanding ios. * without sending completions for outstanding ios.
*/ */
CMD_FLAGS(sc) |= FNIC_DEV_RST_DONE; fnic_priv(sc)->flags |= FNIC_DEV_RST_DONE;
if (io_req && io_req->dr_done) if (io_req && io_req->dr_done)
complete(io_req->dr_done); complete(io_req->dr_done);
else if (io_req && io_req->abts_done) else if (io_req && io_req->abts_done)
complete(io_req->abts_done); complete(io_req->abts_done);
spin_unlock_irqrestore(io_lock, flags); spin_unlock_irqrestore(io_lock, flags);
return true; return true;
} else if (CMD_FLAGS(sc) & FNIC_DEVICE_RESET) { } else if (fnic_priv(sc)->flags & FNIC_DEVICE_RESET) {
spin_unlock_irqrestore(io_lock, flags); spin_unlock_irqrestore(io_lock, flags);
return true; return true;
} }
@ -1392,7 +1387,7 @@ static bool fnic_cleanup_io_iter(struct scsi_cmnd *sc, void *data,
goto cleanup_scsi_cmd; goto cleanup_scsi_cmd;
} }
CMD_SP(sc) = NULL; fnic_priv(sc)->io_req = NULL;
spin_unlock_irqrestore(io_lock, flags); spin_unlock_irqrestore(io_lock, flags);
@ -1416,7 +1411,7 @@ cleanup_scsi_cmd:
atomic64_inc(&fnic_stats->io_stats.io_completions); atomic64_inc(&fnic_stats->io_stats.io_completions);
/* Complete the command to SCSI */ /* Complete the command to SCSI */
if (!(CMD_FLAGS(sc) & FNIC_IO_ISSUED)) if (!(fnic_priv(sc)->flags & FNIC_IO_ISSUED))
shost_printk(KERN_ERR, fnic->lport->host, shost_printk(KERN_ERR, fnic->lport->host,
"Calling done for IO not issued to fw: tag:0x%x sc:0x%p\n", "Calling done for IO not issued to fw: tag:0x%x sc:0x%p\n",
tag, sc); tag, sc);
@ -1428,7 +1423,7 @@ cleanup_scsi_cmd:
(u64)sc->cmnd[2] << 24 | (u64)sc->cmnd[2] << 24 |
(u64)sc->cmnd[3] << 16 | (u64)sc->cmnd[3] << 16 |
(u64)sc->cmnd[4] << 8 | sc->cmnd[5]), (u64)sc->cmnd[4] << 8 | sc->cmnd[5]),
(((u64)CMD_FLAGS(sc) << 32) | CMD_STATE(sc))); fnic_flags_and_state(sc));
scsi_done(sc); scsi_done(sc);
@ -1467,7 +1462,7 @@ void fnic_wq_copy_cleanup_handler(struct vnic_wq_copy *wq,
spin_lock_irqsave(io_lock, flags); spin_lock_irqsave(io_lock, flags);
/* Get the IO context which this desc refers to */ /* Get the IO context which this desc refers to */
io_req = (struct fnic_io_req *)CMD_SP(sc); io_req = fnic_priv(sc)->io_req;
/* fnic interrupts are turned off by now */ /* fnic interrupts are turned off by now */
@ -1476,7 +1471,7 @@ void fnic_wq_copy_cleanup_handler(struct vnic_wq_copy *wq,
goto wq_copy_cleanup_scsi_cmd; goto wq_copy_cleanup_scsi_cmd;
} }
CMD_SP(sc) = NULL; fnic_priv(sc)->io_req = NULL;
spin_unlock_irqrestore(io_lock, flags); spin_unlock_irqrestore(io_lock, flags);
@ -1495,7 +1490,7 @@ wq_copy_cleanup_scsi_cmd:
0, ((u64)sc->cmnd[0] << 32 | 0, ((u64)sc->cmnd[0] << 32 |
(u64)sc->cmnd[2] << 24 | (u64)sc->cmnd[3] << 16 | (u64)sc->cmnd[2] << 24 | (u64)sc->cmnd[3] << 16 |
(u64)sc->cmnd[4] << 8 | sc->cmnd[5]), (u64)sc->cmnd[4] << 8 | sc->cmnd[5]),
(((u64)CMD_FLAGS(sc) << 32) | CMD_STATE(sc))); fnic_flags_and_state(sc));
scsi_done(sc); scsi_done(sc);
} }
@ -1570,15 +1565,15 @@ static bool fnic_rport_abort_io_iter(struct scsi_cmnd *sc, void *data,
io_lock = fnic_io_lock_tag(fnic, abt_tag); io_lock = fnic_io_lock_tag(fnic, abt_tag);
spin_lock_irqsave(io_lock, flags); spin_lock_irqsave(io_lock, flags);
io_req = (struct fnic_io_req *)CMD_SP(sc); io_req = fnic_priv(sc)->io_req;
if (!io_req || io_req->port_id != iter_data->port_id) { if (!io_req || io_req->port_id != iter_data->port_id) {
spin_unlock_irqrestore(io_lock, flags); spin_unlock_irqrestore(io_lock, flags);
return true; return true;
} }
if ((CMD_FLAGS(sc) & FNIC_DEVICE_RESET) && if ((fnic_priv(sc)->flags & FNIC_DEVICE_RESET) &&
(!(CMD_FLAGS(sc) & FNIC_DEV_RST_ISSUED))) { !(fnic_priv(sc)->flags & FNIC_DEV_RST_ISSUED)) {
FNIC_SCSI_DBG(KERN_DEBUG, fnic->lport->host, FNIC_SCSI_DBG(KERN_DEBUG, fnic->lport->host,
"fnic_rport_exch_reset dev rst not pending sc 0x%p\n", "fnic_rport_exch_reset dev rst not pending sc 0x%p\n",
sc); sc);
@ -1590,7 +1585,7 @@ static bool fnic_rport_abort_io_iter(struct scsi_cmnd *sc, void *data,
* Found IO that is still pending with firmware and * Found IO that is still pending with firmware and
* belongs to rport that went away * belongs to rport that went away
*/ */
if (CMD_STATE(sc) == FNIC_IOREQ_ABTS_PENDING) { if (fnic_priv(sc)->state == FNIC_IOREQ_ABTS_PENDING) {
spin_unlock_irqrestore(io_lock, flags); spin_unlock_irqrestore(io_lock, flags);
return true; return true;
} }
@ -1598,20 +1593,20 @@ static bool fnic_rport_abort_io_iter(struct scsi_cmnd *sc, void *data,
shost_printk(KERN_ERR, fnic->lport->host, shost_printk(KERN_ERR, fnic->lport->host,
"fnic_rport_exch_reset: io_req->abts_done is set " "fnic_rport_exch_reset: io_req->abts_done is set "
"state is %s\n", "state is %s\n",
fnic_ioreq_state_to_str(CMD_STATE(sc))); fnic_ioreq_state_to_str(fnic_priv(sc)->state));
} }
if (!(CMD_FLAGS(sc) & FNIC_IO_ISSUED)) { if (!(fnic_priv(sc)->flags & FNIC_IO_ISSUED)) {
shost_printk(KERN_ERR, fnic->lport->host, shost_printk(KERN_ERR, fnic->lport->host,
"rport_exch_reset " "rport_exch_reset "
"IO not yet issued %p tag 0x%x flags " "IO not yet issued %p tag 0x%x flags "
"%x state %d\n", "%x state %d\n",
sc, abt_tag, CMD_FLAGS(sc), CMD_STATE(sc)); sc, abt_tag, fnic_priv(sc)->flags, fnic_priv(sc)->state);
} }
old_ioreq_state = CMD_STATE(sc); old_ioreq_state = fnic_priv(sc)->state;
CMD_STATE(sc) = FNIC_IOREQ_ABTS_PENDING; fnic_priv(sc)->state = FNIC_IOREQ_ABTS_PENDING;
CMD_ABTS_STATUS(sc) = FCPIO_INVALID_CODE; fnic_priv(sc)->abts_status = FCPIO_INVALID_CODE;
if (CMD_FLAGS(sc) & FNIC_DEVICE_RESET) { if (fnic_priv(sc)->flags & FNIC_DEVICE_RESET) {
atomic64_inc(&reset_stats->device_reset_terminates); atomic64_inc(&reset_stats->device_reset_terminates);
abt_tag |= FNIC_TAG_DEV_RST; abt_tag |= FNIC_TAG_DEV_RST;
} }
@ -1637,15 +1632,15 @@ static bool fnic_rport_abort_io_iter(struct scsi_cmnd *sc, void *data,
* lun reset * lun reset
*/ */
spin_lock_irqsave(io_lock, flags); spin_lock_irqsave(io_lock, flags);
if (CMD_STATE(sc) == FNIC_IOREQ_ABTS_PENDING) if (fnic_priv(sc)->state == FNIC_IOREQ_ABTS_PENDING)
CMD_STATE(sc) = old_ioreq_state; fnic_priv(sc)->state = old_ioreq_state;
spin_unlock_irqrestore(io_lock, flags); spin_unlock_irqrestore(io_lock, flags);
} else { } else {
spin_lock_irqsave(io_lock, flags); spin_lock_irqsave(io_lock, flags);
if (CMD_FLAGS(sc) & FNIC_DEVICE_RESET) if (fnic_priv(sc)->flags & FNIC_DEVICE_RESET)
CMD_FLAGS(sc) |= FNIC_DEV_RST_TERM_ISSUED; fnic_priv(sc)->flags |= FNIC_DEV_RST_TERM_ISSUED;
else else
CMD_FLAGS(sc) |= FNIC_IO_INTERNAL_TERM_ISSUED; fnic_priv(sc)->flags |= FNIC_IO_INTERNAL_TERM_ISSUED;
spin_unlock_irqrestore(io_lock, flags); spin_unlock_irqrestore(io_lock, flags);
atomic64_inc(&term_stats->terminates); atomic64_inc(&term_stats->terminates);
iter_data->term_cnt++; iter_data->term_cnt++;
@ -1753,9 +1748,9 @@ int fnic_abort_cmd(struct scsi_cmnd *sc)
FNIC_SCSI_DBG(KERN_DEBUG, FNIC_SCSI_DBG(KERN_DEBUG,
fnic->lport->host, fnic->lport->host,
"Abort Cmd called FCID 0x%x, LUN 0x%llx TAG %x flags %x\n", "Abort Cmd called FCID 0x%x, LUN 0x%llx TAG %x flags %x\n",
rport->port_id, sc->device->lun, tag, CMD_FLAGS(sc)); rport->port_id, sc->device->lun, tag, fnic_priv(sc)->flags);
CMD_FLAGS(sc) = FNIC_NO_FLAGS; fnic_priv(sc)->flags = FNIC_NO_FLAGS;
if (lp->state != LPORT_ST_READY || !(lp->link_up)) { if (lp->state != LPORT_ST_READY || !(lp->link_up)) {
ret = FAILED; ret = FAILED;
@ -1772,11 +1767,11 @@ int fnic_abort_cmd(struct scsi_cmnd *sc)
* happened, the completion wont actually complete the command * happened, the completion wont actually complete the command
* and it will be considered as an aborted command * and it will be considered as an aborted command
* *
* The CMD_SP will not be cleared except while holding io_req_lock. * .io_req will not be cleared except while holding io_req_lock.
*/ */
io_lock = fnic_io_lock_hash(fnic, sc); io_lock = fnic_io_lock_hash(fnic, sc);
spin_lock_irqsave(io_lock, flags); spin_lock_irqsave(io_lock, flags);
io_req = (struct fnic_io_req *)CMD_SP(sc); io_req = fnic_priv(sc)->io_req;
if (!io_req) { if (!io_req) {
spin_unlock_irqrestore(io_lock, flags); spin_unlock_irqrestore(io_lock, flags);
goto fnic_abort_cmd_end; goto fnic_abort_cmd_end;
@ -1784,7 +1779,7 @@ int fnic_abort_cmd(struct scsi_cmnd *sc)
io_req->abts_done = &tm_done; io_req->abts_done = &tm_done;
if (CMD_STATE(sc) == FNIC_IOREQ_ABTS_PENDING) { if (fnic_priv(sc)->state == FNIC_IOREQ_ABTS_PENDING) {
spin_unlock_irqrestore(io_lock, flags); spin_unlock_irqrestore(io_lock, flags);
goto wait_pending; goto wait_pending;
} }
@ -1813,9 +1808,9 @@ int fnic_abort_cmd(struct scsi_cmnd *sc)
* the completion wont be done till mid-layer, since abort * the completion wont be done till mid-layer, since abort
* has already started. * has already started.
*/ */
old_ioreq_state = CMD_STATE(sc); old_ioreq_state = fnic_priv(sc)->state;
CMD_STATE(sc) = FNIC_IOREQ_ABTS_PENDING; fnic_priv(sc)->state = FNIC_IOREQ_ABTS_PENDING;
CMD_ABTS_STATUS(sc) = FCPIO_INVALID_CODE; fnic_priv(sc)->abts_status = FCPIO_INVALID_CODE;
spin_unlock_irqrestore(io_lock, flags); spin_unlock_irqrestore(io_lock, flags);
@ -1837,9 +1832,9 @@ int fnic_abort_cmd(struct scsi_cmnd *sc)
if (fnic_queue_abort_io_req(fnic, tag, task_req, fc_lun.scsi_lun, if (fnic_queue_abort_io_req(fnic, tag, task_req, fc_lun.scsi_lun,
io_req)) { io_req)) {
spin_lock_irqsave(io_lock, flags); spin_lock_irqsave(io_lock, flags);
if (CMD_STATE(sc) == FNIC_IOREQ_ABTS_PENDING) if (fnic_priv(sc)->state == FNIC_IOREQ_ABTS_PENDING)
CMD_STATE(sc) = old_ioreq_state; fnic_priv(sc)->state = old_ioreq_state;
io_req = (struct fnic_io_req *)CMD_SP(sc); io_req = fnic_priv(sc)->io_req;
if (io_req) if (io_req)
io_req->abts_done = NULL; io_req->abts_done = NULL;
spin_unlock_irqrestore(io_lock, flags); spin_unlock_irqrestore(io_lock, flags);
@ -1847,10 +1842,10 @@ int fnic_abort_cmd(struct scsi_cmnd *sc)
goto fnic_abort_cmd_end; goto fnic_abort_cmd_end;
} }
if (task_req == FCPIO_ITMF_ABT_TASK) { if (task_req == FCPIO_ITMF_ABT_TASK) {
CMD_FLAGS(sc) |= FNIC_IO_ABTS_ISSUED; fnic_priv(sc)->flags |= FNIC_IO_ABTS_ISSUED;
atomic64_inc(&fnic_stats->abts_stats.aborts); atomic64_inc(&fnic_stats->abts_stats.aborts);
} else { } else {
CMD_FLAGS(sc) |= FNIC_IO_TERM_ISSUED; fnic_priv(sc)->flags |= FNIC_IO_TERM_ISSUED;
atomic64_inc(&fnic_stats->term_stats.terminates); atomic64_inc(&fnic_stats->term_stats.terminates);
} }
@ -1868,32 +1863,32 @@ int fnic_abort_cmd(struct scsi_cmnd *sc)
/* Check the abort status */ /* Check the abort status */
spin_lock_irqsave(io_lock, flags); spin_lock_irqsave(io_lock, flags);
io_req = (struct fnic_io_req *)CMD_SP(sc); io_req = fnic_priv(sc)->io_req;
if (!io_req) { if (!io_req) {
atomic64_inc(&fnic_stats->io_stats.ioreq_null); atomic64_inc(&fnic_stats->io_stats.ioreq_null);
spin_unlock_irqrestore(io_lock, flags); spin_unlock_irqrestore(io_lock, flags);
CMD_FLAGS(sc) |= FNIC_IO_ABT_TERM_REQ_NULL; fnic_priv(sc)->flags |= FNIC_IO_ABT_TERM_REQ_NULL;
ret = FAILED; ret = FAILED;
goto fnic_abort_cmd_end; goto fnic_abort_cmd_end;
} }
io_req->abts_done = NULL; io_req->abts_done = NULL;
/* fw did not complete abort, timed out */ /* fw did not complete abort, timed out */
if (CMD_ABTS_STATUS(sc) == FCPIO_INVALID_CODE) { if (fnic_priv(sc)->abts_status == FCPIO_INVALID_CODE) {
spin_unlock_irqrestore(io_lock, flags); spin_unlock_irqrestore(io_lock, flags);
if (task_req == FCPIO_ITMF_ABT_TASK) { if (task_req == FCPIO_ITMF_ABT_TASK) {
atomic64_inc(&abts_stats->abort_drv_timeouts); atomic64_inc(&abts_stats->abort_drv_timeouts);
} else { } else {
atomic64_inc(&term_stats->terminate_drv_timeouts); atomic64_inc(&term_stats->terminate_drv_timeouts);
} }
CMD_FLAGS(sc) |= FNIC_IO_ABT_TERM_TIMED_OUT; fnic_priv(sc)->flags |= FNIC_IO_ABT_TERM_TIMED_OUT;
ret = FAILED; ret = FAILED;
goto fnic_abort_cmd_end; goto fnic_abort_cmd_end;
} }
/* IO out of order */ /* IO out of order */
if (!(CMD_FLAGS(sc) & (FNIC_IO_ABORTED | FNIC_IO_DONE))) { if (!(fnic_priv(sc)->flags & (FNIC_IO_ABORTED | FNIC_IO_DONE))) {
spin_unlock_irqrestore(io_lock, flags); spin_unlock_irqrestore(io_lock, flags);
FNIC_SCSI_DBG(KERN_DEBUG, fnic->lport->host, FNIC_SCSI_DBG(KERN_DEBUG, fnic->lport->host,
"Issuing Host reset due to out of order IO\n"); "Issuing Host reset due to out of order IO\n");
@ -1902,7 +1897,7 @@ int fnic_abort_cmd(struct scsi_cmnd *sc)
goto fnic_abort_cmd_end; goto fnic_abort_cmd_end;
} }
CMD_STATE(sc) = FNIC_IOREQ_ABTS_COMPLETE; fnic_priv(sc)->state = FNIC_IOREQ_ABTS_COMPLETE;
start_time = io_req->start_time; start_time = io_req->start_time;
/* /*
@ -1910,9 +1905,9 @@ int fnic_abort_cmd(struct scsi_cmnd *sc)
* free the io_req if successful. If abort fails, * free the io_req if successful. If abort fails,
* Device reset will clean the I/O. * Device reset will clean the I/O.
*/ */
if (CMD_ABTS_STATUS(sc) == FCPIO_SUCCESS) if (fnic_priv(sc)->abts_status == FCPIO_SUCCESS) {
CMD_SP(sc) = NULL; fnic_priv(sc)->io_req = NULL;
else { } else {
ret = FAILED; ret = FAILED;
spin_unlock_irqrestore(io_lock, flags); spin_unlock_irqrestore(io_lock, flags);
goto fnic_abort_cmd_end; goto fnic_abort_cmd_end;
@ -1938,7 +1933,7 @@ fnic_abort_cmd_end:
0, ((u64)sc->cmnd[0] << 32 | 0, ((u64)sc->cmnd[0] << 32 |
(u64)sc->cmnd[2] << 24 | (u64)sc->cmnd[3] << 16 | (u64)sc->cmnd[2] << 24 | (u64)sc->cmnd[3] << 16 |
(u64)sc->cmnd[4] << 8 | sc->cmnd[5]), (u64)sc->cmnd[4] << 8 | sc->cmnd[5]),
(((u64)CMD_FLAGS(sc) << 32) | CMD_STATE(sc))); fnic_flags_and_state(sc));
FNIC_SCSI_DBG(KERN_DEBUG, fnic->lport->host, FNIC_SCSI_DBG(KERN_DEBUG, fnic->lport->host,
"Returning from abort cmd type %x %s\n", task_req, "Returning from abort cmd type %x %s\n", task_req,
@ -2029,7 +2024,7 @@ static bool fnic_pending_aborts_iter(struct scsi_cmnd *sc,
io_lock = fnic_io_lock_tag(fnic, abt_tag); io_lock = fnic_io_lock_tag(fnic, abt_tag);
spin_lock_irqsave(io_lock, flags); spin_lock_irqsave(io_lock, flags);
io_req = (struct fnic_io_req *)CMD_SP(sc); io_req = fnic_priv(sc)->io_req;
if (!io_req) { if (!io_req) {
spin_unlock_irqrestore(io_lock, flags); spin_unlock_irqrestore(io_lock, flags);
return true; return true;
@ -2041,14 +2036,14 @@ static bool fnic_pending_aborts_iter(struct scsi_cmnd *sc,
*/ */
FNIC_SCSI_DBG(KERN_DEBUG, fnic->lport->host, FNIC_SCSI_DBG(KERN_DEBUG, fnic->lport->host,
"Found IO in %s on lun\n", "Found IO in %s on lun\n",
fnic_ioreq_state_to_str(CMD_STATE(sc))); fnic_ioreq_state_to_str(fnic_priv(sc)->state));
if (CMD_STATE(sc) == FNIC_IOREQ_ABTS_PENDING) { if (fnic_priv(sc)->state == FNIC_IOREQ_ABTS_PENDING) {
spin_unlock_irqrestore(io_lock, flags); spin_unlock_irqrestore(io_lock, flags);
return true; return true;
} }
if ((CMD_FLAGS(sc) & FNIC_DEVICE_RESET) && if ((fnic_priv(sc)->flags & FNIC_DEVICE_RESET) &&
(!(CMD_FLAGS(sc) & FNIC_DEV_RST_ISSUED))) { (!(fnic_priv(sc)->flags & FNIC_DEV_RST_ISSUED))) {
FNIC_SCSI_DBG(KERN_INFO, fnic->lport->host, FNIC_SCSI_DBG(KERN_INFO, fnic->lport->host,
"%s dev rst not pending sc 0x%p\n", __func__, "%s dev rst not pending sc 0x%p\n", __func__,
sc); sc);
@ -2059,8 +2054,8 @@ static bool fnic_pending_aborts_iter(struct scsi_cmnd *sc,
if (io_req->abts_done) if (io_req->abts_done)
shost_printk(KERN_ERR, fnic->lport->host, shost_printk(KERN_ERR, fnic->lport->host,
"%s: io_req->abts_done is set state is %s\n", "%s: io_req->abts_done is set state is %s\n",
__func__, fnic_ioreq_state_to_str(CMD_STATE(sc))); __func__, fnic_ioreq_state_to_str(fnic_priv(sc)->state));
old_ioreq_state = CMD_STATE(sc); old_ioreq_state = fnic_priv(sc)->state;
/* /*
* Any pending IO issued prior to reset is expected to be * Any pending IO issued prior to reset is expected to be
* in abts pending state, if not we need to set * in abts pending state, if not we need to set
@ -2068,17 +2063,17 @@ static bool fnic_pending_aborts_iter(struct scsi_cmnd *sc,
* When IO is completed, the IO will be handed over and * When IO is completed, the IO will be handed over and
* handled in this function. * handled in this function.
*/ */
CMD_STATE(sc) = FNIC_IOREQ_ABTS_PENDING; fnic_priv(sc)->state = FNIC_IOREQ_ABTS_PENDING;
BUG_ON(io_req->abts_done); BUG_ON(io_req->abts_done);
if (CMD_FLAGS(sc) & FNIC_DEVICE_RESET) { if (fnic_priv(sc)->flags & FNIC_DEVICE_RESET) {
abt_tag |= FNIC_TAG_DEV_RST; abt_tag |= FNIC_TAG_DEV_RST;
FNIC_SCSI_DBG(KERN_INFO, fnic->lport->host, FNIC_SCSI_DBG(KERN_INFO, fnic->lport->host,
"%s: dev rst sc 0x%p\n", __func__, sc); "%s: dev rst sc 0x%p\n", __func__, sc);
} }
CMD_ABTS_STATUS(sc) = FCPIO_INVALID_CODE; fnic_priv(sc)->abts_status = FCPIO_INVALID_CODE;
io_req->abts_done = &tm_done; io_req->abts_done = &tm_done;
spin_unlock_irqrestore(io_lock, flags); spin_unlock_irqrestore(io_lock, flags);
@ -2089,48 +2084,48 @@ static bool fnic_pending_aborts_iter(struct scsi_cmnd *sc,
FCPIO_ITMF_ABT_TASK_TERM, FCPIO_ITMF_ABT_TASK_TERM,
fc_lun.scsi_lun, io_req)) { fc_lun.scsi_lun, io_req)) {
spin_lock_irqsave(io_lock, flags); spin_lock_irqsave(io_lock, flags);
io_req = (struct fnic_io_req *)CMD_SP(sc); io_req = fnic_priv(sc)->io_req;
if (io_req) if (io_req)
io_req->abts_done = NULL; io_req->abts_done = NULL;
if (CMD_STATE(sc) == FNIC_IOREQ_ABTS_PENDING) if (fnic_priv(sc)->state == FNIC_IOREQ_ABTS_PENDING)
CMD_STATE(sc) = old_ioreq_state; fnic_priv(sc)->state = old_ioreq_state;
spin_unlock_irqrestore(io_lock, flags); spin_unlock_irqrestore(io_lock, flags);
iter_data->ret = FAILED; iter_data->ret = FAILED;
return false; return false;
} else { } else {
spin_lock_irqsave(io_lock, flags); spin_lock_irqsave(io_lock, flags);
if (CMD_FLAGS(sc) & FNIC_DEVICE_RESET) if (fnic_priv(sc)->flags & FNIC_DEVICE_RESET)
CMD_FLAGS(sc) |= FNIC_DEV_RST_TERM_ISSUED; fnic_priv(sc)->flags |= FNIC_DEV_RST_TERM_ISSUED;
spin_unlock_irqrestore(io_lock, flags); spin_unlock_irqrestore(io_lock, flags);
} }
CMD_FLAGS(sc) |= FNIC_IO_INTERNAL_TERM_ISSUED; fnic_priv(sc)->flags |= FNIC_IO_INTERNAL_TERM_ISSUED;
wait_for_completion_timeout(&tm_done, msecs_to_jiffies wait_for_completion_timeout(&tm_done, msecs_to_jiffies
(fnic->config.ed_tov)); (fnic->config.ed_tov));
/* Recheck cmd state to check if it is now aborted */ /* Recheck cmd state to check if it is now aborted */
spin_lock_irqsave(io_lock, flags); spin_lock_irqsave(io_lock, flags);
io_req = (struct fnic_io_req *)CMD_SP(sc); io_req = fnic_priv(sc)->io_req;
if (!io_req) { if (!io_req) {
spin_unlock_irqrestore(io_lock, flags); spin_unlock_irqrestore(io_lock, flags);
CMD_FLAGS(sc) |= FNIC_IO_ABT_TERM_REQ_NULL; fnic_priv(sc)->flags |= FNIC_IO_ABT_TERM_REQ_NULL;
return true; return true;
} }
io_req->abts_done = NULL; io_req->abts_done = NULL;
/* if abort is still pending with fw, fail */ /* if abort is still pending with fw, fail */
if (CMD_ABTS_STATUS(sc) == FCPIO_INVALID_CODE) { if (fnic_priv(sc)->abts_status == FCPIO_INVALID_CODE) {
spin_unlock_irqrestore(io_lock, flags); spin_unlock_irqrestore(io_lock, flags);
CMD_FLAGS(sc) |= FNIC_IO_ABT_TERM_DONE; fnic_priv(sc)->flags |= FNIC_IO_ABT_TERM_DONE;
iter_data->ret = FAILED; iter_data->ret = FAILED;
return false; return false;
} }
CMD_STATE(sc) = FNIC_IOREQ_ABTS_COMPLETE; fnic_priv(sc)->state = FNIC_IOREQ_ABTS_COMPLETE;
/* original sc used for lr is handled by dev reset code */ /* original sc used for lr is handled by dev reset code */
if (sc != iter_data->lr_sc) if (sc != iter_data->lr_sc)
CMD_SP(sc) = NULL; fnic_priv(sc)->io_req = NULL;
spin_unlock_irqrestore(io_lock, flags); spin_unlock_irqrestore(io_lock, flags);
/* original sc used for lr is handled by dev reset code */ /* original sc used for lr is handled by dev reset code */
@ -2271,7 +2266,7 @@ int fnic_device_reset(struct scsi_cmnd *sc)
goto fnic_device_reset_end; goto fnic_device_reset_end;
} }
CMD_FLAGS(sc) = FNIC_DEVICE_RESET; fnic_priv(sc)->flags = FNIC_DEVICE_RESET;
/* Allocate tag if not present */ /* Allocate tag if not present */
if (unlikely(tag < 0)) { if (unlikely(tag < 0)) {
@ -2287,7 +2282,7 @@ int fnic_device_reset(struct scsi_cmnd *sc)
} }
io_lock = fnic_io_lock_hash(fnic, sc); io_lock = fnic_io_lock_hash(fnic, sc);
spin_lock_irqsave(io_lock, flags); spin_lock_irqsave(io_lock, flags);
io_req = (struct fnic_io_req *)CMD_SP(sc); io_req = fnic_priv(sc)->io_req;
/* /*
* If there is a io_req attached to this command, then use it, * If there is a io_req attached to this command, then use it,
@ -2301,11 +2296,11 @@ int fnic_device_reset(struct scsi_cmnd *sc)
} }
memset(io_req, 0, sizeof(*io_req)); memset(io_req, 0, sizeof(*io_req));
io_req->port_id = rport->port_id; io_req->port_id = rport->port_id;
CMD_SP(sc) = (char *)io_req; fnic_priv(sc)->io_req = io_req;
} }
io_req->dr_done = &tm_done; io_req->dr_done = &tm_done;
CMD_STATE(sc) = FNIC_IOREQ_CMD_PENDING; fnic_priv(sc)->state = FNIC_IOREQ_CMD_PENDING;
CMD_LR_STATUS(sc) = FCPIO_INVALID_CODE; fnic_priv(sc)->lr_status = FCPIO_INVALID_CODE;
spin_unlock_irqrestore(io_lock, flags); spin_unlock_irqrestore(io_lock, flags);
FNIC_SCSI_DBG(KERN_DEBUG, fnic->lport->host, "TAG %x\n", tag); FNIC_SCSI_DBG(KERN_DEBUG, fnic->lport->host, "TAG %x\n", tag);
@ -2316,13 +2311,13 @@ int fnic_device_reset(struct scsi_cmnd *sc)
*/ */
if (fnic_queue_dr_io_req(fnic, sc, io_req)) { if (fnic_queue_dr_io_req(fnic, sc, io_req)) {
spin_lock_irqsave(io_lock, flags); spin_lock_irqsave(io_lock, flags);
io_req = (struct fnic_io_req *)CMD_SP(sc); io_req = fnic_priv(sc)->io_req;
if (io_req) if (io_req)
io_req->dr_done = NULL; io_req->dr_done = NULL;
goto fnic_device_reset_clean; goto fnic_device_reset_clean;
} }
spin_lock_irqsave(io_lock, flags); spin_lock_irqsave(io_lock, flags);
CMD_FLAGS(sc) |= FNIC_DEV_RST_ISSUED; fnic_priv(sc)->flags |= FNIC_DEV_RST_ISSUED;
spin_unlock_irqrestore(io_lock, flags); spin_unlock_irqrestore(io_lock, flags);
/* /*
@ -2333,7 +2328,7 @@ int fnic_device_reset(struct scsi_cmnd *sc)
msecs_to_jiffies(FNIC_LUN_RESET_TIMEOUT)); msecs_to_jiffies(FNIC_LUN_RESET_TIMEOUT));
spin_lock_irqsave(io_lock, flags); spin_lock_irqsave(io_lock, flags);
io_req = (struct fnic_io_req *)CMD_SP(sc); io_req = fnic_priv(sc)->io_req;
if (!io_req) { if (!io_req) {
spin_unlock_irqrestore(io_lock, flags); spin_unlock_irqrestore(io_lock, flags);
FNIC_SCSI_DBG(KERN_DEBUG, fnic->lport->host, FNIC_SCSI_DBG(KERN_DEBUG, fnic->lport->host,
@ -2342,7 +2337,7 @@ int fnic_device_reset(struct scsi_cmnd *sc)
} }
io_req->dr_done = NULL; io_req->dr_done = NULL;
status = CMD_LR_STATUS(sc); status = fnic_priv(sc)->lr_status;
/* /*
* If lun reset not completed, bail out with failed. io_req * If lun reset not completed, bail out with failed. io_req
@ -2352,7 +2347,7 @@ int fnic_device_reset(struct scsi_cmnd *sc)
atomic64_inc(&reset_stats->device_reset_timeouts); atomic64_inc(&reset_stats->device_reset_timeouts);
FNIC_SCSI_DBG(KERN_DEBUG, fnic->lport->host, FNIC_SCSI_DBG(KERN_DEBUG, fnic->lport->host,
"Device reset timed out\n"); "Device reset timed out\n");
CMD_FLAGS(sc) |= FNIC_DEV_RST_TIMED_OUT; fnic_priv(sc)->flags |= FNIC_DEV_RST_TIMED_OUT;
spin_unlock_irqrestore(io_lock, flags); spin_unlock_irqrestore(io_lock, flags);
int_to_scsilun(sc->device->lun, &fc_lun); int_to_scsilun(sc->device->lun, &fc_lun);
/* /*
@ -2361,7 +2356,7 @@ int fnic_device_reset(struct scsi_cmnd *sc)
*/ */
while (1) { while (1) {
spin_lock_irqsave(io_lock, flags); spin_lock_irqsave(io_lock, flags);
if (CMD_FLAGS(sc) & FNIC_DEV_RST_TERM_ISSUED) { if (fnic_priv(sc)->flags & FNIC_DEV_RST_TERM_ISSUED) {
spin_unlock_irqrestore(io_lock, flags); spin_unlock_irqrestore(io_lock, flags);
break; break;
} }
@ -2374,8 +2369,8 @@ int fnic_device_reset(struct scsi_cmnd *sc)
msecs_to_jiffies(FNIC_ABT_TERM_DELAY_TIMEOUT)); msecs_to_jiffies(FNIC_ABT_TERM_DELAY_TIMEOUT));
} else { } else {
spin_lock_irqsave(io_lock, flags); spin_lock_irqsave(io_lock, flags);
CMD_FLAGS(sc) |= FNIC_DEV_RST_TERM_ISSUED; fnic_priv(sc)->flags |= FNIC_DEV_RST_TERM_ISSUED;
CMD_STATE(sc) = FNIC_IOREQ_ABTS_PENDING; fnic_priv(sc)->state = FNIC_IOREQ_ABTS_PENDING;
io_req->abts_done = &tm_done; io_req->abts_done = &tm_done;
spin_unlock_irqrestore(io_lock, flags); spin_unlock_irqrestore(io_lock, flags);
FNIC_SCSI_DBG(KERN_DEBUG, fnic->lport->host, FNIC_SCSI_DBG(KERN_DEBUG, fnic->lport->host,
@ -2386,13 +2381,13 @@ int fnic_device_reset(struct scsi_cmnd *sc)
} }
while (1) { while (1) {
spin_lock_irqsave(io_lock, flags); spin_lock_irqsave(io_lock, flags);
if (!(CMD_FLAGS(sc) & FNIC_DEV_RST_DONE)) { if (!(fnic_priv(sc)->flags & FNIC_DEV_RST_DONE)) {
spin_unlock_irqrestore(io_lock, flags); spin_unlock_irqrestore(io_lock, flags);
wait_for_completion_timeout(&tm_done, wait_for_completion_timeout(&tm_done,
msecs_to_jiffies(FNIC_LUN_RESET_TIMEOUT)); msecs_to_jiffies(FNIC_LUN_RESET_TIMEOUT));
break; break;
} else { } else {
io_req = (struct fnic_io_req *)CMD_SP(sc); io_req = fnic_priv(sc)->io_req;
io_req->abts_done = NULL; io_req->abts_done = NULL;
goto fnic_device_reset_clean; goto fnic_device_reset_clean;
} }
@ -2407,7 +2402,7 @@ int fnic_device_reset(struct scsi_cmnd *sc)
FNIC_SCSI_DBG(KERN_DEBUG, FNIC_SCSI_DBG(KERN_DEBUG,
fnic->lport->host, fnic->lport->host,
"Device reset completed - failed\n"); "Device reset completed - failed\n");
io_req = (struct fnic_io_req *)CMD_SP(sc); io_req = fnic_priv(sc)->io_req;
goto fnic_device_reset_clean; goto fnic_device_reset_clean;
} }
@ -2420,7 +2415,7 @@ int fnic_device_reset(struct scsi_cmnd *sc)
*/ */
if (fnic_clean_pending_aborts(fnic, sc, new_sc)) { if (fnic_clean_pending_aborts(fnic, sc, new_sc)) {
spin_lock_irqsave(io_lock, flags); spin_lock_irqsave(io_lock, flags);
io_req = (struct fnic_io_req *)CMD_SP(sc); io_req = fnic_priv(sc)->io_req;
FNIC_SCSI_DBG(KERN_DEBUG, fnic->lport->host, FNIC_SCSI_DBG(KERN_DEBUG, fnic->lport->host,
"Device reset failed" "Device reset failed"
" since could not abort all IOs\n"); " since could not abort all IOs\n");
@ -2429,14 +2424,14 @@ int fnic_device_reset(struct scsi_cmnd *sc)
/* Clean lun reset command */ /* Clean lun reset command */
spin_lock_irqsave(io_lock, flags); spin_lock_irqsave(io_lock, flags);
io_req = (struct fnic_io_req *)CMD_SP(sc); io_req = fnic_priv(sc)->io_req;
if (io_req) if (io_req)
/* Completed, and successful */ /* Completed, and successful */
ret = SUCCESS; ret = SUCCESS;
fnic_device_reset_clean: fnic_device_reset_clean:
if (io_req) if (io_req)
CMD_SP(sc) = NULL; fnic_priv(sc)->io_req = NULL;
spin_unlock_irqrestore(io_lock, flags); spin_unlock_irqrestore(io_lock, flags);
@ -2452,7 +2447,7 @@ fnic_device_reset_end:
0, ((u64)sc->cmnd[0] << 32 | 0, ((u64)sc->cmnd[0] << 32 |
(u64)sc->cmnd[2] << 24 | (u64)sc->cmnd[3] << 16 | (u64)sc->cmnd[2] << 24 | (u64)sc->cmnd[3] << 16 |
(u64)sc->cmnd[4] << 8 | sc->cmnd[5]), (u64)sc->cmnd[4] << 8 | sc->cmnd[5]),
(((u64)CMD_FLAGS(sc) << 32) | CMD_STATE(sc))); fnic_flags_and_state(sc));
/* free tag if it is allocated */ /* free tag if it is allocated */
if (unlikely(tag_gen_flag)) if (unlikely(tag_gen_flag))
@ -2697,7 +2692,7 @@ static bool fnic_abts_pending_iter(struct scsi_cmnd *sc, void *data,
io_lock = fnic_io_lock_hash(fnic, sc); io_lock = fnic_io_lock_hash(fnic, sc);
spin_lock_irqsave(io_lock, flags); spin_lock_irqsave(io_lock, flags);
io_req = (struct fnic_io_req *)CMD_SP(sc); io_req = fnic_priv(sc)->io_req;
if (!io_req) { if (!io_req) {
spin_unlock_irqrestore(io_lock, flags); spin_unlock_irqrestore(io_lock, flags);
return true; return true;
@ -2709,8 +2704,8 @@ static bool fnic_abts_pending_iter(struct scsi_cmnd *sc, void *data,
*/ */
FNIC_SCSI_DBG(KERN_INFO, fnic->lport->host, FNIC_SCSI_DBG(KERN_INFO, fnic->lport->host,
"Found IO in %s on lun\n", "Found IO in %s on lun\n",
fnic_ioreq_state_to_str(CMD_STATE(sc))); fnic_ioreq_state_to_str(fnic_priv(sc)->state));
cmd_state = CMD_STATE(sc); cmd_state = fnic_priv(sc)->state;
spin_unlock_irqrestore(io_lock, flags); spin_unlock_irqrestore(io_lock, flags);
if (cmd_state == FNIC_IOREQ_ABTS_PENDING) if (cmd_state == FNIC_IOREQ_ABTS_PENDING)
iter_data->ret = 1; iter_data->ret = 1;

View File

@ -663,7 +663,7 @@ static inline int generic_NCR5380_psend(struct NCR5380_hostdata *hostdata,
static int generic_NCR5380_dma_xfer_len(struct NCR5380_hostdata *hostdata, static int generic_NCR5380_dma_xfer_len(struct NCR5380_hostdata *hostdata,
struct scsi_cmnd *cmd) struct scsi_cmnd *cmd)
{ {
int transfersize = cmd->SCp.this_residual; int transfersize = NCR5380_to_ncmd(cmd)->this_residual;
if (hostdata->flags & FLAG_NO_PSEUDO_DMA) if (hostdata->flags & FLAG_NO_PSEUDO_DMA)
return 0; return 0;
@ -675,7 +675,7 @@ static int generic_NCR5380_dma_xfer_len(struct NCR5380_hostdata *hostdata,
/* Limit PDMA send to 512 B to avoid random corruption on DTC3181E */ /* Limit PDMA send to 512 B to avoid random corruption on DTC3181E */
if (hostdata->board == BOARD_DTC3181E && if (hostdata->board == BOARD_DTC3181E &&
cmd->sc_data_direction == DMA_TO_DEVICE) cmd->sc_data_direction == DMA_TO_DEVICE)
transfersize = min(cmd->SCp.this_residual, 512); transfersize = min(transfersize, 512);
return min(transfersize, DMA_MAX_SIZE); return min(transfersize, DMA_MAX_SIZE);
} }
@ -702,7 +702,7 @@ static struct scsi_host_template driver_template = {
.sg_tablesize = SG_ALL, .sg_tablesize = SG_ALL,
.cmd_per_lun = 2, .cmd_per_lun = 2,
.dma_boundary = PAGE_SIZE - 1, .dma_boundary = PAGE_SIZE - 1,
.cmd_size = NCR5380_CMD_SIZE, .cmd_size = sizeof(struct NCR5380_cmd),
.max_sectors = 128, .max_sectors = 128,
}; };

View File

@ -12,7 +12,11 @@
#include <asm/amigaints.h> #include <asm/amigaints.h>
#include <asm/amigahw.h> #include <asm/amigahw.h>
#include "scsi.h" #include <scsi/scsi.h>
#include <scsi/scsi_cmnd.h>
#include <scsi/scsi_device.h>
#include <scsi/scsi_eh.h>
#include <scsi/scsi_tcq.h>
#include "wd33c93.h" #include "wd33c93.h"
#include "gvp11.h" #include "gvp11.h"
@ -49,18 +53,19 @@ void gvp11_setup(char *str, int *ints)
static int dma_setup(struct scsi_cmnd *cmd, int dir_in) static int dma_setup(struct scsi_cmnd *cmd, int dir_in)
{ {
struct scsi_pointer *scsi_pointer = WD33C93_scsi_pointer(cmd);
struct Scsi_Host *instance = cmd->device->host; struct Scsi_Host *instance = cmd->device->host;
struct gvp11_hostdata *hdata = shost_priv(instance); struct gvp11_hostdata *hdata = shost_priv(instance);
struct WD33C93_hostdata *wh = &hdata->wh; struct WD33C93_hostdata *wh = &hdata->wh;
struct gvp11_scsiregs *regs = hdata->regs; struct gvp11_scsiregs *regs = hdata->regs;
unsigned short cntr = GVP11_DMAC_INT_ENABLE; unsigned short cntr = GVP11_DMAC_INT_ENABLE;
unsigned long addr = virt_to_bus(cmd->SCp.ptr); unsigned long addr = virt_to_bus(scsi_pointer->ptr);
int bank_mask; int bank_mask;
static int scsi_alloc_out_of_range = 0; static int scsi_alloc_out_of_range = 0;
/* use bounce buffer if the physical address is bad */ /* use bounce buffer if the physical address is bad */
if (addr & wh->dma_xfer_mask) { if (addr & wh->dma_xfer_mask) {
wh->dma_bounce_len = (cmd->SCp.this_residual + 511) & ~0x1ff; wh->dma_bounce_len = (scsi_pointer->this_residual + 511) & ~0x1ff;
if (!scsi_alloc_out_of_range) { if (!scsi_alloc_out_of_range) {
wh->dma_bounce_buffer = wh->dma_bounce_buffer =
@ -109,8 +114,8 @@ static int dma_setup(struct scsi_cmnd *cmd, int dir_in)
if (!dir_in) { if (!dir_in) {
/* copy to bounce buffer for a write */ /* copy to bounce buffer for a write */
memcpy(wh->dma_bounce_buffer, cmd->SCp.ptr, memcpy(wh->dma_bounce_buffer, scsi_pointer->ptr,
cmd->SCp.this_residual); scsi_pointer->this_residual);
} }
} }
@ -126,10 +131,10 @@ static int dma_setup(struct scsi_cmnd *cmd, int dir_in)
if (dir_in) { if (dir_in) {
/* invalidate any cache */ /* invalidate any cache */
cache_clear(addr, cmd->SCp.this_residual); cache_clear(addr, scsi_pointer->this_residual);
} else { } else {
/* push any dirty cache */ /* push any dirty cache */
cache_push(addr, cmd->SCp.this_residual); cache_push(addr, scsi_pointer->this_residual);
} }
bank_mask = (~wh->dma_xfer_mask >> 18) & 0x01c0; bank_mask = (~wh->dma_xfer_mask >> 18) & 0x01c0;
@ -146,6 +151,7 @@ static int dma_setup(struct scsi_cmnd *cmd, int dir_in)
static void dma_stop(struct Scsi_Host *instance, struct scsi_cmnd *SCpnt, static void dma_stop(struct Scsi_Host *instance, struct scsi_cmnd *SCpnt,
int status) int status)
{ {
struct scsi_pointer *scsi_pointer = WD33C93_scsi_pointer(SCpnt);
struct gvp11_hostdata *hdata = shost_priv(instance); struct gvp11_hostdata *hdata = shost_priv(instance);
struct WD33C93_hostdata *wh = &hdata->wh; struct WD33C93_hostdata *wh = &hdata->wh;
struct gvp11_scsiregs *regs = hdata->regs; struct gvp11_scsiregs *regs = hdata->regs;
@ -158,8 +164,8 @@ static void dma_stop(struct Scsi_Host *instance, struct scsi_cmnd *SCpnt,
/* copy from a bounce buffer, if necessary */ /* copy from a bounce buffer, if necessary */
if (status && wh->dma_bounce_buffer) { if (status && wh->dma_bounce_buffer) {
if (wh->dma_dir && SCpnt) if (wh->dma_dir && SCpnt)
memcpy(SCpnt->SCp.ptr, wh->dma_bounce_buffer, memcpy(scsi_pointer->ptr, wh->dma_bounce_buffer,
SCpnt->SCp.this_residual); scsi_pointer->this_residual);
if (wh->dma_buffer_pool == BUF_SCSI_ALLOCED) if (wh->dma_buffer_pool == BUF_SCSI_ALLOCED)
kfree(wh->dma_bounce_buffer); kfree(wh->dma_bounce_buffer);
@ -185,6 +191,7 @@ static struct scsi_host_template gvp11_scsi_template = {
.sg_tablesize = SG_ALL, .sg_tablesize = SG_ALL,
.cmd_per_lun = CMD_PER_LUN, .cmd_per_lun = CMD_PER_LUN,
.dma_boundary = PAGE_SIZE - 1, .dma_boundary = PAGE_SIZE - 1,
.cmd_size = sizeof(struct scsi_pointer),
}; };
static int check_wd33c93(struct gvp11_scsiregs *regs) static int check_wd33c93(struct gvp11_scsiregs *regs)

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