diff --git a/Documentation/scsi/scsi_mid_low_api.rst b/Documentation/scsi/scsi_mid_low_api.rst index 7f59dff43eb5..84cf61b2d6ae 100644 --- a/Documentation/scsi/scsi_mid_low_api.rst +++ b/Documentation/scsi/scsi_mid_low_api.rst @@ -865,7 +865,7 @@ Details:: * * Other types of errors that are detected immediately may be * flagged by setting scp->result to an appropriate value, - * invoking the scp->scsi_done callback, and then returning 0 + * invoking the scsi_done() function, and then returning 0 * from this function. If the command is not performed * immediately (and the LLD is starting (or will start) the given * command) then this function should place 0 in scp->result and @@ -873,11 +873,11 @@ Details:: * * Command ownership. If the driver returns zero, it owns the * command and must take responsibility for ensuring the - * scp->scsi_done callback is executed. Note: the driver may - * call scp->scsi_done before returning zero, but after it has - * called scp->scsi_done, it may not return any value other than + * scsi_done() function is called. Note: the driver may + * call scsi_done() before returning zero, but after it has + * called scsi_done(), it may not return any value other than * zero. If the driver makes a non-zero return, it must not - * execute the command's scsi_done callback at any time. + * call scsi_done(scp) at any time. * * Locks: up to and including 2.6.36, struct Scsi_Host::host_lock * held on entry (with "irqsave") and is expected to be @@ -887,16 +887,16 @@ Details:: * Calling context: in interrupt (soft irq) or process context * * Notes: This function should be relatively fast. Normally it - * will not wait for IO to complete. Hence the scp->scsi_done - * callback is invoked (often directly from an interrupt service + * will not wait for IO to complete. Hence the scsi_done() + * function is invoked (often directly from an interrupt service * routine) some time after this function has returned. In some * cases (e.g. pseudo adapter drivers that manufacture the - * response to a SCSI INQUIRY) the scp->scsi_done callback may be - * invoked before this function returns. If the scp->scsi_done - * callback is not invoked within a certain period the SCSI mid + * response to a SCSI INQUIRY) the scsi_done() function may be + * invoked before this function returns. If the scsi_done() + * function is not invoked within a certain period the SCSI mid * level will commence error processing. If a status of CHECK - * CONDITION is placed in "result" when the scp->scsi_done - * callback is invoked, then the LLD driver should perform + * CONDITION is placed in "result" when the scsi_done() + * function is invoked, then the LLD driver should perform * autosense and fill in the struct scsi_cmnd::sense_buffer * array. The scsi_cmnd::sense_buffer array is zeroed prior to * the mid level queuing a command to an LLD. @@ -1148,12 +1148,8 @@ The scsi_cmnd structure is defined in include/scsi/scsi_cmnd.h Locks ===== Each struct Scsi_Host instance has a spin_lock called struct -Scsi_Host::default_lock which is initialized in scsi_host_alloc() [found in -hosts.c]. Within the same function the struct Scsi_Host::host_lock pointer -is initialized to point at default_lock. Thereafter lock and unlock -operations performed by the mid level use the struct Scsi_Host::host_lock -pointer. Previously drivers could override the host_lock pointer but -this is not allowed anymore. +Scsi_Host::host_lock which is initialized in scsi_host_alloc() [found in +hosts.c]. Autosense diff --git a/Documentation/scsi/ufs.rst b/Documentation/scsi/ufs.rst index a7b2b2ed1c3a..06f1b9b4e8dd 100644 --- a/Documentation/scsi/ufs.rst +++ b/Documentation/scsi/ufs.rst @@ -19,6 +19,7 @@ Universal Flash Storage 3.4 SCSI Error handling 4. BSG Support 5. UFS Reference Clock Frequency configuration + 6. Testing with QEMU 1. Overview @@ -208,3 +209,40 @@ the UFS specification. UFS subsystem will attempt to read the value when executing common controller initialization. If the value is available, UFS subsystem will ensure the bRefClkFreq attribute of the UFS storage device is set accordingly and will modify it if there is a mismatch. + +6. Testing with QEMU +==================== + +QEMU emulates a UFS host controller as a PCI device named "ufs" and +logical units named "ufs-lu". This can be used to test changes to the +UFS core and to ufshcd-pci without UFS hardware. + +The "ufs" and "ufs-lu" devices are available since QEMU 8.2, and the +"mcq" property since QEMU 9.1. + +Enable the following kernel options on top of the architecture +defconfig:: + + CONFIG_SCSI_UFSHCD=y + CONFIG_SCSI_UFSHCD_PCI=y + CONFIG_BLK_DEV_SD=y + +Example for an arm64 guest with one 1 GiB logical unit:: + + qemu-img create -f raw ufs.img 1G + qemu-system-aarch64 -M virt -cpu max -smp 4 -m 2G -nographic \ + -kernel arch/arm64/boot/Image -initrd rootfs.cpio.gz \ + -append "console=ttyAMA0" \ + -drive file=ufs.img,if=none,id=lu0,format=raw \ + -device ufs,id=ufs0,serial=0001,mcq=on \ + -device ufs-lu,drive=lu0,bus=ufs0,lun=0 + +The logical unit appears as a SCSI disk (for example /dev/sda). Drop +"mcq=on" to test the single doorbell mode instead of MCQ. The same +-device options work with qemu-system-x86_64. + +The emulation accepts the link startup and hibernate enter/exit UIC +commands and, since QEMU 11.1, DME get/set and the power mode change +sequence, but it does not model UniPro, M-PHY or the resulting link +state. Clock gating hardware and vendor host drivers are not exercised +either. Changes in those areas still need testing on real hardware. diff --git a/MAINTAINERS b/MAINTAINERS index 6215fcb07770..4ad924aeaf16 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -28041,8 +28041,9 @@ F: lib/union_find.c UNIVERSAL FLASH STORAGE HOST CONTROLLER DRIVER R: Alim Akhtar -R: Avri Altman R: Bart Van Assche +R: Bean Huo +R: Stanley Jhu L: linux-scsi@vger.kernel.org S: Supported F: Documentation/devicetree/bindings/ufs/ diff --git a/block/blk-zoned.c b/block/blk-zoned.c index a5afb842bf35..475aa16bc41a 100644 --- a/block/blk-zoned.c +++ b/block/blk-zoned.c @@ -2018,12 +2018,17 @@ static int disk_revalidate_zone_resources(struct gendisk *disk, struct blk_revalidate_zone_args *args) { struct queue_limits *lim = &disk->queue->limits; + unsigned long long nr_zones; unsigned int pool_size; int ret = 0; args->disk = disk; - args->nr_zones = - DIV_ROUND_UP_ULL(get_capacity(disk), lim->chunk_sectors); + nr_zones = DIV_ROUND_UP_ULL(get_capacity(disk), lim->chunk_sectors); + if (nr_zones > UINT_MAX) { + pr_warn("%s: Too many zones (%llu)\n", disk->disk_name, nr_zones); + return -EINVAL; + } + args->nr_zones = nr_zones; /* Cached zone conditions: 1 byte per zone */ args->zones_cond = kzalloc(args->nr_zones, GFP_NOIO); @@ -2131,6 +2136,12 @@ static int blk_revalidate_zone_cond(struct blk_zone *zone, unsigned int idx, { enum blk_zone_cond cond = zone->cond; + if (idx >= args->nr_zones) { + pr_warn("%s: Zone report index %u exceeds zone count %u\n", + args->disk->disk_name, idx, args->nr_zones); + return -EINVAL; + } + /* Check that the zone condition is consistent with the zone type. */ switch (cond) { case BLK_ZONE_COND_NOT_WP: diff --git a/block/bsg-lib.c b/block/bsg-lib.c index 895db30a7033..536cee4430a7 100644 --- a/block/bsg-lib.c +++ b/block/bsg-lib.c @@ -23,11 +23,14 @@ struct bsg_set { struct bsg_device *bd; bsg_job_fn *job_fn; bsg_timeout_fn *timeout_fn; + unsigned int reply_len; }; static int bsg_transport_sg_io_fn(struct request_queue *q, struct sg_io_v4 *hdr, bool open_for_write, unsigned int timeout) { + struct bsg_set *bset = + container_of(q->tag_set, struct bsg_set, tag_set); struct bsg_job *job; struct request *rq; struct bio *bio; @@ -50,7 +53,7 @@ static int bsg_transport_sg_io_fn(struct request_queue *q, struct sg_io_v4 *hdr, reply = job->reply; memset(job, 0, sizeof(*job)); job->reply = reply; - job->reply_len = SCSI_SENSE_BUFFERSIZE; + job->reply_len = bset->reply_len; job->dd_data = job + 1; job->request_len = hdr->request_len; @@ -301,9 +304,10 @@ static blk_status_t bsg_queue_rq(struct blk_mq_hw_ctx *hctx, static int bsg_init_rq(struct blk_mq_tag_set *set, struct request *req, unsigned int hctx_idx, int numa_node) { + struct bsg_set *bset = container_of(set, struct bsg_set, tag_set); struct bsg_job *job = blk_mq_rq_to_pdu(req); - job->reply = kzalloc(SCSI_SENSE_BUFFERSIZE, GFP_KERNEL); + job->reply = kzalloc(bset->reply_len, GFP_KERNEL); if (!job->reply) return -ENOMEM; return 0; @@ -358,10 +362,12 @@ static const struct blk_mq_ops bsg_mq_ops = { * @job_fn: bsg job handler * @timeout: timeout handler function pointer * @dd_job_size: size of LLD data needed for each job + * @reply_len: size of the reply buffer needed for each job */ struct request_queue *bsg_setup_queue(struct device *dev, const char *name, struct queue_limits *lim, bsg_job_fn *job_fn, - bsg_timeout_fn *timeout, int dd_job_size) + bsg_timeout_fn *timeout, int dd_job_size, + unsigned int reply_len) { struct bsg_set *bset; struct blk_mq_tag_set *set; @@ -374,6 +380,7 @@ struct request_queue *bsg_setup_queue(struct device *dev, const char *name, bset->job_fn = job_fn; bset->timeout_fn = timeout; + bset->reply_len = reply_len; set = &bset->tag_set; set->ops = &bsg_mq_ops; diff --git a/drivers/ata/libata-eh.c b/drivers/ata/libata-eh.c index c93c24b22d9c..b7e8545e569e 100644 --- a/drivers/ata/libata-eh.c +++ b/drivers/ata/libata-eh.c @@ -573,9 +573,9 @@ void ata_scsi_error(struct Scsi_Host *host) int nr_timedout; LIST_HEAD(eh_work_q); - spin_lock_irqsave(host->host_lock, flags); + spin_lock_irqsave(&host->host_lock, flags); list_splice_init(&host->eh_cmd_q, &eh_work_q); - spin_unlock_irqrestore(host->host_lock, flags); + spin_unlock_irqrestore(&host->host_lock, flags); /* * First check what errors we got with ata_scsi_cmd_error_handler(). @@ -1516,11 +1516,13 @@ static bool ata_eh_request_sense(struct ata_queued_cmd *qc) err_mask = ata_exec_internal(dev, &tf, NULL, DMA_NONE, NULL, 0, 0); /* Ignore err_mask; ATA_ERR might be set */ if (tf.status & ATA_SENSE) { - if (ata_scsi_sense_is_valid(tf.lbah, tf.lbam, tf.lbal)) { + u16 sense_code = scsi_sense_code(tf.lbam, tf.lbal); + + if (ata_scsi_sense_is_valid(tf.lbah, sense_code)) { /* Set sense without also setting scsicmd->result */ - scsi_build_sense_buffer(dev->flags & ATA_DFLAG_D_SENSE, - cmd->sense_buffer, tf.lbah, - tf.lbam, tf.lbal); + scsi_set_sense_buffer(dev->flags & ATA_DFLAG_D_SENSE, + cmd->sense_buffer, tf.lbah, + sense_code); qc->flags |= ATA_QCFLAG_SENSE_VALID; return true; } @@ -2094,7 +2096,8 @@ static void ata_eh_get_success_sense(struct ata_link *link) continue; /* This success command had sense data, but we failed to get. */ - ata_scsi_set_sense(dev, qc->scsicmd, ABORTED_COMMAND, 0, 0); + ata_scsi_set_sense(dev, qc->scsicmd, ABORTED_COMMAND, + NO_ADDITIONAL_SENSE_INFORMATION); qc->flags |= ATA_QCFLAG_SENSE_VALID; } ata_eh_done(link, dev, ATA_EH_GET_SUCCESS_SENSE); diff --git a/drivers/ata/libata-sata.c b/drivers/ata/libata-sata.c index ad40f516c6d4..32fd0e804654 100644 --- a/drivers/ata/libata-sata.c +++ b/drivers/ata/libata-sata.c @@ -1588,7 +1588,7 @@ int ata_eh_get_ncq_success_sense(struct ata_link *link) asc = sense[1]; ascq = sense[2]; - if (!ata_scsi_sense_is_valid(sk, asc, ascq)) { + if (!ata_scsi_sense_is_valid(sk, scsi_sense_code(asc, ascq))) { ret = -EIO; continue; } @@ -1605,9 +1605,9 @@ int ata_eh_get_ncq_success_sense(struct ata_link *link) qc->result_tf.auxiliary = get_unaligned_le32(&sense[16]); /* Set sense without also setting scsicmd->result */ - scsi_build_sense_buffer(dev->flags & ATA_DFLAG_D_SENSE, - qc->scsicmd->sense_buffer, sk, - asc, ascq); + scsi_set_sense_buffer(dev->flags & ATA_DFLAG_D_SENSE, + qc->scsicmd->sense_buffer, sk, + scsi_sense_code(asc, ascq)); qc->flags |= ATA_QCFLAG_SENSE_VALID; /* @@ -1684,14 +1684,14 @@ void ata_eh_analyze_ncq_error(struct ata_link *link) * stored the sense data in qc->result_tf.auxiliary. */ if (qc->result_tf.auxiliary) { - char sense_key, asc, ascq; + u16 sense_code; + u8 sense_key; sense_key = (qc->result_tf.auxiliary >> 16) & 0xff; - asc = (qc->result_tf.auxiliary >> 8) & 0xff; - ascq = qc->result_tf.auxiliary & 0xff; - if (ata_scsi_sense_is_valid(sense_key, asc, ascq)) { - ata_scsi_set_sense(dev, qc->scsicmd, sense_key, asc, - ascq); + sense_code = qc->result_tf.auxiliary & 0xffff; + if (ata_scsi_sense_is_valid(sense_key, sense_code)) { + ata_scsi_set_sense(dev, qc->scsicmd, sense_key, + sense_code); qc->flags |= ATA_QCFLAG_SENSE_VALID; } } diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c index b3666519b648..4b9792ee3335 100644 --- a/drivers/ata/libata-scsi.c +++ b/drivers/ata/libata-scsi.c @@ -190,28 +190,25 @@ DEVICE_ATTR(unload_heads, S_IRUGO | S_IWUSR, ata_scsi_park_show, ata_scsi_park_store); EXPORT_SYMBOL_GPL(dev_attr_unload_heads); -bool ata_scsi_sense_is_valid(u8 sk, u8 asc, u8 ascq) +bool ata_scsi_sense_is_valid(u8 sense_key, u16 sense_code) { - /* - * If sk == NO_SENSE, and asc + ascq == NO ADDITIONAL SENSE INFORMATION, - * then there is no sense data to add. - */ - if (sk == 0 && asc == 0 && ascq == 0) + if (sense_key == NO_SENSE && + sense_code == NO_ADDITIONAL_SENSE_INFORMATION) return false; /* If sk > COMPLETED, sense data is bogus. */ - if (sk > COMPLETED) + if (sense_key > COMPLETED) return false; return true; } void ata_scsi_set_sense(struct ata_device *dev, struct scsi_cmnd *cmd, - u8 sk, u8 asc, u8 ascq) + u8 sk, u16 code) { bool d_sense = (dev->flags & ATA_DFLAG_D_SENSE); - scsi_build_sense(cmd, d_sense, sk, asc, ascq); + scsi_set_sense(cmd, d_sense, sk, code); } static void ata_scsi_set_sense_information(struct ata_queued_cmd *qc) @@ -316,8 +313,7 @@ static void ata_scsi_set_passthru_sense_fields(struct ata_queued_cmd *qc) static void ata_scsi_set_invalid_field(struct ata_device *dev, struct scsi_cmnd *cmd, u16 field, u8 bit) { - ata_scsi_set_sense(dev, cmd, ILLEGAL_REQUEST, 0x24, 0x0); - /* "Invalid field in CDB" */ + ata_scsi_set_sense(dev, cmd, ILLEGAL_REQUEST, INVALID_FIELD_IN_CDB); scsi_set_sense_field_pointer(cmd->sense_buffer, SCSI_SENSE_BUFFERSIZE, field, bit, 1); } @@ -325,8 +321,8 @@ static void ata_scsi_set_invalid_field(struct ata_device *dev, static void ata_scsi_set_invalid_parameter(struct ata_device *dev, struct scsi_cmnd *cmd, u16 field) { - /* "Invalid field in parameter list" */ - ata_scsi_set_sense(dev, cmd, ILLEGAL_REQUEST, 0x26, 0x0); + ata_scsi_set_sense(dev, cmd, ILLEGAL_REQUEST, + INVALID_FIELD_IN_PARAMETER_LIST); scsi_set_sense_field_pointer(cmd->sense_buffer, SCSI_SENSE_BUFFERSIZE, field, 0xff, 0); } @@ -525,7 +521,8 @@ int ata_cmd_ioctl(struct scsi_device *scsidev, void __user *arg) * check condition even if no error. Filter that. */ if (scsi_status_is_check_condition(cmd_result)) { if (sshdr.sense_key == RECOVERED_ERROR && - sshdr.asc == 0 && sshdr.ascq == 0x1d) + sshdr.sense_code == + ATA_PASS_THROUGH_INFORMATION_AVAILABLE) cmd_result &= ~SAM_STAT_CHECK_CONDITION; } @@ -613,7 +610,8 @@ int ata_task_ioctl(struct scsi_device *scsidev, void __user *arg) * check condition even if no error. Filter that. */ if (cmd_result & SAM_STAT_CHECK_CONDITION) { if (sshdr.sense_key == RECOVERED_ERROR && - sshdr.asc == 0 && sshdr.ascq == 0x1d) + sshdr.sense_code == + ATA_PASS_THROUGH_INFORMATION_AVAILABLE) cmd_result &= ~SAM_STAT_CHECK_CONDITION; } @@ -792,79 +790,143 @@ static void ata_qc_set_pc_nbytes(struct ata_queued_cmd *qc) qc->nbytes = scsi_bufflen(scmd) + qc->extrabytes; } +struct ata_err_sense { + u8 err_mask; + u8 sense_key; + u16 sense_code; +}; + /** * ata_to_sense_error - convert ATA error to SCSI error * @drv_stat: value contained in ATA status register * @drv_err: value contained in ATA error register * @sk: the sense key we'll fill out - * @asc: the additional sense code we'll fill out - * @ascq: the additional sense code qualifier we'll fill out + * @scode: the additional sense code and its qualifier we'll fill out * * Converts an ATA error into a SCSI error. Fill out pointers to - * SK, ASC, and ASCQ bytes for later use in fixed or descriptor + * the sense key and sense code for later use in fixed or descriptor * format sense blocks. * * LOCKING: * spin_lock_irqsave(host lock) */ -static void ata_to_sense_error(u8 drv_stat, u8 drv_err, u8 *sk, u8 *asc, - u8 *ascq) +static void ata_to_sense_error(u8 drv_stat, u8 drv_err, u8 *sk, u16 *scode) { int i; /* Based on the 3ware driver translation table */ - static const unsigned char sense_table[][4] = { - /* BBD|ECC|ID|MAR */ - {0xd1, ABORTED_COMMAND, 0x00, 0x00}, - // Device busy Aborted command - /* BBD|ECC|ID */ - {0xd0, ABORTED_COMMAND, 0x00, 0x00}, - // Device busy Aborted command - /* ECC|MC|MARK */ - {0x61, HARDWARE_ERROR, 0x00, 0x00}, - // Device fault Hardware error - /* ICRC|ABRT */ /* NB: ICRC & !ABRT is BBD */ - {0x84, ABORTED_COMMAND, 0x47, 0x00}, - // Data CRC error SCSI parity error - /* MC|ID|ABRT|TRK0|MARK */ - {0x37, NOT_READY, 0x04, 0x00}, - // Unit offline Not ready - /* MCR|MARK */ - {0x09, NOT_READY, 0x04, 0x00}, - // Unrecovered disk error Not ready - /* Bad address mark */ - {0x01, MEDIUM_ERROR, 0x13, 0x00}, - // Address mark not found for data field - /* TRK0 - Track 0 not found */ - {0x02, HARDWARE_ERROR, 0x00, 0x00}, - // Hardware error - /* Abort: 0x04 is not translated here, see below */ - /* Media change request */ - {0x08, NOT_READY, 0x04, 0x00}, - // FIXME: faking offline - /* SRV/IDNF - ID not found */ - {0x10, ILLEGAL_REQUEST, 0x21, 0x00}, - // Logical address out of range - /* MC - Media Changed */ - {0x20, UNIT_ATTENTION, 0x28, 0x00}, - // Not ready to ready change, medium may have changed - /* ECC - Uncorrectable ECC error */ - {0x40, MEDIUM_ERROR, 0x11, 0x04}, - // Unrecovered read error - /* BBD - block marked bad */ - {0x80, MEDIUM_ERROR, 0x11, 0x04}, - // Block marked bad Medium error, unrecovered read error - {0xFF, 0xFF, 0xFF, 0xFF}, // END mark + static const struct ata_err_sense sense_table[] = { + { + /* BBD|ECC|ID|MAR - Device busy */ + 0xd1, + ABORTED_COMMAND, + NO_ADDITIONAL_SENSE_INFORMATION + }, + { + /* BBD|ECC|ID - Device busy */ + 0xd0, + ABORTED_COMMAND, + NO_ADDITIONAL_SENSE_INFORMATION + }, + { + /* ECC|MC|MARK - Device fault */ + 0x61, + HARDWARE_ERROR, + NO_ADDITIONAL_SENSE_INFORMATION + }, + { + /* ICRC|ABRT - Data CRC error */ + /* NB: ICRC & !ABRT is BBD */ + 0x84, + ABORTED_COMMAND, + SCSI_PARITY_ERROR + }, + { + /* MC|ID|ABRT|TRK0|MARK - Unit offline */ + 0x37, + NOT_READY, + LU_NOT_READY + }, + { + /* MCR|MARK - Unrecovered disk error */ + 0x09, + NOT_READY, + LU_NOT_READY + }, + { + /* Bad address mark */ + 0x01, + MEDIUM_ERROR, + ADDRESS_MARK_NOT_FOUND_FOR_DATA_FIELD + }, + { + /* TRK0 - Track 0 not found */ + 0x02, + HARDWARE_ERROR, + NO_ADDITIONAL_SENSE_INFORMATION + }, + { + /* Abort: 0x04 is not translated here, see below */ + /* Media change request */ + 0x08, + NOT_READY, + LU_NOT_READY + }, + { + /* SRV/IDNF - ID not found */ + 0x10, + ILLEGAL_REQUEST, + LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE + }, + { + /* MC - Media Changed */ + 0x20, + UNIT_ATTENTION, + NOT_READY_TO_READY_CHANGE_MEDIUM_MAY_HAVE_CHANGED + }, + { + /* ECC - Uncorrectable ECC error */ + 0x40, + MEDIUM_ERROR, + UNRECOVERED_READ_ERROR_AUTO_REALLOCATE_FAILED + }, + { + /* BBD - block marked bad */ + 0x80, + MEDIUM_ERROR, + UNRECOVERED_READ_ERROR_AUTO_REALLOCATE_FAILED + }, + { + /* END mark */ + 0xFF, 0xFF, 0xFFFF + }, }; - static const unsigned char stat_table[][4] = { - /* Busy: must be first because BUSY means no other bits valid */ - { ATA_BUSY, ABORTED_COMMAND, 0x00, 0x00 }, - /* Device fault: INTERNAL TARGET FAILURE */ - { ATA_DF, HARDWARE_ERROR, 0x44, 0x00 }, - /* Corrected data error */ - { ATA_CORR, RECOVERED_ERROR, 0x00, 0x00 }, - - { 0xFF, 0xFF, 0xFF, 0xFF }, /* END mark */ + static const struct ata_err_sense stat_table[] = { + { + /* + * Busy: must be first because BUSY means no other bits + * valid. + */ + ATA_BUSY, + ABORTED_COMMAND, + NO_ADDITIONAL_SENSE_INFORMATION + }, + { + /* Device fault */ + ATA_DF, + HARDWARE_ERROR, + INTERNAL_TARGET_FAILURE + }, + { + /* Corrected data error */ + ATA_CORR, + RECOVERED_ERROR, + NO_ADDITIONAL_SENSE_INFORMATION + }, + { + /* END mark */ + 0xFF, 0xFF, 0xFFFF + }, }; /* @@ -876,13 +938,12 @@ static void ata_to_sense_error(u8 drv_stat, u8 drv_err, u8 *sk, u8 *asc, if (drv_err) { /* Look for drv_err */ - for (i = 0; sense_table[i][0] != 0xFF; i++) { + for (i = 0; sense_table[i].err_mask != 0xFF; i++) { /* Look for best matches first */ - if ((sense_table[i][0] & drv_err) == - sense_table[i][0]) { - *sk = sense_table[i][1]; - *asc = sense_table[i][2]; - *ascq = sense_table[i][3]; + if ((sense_table[i].err_mask & drv_err) == + sense_table[i].err_mask) { + *sk = sense_table[i].sense_key; + *scode = sense_table[i].sense_code; return; } } @@ -893,11 +954,10 @@ static void ata_to_sense_error(u8 drv_stat, u8 drv_err, u8 *sk, u8 *asc, * has only the ABRT bit set, we decode drv_stat. ABRT by itself * is not descriptive enough. */ - for (i = 0; stat_table[i][0] != 0xFF; i++) { - if (stat_table[i][0] & drv_stat) { - *sk = stat_table[i][1]; - *asc = stat_table[i][2]; - *ascq = stat_table[i][3]; + for (i = 0; stat_table[i].err_mask != 0xFF; i++) { + if (stat_table[i].err_mask & drv_stat) { + *sk = stat_table[i].sense_key; + *scode = stat_table[i].sense_code; return; } } @@ -907,8 +967,7 @@ static void ata_to_sense_error(u8 drv_stat, u8 drv_err, u8 *sk, u8 *asc, * that won't cause people to do things like return a disk wrongly. */ *sk = ABORTED_COMMAND; - *asc = 0x00; - *ascq = 0x00; + *scode = NO_ADDITIONAL_SENSE_INFORMATION; } /* @@ -931,40 +990,41 @@ static void ata_gen_passthru_sense(struct ata_queued_cmd *qc) struct ata_device *dev = qc->dev; struct scsi_cmnd *cmd = qc->scsicmd; struct ata_taskfile *tf = &qc->result_tf; - u8 sense_key, asc, ascq; + u16 sense_code; + u8 sense_key; if (!(qc->flags & ATA_QCFLAG_RTF_FILLED)) { ata_dev_dbg(dev, "missing result TF: can't generate ATA PT sense data\n"); if (qc->err_mask) - ata_scsi_set_sense(dev, cmd, ABORTED_COMMAND, 0, 0); + ata_scsi_set_sense(dev, cmd, ABORTED_COMMAND, + NO_ADDITIONAL_SENSE_INFORMATION); return; } /* - * Use ata_to_sense_error() to map status register bits - * onto sense key, asc & ascq. + * Use ata_to_sense_error() to map status register bits onto sense key + * and sense code. */ if (qc->err_mask || tf->status & (ATA_BUSY | ATA_DF | ATA_ERR | ATA_DRQ)) { ata_to_sense_error(tf->status, tf->error, - &sense_key, &asc, &ascq); - ata_scsi_set_sense(qc->dev, cmd, sense_key, asc, ascq); - } else { - /* - * ATA PASS-THROUGH INFORMATION AVAILABLE - * - * Note: we are supposed to call ata_scsi_set_sense(), which - * respects the D_SENSE bit, instead of unconditionally - * generating the sense data in descriptor format. However, - * because hdparm, hddtemp, and udisks incorrectly assume sense - * data in descriptor format, without even looking at the - * RESPONSE CODE field in the returned sense data (to see which - * format the returned sense data is in), we are stuck with - * being bug compatible with older kernels. - */ - scsi_build_sense(cmd, 1, RECOVERED_ERROR, 0, 0x1D); + &sense_key, &sense_code); + ata_scsi_set_sense(qc->dev, cmd, sense_key, sense_code); + return; } + + /* + * Note: we are supposed to call ata_scsi_set_sense(), which respects + * the D_SENSE bit, instead of unconditionally generating the sense data + * in descriptor format. However, because hdparm, hddtemp, and udisks + * incorrectly assume sense data in descriptor format, without even + * looking at the RESPONSE CODE field in the returned sense data (to see + * which format the returned sense data is in), we are stuck with being + * bug compatible with older kernels. + */ + scsi_set_sense(cmd, 1, RECOVERED_ERROR, + ATA_PASS_THROUGH_INFORMATION_AVAILABLE); } /** @@ -981,19 +1041,18 @@ static void ata_gen_ata_sense(struct ata_queued_cmd *qc) struct ata_device *dev = qc->dev; struct scsi_cmnd *cmd = qc->scsicmd; struct ata_taskfile *tf = &qc->result_tf; - u8 sense_key, asc, ascq; if (ata_dev_disabled(dev)) { /* Device disabled after error recovery */ - /* LOGICAL UNIT NOT READY, HARD RESET REQUIRED */ - ata_scsi_set_sense(dev, cmd, NOT_READY, 0x04, 0x21); + ata_scsi_set_sense(dev, cmd, NOT_READY, + LU_NOT_READY_HARD_RESET_REQUIRED); return; } if (ata_id_is_locked(dev->id)) { /* Security locked */ - /* LOGICAL UNIT ACCESS NOT AUTHORIZED */ - ata_scsi_set_sense(dev, cmd, DATA_PROTECT, 0x74, 0x71); + ata_scsi_set_sense(dev, cmd, DATA_PROTECT, + LU_ACCESS_NOT_AUTHORIZED); return; } @@ -1008,9 +1067,12 @@ static void ata_gen_ata_sense(struct ata_queued_cmd *qc) */ if (qc->err_mask || tf->status & (ATA_BUSY | ATA_DF | ATA_ERR | ATA_DRQ)) { + u16 sense_code; + u8 sense_key; + ata_to_sense_error(tf->status, tf->error, - &sense_key, &asc, &ascq); - ata_scsi_set_sense(dev, cmd, sense_key, asc, ascq); + &sense_key, &sense_code); + ata_scsi_set_sense(dev, cmd, sense_key, sense_code); return; } @@ -1019,7 +1081,8 @@ static void ata_gen_ata_sense(struct ata_queued_cmd *qc) "Could not decode error 0x%x, status 0x%x (err_mask=0x%x)\n", tf->error, tf->status, qc->err_mask); aborted: - ata_scsi_set_sense(dev, cmd, ABORTED_COMMAND, 0, 0); + ata_scsi_set_sense(dev, cmd, ABORTED_COMMAND, + NO_ADDITIONAL_SENSE_INFORMATION); } void ata_scsi_sdev_config(struct scsi_device *sdev) @@ -1273,7 +1336,8 @@ static unsigned int ata_scsi_start_stop_xlat(struct ata_queued_cmd *qc) /* Ignore IMMED bit (cdb[1] & 0x1), violates sat-r05 */ if (!ata_dev_power_init_tf(qc->dev, &qc->tf, cdb[4] & 0x1)) { - ata_scsi_set_sense(qc->dev, scmd, ABORTED_COMMAND, 0, 0); + ata_scsi_set_sense(qc->dev, scmd, ABORTED_COMMAND, + NO_ADDITIONAL_SENSE_INFORMATION); return 1; } @@ -1501,8 +1565,8 @@ static unsigned int ata_scsi_verify_xlat(struct ata_queued_cmd *qc) return 1; out_of_range: - ata_scsi_set_sense(qc->dev, scmd, ILLEGAL_REQUEST, 0x21, 0x0); - /* "Logical Block Address out of range" */ + ata_scsi_set_sense(qc->dev, scmd, ILLEGAL_REQUEST, + LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE); return 1; nothing_to_do: @@ -1638,8 +1702,8 @@ static unsigned int ata_scsi_rw_xlat(struct ata_queued_cmd *qc) return 1; out_of_range: - ata_scsi_set_sense(qc->dev, scmd, ILLEGAL_REQUEST, 0x21, 0x0); - /* "Logical Block Address out of range" */ + ata_scsi_set_sense(qc->dev, scmd, ILLEGAL_REQUEST, + LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE); return 1; nothing_to_do: @@ -2015,7 +2079,8 @@ static void ata_scsi_rbuf_fill(struct ata_device *dev, struct scsi_cmnd *cmd, len = actor(dev, cmd, ata_scsi_rbuf); if (len) { if (WARN_ON(len > ATA_SCSI_RBUF_SIZE)) { - ata_scsi_set_sense(dev, cmd, ABORTED_COMMAND, 0, 0); + ata_scsi_set_sense(dev, cmd, ABORTED_COMMAND, + NO_ADDITIONAL_SENSE_INFORMATION); spin_unlock_irqrestore(&ata_scsi_rbuf_lock, flags); return; } @@ -2894,8 +2959,8 @@ static unsigned int ata_scsiop_mode_sense(struct ata_device *dev, return 0; saving_not_supp: - ata_scsi_set_sense(dev, cmd, ILLEGAL_REQUEST, 0x39, 0x0); - /* "Saving parameters not supported" */ + ata_scsi_set_sense(dev, cmd, ILLEGAL_REQUEST, + SAVING_PARAMETERS_NOT_SUPPORTED); return 0; } @@ -3732,12 +3797,12 @@ static unsigned int ata_scsi_write_same_xlat(struct ata_queued_cmd *qc) ata_scsi_set_invalid_field(dev, scmd, fp, bp); return 1; invalid_param_len: - /* "Parameter list length error" */ - ata_scsi_set_sense(dev, scmd, ILLEGAL_REQUEST, 0x1a, 0x0); + ata_scsi_set_sense(dev, scmd, ILLEGAL_REQUEST, + PARAMETER_LIST_LENGTH_ERROR); return 1; invalid_opcode: - /* "Invalid command operation code" */ - ata_scsi_set_sense(dev, scmd, ILLEGAL_REQUEST, 0x20, 0x0); + ata_scsi_set_sense(dev, scmd, ILLEGAL_REQUEST, + INVALID_COMMAND_OP_CODE); return 1; } @@ -4199,8 +4264,8 @@ static unsigned int ata_scsi_zbc_in_xlat(struct ata_queued_cmd *qc) return 1; invalid_param_len: - /* "Parameter list length error" */ - ata_scsi_set_sense(qc->dev, scmd, ILLEGAL_REQUEST, 0x1a, 0x0); + ata_scsi_set_sense(qc->dev, scmd, ILLEGAL_REQUEST, + PARAMETER_LIST_LENGTH_ERROR); return 1; } @@ -4277,8 +4342,8 @@ static unsigned int ata_scsi_zbc_out_xlat(struct ata_queued_cmd *qc) ata_scsi_set_invalid_field(qc->dev, scmd, fp, 0xff); return 1; invalid_param_len: - /* "Parameter list length error" */ - ata_scsi_set_sense(qc->dev, scmd, ILLEGAL_REQUEST, 0x1a, 0x0); + ata_scsi_set_sense(qc->dev, scmd, ILLEGAL_REQUEST, + PARAMETER_LIST_LENGTH_ERROR); return 1; } @@ -4629,8 +4694,8 @@ static unsigned int ata_scsi_mode_select_xlat(struct ata_queued_cmd *qc) return 1; invalid_param_len: - /* "Parameter list length error" */ - ata_scsi_set_sense(qc->dev, scmd, ILLEGAL_REQUEST, 0x1a, 0x0); + ata_scsi_set_sense(qc->dev, scmd, ILLEGAL_REQUEST, + PARAMETER_LIST_LENGTH_ERROR); return 1; skip: @@ -4789,7 +4854,8 @@ ata_scsi_get_phys_element_status_xlat(struct ata_queued_cmd *qc) /* ATA_CMD_GET_PHYS_ELEMENT_STATUS is a DMA command. */ if (!(dev->flags & ATA_DFLAG_DEPOP) || !ata_dma_enabled(dev)) { - ata_scsi_set_sense(dev, scmd, ILLEGAL_REQUEST, 0x20, 0x0); + ata_scsi_set_sense(dev, scmd, ILLEGAL_REQUEST, + INVALID_COMMAND_OP_CODE); return 1; } @@ -4834,7 +4900,8 @@ ata_scsi_remove_element_and_truncate_xlat(struct ata_queued_cmd *qc) u32 id; if (!(dev->flags & ATA_DFLAG_DEPOP)) { - ata_scsi_set_sense(dev, scmd, ILLEGAL_REQUEST, 0x20, 0x0); + ata_scsi_set_sense(dev, scmd, ILLEGAL_REQUEST, + INVALID_COMMAND_OP_CODE); return 1; } @@ -4876,7 +4943,8 @@ ata_scsi_remove_element_and_modify_zones_xlat(struct ata_queued_cmd *qc) u32 id; if (!(dev->flags & ATA_DFLAG_DEPOP_MODIFY)) { - ata_scsi_set_sense(dev, scmd, ILLEGAL_REQUEST, 0x20, 0x0); + ata_scsi_set_sense(dev, scmd, ILLEGAL_REQUEST, + INVALID_COMMAND_OP_CODE); return 1; } @@ -4904,7 +4972,8 @@ ata_scsi_restore_elements_and_rebuild_xlat(struct ata_queued_cmd *qc) struct ata_taskfile *tf = &qc->tf; if (!(dev->flags & ATA_DFLAG_DEPOP_RESTORE)) { - ata_scsi_set_sense(dev, scmd, ILLEGAL_REQUEST, 0x20, 0x0); + ata_scsi_set_sense(dev, scmd, ILLEGAL_REQUEST, + INVALID_COMMAND_OP_CODE); return 1; } @@ -5064,7 +5133,8 @@ static void ata_scsi_simulate(struct ata_device *dev, struct scsi_cmnd *cmd) break; case REQUEST_SENSE: - ata_scsi_set_sense(dev, cmd, 0, 0, 0); + ata_scsi_set_sense(dev, cmd, NO_SENSE, + NO_ADDITIONAL_SENSE_INFORMATION); break; /* if we reach this, then writeback caching is disabled, @@ -5093,8 +5163,8 @@ static void ata_scsi_simulate(struct ata_device *dev, struct scsi_cmnd *cmd) /* all other commands */ default: - ata_scsi_set_sense(dev, cmd, ILLEGAL_REQUEST, 0x20, 0x0); - /* "Invalid command operation code" */ + ata_scsi_set_sense(dev, cmd, ILLEGAL_REQUEST, + INVALID_COMMAND_OP_CODE); break; } diff --git a/drivers/ata/libata.h b/drivers/ata/libata.h index 48274691cd0e..d222a2c92efc 100644 --- a/drivers/ata/libata.h +++ b/drivers/ata/libata.h @@ -164,9 +164,10 @@ extern int ata_scsi_add_hosts(struct ata_host *host, const struct scsi_host_template *sht); extern void ata_scsi_scan_host(struct ata_port *ap, int sync); extern bool ata_scsi_offline_dev(struct ata_device *dev); -extern bool ata_scsi_sense_is_valid(u8 sk, u8 asc, u8 ascq); +extern bool ata_scsi_sense_is_valid(u8 sense_key, u16 sense_code); extern void ata_scsi_set_sense(struct ata_device *dev, - struct scsi_cmnd *cmd, u8 sk, u8 asc, u8 ascq); + struct scsi_cmnd *cmd, u8 sense_key, + u16 sense_code); extern void ata_scsi_media_change_notify(struct ata_device *dev); extern void ata_scsi_hotplug(struct work_struct *work); extern void ata_scsi_dev_rescan(struct work_struct *work); diff --git a/drivers/cdrom/cdrom.c b/drivers/cdrom/cdrom.c index 4f1fd389260f..c717e35ea2af 100644 --- a/drivers/cdrom/cdrom.c +++ b/drivers/cdrom/cdrom.c @@ -345,9 +345,8 @@ int cdrom_dummy_generic_packet(struct cdrom_device_info *cdi, struct packet_command *cgc) { if (cgc->sshdr) { - cgc->sshdr->sense_key = 0x05; - cgc->sshdr->asc = 0x20; - cgc->sshdr->ascq = 0x00; + cgc->sshdr->sense_key = ILLEGAL_REQUEST; + cgc->sshdr->sense_code = INVALID_COMMAND_OP_CODE; } cgc->stat = -EIO; @@ -2979,9 +2978,8 @@ static noinline int mmc_ioctl_cdrom_read_data(struct cdrom_device_info *cdi, cgc->sshdr = &sshdr; cgc->data_direction = CGC_DATA_READ; ret = cdrom_read_block(cdi, cgc, lba, 1, format, blocksize); - if (ret && sshdr.sense_key == 0x05 && - sshdr.asc == 0x20 && - sshdr.ascq == 0x00) { + if (ret && sshdr.sense_key == ILLEGAL_REQUEST && + sshdr.sense_code == INVALID_COMMAND_OP_CODE) { /* * SCSI-II devices are not required to support * READ_CD, so let's try switching block size diff --git a/drivers/infiniband/ulp/iser/iser_initiator.c b/drivers/infiniband/ulp/iser/iser_initiator.c index 12a2d12fef07..d8e732425e77 100644 --- a/drivers/infiniband/ulp/iser/iser_initiator.c +++ b/drivers/infiniband/ulp/iser/iser_initiator.c @@ -604,7 +604,8 @@ static int iser_check_remote_inv(struct iser_conn *iser_conn, struct ib_wc *wc, return -EPROTO; } - task = iscsi_itt_to_ctask(iser_conn->iscsi_conn, hdr->itt); + task = iscsi_itt_to_ctask(iser_conn->iscsi_conn->session, + iser_conn->iscsi_conn, hdr->itt); if (likely(task)) { struct iscsi_iser_task *iser_task = task->dd_data; struct iser_fr_desc *desc; diff --git a/drivers/message/fusion/mptfc.c b/drivers/message/fusion/mptfc.c index b55deb988ad9..bca05099718a 100644 --- a/drivers/message/fusion/mptfc.c +++ b/drivers/message/fusion/mptfc.c @@ -196,20 +196,20 @@ mptfc_block_error_handler(struct fc_rport *rport) hd = shost_priv(shost); ioc = hd->ioc; - spin_lock_irqsave(shost->host_lock, flags); + spin_lock_irqsave(&shost->host_lock, flags); while ((ready = fc_remote_port_chkready(rport) >> 16) == DID_IMM_RETRY || (loops > 0 && ioc->active == 0)) { - spin_unlock_irqrestore(shost->host_lock, flags); + spin_unlock_irqrestore(&shost->host_lock, flags); dfcprintk (ioc, printk(MYIOC_s_DEBUG_FMT "mptfc_block_error_handler.%d: %s, port status is " "%x, active flag %d, deferring recovery.\n", ioc->name, ioc->sh->host_no, dev_name(&rport->dev), ready, ioc->active)); msleep(1000); - spin_lock_irqsave(shost->host_lock, flags); + spin_lock_irqsave(&shost->host_lock, flags); loops --; } - spin_unlock_irqrestore(shost->host_lock, flags); + spin_unlock_irqrestore(&shost->host_lock, flags); if (ready == DID_NO_CONNECT || ioc->active == 0) { dfcprintk (ioc, printk(MYIOC_s_DEBUG_FMT diff --git a/drivers/s390/scsi/zfcp_erp.c b/drivers/s390/scsi/zfcp_erp.c index ec6c0e102119..adfe15f5cb42 100644 --- a/drivers/s390/scsi/zfcp_erp.c +++ b/drivers/s390/scsi/zfcp_erp.c @@ -95,11 +95,11 @@ static void zfcp_erp_action_dismiss_port(struct zfcp_port *port) if (atomic_read(&port->status) & ZFCP_STATUS_COMMON_ERP_INUSE) zfcp_erp_action_dismiss(&port->erp_action); else { - spin_lock(port->adapter->scsi_host->host_lock); + spin_lock(&port->adapter->scsi_host->host_lock); __shost_for_each_device(sdev, port->adapter->scsi_host) if (sdev_to_zfcp(sdev)->port == port) zfcp_erp_action_dismiss_lun(sdev); - spin_unlock(port->adapter->scsi_host->host_lock); + spin_unlock(&port->adapter->scsi_host->host_lock); } } @@ -670,11 +670,11 @@ static void _zfcp_erp_lun_reopen_all(struct zfcp_port *port, int clear, { struct scsi_device *sdev; - spin_lock(port->adapter->scsi_host->host_lock); + spin_lock(&port->adapter->scsi_host->host_lock); __shost_for_each_device(sdev, port->adapter->scsi_host) if (sdev_to_zfcp(sdev)->port == port) _zfcp_erp_lun_reopen(sdev, clear, dbftag, 0); - spin_unlock(port->adapter->scsi_host->host_lock); + spin_unlock(&port->adapter->scsi_host->host_lock); } static void zfcp_erp_strategy_followup_failed(struct zfcp_erp_action *act) @@ -1429,7 +1429,7 @@ static void zfcp_erp_try_rport_unblock(struct zfcp_port *port) write_unlock_irqrestore(&adapter->erp_lock, flags); return; } - spin_lock(shost->host_lock); + spin_lock(&shost->host_lock); __shost_for_each_device(sdev, shost) { struct zfcp_scsi_dev *zsdev = sdev_to_zfcp(sdev); int lun_status; @@ -1451,7 +1451,7 @@ static void zfcp_erp_try_rport_unblock(struct zfcp_port *port) * or meanwhile blocked [new LUN recovery triggered] */ zfcp_dbf_rec_run_lvl(4, "ertru_l", &zsdev->erp_action); - spin_unlock(shost->host_lock); + spin_unlock(&shost->host_lock); write_unlock_irqrestore(&adapter->erp_lock, flags); return; } @@ -1460,7 +1460,7 @@ static void zfcp_erp_try_rport_unblock(struct zfcp_port *port) * and no ERP of severity >= port was meanwhile triggered elsewhere */ zfcp_scsi_schedule_rport_register(port); - spin_unlock(shost->host_lock); + spin_unlock(&shost->host_lock); write_unlock_irqrestore(&adapter->erp_lock, flags); } @@ -1713,10 +1713,10 @@ void zfcp_erp_set_adapter_status(struct zfcp_adapter *adapter, u32 mask) if (adapter->scsi_host == NULL) return; - spin_lock_irqsave(adapter->scsi_host->host_lock, flags); + spin_lock_irqsave(&adapter->scsi_host->host_lock, flags); __shost_for_each_device(sdev, adapter->scsi_host) atomic_or(common_mask, &sdev_to_zfcp(sdev)->status); - spin_unlock_irqrestore(adapter->scsi_host->host_lock, flags); + spin_unlock_irqrestore(&adapter->scsi_host->host_lock, flags); } /** @@ -1757,13 +1757,13 @@ void zfcp_erp_clear_adapter_status(struct zfcp_adapter *adapter, u32 mask) if (adapter->scsi_host == NULL) return; - spin_lock_irqsave(adapter->scsi_host->host_lock, flags); + spin_lock_irqsave(&adapter->scsi_host->host_lock, flags); __shost_for_each_device(sdev, adapter->scsi_host) { atomic_andnot(common_mask, &sdev_to_zfcp(sdev)->status); if (clear_counter) atomic_set(&sdev_to_zfcp(sdev)->erp_counter, 0); } - spin_unlock_irqrestore(adapter->scsi_host->host_lock, flags); + spin_unlock_irqrestore(&adapter->scsi_host->host_lock, flags); } /** @@ -1784,12 +1784,12 @@ void zfcp_erp_set_port_status(struct zfcp_port *port, u32 mask) if (!common_mask) return; - spin_lock_irqsave(port->adapter->scsi_host->host_lock, flags); + spin_lock_irqsave(&port->adapter->scsi_host->host_lock, flags); __shost_for_each_device(sdev, port->adapter->scsi_host) if (sdev_to_zfcp(sdev)->port == port) atomic_or(common_mask, &sdev_to_zfcp(sdev)->status); - spin_unlock_irqrestore(port->adapter->scsi_host->host_lock, flags); + spin_unlock_irqrestore(&port->adapter->scsi_host->host_lock, flags); } /** @@ -1814,7 +1814,7 @@ void zfcp_erp_clear_port_status(struct zfcp_port *port, u32 mask) if (clear_counter) atomic_set(&port->erp_counter, 0); - spin_lock_irqsave(port->adapter->scsi_host->host_lock, flags); + spin_lock_irqsave(&port->adapter->scsi_host->host_lock, flags); __shost_for_each_device(sdev, port->adapter->scsi_host) if (sdev_to_zfcp(sdev)->port == port) { atomic_andnot(common_mask, @@ -1822,7 +1822,7 @@ void zfcp_erp_clear_port_status(struct zfcp_port *port, u32 mask) if (clear_counter) atomic_set(&sdev_to_zfcp(sdev)->erp_counter, 0); } - spin_unlock_irqrestore(port->adapter->scsi_host->host_lock, flags); + spin_unlock_irqrestore(&port->adapter->scsi_host->host_lock, flags); } /** diff --git a/drivers/s390/scsi/zfcp_ext.h b/drivers/s390/scsi/zfcp_ext.h index 0eb9bc9d03e4..cafdeaf29195 100644 --- a/drivers/s390/scsi/zfcp_ext.h +++ b/drivers/s390/scsi/zfcp_ext.h @@ -176,7 +176,7 @@ extern void zfcp_scsi_schedule_rport_register(struct zfcp_port *); extern void zfcp_scsi_schedule_rport_block(struct zfcp_port *); extern void zfcp_scsi_schedule_rports_block(struct zfcp_adapter *); extern void zfcp_scsi_set_prot(struct zfcp_adapter *); -extern void zfcp_scsi_dif_sense_error(struct scsi_cmnd *, int); +extern void zfcp_scsi_dif_sense_error(struct scsi_cmnd *, u16); extern void zfcp_scsi_shost_update_config_data( struct zfcp_adapter *const adapter, const struct fsf_qtcb_bottom_config *const bottom, diff --git a/drivers/s390/scsi/zfcp_fsf.c b/drivers/s390/scsi/zfcp_fsf.c index d407f16e77ef..1ea6ab720fc0 100644 --- a/drivers/s390/scsi/zfcp_fsf.c +++ b/drivers/s390/scsi/zfcp_fsf.c @@ -2485,13 +2485,16 @@ static void zfcp_fsf_fcp_cmnd_handler(struct zfcp_fsf_req *req) set_host_byte(scpnt, DID_ERROR); goto skip_fsfstatus; case FSF_BLOCK_GUARD_CHECK_FAILURE: - zfcp_scsi_dif_sense_error(scpnt, 0x1); + zfcp_scsi_dif_sense_error(scpnt, + LOGICAL_BLOCK_GUARD_CHECK_FAILED); goto skip_fsfstatus; case FSF_APP_TAG_CHECK_FAILURE: - zfcp_scsi_dif_sense_error(scpnt, 0x2); + zfcp_scsi_dif_sense_error(scpnt, + LOGICAL_BLOCK_APPLICATION_TAG_CHECK_FAILED); goto skip_fsfstatus; case FSF_REF_TAG_CHECK_FAILURE: - zfcp_scsi_dif_sense_error(scpnt, 0x3); + zfcp_scsi_dif_sense_error(scpnt, + LOGICAL_BLOCK_REFERENCE_TAG_CHECK_FAILED); goto skip_fsfstatus; } BUILD_BUG_ON(sizeof(struct fcp_resp_with_ext) > FSF_FCP_RSP_SIZE); diff --git a/drivers/s390/scsi/zfcp_scsi.c b/drivers/s390/scsi/zfcp_scsi.c index 3590113c2b74..ea4b968352f4 100644 --- a/drivers/s390/scsi/zfcp_scsi.c +++ b/drivers/s390/scsi/zfcp_scsi.c @@ -849,14 +849,14 @@ void zfcp_scsi_set_prot(struct zfcp_adapter *adapter) /** * zfcp_scsi_dif_sense_error - Report DIF/DIX error as driver sense error * @scmd: The SCSI command to report the error for - * @ascq: The ASCQ to put in the sense buffer + * @sense_code: The combined ASC and ASCQ to put in the sense buffer * * See the error handling in sd_done for the sense codes used here. * Set DID_SOFT_ERROR to retry the request, if possible. */ -void zfcp_scsi_dif_sense_error(struct scsi_cmnd *scmd, int ascq) +void zfcp_scsi_dif_sense_error(struct scsi_cmnd *scmd, u16 sense_code) { - scsi_build_sense(scmd, 1, ILLEGAL_REQUEST, 0x10, ascq); + scsi_set_sense(scmd, 1, ILLEGAL_REQUEST, sense_code); set_host_byte(scmd, DID_SOFT_ERROR); } diff --git a/drivers/s390/scsi/zfcp_sysfs.c b/drivers/s390/scsi/zfcp_sysfs.c index 4f23d585d062..b1ed0cb30a72 100644 --- a/drivers/s390/scsi/zfcp_sysfs.c +++ b/drivers/s390/scsi/zfcp_sysfs.c @@ -270,7 +270,7 @@ static bool zfcp_sysfs_port_in_use(struct zfcp_port *const port) if (atomic_read(&port->units) > 0) goto unlock_port_units_mutex; /* zfcp_unit(s) under port */ - spin_lock_irqsave(adapter->scsi_host->host_lock, flags); + spin_lock_irqsave(&adapter->scsi_host->host_lock, flags); __shost_for_each_device(sdev, adapter->scsi_host) { const struct zfcp_scsi_dev *zsdev = sdev_to_zfcp(sdev); @@ -288,7 +288,7 @@ static bool zfcp_sysfs_port_in_use(struct zfcp_port *const port) in_use = false; unlock_host_lock: - spin_unlock_irqrestore(adapter->scsi_host->host_lock, flags); + spin_unlock_irqrestore(&adapter->scsi_host->host_lock, flags); unlock_port_units_mutex: mutex_unlock(&zfcp_sysfs_port_units_mutex); return in_use; diff --git a/drivers/scsi/3w-9xxx.c b/drivers/scsi/3w-9xxx.c index 9b93a2440af8..e6694f242ebe 100644 --- a/drivers/scsi/3w-9xxx.c +++ b/drivers/scsi/3w-9xxx.c @@ -160,7 +160,7 @@ static ssize_t twa_show_stats(struct device *dev, unsigned long flags = 0; ssize_t len; - spin_lock_irqsave(tw_dev->host->host_lock, flags); + spin_lock_irqsave(&tw_dev->host->host_lock, flags); len = sysfs_emit(buf, "3w-9xxx Driver version: %s\n" "Current commands posted: %4d\n" "Max commands posted: %4d\n" @@ -183,7 +183,7 @@ static ssize_t twa_show_stats(struct device *dev, tw_dev->max_sector_count, tw_dev->num_resets, tw_dev->aen_count); - spin_unlock_irqrestore(tw_dev->host->host_lock, flags); + spin_unlock_irqrestore(&tw_dev->host->host_lock, flags); return len; } /* End twa_show_stats() */ @@ -694,7 +694,7 @@ static long twa_chrdev_ioctl(struct file *file, unsigned int cmd, unsigned long /* See which ioctl we are doing */ switch (cmd) { case TW_IOCTL_FIRMWARE_PASS_THROUGH: - spin_lock_irqsave(tw_dev->host->host_lock, flags); + spin_lock_irqsave(&tw_dev->host->host_lock, flags); twa_get_request_id(tw_dev, &request_id); /* Flag internal command */ @@ -712,7 +712,7 @@ static long twa_chrdev_ioctl(struct file *file, unsigned int cmd, unsigned long /* Now post the command packet to the controller */ twa_post_command_packet(tw_dev, request_id, 1); - spin_unlock_irqrestore(tw_dev->host->host_lock, flags); + spin_unlock_irqrestore(&tw_dev->host->host_lock, flags); timeout = TW_IOCTL_CHRDEV_TIMEOUT*HZ; @@ -734,11 +734,11 @@ static long twa_chrdev_ioctl(struct file *file, unsigned int cmd, unsigned long memcpy(&(tw_ioctl->firmware_command), tw_dev->command_packet_virt[request_id], sizeof(TW_Command_Full)); /* Now complete the io */ - spin_lock_irqsave(tw_dev->host->host_lock, flags); + spin_lock_irqsave(&tw_dev->host->host_lock, flags); tw_dev->posted_request_count--; tw_dev->state[request_id] = TW_S_COMPLETED; twa_free_request_id(tw_dev, request_id); - spin_unlock_irqrestore(tw_dev->host->host_lock, flags); + spin_unlock_irqrestore(&tw_dev->host->host_lock, flags); break; case TW_IOCTL_GET_COMPATIBILITY_INFO: tw_ioctl->driver_command.status = 0; @@ -1223,7 +1223,7 @@ static irqreturn_t twa_interrupt(int irq, void *dev_instance) int handled = 0; /* Get the per adapter lock */ - spin_lock(tw_dev->host->host_lock); + spin_lock(&tw_dev->host->host_lock); /* Read the registers */ status_reg_value = readl(TW_STATUS_REG_ADDR(tw_dev)); @@ -1372,7 +1372,7 @@ static irqreturn_t twa_interrupt(int irq, void *dev_instance) } twa_interrupt_bail: - spin_unlock(tw_dev->host->host_lock); + spin_unlock(&tw_dev->host->host_lock); return IRQ_RETVAL(handled); } /* End twa_interrupt() */ @@ -1585,7 +1585,7 @@ static int twa_reset_device_extension(TW_Device_Extension *tw_dev) set_bit(TW_IN_RESET, &tw_dev->flags); TW_DISABLE_INTERRUPTS(tw_dev); TW_MASK_COMMAND_INTERRUPT(tw_dev); - spin_lock_irqsave(tw_dev->host->host_lock, flags); + spin_lock_irqsave(&tw_dev->host->host_lock, flags); /* Abort all requests that are in progress */ for (i = 0; i < TW_Q_LENGTH; i++) { @@ -1616,7 +1616,7 @@ static int twa_reset_device_extension(TW_Device_Extension *tw_dev) tw_dev->pending_tail = TW_Q_START; tw_dev->reset_print = 0; - spin_unlock_irqrestore(tw_dev->host->host_lock, flags); + spin_unlock_irqrestore(&tw_dev->host->host_lock, flags); if (twa_reset_sequence(tw_dev, 1)) goto out; diff --git a/drivers/scsi/3w-sas.c b/drivers/scsi/3w-sas.c index 52dc1aa639f7..060f97805319 100644 --- a/drivers/scsi/3w-sas.c +++ b/drivers/scsi/3w-sas.c @@ -108,9 +108,9 @@ static ssize_t twl_sysfs_aen_read(struct file *filp, struct kobject *kobj, if (!capable(CAP_SYS_ADMIN)) return -EACCES; - spin_lock_irqsave(tw_dev->host->host_lock, flags); + spin_lock_irqsave(&tw_dev->host->host_lock, flags); ret = memory_read_from_buffer(outbuf, count, &offset, tw_dev->event_queue[0], sizeof(TW_Event) * TW_Q_LENGTH); - spin_unlock_irqrestore(tw_dev->host->host_lock, flags); + spin_unlock_irqrestore(&tw_dev->host->host_lock, flags); return ret; } /* End twl_sysfs_aen_read() */ @@ -139,9 +139,9 @@ static ssize_t twl_sysfs_compat_info(struct file *filp, struct kobject *kobj, if (!capable(CAP_SYS_ADMIN)) return -EACCES; - spin_lock_irqsave(tw_dev->host->host_lock, flags); + spin_lock_irqsave(&tw_dev->host->host_lock, flags); ret = memory_read_from_buffer(outbuf, count, &offset, &tw_dev->tw_compat_info, sizeof(TW_Compatibility_Info)); - spin_unlock_irqrestore(tw_dev->host->host_lock, flags); + spin_unlock_irqrestore(&tw_dev->host->host_lock, flags); return ret; } /* End twl_sysfs_compat_info() */ @@ -165,7 +165,7 @@ static ssize_t twl_show_stats(struct device *dev, unsigned long flags = 0; ssize_t len; - spin_lock_irqsave(tw_dev->host->host_lock, flags); + spin_lock_irqsave(&tw_dev->host->host_lock, flags); len = sysfs_emit(buf, "3w-sas Driver version: %s\n" "Current commands posted: %4d\n" "Max commands posted: %4d\n" @@ -184,7 +184,7 @@ static ssize_t twl_show_stats(struct device *dev, tw_dev->max_sector_count, tw_dev->num_resets, tw_dev->aen_count); - spin_unlock_irqrestore(tw_dev->host->host_lock, flags); + spin_unlock_irqrestore(&tw_dev->host->host_lock, flags); return len; } /* End twl_show_stats() */ @@ -763,7 +763,7 @@ static long twl_chrdev_ioctl(struct file *file, unsigned int cmd, unsigned long /* See which ioctl we are doing */ switch (cmd) { case TW_IOCTL_FIRMWARE_PASS_THROUGH: - spin_lock_irqsave(tw_dev->host->host_lock, flags); + spin_lock_irqsave(&tw_dev->host->host_lock, flags); twl_get_request_id(tw_dev, &request_id); /* Flag internal command */ @@ -781,7 +781,7 @@ static long twl_chrdev_ioctl(struct file *file, unsigned int cmd, unsigned long /* Now post the command packet to the controller */ twl_post_command_packet(tw_dev, request_id); - spin_unlock_irqrestore(tw_dev->host->host_lock, flags); + spin_unlock_irqrestore(&tw_dev->host->host_lock, flags); timeout = TW_IOCTL_CHRDEV_TIMEOUT*HZ; @@ -803,11 +803,11 @@ static long twl_chrdev_ioctl(struct file *file, unsigned int cmd, unsigned long memcpy(&(tw_ioctl->firmware_command), tw_dev->command_packet_virt[request_id], sizeof(TW_Command_Full)); /* Now complete the io */ - spin_lock_irqsave(tw_dev->host->host_lock, flags); + spin_lock_irqsave(&tw_dev->host->host_lock, flags); tw_dev->posted_request_count--; tw_dev->state[request_id] = TW_S_COMPLETED; twl_free_request_id(tw_dev, request_id); - spin_unlock_irqrestore(tw_dev->host->host_lock, flags); + spin_unlock_irqrestore(&tw_dev->host->host_lock, flags); break; default: retval = -ENOTTY; @@ -1125,7 +1125,7 @@ static irqreturn_t twl_interrupt(int irq, void *dev_instance) struct scsi_cmnd *cmd; TW_Command_Full *full_command_packet; - spin_lock(tw_dev->host->host_lock); + spin_lock(&tw_dev->host->host_lock); /* Read host interrupt status */ reg = readl(TWL_HISTAT_REG_ADDR(tw_dev)); @@ -1229,7 +1229,7 @@ static irqreturn_t twl_interrupt(int irq, void *dev_instance) } twl_interrupt_bail: - spin_unlock(tw_dev->host->host_lock); + spin_unlock(&tw_dev->host->host_lock); return IRQ_RETVAL(handled); } /* End twl_interrupt() */ @@ -1360,7 +1360,7 @@ static int twl_reset_device_extension(TW_Device_Extension *tw_dev, int ioctl_res TWL_MASK_INTERRUPTS(tw_dev); TWL_CLEAR_DB_INTERRUPT(tw_dev); - spin_lock_irqsave(tw_dev->host->host_lock, flags); + spin_lock_irqsave(&tw_dev->host->host_lock, flags); /* Abort all requests that are in progress */ for (i = 0; i < TW_Q_LENGTH; i++) { @@ -1386,7 +1386,7 @@ static int twl_reset_device_extension(TW_Device_Extension *tw_dev, int ioctl_res tw_dev->free_tail = TW_Q_START; tw_dev->posted_request_count = 0; - spin_unlock_irqrestore(tw_dev->host->host_lock, flags); + spin_unlock_irqrestore(&tw_dev->host->host_lock, flags); if (twl_reset_sequence(tw_dev, 1)) goto out; diff --git a/drivers/scsi/3w-xxxx.c b/drivers/scsi/3w-xxxx.c index c68678fa72c1..11326465abb6 100644 --- a/drivers/scsi/3w-xxxx.c +++ b/drivers/scsi/3w-xxxx.c @@ -495,7 +495,7 @@ static ssize_t tw_show_stats(struct device *dev, struct device_attribute *attr, unsigned long flags = 0; ssize_t len; - spin_lock_irqsave(tw_dev->host->host_lock, flags); + spin_lock_irqsave(&tw_dev->host->host_lock, flags); len = sysfs_emit(buf, "3w-xxxx Driver version: %s\n" "Current commands posted: %4d\n" "Max commands posted: %4d\n" @@ -518,7 +518,7 @@ static ssize_t tw_show_stats(struct device *dev, struct device_attribute *attr, tw_dev->max_sector_count, tw_dev->num_resets, tw_dev->aen_count); - spin_unlock_irqrestore(tw_dev->host->host_lock, flags); + spin_unlock_irqrestore(&tw_dev->host->host_lock, flags); return len; } /* End tw_show_stats() */ @@ -935,7 +935,7 @@ static long tw_chrdev_ioctl(struct file *file, unsigned int cmd, unsigned long a dprintk(KERN_WARNING "3w-xxxx: tw_chrdev_ioctl(): caught TW_AEN_LISTEN.\n"); memset(tw_ioctl->data_buffer, 0, data_buffer_length); - spin_lock_irqsave(tw_dev->host->host_lock, flags); + spin_lock_irqsave(&tw_dev->host->host_lock, flags); if (tw_dev->aen_head == tw_dev->aen_tail) { tw_aen_code = TW_AEN_QUEUE_EMPTY; } else { @@ -946,12 +946,12 @@ static long tw_chrdev_ioctl(struct file *file, unsigned int cmd, unsigned long a tw_dev->aen_head = tw_dev->aen_head + 1; } } - spin_unlock_irqrestore(tw_dev->host->host_lock, flags); + spin_unlock_irqrestore(&tw_dev->host->host_lock, flags); memcpy(tw_ioctl->data_buffer, &tw_aen_code, sizeof(tw_aen_code)); break; case TW_CMD_PACKET_WITH_DATA: dprintk(KERN_WARNING "3w-xxxx: tw_chrdev_ioctl(): caught TW_CMD_PACKET_WITH_DATA.\n"); - spin_lock_irqsave(tw_dev->host->host_lock, flags); + spin_lock_irqsave(&tw_dev->host->host_lock, flags); tw_state_request_start(tw_dev, &request_id); @@ -983,7 +983,7 @@ static long tw_chrdev_ioctl(struct file *file, unsigned int cmd, unsigned long a /* Now post the command packet to the controller */ tw_post_command_packet(tw_dev, request_id); - spin_unlock_irqrestore(tw_dev->host->host_lock, flags); + spin_unlock_irqrestore(&tw_dev->host->host_lock, flags); timeout = TW_IOCTL_CHRDEV_TIMEOUT*HZ; @@ -1005,11 +1005,11 @@ static long tw_chrdev_ioctl(struct file *file, unsigned int cmd, unsigned long a memcpy(&(tw_ioctl->firmware_command), tw_dev->command_packet_virtual_address[request_id], sizeof(TW_Command)); /* Now complete the io */ - spin_lock_irqsave(tw_dev->host->host_lock, flags); + spin_lock_irqsave(&tw_dev->host->host_lock, flags); tw_dev->posted_request_count--; tw_dev->state[request_id] = TW_S_COMPLETED; tw_state_request_finish(tw_dev, request_id); - spin_unlock_irqrestore(tw_dev->host->host_lock, flags); + spin_unlock_irqrestore(&tw_dev->host->host_lock, flags); break; default: retval = -ENOTTY; @@ -1296,7 +1296,7 @@ static int tw_reset_device_extension(TW_Device_Extension *tw_dev) set_bit(TW_IN_RESET, &tw_dev->flags); TW_DISABLE_INTERRUPTS(tw_dev); TW_MASK_COMMAND_INTERRUPT(tw_dev); - spin_lock_irqsave(tw_dev->host->host_lock, flags); + spin_lock_irqsave(&tw_dev->host->host_lock, flags); /* Abort all requests that are in progress */ for (i=0;ipending_tail = TW_Q_START; tw_dev->reset_print = 0; - spin_unlock_irqrestore(tw_dev->host->host_lock, flags); + spin_unlock_irqrestore(&tw_dev->host->host_lock, flags); if (tw_reset_sequence(tw_dev)) { printk(KERN_WARNING "3w-xxxx: scsi%d: Reset sequence failed.\n", tw_dev->host->host_no); @@ -1977,7 +1977,8 @@ static enum scsi_qc_status tw_scsi_queue_lck(struct scsi_cmnd *SCpnt) printk(KERN_NOTICE "3w-xxxx: scsi%d: Unknown scsi opcode: 0x%x\n", tw_dev->host->host_no, *command); tw_dev->state[request_id] = TW_S_COMPLETED; tw_state_request_finish(tw_dev, request_id); - scsi_build_sense(SCpnt, 1, ILLEGAL_REQUEST, 0x20, 0); + scsi_set_sense(SCpnt, 1, ILLEGAL_REQUEST, + INVALID_COMMAND_OP_CODE); done(SCpnt); retval = 0; } @@ -2005,7 +2006,7 @@ static irqreturn_t tw_interrupt(int irq, void *dev_instance) int handled = 0; /* Get the host lock for io completions */ - spin_lock(tw_dev->host->host_lock); + spin_lock(&tw_dev->host->host_lock); /* Read the registers */ status_reg_value = inl(TW_STATUS_REG_ADDR(tw_dev)); @@ -2185,7 +2186,7 @@ static irqreturn_t tw_interrupt(int irq, void *dev_instance) } tw_interrupt_bail: - spin_unlock(tw_dev->host->host_lock); + spin_unlock(&tw_dev->host->host_lock); return IRQ_RETVAL(handled); } /* End tw_interrupt() */ diff --git a/drivers/scsi/53c700.c b/drivers/scsi/53c700.c index c78f74b8f45c..eb3a69dff1e7 100644 --- a/drivers/scsi/53c700.c +++ b/drivers/scsi/53c700.c @@ -1499,7 +1499,7 @@ NCR_700_intr(int irq, void *dev_id) * lock to enter the done routines. When that happens, we * need to ensure that for this driver, the host lock and the * queue lock point to the same thing. */ - spin_lock_irqsave(host->host_lock, flags); + spin_lock_irqsave(&host->host_lock, flags); if((istat = NCR_700_readb(host, ISTAT_REG)) & (SCSI_INT_PENDING | DMA_INT_PENDING)) { __u32 dsps; @@ -1747,7 +1747,7 @@ NCR_700_intr(int irq, void *dev_id) } } out_unlock: - spin_unlock_irqrestore(host->host_lock, flags); + spin_unlock_irqrestore(&host->host_lock, flags); return IRQ_RETVAL(handled); } @@ -1948,27 +1948,27 @@ NCR_700_host_reset(struct scsi_cmnd * SCp) /* In theory, eh_complete should always be null because the * eh is single threaded, but just in case we're handling a * reset via sg or something */ - spin_lock_irq(SCp->device->host->host_lock); + spin_lock_irq(&SCp->device->host->host_lock); while (hostdata->eh_complete != NULL) { - spin_unlock_irq(SCp->device->host->host_lock); + spin_unlock_irq(&SCp->device->host->host_lock); msleep_interruptible(100); - spin_lock_irq(SCp->device->host->host_lock); + spin_lock_irq(&SCp->device->host->host_lock); } hostdata->eh_complete = &complete; NCR_700_internal_bus_reset(SCp->device->host); NCR_700_chip_reset(SCp->device->host); - spin_unlock_irq(SCp->device->host->host_lock); + spin_unlock_irq(&SCp->device->host->host_lock); wait_for_completion(&complete); - spin_lock_irq(SCp->device->host->host_lock); + spin_lock_irq(&SCp->device->host->host_lock); hostdata->eh_complete = NULL; /* Revalidate the transport parameters of the failing device */ if(hostdata->fast) spi_schedule_dv_device(SCp->device); - spin_unlock_irq(SCp->device->host->host_lock); + spin_unlock_irq(&SCp->device->host->host_lock); return SUCCESS; } diff --git a/drivers/scsi/BusLogic.c b/drivers/scsi/BusLogic.c index 5304d2febd63..27b446c0c5d0 100644 --- a/drivers/scsi/BusLogic.c +++ b/drivers/scsi/BusLogic.c @@ -2744,7 +2744,7 @@ static irqreturn_t blogic_inthandler(int irq_ch, void *devid) /* Acquire exclusive access to Host Adapter. */ - spin_lock_irqsave(adapter->scsi_host->host_lock, processor_flag); + spin_lock_irqsave(&adapter->scsi_host->host_lock, processor_flag); /* Handle Interrupts appropriately for each Host Adapter type. */ @@ -2812,7 +2812,7 @@ static irqreturn_t blogic_inthandler(int irq_ch, void *devid) /* Release exclusive access to Host Adapter. */ - spin_unlock_irqrestore(adapter->scsi_host->host_lock, processor_flag); + spin_unlock_irqrestore(&adapter->scsi_host->host_lock, processor_flag); return IRQ_HANDLED; } @@ -2864,12 +2864,12 @@ static int blogic_hostreset(struct scsi_cmnd *SCpnt) struct blogic_tgt_stats *stats = &adapter->tgt_stats[id]; int rc; - spin_lock_irq(SCpnt->device->host->host_lock); + spin_lock_irq(&SCpnt->device->host->host_lock); blogic_inc_count(&stats->adapter_reset_req); rc = blogic_resetadapter(adapter, false); - spin_unlock_irq(SCpnt->device->host->host_lock); + spin_unlock_irq(&SCpnt->device->host->host_lock); return rc; } @@ -2915,9 +2915,9 @@ static enum scsi_qc_status blogic_qcmd_lck(struct scsi_cmnd *command) */ ccb = blogic_alloc_ccb(adapter); if (ccb == NULL) { - spin_unlock_irq(adapter->scsi_host->host_lock); + spin_unlock_irq(&adapter->scsi_host->host_lock); blogic_delay(1); - spin_lock_irq(adapter->scsi_host->host_lock); + spin_lock_irq(&adapter->scsi_host->host_lock); ccb = blogic_alloc_ccb(adapter); if (ccb == NULL) { command->result = DID_ERROR << 16; @@ -3062,10 +3062,10 @@ static enum scsi_qc_status blogic_qcmd_lck(struct scsi_cmnd *command) be initiated soon. */ if (!blogic_write_outbox(adapter, BLOGIC_MBOX_START, ccb)) { - spin_unlock_irq(adapter->scsi_host->host_lock); + spin_unlock_irq(&adapter->scsi_host->host_lock); blogic_warn("Unable to write Outgoing Mailbox - Pausing for 1 second\n", adapter); blogic_delay(1); - spin_lock_irq(adapter->scsi_host->host_lock); + spin_lock_irq(&adapter->scsi_host->host_lock); if (!blogic_write_outbox(adapter, BLOGIC_MBOX_START, ccb)) { blogic_warn("Still unable to write Outgoing Mailbox - Host Adapter Dead?\n", adapter); @@ -3212,9 +3212,9 @@ static int blogic_resetadapter(struct blogic_adapter *adapter, bool hard_reset) */ if (hard_reset) { - spin_unlock_irq(adapter->scsi_host->host_lock); + spin_unlock_irq(&adapter->scsi_host->host_lock); blogic_delay(adapter->bus_settle_time); - spin_lock_irq(adapter->scsi_host->host_lock); + spin_lock_irq(&adapter->scsi_host->host_lock); } for (tgt_id = 0; tgt_id < adapter->maxdev; tgt_id++) { diff --git a/drivers/scsi/Kconfig b/drivers/scsi/Kconfig index 4a2af0f702e1..1eec66195cf4 100644 --- a/drivers/scsi/Kconfig +++ b/drivers/scsi/Kconfig @@ -753,6 +753,7 @@ config SCSI_IBMVFC tristate "IBM Virtual FC support" depends on PPC_PSERIES && SCSI depends on SCSI_FC_ATTRS + depends on NVME_FC || NVME_FC=n help This is the IBM POWER Virtual FC Client diff --git a/drivers/scsi/Makefile b/drivers/scsi/Makefile index 533623382eca..5b9328dc3b62 100644 --- a/drivers/scsi/Makefile +++ b/drivers/scsi/Makefile @@ -14,29 +14,8 @@ # satisfy certain initialization assumptions in the SCSI layer. # *!*!*!*!*!*!*!*!*!*!*!*!*!*!*!*!*!*!*!*!*!*!*!*!*!*!*!*!*!*!*!*! -CONTEXT_ANALYSIS_constants.o := y -CONTEXT_ANALYSIS_hosts.o := y -CONTEXT_ANALYSIS_scsi.o := y -CONTEXT_ANALYSIS_scsi_common.o := y -CONTEXT_ANALYSIS_scsi_devinfo.o := y -CONTEXT_ANALYSIS_scsi_dh.o := y -CONTEXT_ANALYSIS_scsi_error.o := y -CONTEXT_ANALYSIS_scsi_ioctl.o := y -CONTEXT_ANALYSIS_scsi_lib.o := y -CONTEXT_ANALYSIS_scsi_lib_dma.o := y -CONTEXT_ANALYSIS_scsi_logging.o := y -CONTEXT_ANALYSIS_scsi_netlink.o := y -CONTEXT_ANALYSIS_scsi_pm.o := y -CONTEXT_ANALYSIS_scsi_proc.o := y -CONTEXT_ANALYSIS_scsi_scan.o := y -CONTEXT_ANALYSIS_scsi_sysfs.o := y -CONTEXT_ANALYSIS_scsi_trace.o := y -CONTEXT_ANALYSIS_scsicam.o := y -CONTEXT_ANALYSIS_sd.o := y -CONTEXT_ANALYSIS_sd_dif.o := y -CONTEXT_ANALYSIS_sd_zbc.o := y -CONTEXT_ANALYSIS_sr.o := y -CONTEXT_ANALYSIS_sr_ioctl.o := y +CONTEXT_ANALYSIS := y +CONTEXT_ANALYSIS_BusLogic.o := n CFLAGS_aha152x.o = -DAHA152X_STAT -DAUTOCONF diff --git a/drivers/scsi/NCR5380.c b/drivers/scsi/NCR5380.c index 006dcf981218..6afbd5936892 100644 --- a/drivers/scsi/NCR5380.c +++ b/drivers/scsi/NCR5380.c @@ -718,7 +718,7 @@ static void NCR5380_main(struct work_struct *work) * entire unit. */ - if (!NCR5380_select(instance, cmd)) { + if (!NCR5380_select(hostdata, cmd)) { dsprintk(NDEBUG_MAIN, instance, "main: select complete\n"); } else { dsprintk(NDEBUG_MAIN | NDEBUG_QUEUES, instance, @@ -728,7 +728,7 @@ static void NCR5380_main(struct work_struct *work) } if (hostdata->connected && !hostdata->dma_len) { dsprintk(NDEBUG_MAIN, instance, "main: performing information transfer\n"); - NCR5380_information_transfer(instance); + NCR5380_information_transfer(hostdata); done = 0; } if (!hostdata->connected) { @@ -937,7 +937,7 @@ static irqreturn_t __maybe_unused NCR5380_intr(int irq, void *dev_id) /** * NCR5380_select - attempt arbitration and selection for a given command - * @instance: the Scsi_Host instance + * @hostdata: host private data * @cmd: the scsi_cmnd to execute * * This routine establishes an I_T_L nexus for a SCSI command. This involves @@ -960,10 +960,11 @@ static irqreturn_t __maybe_unused NCR5380_intr(int irq, void *dev_id) * cmd->result host byte set to DID_BAD_TARGET. */ -static bool NCR5380_select(struct Scsi_Host *instance, struct scsi_cmnd *cmd) +static bool NCR5380_select(struct NCR5380_hostdata *hostdata, + struct scsi_cmnd *cmd) __releases(&hostdata->lock) __acquires(&hostdata->lock) { - struct NCR5380_hostdata *hostdata = shost_priv(instance); + struct Scsi_Host *instance = hostdata->host; unsigned char tmp[3], phase; unsigned char *data; int len; @@ -1643,23 +1644,23 @@ static int NCR5380_transfer_dma(struct Scsi_Host *instance, } /* - * Function : NCR5380_information_transfer (struct Scsi_Host *instance) + * Function : NCR5380_information_transfer(struct NCR5380_hostdata *hostdata) * * Purpose : run through the various SCSI phases and do as the target * directs us to. Operates on the currently connected command, * instance->connected. * - * Inputs : instance, instance for which we are doing commands + * Inputs : hostdata, the private host data * * Side effects : SCSI things happen, the disconnected queue will be * modified if a command disconnects, *instance->connected will * change. */ -static void NCR5380_information_transfer(struct Scsi_Host *instance) +static void NCR5380_information_transfer(struct NCR5380_hostdata *hostdata) __releases(&hostdata->lock) __acquires(&hostdata->lock) { - struct NCR5380_hostdata *hostdata = shost_priv(instance); + struct Scsi_Host *instance = hostdata->host; unsigned char msgout = NOP; int sink = 0; int len; diff --git a/drivers/scsi/NCR5380.h b/drivers/scsi/NCR5380.h index d402d4bffcb2..450b08da5858 100644 --- a/drivers/scsi/NCR5380.h +++ b/drivers/scsi/NCR5380.h @@ -278,12 +278,13 @@ static void NCR5380_print(struct Scsi_Host *instance); static int NCR5380_init(struct Scsi_Host *instance, int flags); static int NCR5380_maybe_reset_bus(struct Scsi_Host *); static void NCR5380_exit(struct Scsi_Host *instance); -static void NCR5380_information_transfer(struct Scsi_Host *instance); +static void NCR5380_information_transfer(struct NCR5380_hostdata *hostdata); static irqreturn_t NCR5380_intr(int irq, void *dev_id); static void NCR5380_main(struct work_struct *work); static const char *NCR5380_info(struct Scsi_Host *instance); static void NCR5380_reselect(struct Scsi_Host *instance); -static bool NCR5380_select(struct Scsi_Host *, struct scsi_cmnd *); +static bool NCR5380_select(struct NCR5380_hostdata *hostdata, + struct scsi_cmnd *); static int NCR5380_transfer_dma(struct Scsi_Host *instance, unsigned char *phase, int *count, unsigned char **data); static void NCR5380_transfer_pio(struct Scsi_Host *instance, unsigned char *phase, int *count, diff --git a/drivers/scsi/a100u2w.c b/drivers/scsi/a100u2w.c index 4365b896f5c4..7e6776325d9b 100644 --- a/drivers/scsi/a100u2w.c +++ b/drivers/scsi/a100u2w.c @@ -1058,9 +1058,9 @@ static irqreturn_t inia100_intr(int irqno, void *devid) unsigned long flags; irqreturn_t res; - spin_lock_irqsave(shost->host_lock, flags); + spin_lock_irqsave(&shost->host_lock, flags); res = orc_interrupt(host); - spin_unlock_irqrestore(shost->host_lock, flags); + spin_unlock_irqrestore(&shost->host_lock, flags); return res; } diff --git a/drivers/scsi/a2091.c b/drivers/scsi/a2091.c index f81e53b53e20..223065529654 100644 --- a/drivers/scsi/a2091.c +++ b/drivers/scsi/a2091.c @@ -39,9 +39,9 @@ static irqreturn_t a2091_intr(int irq, void *data) if (!(status & (ISTR_INT_F | ISTR_INT_P)) || !(status & ISTR_INTS)) return IRQ_NONE; - spin_lock_irqsave(instance->host_lock, flags); + spin_lock_irqsave(&instance->host_lock, flags); wd33c93_intr(instance); - spin_unlock_irqrestore(instance->host_lock, flags); + spin_unlock_irqrestore(&instance->host_lock, flags); return IRQ_HANDLED; } diff --git a/drivers/scsi/a3000.c b/drivers/scsi/a3000.c index bf054dd7682b..dd0924572c0e 100644 --- a/drivers/scsi/a3000.c +++ b/drivers/scsi/a3000.c @@ -41,9 +41,9 @@ static irqreturn_t a3000_intr(int irq, void *data) if (!(status & ISTR_INT_P)) return IRQ_NONE; if (status & ISTR_INTS) { - spin_lock_irqsave(instance->host_lock, flags); + spin_lock_irqsave(&instance->host_lock, flags); wd33c93_intr(instance); - spin_unlock_irqrestore(instance->host_lock, flags); + spin_unlock_irqrestore(&instance->host_lock, flags); return IRQ_HANDLED; } pr_warn("Non-serviced A3000 SCSI-interrupt? ISTR = %02x\n", status); diff --git a/drivers/scsi/aacraid/Makefile b/drivers/scsi/aacraid/Makefile index 8f0eec682bb6..415e0ed5ad24 100644 --- a/drivers/scsi/aacraid/Makefile +++ b/drivers/scsi/aacraid/Makefile @@ -1,6 +1,8 @@ # SPDX-License-Identifier: GPL-2.0-only # Adaptec aacraid +CONTEXT_ANALYSIS := y + obj-$(CONFIG_SCSI_AACRAID) := aacraid.o aacraid-objs := linit.o aachba.o commctrl.o comminit.o commsup.o \ diff --git a/drivers/scsi/aacraid/commctrl.c b/drivers/scsi/aacraid/commctrl.c index bd82aeb679ae..ac73c7b6d7be 100644 --- a/drivers/scsi/aacraid/commctrl.c +++ b/drivers/scsi/aacraid/commctrl.c @@ -1043,6 +1043,7 @@ struct aac_reset_iop { }; static int aac_send_reset_adapter(struct aac_dev *dev, void __user *arg) + __must_hold(&dev->ioctl_mutex) { struct aac_reset_iop reset; int retval; diff --git a/drivers/scsi/aacraid/commsup.c b/drivers/scsi/aacraid/commsup.c index c4485629f792..0dba4406494a 100644 --- a/drivers/scsi/aacraid/commsup.c +++ b/drivers/scsi/aacraid/commsup.c @@ -475,6 +475,7 @@ int aac_queue_get(struct aac_dev * dev, u32 * index, u32 qid, struct hw_fib * hw int aac_fib_send(u16 command, struct fib *fibptr, unsigned long size, int priority, int wait, int reply, fib_callback callback, void *callback_data) + __context_unsafe(/*conditional locking*/) { struct aac_dev * dev = fibptr->dev; struct hw_fib * hw_fib = fibptr->hw_fib_va; @@ -698,6 +699,7 @@ int aac_fib_send(u16 command, struct fib *fibptr, unsigned long size, int aac_hba_send(u8 command, struct fib *fibptr, fib_callback callback, void *callback_data) + __context_unsafe(/*conditional locking*/) { struct aac_dev *dev = fibptr->dev; int wait; @@ -1466,6 +1468,7 @@ static void aac_schedule_bus_scan(struct aac_dev *aac) } static int _aac_reset_adapter(struct aac_dev *aac, int forced, u8 reset_type) + __context_unsafe(/*conditional locking*/) { int index, quirks; int retval; @@ -1487,7 +1490,7 @@ static int _aac_reset_adapter(struct aac_dev *aac, int forced, u8 reset_type) */ aac_adapter_disable_int(aac); if (aac->thread && aac->thread->pid != current->pid) { - spin_unlock_irq(host->host_lock); + spin_unlock_irq(&host->host_lock); kthread_stop(aac->thread); aac->thread = NULL; jafo = 1; @@ -1612,7 +1615,7 @@ static int _aac_reset_adapter(struct aac_dev *aac, int forced, u8 reset_type) } if (jafo) { - spin_lock_irq(host->host_lock); + spin_lock_irq(&host->host_lock); } return retval; } @@ -1644,11 +1647,11 @@ int aac_reset_adapter(struct aac_dev *aac, int forced, u8 reset_type) /* Quiesce build, flush cache, write through mode */ if (forced < 2) aac_send_shutdown(aac); - spin_lock_irqsave(host->host_lock, flagv); + spin_lock_irqsave(&host->host_lock, flagv); bled = forced ? forced : (aac_check_reset != 0 && aac_check_reset != 1); retval = _aac_reset_adapter(aac, bled, reset_type); - spin_unlock_irqrestore(host->host_lock, flagv); + spin_unlock_irqrestore(&host->host_lock, flagv); unblock_retval = scsi_host_unblock(host, SDEV_RUNNING); if (!retval) diff --git a/drivers/scsi/advansys.c b/drivers/scsi/advansys.c index 5cdbf2bdb13d..e6fa05ffc024 100644 --- a/drivers/scsi/advansys.c +++ b/drivers/scsi/advansys.c @@ -7072,9 +7072,9 @@ static int advansys_reset(struct scsi_cmnd *scp) ret = FAILED; break; } - spin_lock_irqsave(shost->host_lock, flags); + spin_lock_irqsave(&shost->host_lock, flags); AdvISR(adv_dvc); - spin_unlock_irqrestore(shost->host_lock, flags); + spin_unlock_irqrestore(&shost->host_lock, flags); } ASC_DBG(1, "ret %d\n", ret); @@ -7138,7 +7138,7 @@ static irqreturn_t advansys_interrupt(int irq, void *dev_id) unsigned long flags; ASC_DBG(2, "boardp 0x%p\n", boardp); - spin_lock_irqsave(shost->host_lock, flags); + spin_lock_irqsave(&shost->host_lock, flags); if (ASC_NARROW_BOARD(boardp)) { if (AscIsIntPending(shost->io_port)) { result = IRQ_HANDLED; @@ -7153,7 +7153,7 @@ static irqreturn_t advansys_interrupt(int irq, void *dev_id) ASC_STATS(shost, interrupt); } } - spin_unlock_irqrestore(shost->host_lock, flags); + spin_unlock_irqrestore(&shost->host_lock, flags); ASC_DBG(1, "end\n"); return result; diff --git a/drivers/scsi/aha152x.c b/drivers/scsi/aha152x.c index e3ccb6bb62c0..d751dc8093cc 100644 --- a/drivers/scsi/aha152x.c +++ b/drivers/scsi/aha152x.c @@ -636,7 +636,7 @@ static struct { /* setup & interrupt */ static irqreturn_t intr(int irq, void *dev_id); static void reset_ports(struct Scsi_Host *shpnt); -static void aha152x_error(struct Scsi_Host *shpnt, char *msg); +static void __noreturn aha152x_error(struct Scsi_Host *shpnt, char *msg); static void done(struct Scsi_Host *shpnt, unsigned char status_byte, unsigned char host_byte); @@ -2441,7 +2441,7 @@ static void is_complete(struct Scsi_Host *shpnt) /* * Dump the current driver status and panic */ -static void aha152x_error(struct Scsi_Host *shpnt, char *msg) +static void __noreturn aha152x_error(struct Scsi_Host *shpnt, char *msg) { shost_printk(KERN_EMERG, shpnt, "%s\n", msg); show_queues(shpnt); diff --git a/drivers/scsi/aha1542.c b/drivers/scsi/aha1542.c index 93dab19c1cb9..7ea38d509072 100644 --- a/drivers/scsi/aha1542.c +++ b/drivers/scsi/aha1542.c @@ -306,7 +306,7 @@ static irqreturn_t aha1542_interrupt(int irq, void *dev_id) #endif number_serviced = 0; - spin_lock_irqsave(sh->host_lock, flags); + spin_lock_irqsave(&sh->host_lock, flags); while (1) { flag = inb(INTRFLAGS(sh->io_port)); @@ -339,7 +339,7 @@ static irqreturn_t aha1542_interrupt(int irq, void *dev_id) } while (mbi != aha1542->aha1542_last_mbi_used); if (mb[mbi].status == 0) { - spin_unlock_irqrestore(sh->host_lock, flags); + spin_unlock_irqrestore(&sh->host_lock, flags); /* Hmm, no mail. Must have read it the last time around */ if (!number_serviced) shost_printk(KERN_WARNING, sh, "interrupt received, but no mail.\n"); @@ -367,7 +367,7 @@ static irqreturn_t aha1542_interrupt(int irq, void *dev_id) tmp_cmd = aha1542->int_cmds[mbo]; if (!tmp_cmd) { - spin_unlock_irqrestore(sh->host_lock, flags); + spin_unlock_irqrestore(&sh->host_lock, flags); shost_printk(KERN_WARNING, sh, "Unexpected interrupt\n"); shost_printk(KERN_WARNING, sh, "tarstat=%x, hastat=%x idlun=%x ccb#=%d\n", ccb[mbo].tarstat, ccb[mbo].hastat, ccb[mbo].idlun, mbo); @@ -461,7 +461,7 @@ static enum scsi_qc_status aha1542_queuecommand(struct Scsi_Host *sh, * is how the host adapter will scan for them */ - spin_lock_irqsave(sh->host_lock, flags); + spin_lock_irqsave(&sh->host_lock, flags); mbo = aha1542->aha1542_last_mbo_used + 1; if (mbo >= AHA1542_MAILBOXES) mbo = 0; @@ -518,7 +518,7 @@ static enum scsi_qc_status aha1542_queuecommand(struct Scsi_Host *sh, #endif mb[mbo].status = 1; aha1542_outb(cmd->device->host->io_port, CMD_START_SCSI); - spin_unlock_irqrestore(sh->host_lock, flags); + spin_unlock_irqrestore(&sh->host_lock, flags); return 0; } @@ -873,7 +873,7 @@ static int aha1542_dev_reset(struct scsi_cmnd *cmd) int mbo; struct ccb *ccb = aha1542->ccb; - spin_lock_irqsave(sh->host_lock, flags); + spin_lock_irqsave(&sh->host_lock, flags); mbo = aha1542->aha1542_last_mbo_used + 1; if (mbo >= AHA1542_MAILBOXES) mbo = 0; @@ -913,7 +913,7 @@ static int aha1542_dev_reset(struct scsi_cmnd *cmd) * target */ aha1542_outb(sh->io_port, CMD_START_SCSI); - spin_unlock_irqrestore(sh->host_lock, flags); + spin_unlock_irqrestore(&sh->host_lock, flags); scmd_printk(KERN_WARNING, cmd, "Trying device reset for target\n"); @@ -928,7 +928,7 @@ static int aha1542_reset(struct scsi_cmnd *cmd, u8 reset_cmd) unsigned long flags; int i; - spin_lock_irqsave(sh->host_lock, flags); + spin_lock_irqsave(&sh->host_lock, flags); /* * This does a scsi reset for all devices on the bus. * In principle, we could also reset the 1542 - should @@ -939,7 +939,7 @@ static int aha1542_reset(struct scsi_cmnd *cmd, u8 reset_cmd) if (!wait_mask(STATUS(cmd->device->host->io_port), STATMASK, IDLE, STST | DIAGF | INVDCMD | DF | CDF, 0)) { - spin_unlock_irqrestore(sh->host_lock, flags); + spin_unlock_irqrestore(&sh->host_lock, flags); return FAILED; } @@ -978,7 +978,7 @@ static int aha1542_reset(struct scsi_cmnd *cmd, u8 reset_cmd) } } - spin_unlock_irqrestore(sh->host_lock, flags); + spin_unlock_irqrestore(&sh->host_lock, flags); return SUCCESS; } diff --git a/drivers/scsi/aha1740.c b/drivers/scsi/aha1740.c index c435769359f2..b01701d139b9 100644 --- a/drivers/scsi/aha1740.c +++ b/drivers/scsi/aha1740.c @@ -225,7 +225,7 @@ static irqreturn_t aha1740_intr_handle(int irq, void *dev_id) if (!host) panic("aha1740.c: Irq from unknown host!\n"); - spin_lock_irqsave(host->host_lock, flags); + spin_lock_irqsave(&host->host_lock, flags); base = host->io_port; number_serviced = 0; edev = HOSTDATA(host)->edev; @@ -315,7 +315,7 @@ static irqreturn_t aha1740_intr_handle(int irq, void *dev_id) number_serviced++; } - spin_unlock_irqrestore(host->host_lock, flags); + spin_unlock_irqrestore(&host->host_lock, flags); return IRQ_RETVAL(handled); } @@ -353,7 +353,7 @@ static enum scsi_qc_status aha1740_queuecommand_lck(struct scsi_cmnd *SCpnt) #endif /* locate an available ecb */ - spin_lock_irqsave(SCpnt->device->host->host_lock, flags); + spin_lock_irqsave(&SCpnt->device->host->host_lock, flags); ecbno = host->last_ecb_used + 1; /* An optimization */ if (ecbno >= AHA1740_ECBS) ecbno = 0; @@ -372,7 +372,7 @@ static enum scsi_qc_status aha1740_queuecommand_lck(struct scsi_cmnd *SCpnt) doubles as reserved flag */ host->last_ecb_used = ecbno; - spin_unlock_irqrestore(SCpnt->device->host->host_lock, flags); + spin_unlock_irqrestore(&SCpnt->device->host->host_lock, flags); #ifdef DEBUG printk("Sending command (%d %x)...", ecbno, done); @@ -465,7 +465,7 @@ static enum scsi_qc_status aha1740_queuecommand_lck(struct scsi_cmnd *SCpnt) unsigned int base = SCpnt->device->host->io_port; DEB(printk("aha1740[%d] critical section\n",ecbno)); - spin_lock_irqsave(SCpnt->device->host->host_lock, flags); + spin_lock_irqsave(&SCpnt->device->host->host_lock, flags); for (loopcnt = 0; ; loopcnt++) { if (inb(G2STAT(base)) & G2STAT_MBXOUT) break; if (loopcnt == LOOPCNT_WARN) { @@ -485,7 +485,7 @@ static enum scsi_qc_status aha1740_queuecommand_lck(struct scsi_cmnd *SCpnt) panic("aha1740.c: attn wait failed!\n"); } outb(ATTN_START | (target & 7), ATTN(base)); /* Start it up */ - spin_unlock_irqrestore(SCpnt->device->host->host_lock, flags); + spin_unlock_irqrestore(&SCpnt->device->host->host_lock, flags); DEB(printk("aha1740[%d] request queued.\n",ecbno)); } else printk(KERN_ALERT "aha1740_queuecommand: done can't be NULL\n"); diff --git a/drivers/scsi/aic7xxx/Makefile b/drivers/scsi/aic7xxx/Makefile index 853c72a81ae0..2da370d3d904 100644 --- a/drivers/scsi/aic7xxx/Makefile +++ b/drivers/scsi/aic7xxx/Makefile @@ -5,6 +5,8 @@ # $Id: //depot/linux-aic79xx-2.5.0/drivers/scsi/aic7xxx/Makefile#8 $ # +CONTEXT_ANALYSIS := y + # Let kbuild descend into aicasm when cleaning subdir- += aicasm diff --git a/drivers/scsi/aic7xxx/aic79xx_osm.h b/drivers/scsi/aic7xxx/aic79xx_osm.h index 793fe19993a9..c6eb2b97e929 100644 --- a/drivers/scsi/aic7xxx/aic79xx_osm.h +++ b/drivers/scsi/aic7xxx/aic79xx_osm.h @@ -376,12 +376,14 @@ ahd_lockinit(struct ahd_softc *ahd) static inline void ahd_lock(struct ahd_softc *ahd, unsigned long *flags) + __acquires(&ahd->platform_data->spin_lock) { spin_lock_irqsave(&ahd->platform_data->spin_lock, *flags); } static inline void ahd_unlock(struct ahd_softc *ahd, unsigned long *flags) + __releases(&ahd->platform_data->spin_lock) { spin_unlock_irqrestore(&ahd->platform_data->spin_lock, *flags); } diff --git a/drivers/scsi/aic7xxx/aic7xxx_osm.h b/drivers/scsi/aic7xxx/aic7xxx_osm.h index 51d9f4de0734..5e78fe7d3f32 100644 --- a/drivers/scsi/aic7xxx/aic7xxx_osm.h +++ b/drivers/scsi/aic7xxx/aic7xxx_osm.h @@ -389,12 +389,14 @@ ahc_lockinit(struct ahc_softc *ahc) static inline void ahc_lock(struct ahc_softc *ahc, unsigned long *flags) + __acquires(&ahc->platform_data->spin_lock) { spin_lock_irqsave(&ahc->platform_data->spin_lock, *flags); } static inline void ahc_unlock(struct ahc_softc *ahc, unsigned long *flags) + __releases(&ahc->platform_data->spin_lock) { spin_unlock_irqrestore(&ahc->platform_data->spin_lock, *flags); } diff --git a/drivers/scsi/aic94xx/Makefile b/drivers/scsi/aic94xx/Makefile index db9fbe3a8e4c..4ab04ce6edf2 100644 --- a/drivers/scsi/aic94xx/Makefile +++ b/drivers/scsi/aic94xx/Makefile @@ -6,6 +6,8 @@ # Copyright (C) 2005 Luben Tuikov # +CONTEXT_ANALYSIS := y + ccflags-$(CONFIG_AIC94XX_DEBUG) := -DASD_DEBUG -DASD_ENTER_EXIT obj-$(CONFIG_SCSI_AIC94XX) += aic94xx.o diff --git a/drivers/scsi/arcmsr/Makefile b/drivers/scsi/arcmsr/Makefile index 9051f66cae36..6c12d36994da 100644 --- a/drivers/scsi/arcmsr/Makefile +++ b/drivers/scsi/arcmsr/Makefile @@ -2,6 +2,8 @@ # File: drivers/arcmsr/Makefile # Makefile for the ARECA PCI-X PCI-EXPRESS SATA RAID controllers SCSI driver. +CONTEXT_ANALYSIS := y + arcmsr-objs := arcmsr_attr.o arcmsr_hba.o obj-$(CONFIG_SCSI_ARCMSR) := arcmsr.o diff --git a/drivers/scsi/arm/eesox.c b/drivers/scsi/arm/eesox.c index 99be9da8757f..0cb1308eda4e 100644 --- a/drivers/scsi/arm/eesox.c +++ b/drivers/scsi/arm/eesox.c @@ -124,14 +124,14 @@ eesoxscsi_terminator_ctl(struct Scsi_Host *host, int on_off) struct eesoxscsi_info *info = (struct eesoxscsi_info *)host->hostdata; unsigned long flags; - spin_lock_irqsave(host->host_lock, flags); + spin_lock_irqsave(&host->host_lock, flags); if (on_off) info->control |= EESOX_TERM_ENABLE; else info->control &= ~EESOX_TERM_ENABLE; writeb(info->control, info->ctl_port); - spin_unlock_irqrestore(host->host_lock, flags); + spin_unlock_irqrestore(&host->host_lock, flags); } /* Prototype: void eesoxscsi_intr(irq, *dev_id, *regs) @@ -457,14 +457,14 @@ static ssize_t eesoxscsi_store_term(struct device *dev, struct device_attribute unsigned long flags; if (len > 1) { - spin_lock_irqsave(host->host_lock, flags); + spin_lock_irqsave(&host->host_lock, flags); if (buf[0] != '0') { info->control |= EESOX_TERM_ENABLE; } else { info->control &= ~EESOX_TERM_ENABLE; } writeb(info->control, info->ctl_port); - spin_unlock_irqrestore(host->host_lock, flags); + spin_unlock_irqrestore(&host->host_lock, flags); } return len; diff --git a/drivers/scsi/arm/fas216.c b/drivers/scsi/arm/fas216.c index fccfacaaf1d5..d0752c0bf425 100644 --- a/drivers/scsi/arm/fas216.c +++ b/drivers/scsi/arm/fas216.c @@ -2295,7 +2295,7 @@ static enum scsi_qc_status fas216_noqueue_command_lck(struct scsi_cmnd *SCpnt) * However, we must re-enable interrupts, or else we'll be * waiting forever. */ - spin_unlock_irq(info->host->host_lock); + spin_unlock_irq(&info->host->host_lock); while (!info->internal_done) { /* @@ -2307,13 +2307,13 @@ static enum scsi_qc_status fas216_noqueue_command_lck(struct scsi_cmnd *SCpnt) * to be some time (eg, disconnected). */ if (fas216_readb(info, REG_STAT) & STAT_INT) { - spin_lock_irq(info->host->host_lock); + spin_lock_irq(&info->host->host_lock); fas216_intr(info); - spin_unlock_irq(info->host->host_lock); + spin_unlock_irq(&info->host->host_lock); } } - spin_lock_irq(info->host->host_lock); + spin_lock_irq(&info->host->host_lock); scsi_done(SCpnt); @@ -2662,7 +2662,7 @@ int fas216_eh_host_reset(struct scsi_cmnd *SCpnt) { FAS216_Info *info = (FAS216_Info *)SCpnt->device->host->hostdata; - spin_lock_irq(info->host->host_lock); + spin_lock_irq(&info->host->host_lock); fas216_checkmagic(info); @@ -2679,9 +2679,9 @@ int fas216_eh_host_reset(struct scsi_cmnd *SCpnt) * IRQs if we sleep, but we must relock and disable * IRQs after the sleep. */ - spin_unlock_irq(info->host->host_lock); + spin_unlock_irq(&info->host->host_lock); msleep(50 * 1000/100); - spin_lock_irq(info->host->host_lock); + spin_lock_irq(&info->host->host_lock); /* * Release the SCSI reset. @@ -2690,7 +2690,7 @@ int fas216_eh_host_reset(struct scsi_cmnd *SCpnt) fas216_init_chip(info); - spin_unlock_irq(info->host->host_lock); + spin_unlock_irq(&info->host->host_lock); return SUCCESS; } @@ -2917,9 +2917,9 @@ int fas216_add(struct Scsi_Host *host, struct device *dev) /* * scsi standard says wait 250ms */ - spin_unlock_irq(info->host->host_lock); + spin_unlock_irq(&info->host->host_lock); msleep(100*1000/100); - spin_lock_irq(info->host->host_lock); + spin_lock_irq(&info->host->host_lock); fas216_writeb(info, REG_CNTL1, info->scsi.cfg[0]); fas216_readb(info, REG_INST); diff --git a/drivers/scsi/atp870u.c b/drivers/scsi/atp870u.c index 67459d81f479..c608d22ad2c6 100644 --- a/drivers/scsi/atp870u.c +++ b/drivers/scsi/atp870u.c @@ -225,7 +225,7 @@ static irqreturn_t atp870u_intr_handle(int irq, void *dev_id) /* * Issue more commands */ - spin_lock_irqsave(dev->host->host_lock, flags); + spin_lock_irqsave(&dev->host->host_lock, flags); if (((dev->quhd[c] != dev->quend[c]) || (dev->last_cmd[c] != 0xff)) && (dev->in_snd[c] == 0)) { @@ -234,7 +234,7 @@ static irqreturn_t atp870u_intr_handle(int irq, void *dev_id) #endif send_s870(dev,c); } - spin_unlock_irqrestore(dev->host->host_lock, flags); + spin_unlock_irqrestore(&dev->host->host_lock, flags); /* * Done */ @@ -511,7 +511,7 @@ static irqreturn_t atp870u_intr_handle(int irq, void *dev_id) */ scsi_dma_unmap(workreq); - spin_lock_irqsave(dev->host->host_lock, flags); + spin_lock_irqsave(&dev->host->host_lock, flags); scsi_done(workreq); #ifdef ED_DBGP printk("workreq->scsi_done\n"); @@ -521,7 +521,7 @@ static irqreturn_t atp870u_intr_handle(int irq, void *dev_id) */ dev->id[c][target_id].curr_req = NULL; dev->working[c]--; - spin_unlock_irqrestore(dev->host->host_lock, flags); + spin_unlock_irqrestore(&dev->host->host_lock, flags); /* * Take it back wide */ @@ -533,7 +533,7 @@ static irqreturn_t atp870u_intr_handle(int irq, void *dev_id) /* * If there is stuff to send and nothing going then send it */ - spin_lock_irqsave(dev->host->host_lock, flags); + spin_lock_irqsave(&dev->host->host_lock, flags); if (((dev->last_cmd[c] != 0xff) || (dev->quhd[c] != dev->quend[c])) && (dev->in_snd[c] == 0)) { @@ -542,7 +542,7 @@ static irqreturn_t atp870u_intr_handle(int irq, void *dev_id) #endif send_s870(dev,c); } - spin_unlock_irqrestore(dev->host->host_lock, flags); + spin_unlock_irqrestore(&dev->host->host_lock, flags); dev->in_int[c] = 0; return IRQ_HANDLED; } diff --git a/drivers/scsi/be2iscsi/Makefile b/drivers/scsi/be2iscsi/Makefile index 910885343a75..73d47c687007 100644 --- a/drivers/scsi/be2iscsi/Makefile +++ b/drivers/scsi/be2iscsi/Makefile @@ -4,6 +4,8 @@ # # +CONTEXT_ANALYSIS := y + obj-$(CONFIG_BE2ISCSI) += be2iscsi.o be2iscsi-y := be_iscsi.o be_main.o be_mgmt.o be_cmds.o diff --git a/drivers/scsi/be2iscsi/be_main.c b/drivers/scsi/be2iscsi/be_main.c index fd18d4d3d219..356ab9c0fb7c 100644 --- a/drivers/scsi/be2iscsi/be_main.c +++ b/drivers/scsi/be2iscsi/be_main.c @@ -1117,6 +1117,7 @@ static void be_complete_io(struct beiscsi_conn *beiscsi_conn, struct iscsi_task *task, struct common_sol_cqe *csol_cqe) + __must_hold(&beiscsi_conn->conn->session->back_lock) { struct beiscsi_io_task *io_task = task->dd_data; struct be_status_bhs *sts_bhs = @@ -1178,13 +1179,14 @@ be_complete_io(struct beiscsi_conn *beiscsi_conn, scsi_dma_unmap(io_task->scsi_cmnd); io_task->scsi_cmnd = NULL; } - iscsi_complete_scsi_task(task, exp_cmdsn, max_cmdsn); + iscsi_complete_scsi_task(conn->session, task, exp_cmdsn, max_cmdsn); } static void be_complete_logout(struct beiscsi_conn *beiscsi_conn, struct iscsi_task *task, struct common_sol_cqe *csol_cqe) + __must_hold(&beiscsi_conn->conn->session->back_lock) { struct iscsi_logout_rsp *hdr; struct beiscsi_io_task *io_task = task->dd_data; @@ -1205,13 +1207,14 @@ be_complete_logout(struct beiscsi_conn *beiscsi_conn, hdr->dlength[2] = 0; hdr->hlength = 0; hdr->itt = io_task->libiscsi_itt; - __iscsi_complete_pdu(conn, (struct iscsi_hdr *)hdr, NULL, 0); + __iscsi_complete_pdu(conn->session, conn, (struct iscsi_hdr *)hdr, NULL, 0); } static void be_complete_tmf(struct beiscsi_conn *beiscsi_conn, struct iscsi_task *task, struct common_sol_cqe *csol_cqe) + __must_hold(&beiscsi_conn->conn->session->back_lock) { struct iscsi_tm_rsp *hdr; struct iscsi_conn *conn = beiscsi_conn->conn; @@ -1226,7 +1229,7 @@ be_complete_tmf(struct beiscsi_conn *beiscsi_conn, csol_cqe->cmd_wnd - 1); hdr->itt = io_task->libiscsi_itt; - __iscsi_complete_pdu(conn, (struct iscsi_hdr *)hdr, NULL, 0); + __iscsi_complete_pdu(conn->session, conn, (struct iscsi_hdr *)hdr, NULL, 0); } static void @@ -1260,7 +1263,7 @@ hwi_complete_drvr_msgs(struct beiscsi_conn *beiscsi_conn, spin_lock_bh(&session->back_lock); task = pwrb_handle->pio_handle; if (task) - __iscsi_put_task(task); + __iscsi_put_task(session, task); spin_unlock_bh(&session->back_lock); } @@ -1268,6 +1271,7 @@ static void be_complete_nopin_resp(struct beiscsi_conn *beiscsi_conn, struct iscsi_task *task, struct common_sol_cqe *csol_cqe) + __must_hold(&beiscsi_conn->conn->session->back_lock) { struct iscsi_nopin *hdr; struct iscsi_conn *conn = beiscsi_conn->conn; @@ -1281,7 +1285,7 @@ be_complete_nopin_resp(struct beiscsi_conn *beiscsi_conn, hdr->opcode = ISCSI_OP_NOOP_IN; hdr->itt = io_task->libiscsi_itt; - __iscsi_complete_pdu(conn, (struct iscsi_hdr *)hdr, NULL, 0); + __iscsi_complete_pdu(conn->session, conn, (struct iscsi_hdr *)hdr, NULL, 0); } static void adapter_get_sol_cqe(struct beiscsi_hba *phba, @@ -1423,6 +1427,7 @@ static void hwi_complete_cmd(struct beiscsi_conn *beiscsi_conn, static unsigned int beiscsi_complete_pdu(struct beiscsi_conn *beiscsi_conn, struct pdu_base *phdr, void *pdata, unsigned int dlen) + __must_hold(&beiscsi_conn->conn->session->back_lock) { struct beiscsi_hba *phba = beiscsi_conn->phba; struct iscsi_conn *conn = beiscsi_conn->conn; @@ -1460,7 +1465,8 @@ beiscsi_complete_pdu(struct beiscsi_conn *beiscsi_conn, code); return 1; } - __iscsi_complete_pdu(conn, (struct iscsi_hdr *)phdr, pdata, dlen); + __iscsi_complete_pdu(conn->session, conn, (struct iscsi_hdr *)phdr, pdata, + dlen); return 0; } diff --git a/drivers/scsi/bfa/Makefile b/drivers/scsi/bfa/Makefile index 442fc3db8f1f..50c16fcfb01c 100644 --- a/drivers/scsi/bfa/Makefile +++ b/drivers/scsi/bfa/Makefile @@ -1,4 +1,7 @@ # SPDX-License-Identifier: GPL-2.0 + +CONTEXT_ANALYSIS := y + obj-$(CONFIG_SCSI_BFA_FC) := bfa.o bfa-y := bfad.o bfad_im.o bfad_attr.o bfad_debugfs.o bfad_bsg.o diff --git a/drivers/scsi/bfa/bfa_fcs.c b/drivers/scsi/bfa/bfa_fcs.c index 9b57312f43f5..3e5d3a141f32 100644 --- a/drivers/scsi/bfa/bfa_fcs.c +++ b/drivers/scsi/bfa/bfa_fcs.c @@ -760,53 +760,16 @@ bfa_fcs_fabric_psymb_init(struct bfa_fcs_fabric_s *fabric) bfa_ioc_get_adapter_model(&fabric->fcs->bfa->ioc, model); - /* Model name/number */ - strscpy(port_cfg->sym_name.symname, model, - BFA_SYMNAME_MAXLEN); - strlcat(port_cfg->sym_name.symname, BFA_FCS_PORT_SYMBNAME_SEPARATOR, - BFA_SYMNAME_MAXLEN); - - /* Driver Version */ - strlcat(port_cfg->sym_name.symname, driver_info->version, - BFA_SYMNAME_MAXLEN); - strlcat(port_cfg->sym_name.symname, BFA_FCS_PORT_SYMBNAME_SEPARATOR, - BFA_SYMNAME_MAXLEN); - - /* Host machine name */ - strlcat(port_cfg->sym_name.symname, - driver_info->host_machine_name, - BFA_SYMNAME_MAXLEN); - strlcat(port_cfg->sym_name.symname, BFA_FCS_PORT_SYMBNAME_SEPARATOR, - BFA_SYMNAME_MAXLEN); - - /* - * Host OS Info : - * If OS Patch Info is not there, do not truncate any bytes from the - * OS name string and instead copy the entire OS info string (64 bytes). - */ - if (driver_info->host_os_patch[0] == '\0') { - strlcat(port_cfg->sym_name.symname, - driver_info->host_os_name, - BFA_SYMNAME_MAXLEN); - strlcat(port_cfg->sym_name.symname, - BFA_FCS_PORT_SYMBNAME_SEPARATOR, - BFA_SYMNAME_MAXLEN); - } else { - strlcat(port_cfg->sym_name.symname, - driver_info->host_os_name, - BFA_SYMNAME_MAXLEN); - strlcat(port_cfg->sym_name.symname, - BFA_FCS_PORT_SYMBNAME_SEPARATOR, - BFA_SYMNAME_MAXLEN); - - /* Append host OS Patch Info */ - strlcat(port_cfg->sym_name.symname, - driver_info->host_os_patch, - BFA_SYMNAME_MAXLEN); - } - - /* null terminate */ - port_cfg->sym_name.symname[BFA_SYMNAME_MAXLEN - 1] = 0; + snprintf(port_cfg->sym_name.symname, BFA_SYMNAME_MAXLEN, + "%s" BFA_FCS_PORT_SYMBNAME_SEPARATOR + "%s" BFA_FCS_PORT_SYMBNAME_SEPARATOR + "%s" BFA_FCS_PORT_SYMBNAME_SEPARATOR + "%s" BFA_FCS_PORT_SYMBNAME_SEPARATOR + "%s", + model, driver_info->version, + driver_info->host_machine_name, + driver_info->host_os_name, + driver_info->host_os_patch); } /* @@ -821,30 +784,13 @@ bfa_fcs_fabric_nsymb_init(struct bfa_fcs_fabric_s *fabric) bfa_ioc_get_adapter_model(&fabric->fcs->bfa->ioc, model); - /* Model name/number */ - strscpy(port_cfg->node_sym_name.symname, model, - BFA_SYMNAME_MAXLEN); - strlcat(port_cfg->node_sym_name.symname, - BFA_FCS_PORT_SYMBNAME_SEPARATOR, - BFA_SYMNAME_MAXLEN); - - /* Driver Version */ - strlcat(port_cfg->node_sym_name.symname, (char *)driver_info->version, - BFA_SYMNAME_MAXLEN); - strlcat(port_cfg->node_sym_name.symname, - BFA_FCS_PORT_SYMBNAME_SEPARATOR, - BFA_SYMNAME_MAXLEN); - - /* Host machine name */ - strlcat(port_cfg->node_sym_name.symname, - driver_info->host_machine_name, - BFA_SYMNAME_MAXLEN); - strlcat(port_cfg->node_sym_name.symname, - BFA_FCS_PORT_SYMBNAME_SEPARATOR, - BFA_SYMNAME_MAXLEN); - - /* null terminate */ - port_cfg->node_sym_name.symname[BFA_SYMNAME_MAXLEN - 1] = 0; + /* Model name/number, Driver Version, Host machine name */ + snprintf(port_cfg->node_sym_name.symname, BFA_SYMNAME_MAXLEN, + "%s" BFA_FCS_PORT_SYMBNAME_SEPARATOR + "%s" BFA_FCS_PORT_SYMBNAME_SEPARATOR + "%s" BFA_FCS_PORT_SYMBNAME_SEPARATOR, + model, (char *)driver_info->version, + driver_info->host_machine_name); } /* diff --git a/drivers/scsi/bfa/bfad_bsg.c b/drivers/scsi/bfa/bfad_bsg.c index 292bc9aa43f1..143a3913c650 100644 --- a/drivers/scsi/bfa/bfad_bsg.c +++ b/drivers/scsi/bfa/bfad_bsg.c @@ -2552,7 +2552,7 @@ static void bfad_reset_sdev_bflags(struct bfad_im_port_s *im_port, struct scsi_device *sdev; unsigned long flags; - spin_lock_irqsave(im_port->shost->host_lock, flags); + spin_lock_irqsave(&im_port->shost->host_lock, flags); list_for_each_entry(itnim, &im_port->itnim_mapped_list, list_entry) { sdev = __scsi_device_lookup(im_port->shost, itnim->channel, itnim->scsi_tgt_id, 0); @@ -2563,7 +2563,7 @@ static void bfad_reset_sdev_bflags(struct bfad_im_port_s *im_port, sdev->sdev_bflags &= ~scan_flags; } } - spin_unlock_irqrestore(im_port->shost->host_lock, flags); + spin_unlock_irqrestore(&im_port->shost->host_lock, flags); } /* Function to reset the LUN SCAN mode */ diff --git a/drivers/scsi/bnx2fc/Makefile b/drivers/scsi/bnx2fc/Makefile index 1d72e279a97d..3feb6b4dae64 100644 --- a/drivers/scsi/bnx2fc/Makefile +++ b/drivers/scsi/bnx2fc/Makefile @@ -1,4 +1,7 @@ # SPDX-License-Identifier: GPL-2.0-only + +CONTEXT_ANALYSIS := y + obj-$(CONFIG_SCSI_BNX2X_FCOE) += bnx2fc.o bnx2fc-y := bnx2fc_els.o bnx2fc_fcoe.o bnx2fc_hwi.o bnx2fc_io.o bnx2fc_tgt.o \ diff --git a/drivers/scsi/bnx2fc/bnx2fc.h b/drivers/scsi/bnx2fc/bnx2fc.h index 8c8968ec8cb4..2fc80c607437 100644 --- a/drivers/scsi/bnx2fc/bnx2fc.h +++ b/drivers/scsi/bnx2fc/bnx2fc.h @@ -423,7 +423,8 @@ struct bnx2fc_cmd { struct scsi_cmnd *sc_cmd; struct bnx2fc_cmd_mgr *cmd_mgr; struct bnx2fc_mp_req mp_req; - void (*cb_func)(struct bnx2fc_els_cb_arg *cb_arg); + void (*cb_func)(struct bnx2fc_rport *tgt, + struct bnx2fc_els_cb_arg *cb_arg); struct bnx2fc_els_cb_arg *cb_arg; struct delayed_work timeout_work; /* timer for ULP timeouts */ struct completion abts_done; @@ -592,9 +593,11 @@ int bnx2fc_send_stat_req(struct bnx2fc_hba *hba); int bnx2fc_post_io_req(struct bnx2fc_rport *tgt, struct bnx2fc_cmd *io_req); int bnx2fc_send_rec(struct bnx2fc_cmd *orig_io_req); int bnx2fc_send_srr(struct bnx2fc_cmd *orig_io_req, u32 offset, u8 r_ctl); -void bnx2fc_process_seq_cleanup_compl(struct bnx2fc_cmd *seq_clnup_req, +void bnx2fc_process_seq_cleanup_compl(struct bnx2fc_rport *tgt, + struct bnx2fc_cmd *seq_clnp_req, struct fcoe_task_ctx_entry *task, - u8 rx_state); + u8 rx_state) + __must_hold(&tgt->tgt_lock); int bnx2fc_initiate_seq_cleanup(struct bnx2fc_cmd *orig_io_req, u32 offset, enum fc_rctl r_ctl); diff --git a/drivers/scsi/bnx2fc/bnx2fc_els.c b/drivers/scsi/bnx2fc/bnx2fc_els.c index 749e30aaf926..bca28acaa1a2 100644 --- a/drivers/scsi/bnx2fc/bnx2fc_els.c +++ b/drivers/scsi/bnx2fc/bnx2fc_els.c @@ -22,10 +22,12 @@ static void bnx2fc_flogi_resp(struct fc_seq *seq, struct fc_frame *fp, void *arg); static int bnx2fc_initiate_els(struct bnx2fc_rport *tgt, unsigned int op, void *data, u32 data_len, - void (*cb_func)(struct bnx2fc_els_cb_arg *cb_arg), + void (*cb_func)(struct bnx2fc_rport *tgt, + struct bnx2fc_els_cb_arg *cb_arg), struct bnx2fc_els_cb_arg *cb_arg, u32 timer_msec); -static void bnx2fc_rrq_compl(struct bnx2fc_els_cb_arg *cb_arg) +static void bnx2fc_rrq_compl(struct bnx2fc_rport *tgt, + struct bnx2fc_els_cb_arg *cb_arg) { struct bnx2fc_cmd *orig_io_req; struct bnx2fc_cmd *rrq_req; @@ -119,10 +121,10 @@ int bnx2fc_send_rrq(struct bnx2fc_cmd *aborted_io_req) return rc; } -static void bnx2fc_l2_els_compl(struct bnx2fc_els_cb_arg *cb_arg) +static void bnx2fc_l2_els_compl(struct bnx2fc_rport *tgt, + struct bnx2fc_els_cb_arg *cb_arg) { struct bnx2fc_cmd *els_req; - struct bnx2fc_rport *tgt; struct bnx2fc_mp_req *mp_req; struct fc_frame_header *fc_hdr; unsigned char *buf; @@ -150,7 +152,6 @@ static void bnx2fc_l2_els_compl(struct bnx2fc_els_cb_arg *cb_arg) goto free_arg; } - tgt = els_req->tgt; mp_req = &(els_req->mp_req); fc_hdr = &(mp_req->resp_fc_hdr); resp_len = mp_req->resp_len; @@ -262,7 +263,9 @@ int bnx2fc_send_rls(struct bnx2fc_rport *tgt, struct fc_frame *fp) return rc; } -static void bnx2fc_srr_compl(struct bnx2fc_els_cb_arg *cb_arg) +static void bnx2fc_srr_compl(struct bnx2fc_rport *tgt, + struct bnx2fc_els_cb_arg *cb_arg) + __must_hold(&tgt->tgt_lock) { struct bnx2fc_mp_req *mp_req; struct fc_frame_header *fc_hdr, *fh; @@ -296,7 +299,6 @@ static void bnx2fc_srr_compl(struct bnx2fc_els_cb_arg *cb_arg) } orig_io_req->srr_retry++; if (orig_io_req->srr_retry <= SRR_RETRY_COUNT) { - struct bnx2fc_rport *tgt = orig_io_req->tgt; spin_unlock_bh(&tgt->tgt_lock); rc = bnx2fc_send_srr(orig_io_req, orig_io_req->srr_offset, @@ -372,7 +374,9 @@ static void bnx2fc_srr_compl(struct bnx2fc_els_cb_arg *cb_arg) kref_put(&orig_io_req->refcount, bnx2fc_cmd_release); } -static void bnx2fc_rec_compl(struct bnx2fc_els_cb_arg *cb_arg) +static void bnx2fc_rec_compl(struct bnx2fc_rport *tgt, + struct bnx2fc_els_cb_arg *cb_arg) + __must_hold(&tgt->tgt_lock) { struct bnx2fc_cmd *orig_io_req, *new_io_req; struct bnx2fc_cmd *rec_req; @@ -380,7 +384,6 @@ static void bnx2fc_rec_compl(struct bnx2fc_els_cb_arg *cb_arg) struct fc_frame_header *fc_hdr, *fh; struct fc_els_ls_rjt *rjt; struct fc_els_rec_acc *acc; - struct bnx2fc_rport *tgt; struct fcoe_err_report_entry *err_entry; struct scsi_cmnd *sc_cmd; enum fc_rctl r_ctl; @@ -399,7 +402,6 @@ static void bnx2fc_rec_compl(struct bnx2fc_els_cb_arg *cb_arg) rec_req = cb_arg->io_req; orig_io_req = cb_arg->aborted_io_req; BNX2FC_IO_DBG(rec_req, "rec_compl: orig xid = 0x%x", orig_io_req->xid); - tgt = orig_io_req->tgt; /* Handle REC timeout case */ if (test_and_clear_bit(BNX2FC_FLAG_ELS_TIMEOUT, &rec_req->req_flags)) { @@ -669,7 +671,8 @@ int bnx2fc_send_srr(struct bnx2fc_cmd *orig_io_req, u32 offset, u8 r_ctl) static int bnx2fc_initiate_els(struct bnx2fc_rport *tgt, unsigned int op, void *data, u32 data_len, - void (*cb_func)(struct bnx2fc_els_cb_arg *cb_arg), + void (*cb_func)(struct bnx2fc_rport *tgt, + struct bnx2fc_els_cb_arg *cb_arg), struct bnx2fc_els_cb_arg *cb_arg, u32 timer_msec) { struct fcoe_port *port = tgt->port; @@ -847,7 +850,7 @@ void bnx2fc_process_els_compl(struct bnx2fc_cmd *els_req, /* Parse ELS response */ if ((els_req->cb_func) && (els_req->cb_arg)) { - els_req->cb_func(els_req->cb_arg); + els_req->cb_func(els_req->tgt, els_req->cb_arg); els_req->cb_arg = NULL; } diff --git a/drivers/scsi/bnx2fc/bnx2fc_hwi.c b/drivers/scsi/bnx2fc/bnx2fc_hwi.c index a5ecb87d5b2d..833ec0e35731 100644 --- a/drivers/scsi/bnx2fc/bnx2fc_hwi.c +++ b/drivers/scsi/bnx2fc/bnx2fc_hwi.c @@ -943,7 +943,7 @@ void bnx2fc_process_cq_compl(struct bnx2fc_rport *tgt, u16 wqe, case BNX2FC_SEQ_CLEANUP: BNX2FC_IO_DBG(io_req, "cq_compl(0x%x) - seq cleanup resp\n", io_req->xid); - bnx2fc_process_seq_cleanup_compl(io_req, task, rx_state); + bnx2fc_process_seq_cleanup_compl(tgt, io_req, task, rx_state); kref_put(&io_req->refcount, bnx2fc_cmd_release); break; diff --git a/drivers/scsi/bnx2fc/bnx2fc_io.c b/drivers/scsi/bnx2fc/bnx2fc_io.c index 9c7a541a4523..60346d77cb6d 100644 --- a/drivers/scsi/bnx2fc/bnx2fc_io.c +++ b/drivers/scsi/bnx2fc/bnx2fc_io.c @@ -142,7 +142,7 @@ static void bnx2fc_cmd_timeout(struct work_struct *work) set_bit(BNX2FC_FLAG_ELS_TIMEOUT, &io_req->req_flags); if ((io_req->cb_func) && (io_req->cb_arg)) { - io_req->cb_func(io_req->cb_arg); + io_req->cb_func(tgt, io_req->cb_arg); io_req->cb_arg = NULL; } } @@ -1079,10 +1079,10 @@ int bnx2fc_eh_device_reset(struct scsi_cmnd *sc_cmd) FCP_TMF_LUN_RESET); } -static int bnx2fc_abts_cleanup(struct bnx2fc_cmd *io_req) +static int bnx2fc_abts_cleanup(struct bnx2fc_rport *tgt, + struct bnx2fc_cmd *io_req) __must_hold(&tgt->tgt_lock) { - struct bnx2fc_rport *tgt = io_req->tgt; unsigned int time_left; init_completion(&io_req->cleanup_done); @@ -1212,7 +1212,7 @@ int bnx2fc_eh_abort(struct scsi_cmnd *sc_cmd) * cleanup the command and return that I/O was successfully * aborted. */ - bnx2fc_abts_cleanup(io_req); + bnx2fc_abts_cleanup(tgt, io_req); /* This only occurs when an task abort was requested while ABTS is in progress. Setting the IO_CLEANUP flag will skip the RRQ process in the case when the fw generated SCSI_CMD cmpl @@ -1262,7 +1262,7 @@ int bnx2fc_eh_abort(struct scsi_cmnd *sc_cmd) * Cleanup firmware residuals before returning control back * to SCSI ML. */ - rc = bnx2fc_abts_cleanup(io_req); + rc = bnx2fc_abts_cleanup(tgt, io_req); goto done; } else { /* @@ -1282,16 +1282,17 @@ int bnx2fc_eh_abort(struct scsi_cmnd *sc_cmd) return rc; } -void bnx2fc_process_seq_cleanup_compl(struct bnx2fc_cmd *seq_clnp_req, +void bnx2fc_process_seq_cleanup_compl(struct bnx2fc_rport *tgt, + struct bnx2fc_cmd *seq_clnp_req, struct fcoe_task_ctx_entry *task, u8 rx_state) + __must_hold(&tgt->tgt_lock) { struct bnx2fc_els_cb_arg *cb_arg = seq_clnp_req->cb_arg; struct bnx2fc_cmd *orig_io_req = cb_arg->aborted_io_req; u32 offset = cb_arg->offset; enum fc_rctl r_ctl = cb_arg->r_ctl; int rc = 0; - struct bnx2fc_rport *tgt = orig_io_req->tgt; BNX2FC_IO_DBG(orig_io_req, "Entered process_cleanup_compl xid = 0x%x" "cmd_type = %d\n", diff --git a/drivers/scsi/bnx2fc/bnx2fc_tgt.c b/drivers/scsi/bnx2fc/bnx2fc_tgt.c index 77dcdfc412b1..e6942cb6cae6 100644 --- a/drivers/scsi/bnx2fc/bnx2fc_tgt.c +++ b/drivers/scsi/bnx2fc/bnx2fc_tgt.c @@ -224,7 +224,7 @@ void bnx2fc_flush_active_ios(struct bnx2fc_rport *tgt) bnx2fc_cmd_release); /* drop timer hold */ if ((io_req->cb_func) && (io_req->cb_arg)) { - io_req->cb_func(io_req->cb_arg); + io_req->cb_func(tgt, io_req->cb_arg); io_req->cb_arg = NULL; } diff --git a/drivers/scsi/bnx2i/Makefile b/drivers/scsi/bnx2i/Makefile index 25378671bb1e..2d8e8f0fdd29 100644 --- a/drivers/scsi/bnx2i/Makefile +++ b/drivers/scsi/bnx2i/Makefile @@ -1,4 +1,7 @@ # SPDX-License-Identifier: GPL-2.0-only + +CONTEXT_ANALYSIS := y + bnx2i-y := bnx2i_init.o bnx2i_hwi.o bnx2i_iscsi.o bnx2i_sysfs.o obj-$(CONFIG_SCSI_BNX2_ISCSI) += bnx2i.o diff --git a/drivers/scsi/bnx2i/bnx2i_hwi.c b/drivers/scsi/bnx2i/bnx2i_hwi.c index d24cc2c795d6..c22f1c981d02 100644 --- a/drivers/scsi/bnx2i/bnx2i_hwi.c +++ b/drivers/scsi/bnx2i/bnx2i_hwi.c @@ -383,6 +383,7 @@ int bnx2i_send_iscsi_tmf(struct bnx2i_conn *bnx2i_conn, struct iscsi_task *mtask) { struct iscsi_conn *conn = bnx2i_conn->cls_conn->dd_data; + struct iscsi_session *session = conn->session; struct iscsi_tm *tmfabort_hdr; struct scsi_cmnd *ref_sc; struct iscsi_task *ctask; @@ -404,7 +405,12 @@ int bnx2i_send_iscsi_tmf(struct bnx2i_conn *bnx2i_conn, switch (tmfabort_hdr->flags & ISCSI_FLAG_TM_FUNC_MASK) { case ISCSI_TM_FUNC_ABORT_TASK: case ISCSI_TM_FUNC_TASK_REASSIGN: - ctask = iscsi_itt_to_task(conn, tmfabort_hdr->rtt); + /* + * TODO: hold session->back_lock around the iscsi_itt_to_task() + * call below. + */ + __assume_ctx_lock(&session->back_lock); + ctask = iscsi_itt_to_task(session, conn, tmfabort_hdr->rtt); if (!ctask || !ctask->sc) /* * the iscsi layer must have completed the cmd while @@ -1347,7 +1353,7 @@ int bnx2i_process_scsi_cmd_resp(struct iscsi_session *session, resp_cqe = (struct bnx2i_cmd_response *)cqe; spin_lock_bh(&session->back_lock); - task = iscsi_itt_to_task(conn, + task = iscsi_itt_to_task(session, conn, resp_cqe->itt & ISCSI_CMD_RESPONSE_INDEX); if (!task) goto fail; @@ -1414,7 +1420,7 @@ int bnx2i_process_scsi_cmd_resp(struct iscsi_session *session, } done: - __iscsi_complete_pdu(conn, (struct iscsi_hdr *)hdr, + __iscsi_complete_pdu(session, conn, (struct iscsi_hdr *)hdr, conn->data, datalen); fail: spin_unlock_bh(&session->back_lock); @@ -1443,7 +1449,7 @@ static int bnx2i_process_login_resp(struct iscsi_session *session, login = (struct bnx2i_login_response *) cqe; spin_lock(&session->back_lock); - task = iscsi_itt_to_task(conn, + task = iscsi_itt_to_task(session, conn, login->itt & ISCSI_LOGIN_RESPONSE_INDEX); if (!task) goto done; @@ -1481,7 +1487,7 @@ static int bnx2i_process_login_resp(struct iscsi_session *session, } } - __iscsi_complete_pdu(conn, (struct iscsi_hdr *)resp_hdr, + __iscsi_complete_pdu(session, conn, (struct iscsi_hdr *)resp_hdr, bnx2i_conn->gen_pdu.resp_buf, bnx2i_conn->gen_pdu.resp_wr_ptr - bnx2i_conn->gen_pdu.resp_buf); done: @@ -1511,7 +1517,8 @@ static int bnx2i_process_text_resp(struct iscsi_session *session, text = (struct bnx2i_text_response *) cqe; spin_lock(&session->back_lock); - task = iscsi_itt_to_task(conn, text->itt & ISCSI_LOGIN_RESPONSE_INDEX); + task = iscsi_itt_to_task(session, conn, + text->itt & ISCSI_LOGIN_RESPONSE_INDEX); if (!task) goto done; @@ -1541,7 +1548,7 @@ static int bnx2i_process_text_resp(struct iscsi_session *session, bnx2i_conn->gen_pdu.resp_wr_ptr++; } } - __iscsi_complete_pdu(conn, (struct iscsi_hdr *)resp_hdr, + __iscsi_complete_pdu(session, conn, (struct iscsi_hdr *)resp_hdr, bnx2i_conn->gen_pdu.resp_buf, bnx2i_conn->gen_pdu.resp_wr_ptr - bnx2i_conn->gen_pdu.resp_buf); @@ -1570,7 +1577,7 @@ static int bnx2i_process_tmf_resp(struct iscsi_session *session, tmf_cqe = (struct bnx2i_tmf_response *)cqe; spin_lock(&session->back_lock); - task = iscsi_itt_to_task(conn, + task = iscsi_itt_to_task(session, conn, tmf_cqe->itt & ISCSI_TMF_RESPONSE_INDEX); if (!task) goto done; @@ -1583,7 +1590,7 @@ static int bnx2i_process_tmf_resp(struct iscsi_session *session, resp_hdr->itt = task->hdr->itt; resp_hdr->response = tmf_cqe->response; - __iscsi_complete_pdu(conn, (struct iscsi_hdr *)resp_hdr, NULL, 0); + __iscsi_complete_pdu(session, conn, (struct iscsi_hdr *)resp_hdr, NULL, 0); done: spin_unlock(&session->back_lock); return 0; @@ -1609,7 +1616,7 @@ static int bnx2i_process_logout_resp(struct iscsi_session *session, logout = (struct bnx2i_logout_response *) cqe; spin_lock(&session->back_lock); - task = iscsi_itt_to_task(conn, + task = iscsi_itt_to_task(session, conn, logout->itt & ISCSI_LOGOUT_RESPONSE_INDEX); if (!task) goto done; @@ -1628,7 +1635,7 @@ static int bnx2i_process_logout_resp(struct iscsi_session *session, resp_hdr->t2wait = cpu_to_be32(logout->time_to_wait); resp_hdr->t2retain = cpu_to_be32(logout->time_to_retain); - __iscsi_complete_pdu(conn, (struct iscsi_hdr *)resp_hdr, NULL, 0); + __iscsi_complete_pdu(session, conn, (struct iscsi_hdr *)resp_hdr, NULL, 0); bnx2i_conn->ep->state = EP_STATE_LOGOUT_RESP_RCVD; done: @@ -1654,10 +1661,10 @@ static void bnx2i_process_nopin_local_cmpl(struct iscsi_session *session, nop_in = (struct bnx2i_nop_in_msg *)cqe; spin_lock(&session->back_lock); - task = iscsi_itt_to_task(conn, + task = iscsi_itt_to_task(session, conn, nop_in->itt & ISCSI_NOP_IN_MSG_INDEX); if (task) - __iscsi_put_task(task); + __iscsi_put_task(session, task); spin_unlock(&session->back_lock); } @@ -1713,7 +1720,7 @@ static int bnx2i_process_nopin_mesg(struct iscsi_session *session, } /* this is a response to one of our nop-outs */ - task = iscsi_itt_to_task(conn, + task = iscsi_itt_to_task(session, conn, (itt_t) (nop_in->itt & ISCSI_NOP_IN_MSG_INDEX)); if (task) { hdr->flags = ISCSI_FLAG_CMD_FINAL; @@ -1722,7 +1729,7 @@ static int bnx2i_process_nopin_mesg(struct iscsi_session *session, memcpy(&hdr->lun, nop_in->lun, 8); } done: - __iscsi_complete_pdu(conn, (struct iscsi_hdr *)hdr, NULL, 0); + __iscsi_complete_pdu(session, conn, (struct iscsi_hdr *)hdr, NULL, 0); spin_unlock(&session->back_lock); return tgt_async_nop; @@ -1773,7 +1780,7 @@ static void bnx2i_process_async_mesg(struct iscsi_session *session, resp_hdr->param2 = cpu_to_be16(async_cqe->param2); resp_hdr->param3 = cpu_to_be16(async_cqe->param3); - __iscsi_complete_pdu(bnx2i_conn->cls_conn->dd_data, + __iscsi_complete_pdu(session, bnx2i_conn->cls_conn->dd_data, (struct iscsi_hdr *)resp_hdr, NULL, 0); spin_unlock(&session->back_lock); } @@ -1811,7 +1818,7 @@ static void bnx2i_process_reject_mesg(struct iscsi_session *session, hdr->max_cmdsn = cpu_to_be32(reject->max_cmd_sn); hdr->exp_cmdsn = cpu_to_be32(reject->exp_cmd_sn); hdr->ffffffff = cpu_to_be32(RESERVED_ITT); - __iscsi_complete_pdu(conn, (struct iscsi_hdr *)hdr, conn->data, + __iscsi_complete_pdu(session, conn, (struct iscsi_hdr *)hdr, conn->data, reject->data_length); spin_unlock(&session->back_lock); } @@ -1834,7 +1841,7 @@ static void bnx2i_process_cmd_cleanup_resp(struct iscsi_session *session, cmd_clean_rsp = (struct bnx2i_cleanup_response *)cqe; spin_lock(&session->back_lock); - task = iscsi_itt_to_task(conn, + task = iscsi_itt_to_task(session, conn, cmd_clean_rsp->itt & ISCSI_CLEANUP_RESPONSE_INDEX); if (!task) printk(KERN_ALERT "bnx2i: cmd clean ITT %x not active\n", @@ -1908,7 +1915,7 @@ static int bnx2i_queue_scsi_cmd_resp(struct iscsi_session *session, int rc = 0; spin_lock(&session->back_lock); - task = iscsi_itt_to_task(bnx2i_conn->cls_conn->dd_data, + task = iscsi_itt_to_task(session, bnx2i_conn->cls_conn->dd_data, cqe->itt & ISCSI_CMD_RESPONSE_INDEX); if (!task || !task->sc) { spin_unlock(&session->back_lock); diff --git a/drivers/scsi/bnx2i/bnx2i_iscsi.c b/drivers/scsi/bnx2i/bnx2i_iscsi.c index 6c80e5b514fd..c868eada72c3 100644 --- a/drivers/scsi/bnx2i/bnx2i_iscsi.c +++ b/drivers/scsi/bnx2i/bnx2i_iscsi.c @@ -1154,6 +1154,7 @@ static void bnx2i_cpy_scsi_cdb(struct scsi_cmnd *sc, struct bnx2i_cmd *cmd) } static void bnx2i_cleanup_task(struct iscsi_task *task) + __must_hold(&task->conn->session->back_lock) { struct iscsi_conn *conn = task->conn; struct bnx2i_conn *bnx2i_conn = conn->dd_data; diff --git a/drivers/scsi/ch.c b/drivers/scsi/ch.c index 4010fdbf813c..b2c9fb71c9e0 100644 --- a/drivers/scsi/ch.c +++ b/drivers/scsi/ch.c @@ -112,7 +112,6 @@ typedef struct { int minor; char name[8]; struct scsi_device *device; - struct scsi_device **dt; /* ptrs to data transfer elements */ u_int firsts[CH_TYPES]; u_int counts[CH_TYPES]; u_int voltags; @@ -123,38 +122,32 @@ static DEFINE_IDR(ch_index_idr); static DEFINE_SPINLOCK(ch_index_lock); static const struct { - unsigned char sense; - unsigned char asc; - unsigned char ascq; - int errno; + u8 sense_key; + u16 sense_code; + int errno; } ch_err[] = { /* Just filled in what looks right. Hav'nt checked any standard paper for these errno assignments, so they may be wrong... */ { - .sense = ILLEGAL_REQUEST, - .asc = 0x21, - .ascq = 0x01, - .errno = EBADSLT, /* Invalid element address */ + .sense_key = ILLEGAL_REQUEST, + .sense_code = INVALID_ELEMENT_ADDRESS, + .errno = EBADSLT, },{ - .sense = ILLEGAL_REQUEST, - .asc = 0x28, - .ascq = 0x01, - .errno = EBADE, /* Import or export element accessed */ + .sense_key = ILLEGAL_REQUEST, + .sense_code = IMPORT_OR_EXPORT_ELEMENT_ACCESSED, + .errno = EBADE, },{ - .sense = ILLEGAL_REQUEST, - .asc = 0x3B, - .ascq = 0x0D, - .errno = EXFULL, /* Medium destination element full */ + .sense_key = ILLEGAL_REQUEST, + .sense_code = MEDIUM_DESTINATION_ELEMENT_FULL, + .errno = EXFULL, },{ - .sense = ILLEGAL_REQUEST, - .asc = 0x3B, - .ascq = 0x0E, - .errno = EBADE, /* Medium source element empty */ + .sense_key = ILLEGAL_REQUEST, + .sense_code = MEDIUM_SOURCE_ELEMENT_EMPTY, + .errno = EBADE, },{ - .sense = ILLEGAL_REQUEST, - .asc = 0x20, - .ascq = 0x00, - .errno = EBADRQC, /* Invalid command operation code */ + .sense_key = ILLEGAL_REQUEST, + .sense_code = INVALID_COMMAND_OP_CODE, + .errno = EBADRQC, },{ /* end of list */ } @@ -167,12 +160,10 @@ static int ch_find_errno(struct scsi_sense_hdr *sshdr) int i,errno = 0; /* Check to see if additional sense information is available */ - if (scsi_sense_valid(sshdr) && - sshdr->asc != 0) { + if (scsi_sense_valid(sshdr) && scsi_sense_asc(sshdr) != 0) { for (i = 0; ch_err[i].errno != 0; i++) { - if (ch_err[i].sense == sshdr->sense_key && - ch_err[i].asc == sshdr->asc && - ch_err[i].ascq == sshdr->ascq) { + if (ch_err[i].sense_key == sshdr->sense_key && + ch_err[i].sense_code == sshdr->sense_code) { errno = -ch_err[i].errno; break; } @@ -191,9 +182,8 @@ ch_do_scsi(scsi_changer *ch, unsigned char *cmd, int cmd_len, struct scsi_sense_hdr sshdr; struct scsi_failure failure_defs[] = { { - .sense = UNIT_ATTENTION, - .asc = SCMD_FAILURE_ASC_ANY, - .ascq = SCMD_FAILURE_ASCQ_ANY, + .sense_key = UNIT_ATTENTION, + .sense_code = SCMD_FAILURE_SENSE_CODE_ANY, .allowed = 3, .result = SAM_STAT_CHECK_CONDITION, }, @@ -363,15 +353,10 @@ ch_readconfig(scsi_changer *ch) vendor_labels[i]); } - /* look up the devices of the data transfer elements */ - ch->dt = kzalloc_objs(*ch->dt, ch->counts[CHET_DT]); - - if (!ch->dt) { - kfree(buffer); - return -ENOMEM; - } - + /* report the devices of the data transfer elements */ for (elem = 0; elem < ch->counts[CHET_DT]; elem++) { + struct scsi_device *sdev; + id = -1; lun = 0; if (elem < CH_DT_MAX && -1 != dt_id[elem]) { @@ -387,10 +372,8 @@ ch_readconfig(scsi_changer *ch) VPRINTK(KERN_INFO, "dt 0x%x: ",elem+ch->firsts[CHET_DT]); if (data[6] & 0x80) { VPRINTK(KERN_CONT, "not this SCSI bus\n"); - ch->dt[elem] = NULL; } else if (0 == (data[6] & 0x30)) { VPRINTK(KERN_CONT, "ID/LUN unknown\n"); - ch->dt[elem] = NULL; } else { id = ch->device->id; lun = 0; @@ -400,18 +383,16 @@ ch_readconfig(scsi_changer *ch) } if (-1 != id) { VPRINTK(KERN_CONT, "ID %i, LUN %i, ",id,lun); - ch->dt[elem] = - scsi_device_lookup(ch->device->host, - ch->device->channel, - id,lun); - if (!ch->dt[elem]) { + sdev = scsi_device_lookup(ch->device->host, + ch->device->channel, + id, lun); + if (!sdev) { /* should not happen */ VPRINTK(KERN_CONT, "Huh? device not found!\n"); } else { VPRINTK(KERN_CONT, "name: %8.8s %16.16s %4.4s\n", - ch->dt[elem]->vendor, - ch->dt[elem]->model, - ch->dt[elem]->rev); + sdev->vendor, sdev->model, sdev->rev); + scsi_device_put(sdev); } } } @@ -575,7 +556,6 @@ static void ch_destroy(struct kref *ref) scsi_changer *ch = container_of(ref, scsi_changer, ref); ch->device = NULL; - kfree(ch->dt); kfree(ch); } diff --git a/drivers/scsi/constants.c b/drivers/scsi/constants.c index 340785536998..767631835c81 100644 --- a/drivers/scsi/constants.c +++ b/drivers/scsi/constants.c @@ -292,7 +292,7 @@ bool scsi_opcode_sa_name(int opcode, int service_action, } struct error_info { - unsigned short code12; /* 0x0302 looks better than 0x03,0x02 */ + unsigned short code; /* 0x0302 looks better than 0x03,0x02 */ unsigned short size; }; @@ -318,20 +318,46 @@ static const char *additional_text = ; struct error_info2 { - unsigned char code1, code2_min, code2_max; - const char * str; - const char * fmt; + u8 asc; + u8 ascq_min; + u8 ascq_max; + const char *str; + const char *fmt; }; static const struct error_info2 additional2[] = { - {0x40, 0x00, 0x7f, "Ram failure", ""}, - {0x40, 0x80, 0xff, "Diagnostic failure on component", ""}, - {0x41, 0x00, 0xff, "Data path failure", ""}, - {0x42, 0x00, 0xff, "Power-on or self-test failure", ""}, - {0x4D, 0x00, 0xff, "Tagged overlapped commands", "task tag "}, - {0x70, 0x00, 0xff, "Decompression exception", "short algorithm id of "}, - {0, 0, 0, NULL, NULL} + { + ASC_RAM_FAILURE, + 0x00, 0x7f, + "Ram failure", "" + }, + { + ASC_RAM_FAILURE, + 0x80, 0xff, + "Diagnostic failure on component", "" + }, + { + ASC_DATA_PATH_FAILURE, + 0x00, 0xff, + "Data path failure", "" + }, + { + ASC_POWER_ON_OR_SELFTEST_FAILURE, + 0x00, 0xff, + "Power-on or self-test failure", "" + }, + { + ASC_TAGGED_OVERLAPPED_COMMANDS, + 0x00, 0xff, + "Tagged overlapped commands", "task tag " + }, + { + ASC_DECOMPRESSION_EXCEPTION_SHORT_ALGORITHM_ID, + 0x00, 0xff, + "Decompression exception", "short algorithm id of " + }, + { 0, 0, 0, NULL, NULL } }; /* description of the sense key values */ @@ -375,22 +401,21 @@ EXPORT_SYMBOL(scsi_sense_key_string); * This string may contain a "%x" and should be printed with ascq as arg. */ const char * -scsi_extd_sense_format(unsigned char asc, unsigned char ascq, const char **fmt) +scsi_extd_sense_format(const struct scsi_sense_hdr *sshdr, const char **fmt) { - int i; - unsigned short code = ((asc << 8) | ascq); unsigned offset = 0; + int i; *fmt = NULL; for (i = 0; i < ARRAY_SIZE(additional); i++) { - if (additional[i].code12 == code) + if (additional[i].code == sshdr->sense_code) return additional_text + offset; offset += additional[i].size; } for (i = 0; additional2[i].fmt; i++) { - if (additional2[i].code1 == asc && - ascq >= additional2[i].code2_min && - ascq <= additional2[i].code2_max) { + if (additional2[i].asc == scsi_sense_asc(sshdr) && + scsi_sense_ascq(sshdr) >= additional2[i].ascq_min && + scsi_sense_ascq(sshdr) <= additional2[i].ascq_max) { *fmt = additional2[i].fmt; return additional2[i].str; } diff --git a/drivers/scsi/csiostor/Makefile b/drivers/scsi/csiostor/Makefile index d047e22eac0d..a19031efa7c4 100644 --- a/drivers/scsi/csiostor/Makefile +++ b/drivers/scsi/csiostor/Makefile @@ -4,6 +4,8 @@ # ## +CONTEXT_ANALYSIS := y + ccflags-y += -I$(srctree)/drivers/net/ethernet/chelsio/cxgb4 obj-$(CONFIG_SCSI_CHELSIO_FCOE) += csiostor.o diff --git a/drivers/scsi/csiostor/csio_attr.c b/drivers/scsi/csiostor/csio_attr.c index 200e50089711..7fddb98e1024 100644 --- a/drivers/scsi/csiostor/csio_attr.c +++ b/drivers/scsi/csiostor/csio_attr.c @@ -84,9 +84,9 @@ csio_reg_rnode(struct csio_rnode *rn) ln->num_reg_rnodes++; rport = rn->rport; - spin_lock_irq(shost->host_lock); + spin_lock_irq(&shost->host_lock); *((struct csio_rnode **)rport->dd_data) = rn; - spin_unlock_irq(shost->host_lock); + spin_unlock_irq(&shost->host_lock); sp = &rn->rn_sparm; rport->maxframe_size = ntohs(sp->csp.sp_bb_data); @@ -630,7 +630,7 @@ csio_vport_delete(struct fc_vport *fc_vport) /* Quiesce ios and send remove event to lnode */ scsi_block_requests(shost); spin_lock_irq(&hw->lock); - csio_scsim_cleanup_io_lnode(csio_hw_to_scsim(hw), ln); + csio_scsim_cleanup_io_lnode(hw, ln); csio_lnode_close(ln); spin_unlock_irq(&hw->lock); scsi_unblock_requests(shost); @@ -655,7 +655,7 @@ csio_vport_disable(struct fc_vport *fc_vport, bool disable) /* Quiesce ios and send stop event to lnode */ scsi_block_requests(shost); spin_lock_irq(&hw->lock); - csio_scsim_cleanup_io_lnode(csio_hw_to_scsim(hw), ln); + csio_scsim_cleanup_io_lnode(hw, ln); csio_lnode_stop(ln); spin_unlock_irq(&hw->lock); scsi_unblock_requests(shost); diff --git a/drivers/scsi/csiostor/csio_hw.c b/drivers/scsi/csiostor/csio_hw.c index df9f81f29950..b5a36615a22b 100644 --- a/drivers/scsi/csiostor/csio_hw.c +++ b/drivers/scsi/csiostor/csio_hw.c @@ -92,7 +92,8 @@ static void csio_hw_mbm_cleanup(struct csio_hw *); static void csio_hws_uninit(struct csio_hw *, enum csio_hw_ev); static void csio_hws_configuring(struct csio_hw *, enum csio_hw_ev); static void csio_hws_initializing(struct csio_hw *, enum csio_hw_ev); -static void csio_hws_ready(struct csio_hw *, enum csio_hw_ev); +static void csio_hws_ready(struct csio_hw *hw, enum csio_hw_ev) + __must_hold(&hw->lock); static void csio_hws_quiescing(struct csio_hw *, enum csio_hw_ev); static void csio_hws_quiesced(struct csio_hw *, enum csio_hw_ev); static void csio_hws_resetting(struct csio_hw *, enum csio_hw_ev); @@ -914,6 +915,7 @@ csio_hw_dev_ready(struct csio_hw *hw) */ static int csio_do_hello(struct csio_hw *hw, enum csio_dev_state *state) + __must_hold(&hw->lock) { struct csio_mb *mbp; int rv = 0; @@ -2050,6 +2052,7 @@ csio_hw_flash_config(struct csio_hw *hw, u32 *fw_cfg_param, char *path) */ static int csio_hw_use_fwconfig(struct csio_hw *hw, int reset, u32 *fw_cfg_param) + __must_hold(&hw->lock) { struct csio_mb *mbp = NULL; struct fw_caps_config_cmd *caps_cmd; @@ -2475,6 +2478,7 @@ static int csio_hw_check_fwver(struct csio_hw *hw) */ static void csio_hw_configure(struct csio_hw *hw) + __must_hold(&hw->lock) { int reset = 1; int rv; @@ -2604,6 +2608,7 @@ csio_hw_configure(struct csio_hw *hw) */ static void csio_hw_initialize(struct csio_hw *hw) + __must_hold(&hw->lock) { struct csio_mb *mbp; enum fw_retval retval; @@ -2778,6 +2783,7 @@ csio_hw_fatal_err(struct csio_hw *hw) */ static void csio_hws_uninit(struct csio_hw *hw, enum csio_hw_ev evt) + __must_hold(&hw->lock) { hw->prev_evt = hw->cur_evt; hw->cur_evt = evt; @@ -2803,6 +2809,7 @@ csio_hws_uninit(struct csio_hw *hw, enum csio_hw_ev evt) */ static void csio_hws_configuring(struct csio_hw *hw, enum csio_hw_ev evt) + __must_hold(&hw->lock) { hw->prev_evt = hw->cur_evt; hw->cur_evt = evt; @@ -2879,6 +2886,7 @@ csio_hws_initializing(struct csio_hw *hw, enum csio_hw_ev evt) */ static void csio_hws_ready(struct csio_hw *hw, enum csio_hw_ev evt) + __must_hold(&hw->lock) { /* Remember the event */ hw->evtflag = evt; @@ -2897,9 +2905,9 @@ csio_hws_ready(struct csio_hw *hw, enum csio_hw_ev evt) /* cleanup all outstanding cmds */ if (evt == CSIO_HWE_HBA_RESET || evt == CSIO_HWE_PCIERR_DETECTED) - csio_scsim_cleanup_io(csio_hw_to_scsim(hw), false); + csio_scsim_cleanup_io(hw, false); else - csio_scsim_cleanup_io(csio_hw_to_scsim(hw), true); + csio_scsim_cleanup_io(hw, true); csio_hw_intr_disable(hw); csio_hw_mbm_cleanup(hw); @@ -2988,6 +2996,7 @@ csio_hws_quiescing(struct csio_hw *hw, enum csio_hw_ev evt) */ static void csio_hws_quiesced(struct csio_hw *hw, enum csio_hw_ev evt) + __must_hold(&hw->lock) { hw->prev_evt = hw->cur_evt; hw->cur_evt = evt; @@ -3013,6 +3022,7 @@ csio_hws_quiesced(struct csio_hw *hw, enum csio_hw_ev evt) */ static void csio_hws_resetting(struct csio_hw *hw, enum csio_hw_ev evt) + __must_hold(&hw->lock) { hw->prev_evt = hw->cur_evt; hw->cur_evt = evt; @@ -3074,6 +3084,7 @@ csio_hws_removing(struct csio_hw *hw, enum csio_hw_ev evt) */ static void csio_hws_pcierr(struct csio_hw *hw, enum csio_hw_ev evt) + __must_hold(&hw->lock) { hw->prev_evt = hw->cur_evt; hw->cur_evt = evt; @@ -3763,6 +3774,7 @@ csio_hw_mb_timer(struct timer_list *t) */ static void csio_hw_mbm_cleanup(struct csio_hw *hw) + __must_hold(&hw->lock) { LIST_HEAD(cbfn_q); @@ -3883,6 +3895,7 @@ csio_free_evt(struct csio_hw *hw, struct csio_evt_msg *evt_entry) void csio_evtq_flush(struct csio_hw *hw) + __must_hold(&hw->lock) { uint32_t count; count = 30; @@ -4142,6 +4155,7 @@ csio_mgmt_tmo_handler(struct timer_list *t) static void csio_mgmtm_cleanup(struct csio_mgmtm *mgmtm) + __must_hold(&mgmtm->hw->lock) { struct csio_hw *hw = mgmtm->hw; struct csio_ioreq *io_req; diff --git a/drivers/scsi/csiostor/csio_lnode.c b/drivers/scsi/csiostor/csio_lnode.c index 78d5ecd14f65..161973957976 100644 --- a/drivers/scsi/csiostor/csio_lnode.c +++ b/drivers/scsi/csiostor/csio_lnode.c @@ -872,6 +872,7 @@ csio_ln_read_fcf_entry(struct csio_lnode *ln, static void csio_handle_link_up(struct csio_hw *hw, uint8_t portid, uint32_t fcfi, uint32_t vnpi) + __must_hold(&hw->lock) { struct csio_lnode *ln = NULL; @@ -1165,6 +1166,7 @@ csio_lns_uninit(struct csio_lnode *ln, enum csio_ln_ev evt) */ static void csio_lns_online(struct csio_lnode *ln, enum csio_ln_ev evt) + __must_hold(&csio_lnode_to_hw(ln)->lock) { struct csio_hw *hw = csio_lnode_to_hw(ln); @@ -1216,6 +1218,7 @@ csio_lns_online(struct csio_lnode *ln, enum csio_ln_ev evt) */ static void csio_lns_ready(struct csio_lnode *ln, enum csio_ln_ev evt) + __must_hold(&csio_lnode_to_hw(ln)->lock) { struct csio_hw *hw = csio_lnode_to_hw(ln); diff --git a/drivers/scsi/csiostor/csio_rnode.c b/drivers/scsi/csiostor/csio_rnode.c index 713e13adf4dc..fe985836c15c 100644 --- a/drivers/scsi/csiostor/csio_rnode.c +++ b/drivers/scsi/csiostor/csio_rnode.c @@ -546,6 +546,7 @@ csio_rn_verify_rparams(struct csio_lnode *ln, struct csio_rnode *rn, static void __csio_reg_rnode(struct csio_rnode *rn) + __must_hold(&csio_lnode_to_hw(csio_rnode_to_lnode(rn))->lock) { struct csio_lnode *ln = csio_rnode_to_lnode(rn); struct csio_hw *hw = csio_lnode_to_hw(ln); @@ -563,6 +564,7 @@ __csio_reg_rnode(struct csio_rnode *rn) static void __csio_unreg_rnode(struct csio_rnode *rn) + __must_hold(&csio_lnode_to_hw(csio_rnode_to_lnode(rn))->lock) { struct csio_lnode *ln = csio_rnode_to_lnode(rn); struct csio_hw *hw = csio_lnode_to_hw(ln); @@ -586,8 +588,7 @@ __csio_unreg_rnode(struct csio_rnode *rn) /* Cleanup I/Os that were waiting for rnode to unregister */ if (cmpl) - csio_scsi_cleanup_io_q(csio_hw_to_scsim(hw), &tmp_q); - + csio_scsi_cleanup_io_q(hw, &tmp_q); } /*****************************************************************************/ @@ -602,6 +603,7 @@ __csio_unreg_rnode(struct csio_rnode *rn) */ static void csio_rns_uninit(struct csio_rnode *rn, enum csio_rn_ev evt) + __must_hold(&csio_rnode_to_lnode(rn)->hwp->lock) { struct csio_lnode *ln = csio_rnode_to_lnode(rn); int ret = 0; @@ -642,6 +644,7 @@ csio_rns_uninit(struct csio_rnode *rn, enum csio_rn_ev evt) */ static void csio_rns_ready(struct csio_rnode *rn, enum csio_rn_ev evt) + __must_hold(&csio_rnode_to_lnode(rn)->hwp->lock) { struct csio_lnode *ln = csio_rnode_to_lnode(rn); int ret = 0; @@ -727,6 +730,7 @@ csio_rns_ready(struct csio_rnode *rn, enum csio_rn_ev evt) */ static void csio_rns_offline(struct csio_rnode *rn, enum csio_rn_ev evt) + __must_hold(&csio_rnode_to_lnode(rn)->hwp->lock) { struct csio_lnode *ln = csio_rnode_to_lnode(rn); int ret = 0; @@ -786,6 +790,7 @@ csio_rns_offline(struct csio_rnode *rn, enum csio_rn_ev evt) */ static void csio_rns_disappeared(struct csio_rnode *rn, enum csio_rn_ev evt) + __must_hold(&csio_rnode_to_lnode(rn)->hwp->lock) { struct csio_lnode *ln = csio_rnode_to_lnode(rn); int ret = 0; diff --git a/drivers/scsi/csiostor/csio_scsi.c b/drivers/scsi/csiostor/csio_scsi.c index b1de615cf316..d81d10603fcc 100644 --- a/drivers/scsi/csiostor/csio_scsi.c +++ b/drivers/scsi/csiostor/csio_scsi.c @@ -1150,15 +1150,15 @@ csio_scsi_cmpl_handler(struct csio_hw *hw, void *wr, uint32_t len, /* * csio_scsi_cleanup_io_q - Cleanup the given queue. - * @scm: SCSI module. + * @hw: HW module. * @q: Queue to be cleaned up. * * Called with lock held. Has to exit with lock held. */ -void -csio_scsi_cleanup_io_q(struct csio_scsim *scm, struct list_head *q) +void csio_scsi_cleanup_io_q(struct csio_hw *hw, struct list_head *q) + __must_hold(&hw->lock) { - struct csio_hw *hw = scm->hw; + struct csio_scsim *scm = csio_hw_to_scsim(hw); struct csio_ioreq *ioreq; struct list_head *tmp, *next; struct scsi_cmnd *scmnd; @@ -1215,7 +1215,7 @@ csio_abrt_cls(struct csio_ioreq *ioreq, struct scsi_cmnd *scmnd) /* * csio_scsi_abort_io_q - Abort all I/Os on given queue - * @scm: SCSI module. + * @hw: HW module. * @q: Queue to abort. * @tmo: Timeout in ms * @@ -1229,10 +1229,10 @@ csio_abrt_cls(struct csio_ioreq *ioreq, struct scsi_cmnd *scmnd) * of this function has to ensure that the number of I/os to be aborted * is finite enough to not cause lock-held-for-too-long issues. */ -static int -csio_scsi_abort_io_q(struct csio_scsim *scm, struct list_head *q, uint32_t tmo) +static int csio_scsi_abort_io_q(struct csio_hw *hw, struct list_head *q, + uint32_t tmo) + __must_hold(&hw->lock) { - struct csio_hw *hw = scm->hw; struct list_head *tmp, *next; int count = DIV_ROUND_UP(tmo, CSIO_SCSI_ABORT_Q_POLL_MS); struct scsi_cmnd *scmnd; @@ -1264,15 +1264,15 @@ csio_scsi_abort_io_q(struct csio_scsim *scm, struct list_head *q, uint32_t tmo) /* * csio_scsim_cleanup_io - Cleanup all I/Os in SCSI module. - * @scm: SCSI module. + * @hw: HW module. * @abort: abort required. * Called with lock held, should exit with lock held. * Can sleep when waiting for I/Os to complete. */ -int -csio_scsim_cleanup_io(struct csio_scsim *scm, bool abort) +int csio_scsim_cleanup_io(struct csio_hw *hw, bool abort) + __must_hold(&hw->lock) { - struct csio_hw *hw = scm->hw; + struct csio_scsim *scm = csio_hw_to_scsim(hw); int rv = 0; int count = DIV_ROUND_UP(60 * 1000, CSIO_SCSI_ABORT_Q_POLL_MS); @@ -1293,13 +1293,13 @@ csio_scsim_cleanup_io(struct csio_scsim *scm, bool abort) /* Else abort */ if (abort) { - rv = csio_scsi_abort_io_q(scm, &scm->active_q, 30000); + rv = csio_scsi_abort_io_q(hw, &scm->active_q, 30000); if (rv == 0) return rv; csio_dbg(hw, "Some I/O aborts timed out, cleaning up..\n"); } - csio_scsi_cleanup_io_q(scm, &scm->active_q); + csio_scsi_cleanup_io_q(hw, &scm->active_q); CSIO_DB_ASSERT(list_empty(&scm->active_q)); @@ -1308,16 +1308,16 @@ csio_scsim_cleanup_io(struct csio_scsim *scm, bool abort) /* * csio_scsim_cleanup_io_lnode - Cleanup all I/Os of given lnode. - * @scm: SCSI module. + * @hw: HW module * @lnode: lnode * * Called with lock held, should exit with lock held. * Can sleep (with dropped lock) when waiting for I/Os to complete. */ -int -csio_scsim_cleanup_io_lnode(struct csio_scsim *scm, struct csio_lnode *ln) +int csio_scsim_cleanup_io_lnode(struct csio_hw *hw, struct csio_lnode *ln) + __must_hold(&hw->lock) { - struct csio_hw *hw = scm->hw; + struct csio_scsim *scm = csio_hw_to_scsim(hw); struct csio_scsi_level_data sld; int rv; int count = DIV_ROUND_UP(60 * 1000, CSIO_SCSI_ABORT_Q_POLL_MS); @@ -1347,10 +1347,10 @@ csio_scsim_cleanup_io_lnode(struct csio_scsim *scm, struct csio_lnode *ln) csio_dbg(hw, "Some I/Os pending on ln:%p, aborting them..\n", ln); /* I/Os are pending, abort them */ - rv = csio_scsi_abort_io_q(scm, &ln->cmpl_q, 30000); + rv = csio_scsi_abort_io_q(hw, &ln->cmpl_q, 30000); if (rv != 0) { csio_dbg(hw, "Some I/O aborts timed out, cleaning up..\n"); - csio_scsi_cleanup_io_q(scm, &ln->cmpl_q); + csio_scsi_cleanup_io_q(hw, &ln->cmpl_q); } CSIO_DB_ASSERT(list_empty(&ln->cmpl_q)); @@ -2194,7 +2194,7 @@ csio_eh_lun_reset_handler(struct scsi_cmnd *cmnd) spin_lock_irq(&hw->lock); csio_scsi_gather_active_ios(scsim, &sld, &local_q); - retval = csio_scsi_abort_io_q(scsim, &local_q, 30000); + retval = csio_scsi_abort_io_q(hw, &local_q, 30000); spin_unlock_irq(&hw->lock); /* Aborts may have timed out */ @@ -2256,14 +2256,14 @@ csio_scan_finished(struct Scsi_Host *shost, unsigned long time) struct csio_lnode *ln = shost_priv(shost); int rv = 1; - spin_lock_irq(shost->host_lock); + spin_lock_irq(&shost->host_lock); if (!ln->hwp || csio_list_deleted(&ln->sm.sm_list)) goto out; rv = csio_scan_done(ln, jiffies, time, csio_max_scan_tmo * HZ, csio_delta_scan_tmo * HZ); out: - spin_unlock_irq(shost->host_lock); + spin_unlock_irq(&shost->host_lock); return rv; } diff --git a/drivers/scsi/csiostor/csio_scsi.h b/drivers/scsi/csiostor/csio_scsi.h index 39dda3c88f0d..610aae12be8a 100644 --- a/drivers/scsi/csiostor/csio_scsi.h +++ b/drivers/scsi/csiostor/csio_scsi.h @@ -338,10 +338,9 @@ csio_scsi_close(struct csio_ioreq *ioreq) return ioreq->drv_status; } -void csio_scsi_cleanup_io_q(struct csio_scsim *, struct list_head *); -int csio_scsim_cleanup_io(struct csio_scsim *, bool abort); -int csio_scsim_cleanup_io_lnode(struct csio_scsim *, - struct csio_lnode *); +void csio_scsi_cleanup_io_q(struct csio_hw *, struct list_head *); +int csio_scsim_cleanup_io(struct csio_hw *, bool abort); +int csio_scsim_cleanup_io_lnode(struct csio_hw *, struct csio_lnode *); struct csio_ioreq *csio_scsi_cmpl_handler(struct csio_hw *, void *, uint32_t, struct csio_fl_dma_buf *, void *, uint8_t **); diff --git a/drivers/scsi/cxgbi/Makefile b/drivers/scsi/cxgbi/Makefile index abfd38a26fec..c614afa18a33 100644 --- a/drivers/scsi/cxgbi/Makefile +++ b/drivers/scsi/cxgbi/Makefile @@ -1,4 +1,7 @@ # SPDX-License-Identifier: GPL-2.0-only + +CONTEXT_ANALYSIS := y + ccflags-y += -I $(srctree)/drivers/net/ethernet/chelsio/libcxgb obj-$(CONFIG_SCSI_CXGB3_ISCSI) += libcxgbi.o cxgb3i/ diff --git a/drivers/scsi/cxgbi/libcxgbi.c b/drivers/scsi/cxgbi/libcxgbi.c index ea9631bfe2e2..b0bffbc38183 100644 --- a/drivers/scsi/cxgbi/libcxgbi.c +++ b/drivers/scsi/cxgbi/libcxgbi.c @@ -1537,9 +1537,16 @@ skb_read_pdu_bhs(struct cxgbi_sock *csk, struct iscsi_conn *conn, * for the last pdu of a sequence. */ itt_t itt = ((struct iscsi_data *)skb->data)->itt; - struct iscsi_task *task = iscsi_itt_to_ctask(conn, itt); - u32 data_sn = be32_to_cpu(((struct iscsi_data *) - skb->data)->datasn); + struct iscsi_task *task; + u32 data_sn; + + /* + * TODO: hold session->back_lock around the iscsi_itt_to_task() + * call below. + */ + __assume_ctx_lock(&conn->session->back_lock); + task = iscsi_itt_to_ctask(conn->session, conn, itt); + data_sn = be32_to_cpu(((struct iscsi_data *)skb->data)->datasn); if (task && task->sc) { struct iscsi_tcp_task *tcp_task = task->dd_data; diff --git a/drivers/scsi/dc395x.c b/drivers/scsi/dc395x.c index ba490174a417..5a4f2713dcfa 100644 --- a/drivers/scsi/dc395x.c +++ b/drivers/scsi/dc395x.c @@ -91,8 +91,8 @@ #endif -#define DC395x_LOCK_IO(dev,flags) spin_lock_irqsave(((struct Scsi_Host *)dev)->host_lock, flags) -#define DC395x_UNLOCK_IO(dev,flags) spin_unlock_irqrestore(((struct Scsi_Host *)dev)->host_lock, flags) +#define DC395x_LOCK_IO(dev,flags) spin_lock_irqsave(&((struct Scsi_Host *)dev)->host_lock, flags) +#define DC395x_UNLOCK_IO(dev,flags) spin_unlock_irqrestore(&((struct Scsi_Host *)dev)->host_lock, flags) #define DC395x_read8(acb,address) (u8)(inb(acb->io_port_base + (address))) #define DC395x_read16(acb,address) (u16)(inw(acb->io_port_base + (address))) @@ -1016,9 +1016,9 @@ static int dc395x_eh_bus_reset(struct scsi_cmnd *cmd) { int rc; - spin_lock_irq(cmd->device->host->host_lock); + spin_lock_irq(&cmd->device->host->host_lock); rc = __dc395x_eh_bus_reset(cmd); - spin_unlock_irq(cmd->device->host->host_lock); + spin_unlock_irq(&cmd->device->host->host_lock); return rc; } @@ -3808,13 +3808,11 @@ static void adapter_uninit_chip(struct AdapterCtlBlk *acb) static void adapter_uninit(struct AdapterCtlBlk *acb) { unsigned long flags; - DC395x_LOCK_IO(acb->scsi_host, flags); - /* remove timers */ - if (timer_pending(&acb->waiting_timer)) - timer_delete(&acb->waiting_timer); - if (timer_pending(&acb->selto_timer)) - timer_delete(&acb->selto_timer); + /* Drain the self-rearming timer; must not run under host_lock. */ + timer_shutdown_sync(&acb->waiting_timer); + + DC395x_LOCK_IO(acb->scsi_host, flags); adapter_uninit_chip(acb); adapter_remove_and_free_all_devices(acb); diff --git a/drivers/scsi/device_handler/scsi_dh_alua.c b/drivers/scsi/device_handler/scsi_dh_alua.c index d81ec47a7140..87ac0a6d63e5 100644 --- a/drivers/scsi/device_handler/scsi_dh_alua.c +++ b/drivers/scsi/device_handler/scsi_dh_alua.c @@ -433,61 +433,43 @@ static enum scsi_disposition alua_check_sense(struct scsi_device *sdev, { switch (sense_hdr->sense_key) { case NOT_READY: - if (sense_hdr->asc == 0x04 && sense_hdr->ascq == 0x0a) { - /* - * LUN Not Accessible - ALUA state transition - */ + if (sense_hdr->sense_code == + LU_NOT_ACCESSIBLE_ASYMMETRIC_ACCESS_STATE_TRANSITION) { alua_handle_state_transition(sdev); return NEEDS_RETRY; } break; case UNIT_ATTENTION: - if (sense_hdr->asc == 0x04 && sense_hdr->ascq == 0x0a) { - /* - * LUN Not Accessible - ALUA state transition - */ + if (sense_hdr->sense_code == + LU_NOT_ACCESSIBLE_ASYMMETRIC_ACCESS_STATE_TRANSITION) { alua_handle_state_transition(sdev); return NEEDS_RETRY; } - if (sense_hdr->asc == 0x29 && sense_hdr->ascq == 0x00) { + if (sense_hdr->sense_code == + POWER_ON_RESET_OR_BUS_DEVICE_RESET_OCCURRED) { /* - * Power On, Reset, or Bus Device Reset. * Might have obscured a state transition, * so schedule a recheck. */ alua_check(sdev, true); return ADD_TO_MLQUEUE; } - if (sense_hdr->asc == 0x29 && sense_hdr->ascq == 0x04) - /* - * Device internal reset - */ + if (sense_hdr->sense_code == DEVICE_INTERNAL_RESET) return ADD_TO_MLQUEUE; - if (sense_hdr->asc == 0x2a && sense_hdr->ascq == 0x01) - /* - * Mode Parameters Changed - */ + if (sense_hdr->sense_code == MODE_PARAMETERS_CHANGED) return ADD_TO_MLQUEUE; - if (sense_hdr->asc == 0x2a && sense_hdr->ascq == 0x06) { - /* - * ALUA state changed - */ + if (sense_hdr->sense_code == ASYMMETRIC_ACCESS_STATE_CHANGED) { alua_check(sdev, true); return ADD_TO_MLQUEUE; } - if (sense_hdr->asc == 0x2a && sense_hdr->ascq == 0x07) { - /* - * Implicit ALUA state transition failed - */ + if (sense_hdr->sense_code == + IMPLICIT_ASYMMETRIC_ACCESS_STATE_TRANSITION_FAILED) { alua_check(sdev, true); return ADD_TO_MLQUEUE; } - if (sense_hdr->asc == 0x3f && sense_hdr->ascq == 0x03) - /* - * Inquiry data has changed - */ + if (sense_hdr->sense_code == INQUIRY_DATA_HAS_CHANGED) return ADD_TO_MLQUEUE; - if (sense_hdr->asc == 0x3f && sense_hdr->ascq == 0x0e) + if (sense_hdr->sense_code == REPORTED_LUNS_DATA_HAS_CHANGED) /* * REPORTED_LUNS_DATA_HAS_CHANGED is reported * when switching controllers on targets like @@ -517,12 +499,12 @@ static int alua_tur(struct scsi_device *sdev) ALUA_FAILOVER_RETRIES, &sense_hdr); if ((sense_hdr.sense_key == NOT_READY || sense_hdr.sense_key == UNIT_ATTENTION) && - sense_hdr.asc == 0x04 && sense_hdr.ascq == 0x0a) + sense_hdr.sense_code == + LU_NOT_ACCESSIBLE_ASYMMETRIC_ACCESS_STATE_TRANSITION) return SCSI_DH_RETRY; - else if (retval) + if (retval) return SCSI_DH_IO; - else - return SCSI_DH_OK; + return SCSI_DH_OK; } /* @@ -619,7 +601,8 @@ static int alua_rtpg(struct scsi_device *sdev, struct alua_port_group *pg) * transition. So set the state to 'transitioning' directly. */ if (sense_hdr.sense_key == NOT_READY && - sense_hdr.asc == 0x04 && sense_hdr.ascq == 0x0a) { + sense_hdr.sense_code == + LU_NOT_ACCESSIBLE_ASYMMETRIC_ACCESS_STATE_TRANSITION) { transitioning_sense = true; goto skip_rtpg; } diff --git a/drivers/scsi/device_handler/scsi_dh_emc.c b/drivers/scsi/device_handler/scsi_dh_emc.c index ff41b51ef462..4b0ea6045ba3 100644 --- a/drivers/scsi/device_handler/scsi_dh_emc.c +++ b/drivers/scsi/device_handler/scsi_dh_emc.c @@ -105,10 +105,10 @@ static int trespass_endio(struct scsi_device *sdev, sdev_printk(KERN_ERR, sdev, "%s: Found valid sense data 0x%2x, " "0x%2x, 0x%2x while sending CLARiiON trespass " "command.\n", CLARIION_NAME, sshdr->sense_key, - sshdr->asc, sshdr->ascq); + scsi_sense_asc(sshdr), scsi_sense_ascq(sshdr)); - if (sshdr->sense_key == 0x05 && sshdr->asc == 0x04 && - sshdr->ascq == 0x00) { + if (sshdr->sense_key == ILLEGAL_REQUEST && + sshdr->sense_code == LU_NOT_READY) { /* * Array based copy in progress -- do not send * mode_select or copy will be aborted mid-stream. @@ -117,18 +117,18 @@ static int trespass_endio(struct scsi_device *sdev, "progress while sending CLARiiON trespass " "command.\n", CLARIION_NAME); err = SCSI_DH_DEV_TEMP_BUSY; - } else if (sshdr->sense_key == 0x02 && sshdr->asc == 0x04 && - sshdr->ascq == 0x03) { - /* - * LUN Not Ready - Manual Intervention Required - * indicates in-progress ucode upgrade (NDU). - */ + } else if (sshdr->sense_key == NOT_READY && + sshdr->sense_code == + LU_NOT_READY_MANUAL_INTERVENTION_REQUIRED) { + /* Indicates in-progress ucode upgrade (NDU). */ sdev_printk(KERN_INFO, sdev, "%s: Detected in-progress " "ucode upgrade NDU operation while sending " "CLARiiON trespass command.\n", CLARIION_NAME); err = SCSI_DH_DEV_TEMP_BUSY; - } else + } else { err = SCSI_DH_DEV_FAILED; + } + return err; } @@ -288,7 +288,8 @@ static enum scsi_disposition clariion_check_sense(struct scsi_device *sdev, { switch (sense_hdr->sense_key) { case NOT_READY: - if (sense_hdr->asc == 0x04 && sense_hdr->ascq == 0x03) + if (sense_hdr->sense_code == + LU_NOT_READY_MANUAL_INTERVENTION_REQUIRED) /* * LUN Not Ready - Manual Intervention Required * indicates this is a passive path. @@ -305,7 +306,7 @@ static enum scsi_disposition clariion_check_sense(struct scsi_device *sdev, return SUCCESS; break; case ILLEGAL_REQUEST: - if (sense_hdr->asc == 0x25 && sense_hdr->ascq == 0x01) + if (sense_hdr->sense_code == scsi_sense_code(0x25, 0x01)) /* * An array based copy is in progress. Do not * fail the path, do not bypass to another PG, @@ -319,7 +320,8 @@ static enum scsi_disposition clariion_check_sense(struct scsi_device *sdev, return SUCCESS; break; case UNIT_ATTENTION: - if (sense_hdr->asc == 0x29 && sense_hdr->ascq == 0x00) + if (sense_hdr->sense_code == + POWER_ON_RESET_OR_BUS_DEVICE_RESET_OCCURRED) /* * Unit Attention Code. This is the first IO * to the new path, so just retry. diff --git a/drivers/scsi/device_handler/scsi_dh_hp_sw.c b/drivers/scsi/device_handler/scsi_dh_hp_sw.c index 6e8849d7f0a3..d8653452ed2b 100644 --- a/drivers/scsi/device_handler/scsi_dh_hp_sw.c +++ b/drivers/scsi/device_handler/scsi_dh_hp_sw.c @@ -47,7 +47,8 @@ static int tur_done(struct scsi_device *sdev, struct hp_sw_dh_data *h, switch (sshdr->sense_key) { case NOT_READY: - if (sshdr->asc == 0x04 && sshdr->ascq == 2) { + if (sshdr->sense_code == + LU_NOT_READY_INITIALIZING_COMMAND_REQUIRED) { /* * LUN not ready - Initialization command required * @@ -61,8 +62,8 @@ static int tur_done(struct scsi_device *sdev, struct hp_sw_dh_data *h, default: sdev_printk(KERN_WARNING, sdev, "%s: sending tur failed, sense %x/%x/%x\n", - HP_SW_NAME, sshdr->sense_key, sshdr->asc, - sshdr->ascq); + HP_SW_NAME, sshdr->sense_key, + scsi_sense_asc(sshdr), scsi_sense_ascq(sshdr)); break; } return ret; @@ -84,9 +85,8 @@ static int hp_sw_tur(struct scsi_device *sdev, struct hp_sw_dh_data *h) REQ_FAILFAST_TRANSPORT | REQ_FAILFAST_DRIVER; struct scsi_failure failure_defs[] = { { - .sense = UNIT_ATTENTION, - .asc = SCMD_FAILURE_ASC_ANY, - .ascq = SCMD_FAILURE_ASCQ_ANY, + .sense_key = UNIT_ATTENTION, + .sense_code = SCMD_FAILURE_SENSE_CODE_ANY, .allowed = SCMD_FAILURE_NO_LIMIT, .result = SAM_STAT_CHECK_CONDITION, }, @@ -133,14 +133,9 @@ static int hp_sw_start_stop(struct hp_sw_dh_data *h) REQ_FAILFAST_TRANSPORT | REQ_FAILFAST_DRIVER; struct scsi_failure failure_defs[] = { { - /* - * LUN not ready - manual intervention required - * - * Switch-over in progress, retry. - */ - .sense = NOT_READY, - .asc = 0x04, - .ascq = 0x03, + /* Switch-over in progress, retry. */ + .sense_key = NOT_READY, + .sense_code = LU_NOT_READY_MANUAL_INTERVENTION_REQUIRED, .allowed = HP_SW_RETRIES, .result = SAM_STAT_CHECK_CONDITION, }, @@ -167,7 +162,8 @@ static int hp_sw_start_stop(struct hp_sw_dh_data *h) switch (sshdr.sense_key) { case NOT_READY: - if (sshdr.asc == 0x04 && sshdr.ascq == 3) { + if (sshdr.sense_code == + LU_NOT_READY_MANUAL_INTERVENTION_REQUIRED) { rc = SCSI_DH_RETRY; break; } @@ -176,7 +172,8 @@ static int hp_sw_start_stop(struct hp_sw_dh_data *h) sdev_printk(KERN_WARNING, sdev, "%s: sending start_stop_unit failed, " "sense %x/%x/%x\n", HP_SW_NAME, - sshdr.sense_key, sshdr.asc, sshdr.ascq); + sshdr.sense_key, scsi_sense_asc(&sshdr), + scsi_sense_ascq(&sshdr)); rc = SCSI_DH_IO; } diff --git a/drivers/scsi/device_handler/scsi_dh_rdac.c b/drivers/scsi/device_handler/scsi_dh_rdac.c index 88c8e36b221e..742534c99386 100644 --- a/drivers/scsi/device_handler/scsi_dh_rdac.c +++ b/drivers/scsi/device_handler/scsi_dh_rdac.c @@ -493,7 +493,8 @@ static int mode_select_handle_sense(struct scsi_device *sdev, RDAC_LOG(RDAC_LOG_FAILOVER, sdev, "array %s, ctlr %d, " "MODE_SELECT returned with sense %02x/%02x/%02x", (char *) h->ctlr->array_name, h->ctlr->index, - sense_hdr->sense_key, sense_hdr->asc, sense_hdr->ascq); + sense_hdr->sense_key, scsi_sense_asc(sense_hdr), + scsi_sense_ascq(sense_hdr)); return SCSI_DH_IO; } @@ -514,35 +515,29 @@ static void send_mode_select(struct work_struct *work) REQ_FAILFAST_TRANSPORT | REQ_FAILFAST_DRIVER; struct scsi_failure failure_defs[] = { { - .sense = NO_SENSE, - .asc = SCMD_FAILURE_ASC_ANY, - .ascq = SCMD_FAILURE_ASCQ_ANY, + .sense_key = NO_SENSE, + .sense_code = SCMD_FAILURE_SENSE_CODE_ANY, .result = SAM_STAT_CHECK_CONDITION, }, { - .sense = ABORTED_COMMAND, - .asc = SCMD_FAILURE_ASC_ANY, - .ascq = SCMD_FAILURE_ASCQ_ANY, + .sense_key = ABORTED_COMMAND, + .sense_code = SCMD_FAILURE_SENSE_CODE_ANY, .result = SAM_STAT_CHECK_CONDITION, }, { - .sense = UNIT_ATTENTION, - .asc = SCMD_FAILURE_ASC_ANY, - .ascq = SCMD_FAILURE_ASCQ_ANY, + .sense_key = UNIT_ATTENTION, + .sense_code = SCMD_FAILURE_SENSE_CODE_ANY, .result = SAM_STAT_CHECK_CONDITION, }, - /* LUN Not Ready and is in the Process of Becoming Ready */ { - .sense = NOT_READY, - .asc = 0x04, - .ascq = 0x01, + .sense_key = NOT_READY, + .sense_code = LU_IS_IN_PROCESS_OF_BECOMING_READY, .result = SAM_STAT_CHECK_CONDITION, }, - /* Command Lock contention */ + /* Command Lock contention (not a standard sense code) */ { - .sense = ILLEGAL_REQUEST, - .asc = 0x91, - .ascq = 0x36, + .sense_key = ILLEGAL_REQUEST, + .sense_code = scsi_sense_code(0x91, 0x36), .allowed = SCMD_FAILURE_NO_LIMIT, .result = SAM_STAT_CHECK_CONDITION, }, @@ -674,33 +669,34 @@ static enum scsi_disposition rdac_check_sense(struct scsi_device *sdev, { struct rdac_dh_data *h = sdev->handler_data; - RDAC_LOG(RDAC_LOG_SENSE, sdev, "array %s, ctlr %d, " - "I/O returned with sense %02x/%02x/%02x", - (char *) h->ctlr->array_name, h->ctlr->index, - sense_hdr->sense_key, sense_hdr->asc, sense_hdr->ascq); + RDAC_LOG(RDAC_LOG_SENSE, sdev, + "array %s, ctlr %d, I/O returned with sense %02x/%02x/%02x", + (char *) h->ctlr->array_name, h->ctlr->index, + sense_hdr->sense_key, scsi_sense_asc(sense_hdr), + scsi_sense_ascq(sense_hdr)); switch (sense_hdr->sense_key) { case NOT_READY: - if (sense_hdr->asc == 0x04 && sense_hdr->ascq == 0x01) + if (sense_hdr->sense_code == LU_IS_IN_PROCESS_OF_BECOMING_READY) /* LUN Not Ready - Logical Unit Not Ready and is in * the process of becoming ready * Just retry. */ return ADD_TO_MLQUEUE; - if (sense_hdr->asc == 0x04 && sense_hdr->ascq == 0x81) + if (sense_hdr->sense_code == scsi_sense_code(0x04, 0x81)) /* LUN Not Ready - Storage firmware incompatible * Manual code synchonisation required. * * Nothing we can do here. Try to bypass the path. */ return SUCCESS; - if (sense_hdr->asc == 0x04 && sense_hdr->ascq == 0xA1) + if (sense_hdr->sense_code == scsi_sense_code(0x04, 0xA1)) /* LUN Not Ready - Quiescense in progress * * Just retry and wait. */ return ADD_TO_MLQUEUE; - if (sense_hdr->asc == 0xA1 && sense_hdr->ascq == 0x02) + if (sense_hdr->sense_code == scsi_sense_code(0xA1, 0x02)) /* LUN Not Ready - Quiescense in progress * or has been achieved * Just retry. @@ -708,7 +704,7 @@ static enum scsi_disposition rdac_check_sense(struct scsi_device *sdev, return ADD_TO_MLQUEUE; break; case ILLEGAL_REQUEST: - if (sense_hdr->asc == 0x94 && sense_hdr->ascq == 0x01) { + if (sense_hdr->sense_code == scsi_sense_code(0x94, 0x01)) { /* Invalid Request - Current Logical Unit Ownership. * Controller is not the current owner of the LUN, * Fail the path, so that the other path be used. @@ -718,12 +714,13 @@ static enum scsi_disposition rdac_check_sense(struct scsi_device *sdev, } break; case UNIT_ATTENTION: - if (sense_hdr->asc == 0x29 && sense_hdr->ascq == 0x00) + if (sense_hdr->sense_code == + POWER_ON_RESET_OR_BUS_DEVICE_RESET_OCCURRED) /* * Power On, Reset, or Bus Device Reset, just retry. */ return ADD_TO_MLQUEUE; - if (sense_hdr->asc == 0x8b && sense_hdr->ascq == 0x02) + if (sense_hdr->sense_code == scsi_sense_code(0x8b, 0x02)) /* * Quiescence in progress , just retry. */ diff --git a/drivers/scsi/elx/Makefile b/drivers/scsi/elx/Makefile index a8537d7a2a6e..0ed508e379fb 100644 --- a/drivers/scsi/elx/Makefile +++ b/drivers/scsi/elx/Makefile @@ -4,6 +4,7 @@ # * “Broadcom” refers to Broadcom Inc. and/or its subsidiaries. # */ +CONTEXT_ANALYSIS := y obj-$(CONFIG_SCSI_EFCT) := efct.o diff --git a/drivers/scsi/esas2r/Makefile b/drivers/scsi/esas2r/Makefile index 279d9cb3ca69..325fa0e634fa 100644 --- a/drivers/scsi/esas2r/Makefile +++ b/drivers/scsi/esas2r/Makefile @@ -1,4 +1,7 @@ # SPDX-License-Identifier: GPL-2.0-only + +CONTEXT_ANALYSIS := y + obj-$(CONFIG_SCSI_ESAS2R) += esas2r.o esas2r-objs := esas2r_log.o esas2r_disc.o esas2r_flash.o esas2r_init.o \ diff --git a/drivers/scsi/esp_scsi.c b/drivers/scsi/esp_scsi.c index 897a01d3e303..9993b0ae9c4f 100644 --- a/drivers/scsi/esp_scsi.c +++ b/drivers/scsi/esp_scsi.c @@ -2174,7 +2174,7 @@ irqreturn_t scsi_esp_intr(int irq, void *dev_id) unsigned long flags; irqreturn_t ret; - spin_lock_irqsave(esp->host->host_lock, flags); + spin_lock_irqsave(&esp->host->host_lock, flags); ret = IRQ_NONE; if (esp->ops->irq_pending(esp)) { ret = IRQ_HANDLED; @@ -2194,7 +2194,7 @@ irqreturn_t scsi_esp_intr(int irq, void *dev_id) break; } } - spin_unlock_irqrestore(esp->host->host_lock, flags); + spin_unlock_irqrestore(&esp->host->host_lock, flags); return ret; } @@ -2497,7 +2497,7 @@ static int esp_eh_abort_handler(struct scsi_cmnd *cmd) /* XXX This helps a lot with debugging but might be a bit * XXX much for the final driver. */ - spin_lock_irqsave(esp->host->host_lock, flags); + spin_lock_irqsave(&esp->host->host_lock, flags); shost_printk(KERN_ERR, esp->host, "Aborting command [%p:%02x]\n", cmd, cmd->cmnd[0]); ent = esp->active_cmd; @@ -2514,9 +2514,9 @@ static int esp_eh_abort_handler(struct scsi_cmnd *cmd) ent->cmd, ent->cmd->cmnd[0]); } esp_dump_cmd_log(esp); - spin_unlock_irqrestore(esp->host->host_lock, flags); + spin_unlock_irqrestore(&esp->host->host_lock, flags); - spin_lock_irqsave(esp->host->host_lock, flags); + spin_lock_irqsave(&esp->host->host_lock, flags); ent = NULL; list_for_each_entry(tmp, &esp->queued_cmds, list) { @@ -2579,12 +2579,12 @@ static int esp_eh_abort_handler(struct scsi_cmnd *cmd) goto out_failure; } - spin_unlock_irqrestore(esp->host->host_lock, flags); + spin_unlock_irqrestore(&esp->host->host_lock, flags); if (!wait_for_completion_timeout(&eh_done, 5 * HZ)) { - spin_lock_irqsave(esp->host->host_lock, flags); + spin_lock_irqsave(&esp->host->host_lock, flags); ent->eh_done = NULL; - spin_unlock_irqrestore(esp->host->host_lock, flags); + spin_unlock_irqrestore(&esp->host->host_lock, flags); return FAILED; } @@ -2592,7 +2592,7 @@ static int esp_eh_abort_handler(struct scsi_cmnd *cmd) return SUCCESS; out_success: - spin_unlock_irqrestore(esp->host->host_lock, flags); + spin_unlock_irqrestore(&esp->host->host_lock, flags); return SUCCESS; out_failure: @@ -2600,7 +2600,7 @@ static int esp_eh_abort_handler(struct scsi_cmnd *cmd) * XXX since we know which target/lun in particular is * XXX causing trouble. */ - spin_unlock_irqrestore(esp->host->host_lock, flags); + spin_unlock_irqrestore(&esp->host->host_lock, flags); return FAILED; } @@ -2612,7 +2612,7 @@ static int esp_eh_bus_reset_handler(struct scsi_cmnd *cmd) init_completion(&eh_reset); - spin_lock_irqsave(esp->host->host_lock, flags); + spin_lock_irqsave(&esp->host->host_lock, flags); esp->eh_reset = &eh_reset; @@ -2624,14 +2624,14 @@ static int esp_eh_bus_reset_handler(struct scsi_cmnd *cmd) esp->flags |= ESP_FLAG_RESETTING; scsi_esp_cmd(esp, ESP_CMD_RS); - spin_unlock_irqrestore(esp->host->host_lock, flags); + spin_unlock_irqrestore(&esp->host->host_lock, flags); ssleep(esp_bus_reset_settle); if (!wait_for_completion_timeout(&eh_reset, 5 * HZ)) { - spin_lock_irqsave(esp->host->host_lock, flags); + spin_lock_irqsave(&esp->host->host_lock, flags); esp->eh_reset = NULL; - spin_unlock_irqrestore(esp->host->host_lock, flags); + spin_unlock_irqrestore(&esp->host->host_lock, flags); return FAILED; } @@ -2645,10 +2645,10 @@ static int esp_eh_host_reset_handler(struct scsi_cmnd *cmd) struct esp *esp = shost_priv(cmd->device->host); unsigned long flags; - spin_lock_irqsave(esp->host->host_lock, flags); + spin_lock_irqsave(&esp->host->host_lock, flags); esp_bootup_reset(esp); esp_reset_cleanup(esp); - spin_unlock_irqrestore(esp->host->host_lock, flags); + spin_unlock_irqrestore(&esp->host->host_lock, flags); ssleep(esp_bus_reset_settle); diff --git a/drivers/scsi/fcoe/Makefile b/drivers/scsi/fcoe/Makefile index 1183e80a09e7..5e7121231801 100644 --- a/drivers/scsi/fcoe/Makefile +++ b/drivers/scsi/fcoe/Makefile @@ -1,4 +1,7 @@ # SPDX-License-Identifier: GPL-2.0-only + +CONTEXT_ANALYSIS := y + obj-$(CONFIG_FCOE) += fcoe.o obj-$(CONFIG_LIBFCOE) += libfcoe.o diff --git a/drivers/scsi/fcoe/fcoe.c b/drivers/scsi/fcoe/fcoe.c index 438ac7c3a9e3..a2cf65fac297 100644 --- a/drivers/scsi/fcoe/fcoe.c +++ b/drivers/scsi/fcoe/fcoe.c @@ -2705,7 +2705,7 @@ static void fcoe_vport_remove(struct fc_lport *lport) fc_host = shost_to_fc_host(shost); /* Loop through all the vports and mark them for deletion */ - spin_lock_irqsave(shost->host_lock, flags); + spin_lock_irqsave(&shost->host_lock, flags); list_for_each_entry_safe(vport, next_vport, &fc_host->vports, peers) { if (vport->flags & (FC_VPORT_DEL | FC_VPORT_CREATING)) { continue; @@ -2715,7 +2715,7 @@ static void fcoe_vport_remove(struct fc_lport *lport) &vport->vport_delete_work); } } - spin_unlock_irqrestore(shost->host_lock, flags); + spin_unlock_irqrestore(&shost->host_lock, flags); flush_workqueue(fc_host_work_q(shost)); } diff --git a/drivers/scsi/fcoe/fcoe_ctlr.c b/drivers/scsi/fcoe/fcoe_ctlr.c index 496ddd45f74d..bf92293a0ef0 100644 --- a/drivers/scsi/fcoe/fcoe_ctlr.c +++ b/drivers/scsi/fcoe/fcoe_ctlr.c @@ -42,7 +42,8 @@ static void fcoe_ctlr_timer_work(struct work_struct *); static void fcoe_ctlr_recv_work(struct work_struct *); static int fcoe_ctlr_flogi_retry(struct fcoe_ctlr *); -static void fcoe_ctlr_vn_start(struct fcoe_ctlr *); +static void fcoe_ctlr_vn_start(struct fcoe_ctlr *fip) + __must_hold(&fip->ctlr_mutex); static int fcoe_ctlr_vn_recv(struct fcoe_ctlr *, struct sk_buff *); static void fcoe_ctlr_vn_timeout(struct fcoe_ctlr *); static int fcoe_ctlr_vn_lookup(struct fcoe_ctlr *, u32, u8 *); @@ -154,13 +155,14 @@ EXPORT_SYMBOL(fcoe_ctlr_init); /** * fcoe_sysfs_fcf_add() - Add a fcoe_fcf{,_device} to a fcoe_ctlr{,_device} + * @fip: The FCoE controller * @new: The newly discovered FCF * * Called with fip->ctlr_mutex held */ -static int fcoe_sysfs_fcf_add(struct fcoe_fcf *new) +static int fcoe_sysfs_fcf_add(struct fcoe_ctlr *fip, struct fcoe_fcf *new) + __must_hold(&fip->ctlr_mutex) { - struct fcoe_ctlr *fip = new->fip; struct fcoe_ctlr_device *ctlr_dev; struct fcoe_fcf_device *temp, *fcf_dev; int rc = -ENOMEM; @@ -227,13 +229,14 @@ static int fcoe_sysfs_fcf_add(struct fcoe_fcf *new) /** * fcoe_sysfs_fcf_del() - Remove a fcoe_fcf{,_device} to a fcoe_ctlr{,_device} + * @fip: The FCoE controller * @new: The FCF to be removed * * Called with fip->ctlr_mutex held */ -static void fcoe_sysfs_fcf_del(struct fcoe_fcf *new) +static void fcoe_sysfs_fcf_del(struct fcoe_ctlr *fip, struct fcoe_fcf *new) + __must_hold(&fip->ctlr_mutex) { - struct fcoe_ctlr *fip = new->fip; struct fcoe_ctlr_device *cdev; struct fcoe_fcf_device *fcf_dev; @@ -268,13 +271,14 @@ static void fcoe_sysfs_fcf_del(struct fcoe_fcf *new) * Called with &fcoe_ctlr lock held. */ static void fcoe_ctlr_reset_fcfs(struct fcoe_ctlr *fip) + __must_hold(&fip->ctlr_mutex) { struct fcoe_fcf *fcf; struct fcoe_fcf *next; fip->sel_fcf = NULL; list_for_each_entry_safe(fcf, next, &fip->fcfs, list) { - fcoe_sysfs_fcf_del(fcf); + fcoe_sysfs_fcf_del(fip, fcf); } WARN_ON(fip->fcf_count); @@ -316,6 +320,8 @@ EXPORT_SYMBOL(fcoe_ctlr_destroy); * Called with neither ctlr_mutex nor ctlr_lock held. */ static void fcoe_ctlr_announce(struct fcoe_ctlr *fip) + __must_not_hold(&fip->ctlr_mutex) + __must_not_hold(&fip->ctlr_lock) { struct fcoe_fcf *sel; struct fcoe_fcf *fcf; @@ -476,6 +482,7 @@ EXPORT_SYMBOL(fcoe_ctlr_link_up); * @fip: The FCoE controller to reset */ static void fcoe_ctlr_reset(struct fcoe_ctlr *fip) + __must_hold(&fip->ctlr_mutex) { fcoe_ctlr_reset_fcfs(fip); timer_delete(&fip->timer); @@ -817,6 +824,7 @@ EXPORT_SYMBOL(fcoe_ctlr_els_send); * Returns the time in jiffies for the next call. */ static unsigned long fcoe_ctlr_age_fcfs(struct fcoe_ctlr *fip) + __must_hold(&fip->ctlr_mutex) { struct fcoe_fcf *fcf; struct fcoe_fcf *next; @@ -866,7 +874,7 @@ static unsigned long fcoe_ctlr_age_fcfs(struct fcoe_ctlr *fip) list_for_each_entry_safe(fcf, next, &del_list, list) { /* Removes fcf from current list */ - fcoe_sysfs_fcf_del(fcf); + fcoe_sysfs_fcf_del(fip, fcf); } if (sel_time && !fip->sel_fcf && !fip->sel_time) { @@ -1049,7 +1057,7 @@ static void fcoe_ctlr_recv_adv(struct fcoe_ctlr *fip, struct sk_buff *skb) memcpy(fcf, &new, sizeof(new)); fcf->fip = fip; - rc = fcoe_sysfs_fcf_add(fcf); + rc = fcoe_sysfs_fcf_add(fip, fcf); if (rc) { printk(KERN_ERR "Failed to allocate sysfs instance " "for FCF, fab %16.16llx mac %pM\n", @@ -1612,6 +1620,7 @@ static int fcoe_ctlr_recv_handler(struct fcoe_ctlr *fip, struct sk_buff *skb) * Called with lock held. */ static struct fcoe_fcf *fcoe_ctlr_select(struct fcoe_ctlr *fip) + __must_hold(&fip->ctlr_mutex) { struct fcoe_fcf *fcf; struct fcoe_fcf *best = fip->sel_fcf; @@ -1664,6 +1673,8 @@ static struct fcoe_fcf *fcoe_ctlr_select(struct fcoe_ctlr *fip) * Caller must verify that fip->sel_fcf is not NULL. */ static int fcoe_ctlr_flogi_send_locked(struct fcoe_ctlr *fip) + __must_hold(&fip->ctlr_mutex) + __must_hold(&fip->ctlr_lock) { struct sk_buff *skb; struct sk_buff *skb_orig; @@ -1733,6 +1744,7 @@ static int fcoe_ctlr_flogi_retry(struct fcoe_ctlr *fip) * Called with ctlr_mutex held. The caller must not hold ctlr_lock. */ static void fcoe_ctlr_flogi_send(struct fcoe_ctlr *fip) + __must_hold(&fip->ctlr_mutex) { struct fcoe_fcf *fcf; @@ -2012,6 +2024,7 @@ static inline struct fcoe_rport *fcoe_ctlr_rport(struct fc_rport_priv *rdata) static void fcoe_ctlr_vn_send(struct fcoe_ctlr *fip, enum fip_vn2vn_subcode sub, const u8 *dest, size_t min_len) + __must_hold(&fip->ctlr_mutex) { struct sk_buff *skb; struct fip_vn2vn_probe_frame { @@ -2152,11 +2165,14 @@ static struct fc_rport_operations fcoe_ctlr_vn_rport_ops = { /** * fcoe_ctlr_disc_stop_locked() - stop discovery in VN2VN mode + * @fip: The FCoE controller * @lport: The local port * * Called with ctlr_mutex held. */ -static void fcoe_ctlr_disc_stop_locked(struct fc_lport *lport) +static void fcoe_ctlr_disc_stop_locked(struct fcoe_ctlr *fip, + struct fc_lport *lport) + __must_hold(&fip->ctlr_mutex) { struct fc_rport_priv *rdata; @@ -2183,7 +2199,7 @@ static void fcoe_ctlr_disc_stop(struct fc_lport *lport) struct fcoe_ctlr *fip = lport->disc.priv; mutex_lock(&fip->ctlr_mutex); - fcoe_ctlr_disc_stop_locked(lport); + fcoe_ctlr_disc_stop_locked(fip, lport); mutex_unlock(&fip->ctlr_mutex); } @@ -2208,11 +2224,12 @@ static void fcoe_ctlr_disc_stop_final(struct fc_lport *lport) * Called with fcoe_ctlr lock held. */ static void fcoe_ctlr_vn_restart(struct fcoe_ctlr *fip) + __must_hold(&fip->ctlr_mutex) { unsigned long wait; u32 port_id; - fcoe_ctlr_disc_stop_locked(fip->lp); + fcoe_ctlr_disc_stop_locked(fip, fip->lp); /* * Get proposed port ID. @@ -2246,6 +2263,7 @@ static void fcoe_ctlr_vn_restart(struct fcoe_ctlr *fip) * Called with fcoe_ctlr lock held. */ static void fcoe_ctlr_vn_start(struct fcoe_ctlr *fip) + __must_hold(&fip->ctlr_mutex) { fip->probe_tries = 0; prandom_seed_state(&fip->rnd_state, fip->lp->wwpn); @@ -2387,6 +2405,7 @@ static int fcoe_ctlr_vn_parse(struct fcoe_ctlr *fip, * Called with ctlr_mutex held. */ static void fcoe_ctlr_vn_send_claim(struct fcoe_ctlr *fip) + __must_hold(&fip->ctlr_mutex) { fcoe_ctlr_vn_send(fip, FIP_SC_VN_CLAIM_NOTIFY, fcoe_all_vn2vn, 0); fip->sol_time = jiffies; @@ -2401,6 +2420,7 @@ static void fcoe_ctlr_vn_send_claim(struct fcoe_ctlr *fip) */ static void fcoe_ctlr_vn_probe_req(struct fcoe_ctlr *fip, struct fcoe_rport *frport) + __must_hold(&fip->ctlr_mutex) { if (frport->rdata.ids.port_id != fip->port_id) return; @@ -2452,6 +2472,7 @@ static void fcoe_ctlr_vn_probe_req(struct fcoe_ctlr *fip, */ static void fcoe_ctlr_vn_probe_reply(struct fcoe_ctlr *fip, struct fcoe_rport *frport) + __must_hold(&fip->ctlr_mutex) { if (frport->rdata.ids.port_id != fip->port_id) return; @@ -2481,6 +2502,7 @@ static void fcoe_ctlr_vn_probe_reply(struct fcoe_ctlr *fip, * Called with ctlr_mutex held. */ static void fcoe_ctlr_vn_add(struct fcoe_ctlr *fip, struct fcoe_rport *new) + __must_hold(&fip->ctlr_mutex) { struct fc_lport *lport = fip->lp; struct fc_rport_priv *rdata; @@ -2564,6 +2586,7 @@ static int fcoe_ctlr_vn_lookup(struct fcoe_ctlr *fip, u32 port_id, u8 *mac) */ static void fcoe_ctlr_vn_claim_notify(struct fcoe_ctlr *fip, struct fcoe_rport *new) + __must_hold(&fip->ctlr_mutex) { if (new->flags & FIP_FL_REC_OR_P2P) { LIBFCOE_FIP_DBG(fip, "send probe req for P2P/REC\n"); @@ -2619,6 +2642,7 @@ static void fcoe_ctlr_vn_claim_notify(struct fcoe_ctlr *fip, */ static void fcoe_ctlr_vn_claim_resp(struct fcoe_ctlr *fip, struct fcoe_rport *new) + __must_hold(&fip->ctlr_mutex) { LIBFCOE_FIP_DBG(fip, "claim resp from from rport %x - state %s\n", new->rdata.ids.port_id, fcoe_ctlr_state(fip->state)); @@ -2635,6 +2659,7 @@ static void fcoe_ctlr_vn_claim_resp(struct fcoe_ctlr *fip, */ static void fcoe_ctlr_vn_beacon(struct fcoe_ctlr *fip, struct fcoe_rport *new) + __must_hold(&fip->ctlr_mutex) { struct fc_lport *lport = fip->lp; struct fc_rport_priv *rdata; @@ -2688,6 +2713,7 @@ static void fcoe_ctlr_vn_beacon(struct fcoe_ctlr *fip, * Returns the soonest time for next age-out or a time far in the future. */ static unsigned long fcoe_ctlr_vn_age(struct fcoe_ctlr *fip) + __must_hold(&fip->ctlr_mutex) { struct fc_lport *lport = fip->lp; struct fc_rport_priv *rdata; @@ -2890,6 +2916,7 @@ static int fcoe_ctlr_vlan_parse(struct fcoe_ctlr *fip, static void fcoe_ctlr_vlan_send(struct fcoe_ctlr *fip, enum fip_vlan_subcode sub, const u8 *dest) + __must_hold(&fip->ctlr_mutex) { struct sk_buff *skb; struct fip_vlan_notify_frame { @@ -2951,6 +2978,7 @@ static void fcoe_ctlr_vlan_send(struct fcoe_ctlr *fip, */ static void fcoe_ctlr_vlan_disc_reply(struct fcoe_ctlr *fip, struct fcoe_rport *frport) + __must_hold(&fip->ctlr_mutex) { enum fip_vlan_subcode sub = FIP_SC_VL_NOTE; diff --git a/drivers/scsi/fdomain.c b/drivers/scsi/fdomain.c index 22fbb0222f07..b5766f752cdd 100644 --- a/drivers/scsi/fdomain.c +++ b/drivers/scsi/fdomain.c @@ -273,7 +273,7 @@ static void fdomain_work(struct work_struct *work) int status; int done = 0; - spin_lock_irqsave(sh->host_lock, flags); + spin_lock_irqsave(&sh->host_lock, flags); if (scsi_pointer->phase & in_arbitration) { status = inb(fd->base + REG_ASTAT); @@ -380,7 +380,7 @@ static void fdomain_work(struct work_struct *work) fd->base + REG_ICTL); } out: - spin_unlock_irqrestore(sh->host_lock, flags); + spin_unlock_irqrestore(&sh->host_lock, flags); } static irqreturn_t fdomain_irq(int irq, void *dev_id) @@ -416,7 +416,7 @@ static enum scsi_qc_status fdomain_queue(struct Scsi_Host *sh, scsi_pointer->phase = in_arbitration; scsi_set_resid(cmd, scsi_bufflen(cmd)); - spin_lock_irqsave(sh->host_lock, flags); + spin_lock_irqsave(&sh->host_lock, flags); fd->cur_cmd = cmd; @@ -431,7 +431,7 @@ static enum scsi_qc_status fdomain_queue(struct Scsi_Host *sh, /* Start arbitration */ outb(ACTL_ARB | ACTL_IRQEN | PARITY_MASK, fd->base + REG_ACTL); - spin_unlock_irqrestore(sh->host_lock, flags); + spin_unlock_irqrestore(&sh->host_lock, flags); return 0; } @@ -445,7 +445,7 @@ static int fdomain_abort(struct scsi_cmnd *cmd) if (!fd->cur_cmd) return FAILED; - spin_lock_irqsave(sh->host_lock, flags); + spin_lock_irqsave(&sh->host_lock, flags); fdomain_make_bus_idle(fd); fdomain_scsi_pointer(fd->cur_cmd)->phase |= aborted; @@ -453,7 +453,7 @@ static int fdomain_abort(struct scsi_cmnd *cmd) /* Aborts are not done well. . . */ set_host_byte(fd->cur_cmd, DID_ABORT); fdomain_finish_cmd(fd); - spin_unlock_irqrestore(sh->host_lock, flags); + spin_unlock_irqrestore(&sh->host_lock, flags); return SUCCESS; } @@ -463,9 +463,9 @@ static int fdomain_host_reset(struct scsi_cmnd *cmd) struct fdomain *fd = shost_priv(sh); unsigned long flags; - spin_lock_irqsave(sh->host_lock, flags); + spin_lock_irqsave(&sh->host_lock, flags); fdomain_reset(fd->base); - spin_unlock_irqrestore(sh->host_lock, flags); + spin_unlock_irqrestore(&sh->host_lock, flags); return SUCCESS; } diff --git a/drivers/scsi/fnic/Makefile b/drivers/scsi/fnic/Makefile index 48c5e0cb8ca6..22a463380dee 100644 --- a/drivers/scsi/fnic/Makefile +++ b/drivers/scsi/fnic/Makefile @@ -1,4 +1,7 @@ # SPDX-License-Identifier: GPL-2.0 + +CONTEXT_ANALYSIS := y + obj-$(CONFIG_FCOE_FNIC) += fnic.o fnic-y := \ diff --git a/drivers/scsi/fnic/fdls_disc.c b/drivers/scsi/fnic/fdls_disc.c index 8cb40466872f..b04bb9a5dfa8 100644 --- a/drivers/scsi/fnic/fdls_disc.c +++ b/drivers/scsi/fnic/fdls_disc.c @@ -87,7 +87,8 @@ static void fnic_fdls_start_flogi(struct fnic_iport_s *iport); static struct fnic_tport_s *fdls_create_tport(struct fnic_iport_s *iport, uint32_t fcid, uint64_t wwpn); -static void fdls_target_restart_nexus(struct fnic_tport_s *tport); +static void fdls_target_restart_nexus(struct fnic_iport_s *iport, + struct fnic_tport_s *tport); static void fdls_start_tport_timer(struct fnic_iport_s *iport, struct fnic_tport_s *tport, int timeout); static void fdls_tport_timer_callback(struct timer_list *t); @@ -417,6 +418,7 @@ static void fdls_reset_oxid_pool(struct fnic_iport_s *iport) } void fnic_del_fabric_timer_sync(struct fnic *fnic) + __must_hold(&fnic->fnic_lock) { fnic->iport.fabric.del_timer_inprogress = 1; spin_unlock_irqrestore(&fnic->fnic_lock, fnic->lock_flags); @@ -425,8 +427,8 @@ void fnic_del_fabric_timer_sync(struct fnic *fnic) fnic->iport.fabric.del_timer_inprogress = 0; } -void fnic_del_tport_timer_sync(struct fnic *fnic, - struct fnic_tport_s *tport) +void fnic_del_tport_timer_sync(struct fnic *fnic, struct fnic_tport_s *tport) + __must_hold(&fnic->fnic_lock) { tport->del_timer_inprogress = 1; spin_unlock_irqrestore(&fnic->fnic_lock, fnic->lock_flags); @@ -437,6 +439,7 @@ void fnic_del_tport_timer_sync(struct fnic *fnic, static void fdls_start_fabric_timer(struct fnic_iport_s *iport, int timeout) + __must_hold(&iport->fnic->fnic_lock) { u64 fabric_tov; struct fnic *fnic = iport->fnic; @@ -462,6 +465,7 @@ fdls_start_fabric_timer(struct fnic_iport_s *iport, int timeout) static void fdls_start_tport_timer(struct fnic_iport_s *iport, struct fnic_tport_s *tport, int timeout) + __must_hold(&iport->fnic->fnic_lock) { u64 fabric_tov; struct fnic *fnic = iport->fnic; @@ -717,6 +721,7 @@ int fdls_send_ls_req_abts(struct fnic_iport_s *iport, void fdls_send_tport_abts(struct fnic_iport_s *iport, struct fnic_tport_s *tport) + __must_hold(&iport->fnic->fnic_lock) { uint8_t *frame; uint8_t s_id[3]; @@ -760,7 +765,9 @@ fdls_send_tport_abts(struct fnic_iport_s *iport, /* Even if fnic_send_fcoe_frame() fails we want to retry after timeout */ fdls_start_tport_timer(iport, tport, 2 * iport->e_d_tov); } + static void fdls_send_fabric_abts(struct fnic_iport_s *iport) + __must_hold(&iport->fnic->fnic_lock) { uint8_t *frame; uint8_t s_id[3]; @@ -932,6 +939,7 @@ static void fdls_send_fdmi_abts(struct fnic_iport_s *iport) } static void fdls_send_fabric_flogi(struct fnic_iport_s *iport) + __must_hold(&iport->fnic->fnic_lock) { uint8_t *frame; struct fc_std_flogi *pflogi; @@ -992,6 +1000,7 @@ static void fdls_send_fabric_flogi(struct fnic_iport_s *iport) } static void fdls_send_fabric_plogi(struct fnic_iport_s *iport) + __must_hold(&iport->fnic->fnic_lock) { uint8_t *frame; struct fc_std_flogi *pplogi; @@ -1084,6 +1093,7 @@ static void fdls_send_fdmi_plogi(struct fnic_iport_s *iport) } static void fdls_send_rpn_id(struct fnic_iport_s *iport) + __must_hold(&iport->fnic->fnic_lock) { uint8_t *frame; struct fc_std_rpn_id *prpn_id; @@ -1143,6 +1153,7 @@ static void fdls_send_rpn_id(struct fnic_iport_s *iport) } static void fdls_send_scr(struct fnic_iport_s *iport) + __must_hold(&iport->fnic->fnic_lock) { uint8_t *frame; struct fc_std_scr *pscr; @@ -1198,6 +1209,7 @@ static void fdls_send_scr(struct fnic_iport_s *iport) } static void fdls_send_gpn_ft(struct fnic_iport_s *iport, int fdls_state) + __must_hold(&iport->fnic->fnic_lock) { uint8_t *frame; struct fc_std_gpn_ft *pgpn_ft; @@ -1257,6 +1269,7 @@ static void fdls_send_gpn_ft(struct fnic_iport_s *iport, int fdls_state) static void fdls_send_tgt_adisc(struct fnic_iport_s *iport, struct fnic_tport_s *tport) + __must_hold(&iport->fnic->fnic_lock) { uint8_t *frame; struct fc_std_els_adisc *padisc; @@ -1322,6 +1335,7 @@ fdls_send_tgt_adisc(struct fnic_iport_s *iport, struct fnic_tport_s *tport) } bool fdls_delete_tport(struct fnic_iport_s *iport, struct fnic_tport_s *tport) + __must_hold(&iport->fnic->fnic_lock) { struct fnic_tport_event_s *tport_del_evt; struct fnic *fnic = iport->fnic; @@ -1387,6 +1401,7 @@ bool fdls_delete_tport(struct fnic_iport_s *iport, struct fnic_tport_s *tport) static void fdls_send_tgt_plogi(struct fnic_iport_s *iport, struct fnic_tport_s *tport) + __must_hold(&iport->fnic->fnic_lock) { uint8_t *frame; struct fc_std_flogi *pplogi; @@ -1455,6 +1470,7 @@ fnic_fc_plogi_rsp_rdf(struct fnic_iport_s *iport, } static void fdls_send_register_fc4_types(struct fnic_iport_s *iport) + __must_hold(&iport->fnic->fnic_lock) { uint8_t *frame; struct fc_std_rft_id *prft_id; @@ -1522,6 +1538,7 @@ static void fdls_send_register_fc4_types(struct fnic_iport_s *iport) } static void fdls_send_register_fc4_features(struct fnic_iport_s *iport) + __must_hold(&iport->fnic->fnic_lock) { uint8_t *frame; struct fc_std_rff_id *prff_id; @@ -1581,6 +1598,7 @@ static void fdls_send_register_fc4_features(struct fnic_iport_s *iport) static void fdls_send_tgt_prli(struct fnic_iport_s *iport, struct fnic_tport_s *tport) + __must_hold(&iport->fnic->fnic_lock) { uint8_t *frame; struct fc_std_els_prli *pprli; @@ -1662,6 +1680,7 @@ fdls_send_tgt_prli(struct fnic_iport_s *iport, struct fnic_tport_s *tport) * Currently this assumes to be called with fnic lock held. */ void fdls_send_fabric_logo(struct fnic_iport_s *iport) + __must_hold(&iport->fnic->fnic_lock) { uint8_t *frame; struct fc_std_logo *plogo; @@ -1761,6 +1780,7 @@ void fdls_tgt_logout(struct fnic_iport_s *iport, struct fnic_tport_s *tport) } static void fdls_tgt_discovery_start(struct fnic_iport_s *iport) + __must_hold(&iport->fnic->fnic_lock) { struct fnic_tport_s *tport, *next; u32 old_link_down_cnt = iport->fnic->link_down_cnt; @@ -1810,9 +1830,10 @@ static void fdls_tgt_discovery_start(struct fnic_iport_s *iport) * safely since the memory it is * pointing to it will be freed later */ -static void fdls_target_restart_nexus(struct fnic_tport_s *tport) +static void fdls_target_restart_nexus(struct fnic_iport_s *iport, + struct fnic_tport_s *tport) + __must_hold(&iport->fnic->fnic_lock) { - struct fnic_iport_s *iport = tport->iport; struct fnic_tport_s *new_tport = NULL; uint32_t fcid; uint64_t wwpn; @@ -2617,6 +2638,7 @@ static void fdls_tport_timer_callback(struct timer_list *t) } static void fnic_fdls_start_flogi(struct fnic_iport_s *iport) + __must_hold(&iport->fnic->fnic_lock) { iport->fabric.retry_counter = 0; fdls_send_fabric_flogi(iport); @@ -2625,6 +2647,7 @@ static void fnic_fdls_start_flogi(struct fnic_iport_s *iport) } static void fnic_fdls_start_plogi(struct fnic_iport_s *iport) + __must_hold(&iport->fnic->fnic_lock) { iport->fabric.retry_counter = 0; fdls_send_fabric_plogi(iport); @@ -2643,6 +2666,7 @@ static void fnic_fdls_start_plogi(struct fnic_iport_s *iport) static void fdls_process_tgt_adisc_rsp(struct fnic_iport_s *iport, struct fc_frame_header *fchdr) + __must_hold(&iport->fnic->fnic_lock) { uint32_t tgt_fcid; struct fnic_tport_s *tport; @@ -2733,6 +2757,7 @@ fdls_process_tgt_adisc_rsp(struct fnic_iport_s *iport, static void fdls_process_tgt_plogi_rsp(struct fnic_iport_s *iport, struct fc_frame_header *fchdr) + __must_hold(&iport->fnic->fnic_lock) { uint32_t tgt_fcid; struct fnic_tport_s *tport; @@ -2767,7 +2792,7 @@ fdls_process_tgt_plogi_rsp(struct fnic_iport_s *iport, if (tport->state != FDLS_TGT_STATE_PLOGI) { FNIC_FCS_DBG(KERN_INFO, fnic, "PLOGI rsp recvd in wrong state. Drop the frame and restart nexus"); - fdls_target_restart_nexus(tport); + fdls_target_restart_nexus(iport, tport); return; } @@ -2854,9 +2879,11 @@ fdls_process_tgt_plogi_rsp(struct fnic_iport_s *iport, fdls_set_tport_state(tport, FDLS_TGT_STATE_PRLI); fdls_send_tgt_prli(iport, tport); } + static void fdls_process_tgt_prli_rsp(struct fnic_iport_s *iport, struct fc_frame_header *fchdr) + __must_hold(&iport->fnic->fnic_lock) { uint32_t tgt_fcid; struct fnic_tport_s *tport; @@ -2893,7 +2920,7 @@ fdls_process_tgt_prli_rsp(struct fnic_iport_s *iport, if (tport->state != FDLS_TGT_STATE_PRLI) { FNIC_FCS_DBG(KERN_INFO, fnic, "PRLI rsp recvd in wrong state. Drop frame. Restarting nexus"); - fdls_target_restart_nexus(tport); + fdls_target_restart_nexus(iport, tport); return; } @@ -3025,6 +3052,7 @@ fdls_process_tgt_prli_rsp(struct fnic_iport_s *iport, static void fdls_process_rff_id_rsp(struct fnic_iport_s *iport, struct fc_frame_header *fchdr) + __must_hold(&iport->fnic->fnic_lock) { struct fnic *fnic = iport->fnic; struct fnic_fdls_fabric_s *fdls = &iport->fabric; @@ -3098,6 +3126,7 @@ fdls_process_rff_id_rsp(struct fnic_iport_s *iport, static void fdls_process_rft_id_rsp(struct fnic_iport_s *iport, struct fc_frame_header *fchdr) + __must_hold(&iport->fnic->fnic_lock) { struct fnic_fdls_fabric_s *fdls = &iport->fabric; struct fc_std_rft_id *rft_rsp = (struct fc_std_rft_id *) fchdr; @@ -3173,6 +3202,7 @@ fdls_process_rft_id_rsp(struct fnic_iport_s *iport, static void fdls_process_rpn_id_rsp(struct fnic_iport_s *iport, struct fc_frame_header *fchdr) + __must_hold(&iport->fnic->fnic_lock) { struct fnic_fdls_fabric_s *fdls = &iport->fabric; struct fc_std_rpn_id *rpn_rsp = (struct fc_std_rpn_id *) fchdr; @@ -3243,6 +3273,7 @@ fdls_process_rpn_id_rsp(struct fnic_iport_s *iport, static void fdls_process_scr_rsp(struct fnic_iport_s *iport, struct fc_frame_header *fchdr) + __must_hold(&iport->fnic->fnic_lock) { struct fnic_fdls_fabric_s *fdls = &iport->fabric; struct fc_std_scr *scr_rsp = (struct fc_std_scr *) fchdr; @@ -3315,6 +3346,7 @@ fdls_process_scr_rsp(struct fnic_iport_s *iport, static void fdls_process_gpn_ft_tgt_list(struct fnic_iport_s *iport, struct fc_frame_header *fchdr, int len) + __must_hold(&iport->fnic->fnic_lock) { struct fc_gpn_ft_rsp_iu *gpn_ft_tgt; struct fnic_tport_s *tport, *next; @@ -3413,6 +3445,7 @@ fdls_process_gpn_ft_tgt_list(struct fnic_iport_s *iport, static void fdls_process_gpn_ft_rsp(struct fnic_iport_s *iport, struct fc_frame_header *fchdr, int len) + __must_hold(&iport->fnic->fnic_lock) { struct fnic_fdls_fabric_s *fdls = &iport->fabric; struct fc_std_gpn_ft *gpn_ft_rsp = (struct fc_std_gpn_ft *) fchdr; @@ -3549,6 +3582,7 @@ fdls_process_gpn_ft_rsp(struct fnic_iport_s *iport, static void fdls_process_fabric_logo_rsp(struct fnic_iport_s *iport, struct fc_frame_header *fchdr) + __must_hold(&iport->fnic->fnic_lock) { struct fc_std_flogi *flogo_rsp = (struct fc_std_flogi *) fchdr; struct fnic_fdls_fabric_s *fdls = &iport->fabric; @@ -3602,6 +3636,7 @@ fdls_process_fabric_logo_rsp(struct fnic_iport_s *iport, static void fdls_process_flogi_rsp(struct fnic_iport_s *iport, struct fc_frame_header *fchdr, void *rx_frame) + __must_hold(&iport->fnic->fnic_lock) { struct fnic_fdls_fabric_s *fabric = &iport->fabric; struct fc_std_flogi *flogi_rsp = (struct fc_std_flogi *) fchdr; @@ -3741,6 +3776,7 @@ fdls_process_flogi_rsp(struct fnic_iport_s *iport, static void fdls_process_fabric_plogi_rsp(struct fnic_iport_s *iport, struct fc_frame_header *fchdr) + __must_hold(&iport->fnic->fnic_lock) { struct fc_std_flogi *plogi_rsp = (struct fc_std_flogi *) fchdr; struct fc_std_els_rjt_rsp *els_rjt = (struct fc_std_els_rjt_rsp *) fchdr; @@ -4002,6 +4038,7 @@ static void fdls_process_fdmi_abts_rsp(struct fnic_iport_s *iport, static void fdls_process_fabric_abts_rsp(struct fnic_iport_s *iport, struct fc_frame_header *fchdr) + __must_hold(&iport->fnic->fnic_lock) { uint32_t s_id; struct fc_std_abts_ba_acc *ba_acc = (struct fc_std_abts_ba_acc *)fchdr; @@ -4359,6 +4396,7 @@ fdls_process_els_req(struct fnic_iport_s *iport, struct fc_frame_header *fchdr, static void fdls_process_tgt_abts_rsp(struct fnic_iport_s *iport, struct fc_frame_header *fchdr) + __must_hold(&iport->fnic->fnic_lock) { uint32_t s_id; struct fnic_tport_s *tport; @@ -4548,6 +4586,7 @@ fdls_process_plogi_req(struct fnic_iport_s *iport, static void fdls_process_logo_req(struct fnic_iport_s *iport, struct fc_frame_header *fchdr) + __must_hold(&iport->fnic->fnic_lock) { struct fc_std_logo *logo = (struct fc_std_logo *)fchdr; uint32_t nport_id; @@ -4625,6 +4664,7 @@ fdls_process_logo_req(struct fnic_iport_s *iport, struct fc_frame_header *fchdr) static void fdls_process_rscn(struct fnic_iport_s *iport, struct fc_frame_header *fchdr) + __must_hold(&iport->fnic->fnic_lock) { struct fc_std_rscn *rscn; struct fc_els_rscn_page *rscn_port = NULL; @@ -4758,6 +4798,7 @@ fdls_process_rscn(struct fnic_iport_s *iport, struct fc_frame_header *fchdr) } void fnic_fdls_disc_start(struct fnic_iport_s *iport) + __must_hold(&iport->fnic->fnic_lock) { struct fnic *fnic = iport->fnic; @@ -5102,6 +5143,7 @@ fnic_fdls_validate_and_get_frame_type(struct fnic_iport_s *iport, void fnic_fdls_recv_frame(struct fnic_iport_s *iport, void *rx_frame, int len, int fchdr_offset) + __must_hold(&iport->fnic->fnic_lock) { struct fc_frame_header *fchdr; uint32_t s_id = 0; @@ -5223,6 +5265,7 @@ void fnic_fdls_disc_init(struct fnic_iport_s *iport) } void fnic_fdls_link_down(struct fnic_iport_s *iport) + __must_hold(&iport->fnic->fnic_lock) { struct fnic_tport_s *tport, *next; struct fnic *fnic = iport->fnic; diff --git a/drivers/scsi/fnic/fip.c b/drivers/scsi/fnic/fip.c index 231dec180675..8f44abfc01a5 100644 --- a/drivers/scsi/fnic/fip.c +++ b/drivers/scsi/fnic/fip.c @@ -602,6 +602,7 @@ void fnic_common_fip_cleanup(struct fnic *fnic) * and clean up and restart the vlan discovery. */ void fnic_fcoe_process_cvl(struct fnic *fnic, struct fip_header *fiph) + __must_hold(&fnic->fnic_lock) { struct fnic_iport_s *iport = &fnic->iport; struct fip_cvl *cvl_msg = (struct fip_cvl *)fiph; @@ -678,6 +679,7 @@ void fnic_fcoe_process_cvl(struct fnic *fnic, struct fip_header *fiph) * @frame: Received ethernet frame */ int fdls_fip_recv_frame(struct fnic *fnic, void *frame) + __must_hold(&fnic->fnic_lock) { struct ethhdr *eth = (struct ethhdr *)frame; struct fip_header *fiph; diff --git a/drivers/scsi/fnic/fnic.h b/drivers/scsi/fnic/fnic.h index c576a7f5083e..3ba1592940ca 100644 --- a/drivers/scsi/fnic/fnic.h +++ b/drivers/scsi/fnic/fnic.h @@ -31,7 +31,7 @@ #define DRV_NAME "fnic" #define DRV_DESCRIPTION "Cisco FCoE HBA Driver" -#define DRV_VERSION "1.9.0.0" +#define DRV_VERSION "1.9.0.1" #define PFX DRV_NAME ": " #define DFX DRV_NAME "%d: " diff --git a/drivers/scsi/fnic/fnic_fcs.c b/drivers/scsi/fnic/fnic_fcs.c index b00672ef8b00..b5a6a2b99c4e 100644 --- a/drivers/scsi/fnic/fnic_fcs.c +++ b/drivers/scsi/fnic/fnic_fcs.c @@ -942,10 +942,10 @@ void fnic_free_wq_buf(struct vnic_wq *wq, struct vnic_wq_buf *buf) } void -fnic_fdls_add_tport(struct fnic_iport_s *iport, struct fnic_tport_s *tport, - unsigned long flags) +fnic_fdls_add_tport(struct fnic *fnic, struct fnic_tport_s *tport, + unsigned long flags) + __must_hold(&fnic->fnic_lock) { - struct fnic *fnic = iport->fnic; struct fc_rport *rport; struct fc_rport_identifiers ids; struct rport_dd_data_s *rdd_data; @@ -975,18 +975,17 @@ fnic_fdls_add_tport(struct fnic_iport_s *iport, struct fnic_tport_s *tport, rport->supported_classes = FC_COS_CLASS3 | FC_RPORT_ROLE_FCP_TARGET; rdd_data = rport->dd_data; rdd_data->tport = tport; - rdd_data->iport = iport; + rdd_data->iport = &fnic->iport; tport->rport = rport; tport->flags |= FNIC_FDLS_SCSI_REGISTERED; } void -fnic_fdls_remove_tport(struct fnic_iport_s *iport, - struct fnic_tport_s *tport, unsigned long flags) +fnic_fdls_remove_tport(struct fnic *fnic, struct fnic_tport_s *tport, + unsigned long flags) + __must_hold(&fnic->fnic_lock) { - struct fnic *fnic = iport->fnic; struct rport_dd_data_s *rdd_data; - struct fc_rport *rport; if (!tport) @@ -1038,7 +1037,7 @@ void fnic_delete_fcp_tports(struct fnic *fnic) fdls_set_tport_state(tport, FDLS_TGT_STATE_OFFLINING); fnic_del_tport_timer_sync(fnic, tport); if (IS_FNIC_FCP_INITIATOR(fnic)) - fnic_fdls_remove_tport(&fnic->iport, tport, flags); + fnic_fdls_remove_tport(fnic, tport, flags); else if (IS_FNIC_NVME_INITIATOR(fnic)) nvfnic_delete_tport(&fnic->iport, tport, flags); } @@ -1067,7 +1066,7 @@ void fnic_tport_event_handler(struct work_struct *work) "Add rport event"); if (tport->state == FDLS_TGT_STATE_READY) { if (IS_FNIC_FCP_INITIATOR(fnic)) - fnic_fdls_add_tport(&fnic->iport, tport, flags); + fnic_fdls_add_tport(fnic, tport, flags); else if (IS_FNIC_NVME_INITIATOR(fnic)) nvfnic_add_tport(fnic, tport, flags); } else { @@ -1081,7 +1080,7 @@ void fnic_tport_event_handler(struct work_struct *work) "Remove rport event"); if (tport->state == FDLS_TGT_STATE_OFFLINING) { if (IS_FNIC_FCP_INITIATOR(fnic)) - fnic_fdls_remove_tport(&fnic->iport, tport, flags); + fnic_fdls_remove_tport(fnic, tport, flags); else if (IS_FNIC_NVME_INITIATOR(fnic)) nvfnic_delete_tport(&fnic->iport, tport, flags); } else { diff --git a/drivers/scsi/fnic/fnic_fdls.h b/drivers/scsi/fnic/fnic_fdls.h index ce4b3aae77e3..75f83c78aea1 100644 --- a/drivers/scsi/fnic/fnic_fdls.h +++ b/drivers/scsi/fnic/fnic_fdls.h @@ -433,10 +433,9 @@ int fnic_send_fip_frame(struct fnic_iport_s *iport, void *frame, int frame_size); void fnic_fdls_learn_fcoe_macs(struct fnic_iport_s *iport, void *rx_frame, uint8_t *fcid); -void fnic_fdls_add_tport(struct fnic_iport_s *iport, - struct fnic_tport_s *tport, unsigned long flags); -void fnic_fdls_remove_tport(struct fnic_iport_s *iport, - struct fnic_tport_s *tport, +void fnic_fdls_add_tport(struct fnic *fnic, struct fnic_tport_s *tport, + unsigned long flags); +void fnic_fdls_remove_tport(struct fnic *fnic, struct fnic_tport_s *tport, unsigned long flags); void fnic_fcpio_reset(struct fnic *fnic); diff --git a/drivers/scsi/fnic/fnic_isr.c b/drivers/scsi/fnic/fnic_isr.c index 02856745580f..43149d8312ec 100644 --- a/drivers/scsi/fnic/fnic_isr.c +++ b/drivers/scsi/fnic/fnic_isr.c @@ -245,7 +245,14 @@ int fnic_set_intr_mode_msix(struct fnic *fnic) unsigned int m = ARRAY_SIZE(fnic->wq); unsigned int o = ARRAY_SIZE(fnic->hw_copy_wq); unsigned int min_irqs = n + m + 1 + 1; /*rq, raw wq, wq, err*/ - + /* + * Make driver critical vectors unmanaged, or else it can get tied + * to an offline CPU. This can happen when hyper-threading is off. + */ + struct irq_affinity affd = { + .pre_vectors = n + m + 1, /* rq, raw wq, 1 ioq */ + .post_vectors = 1, /* err */ + }; /* * We need n RQs, m WQs, o Copy WQs, n+m+o CQs, and n+m+o+1 INTRs * (last INTR is used for WQ/RQ errors and notification area) @@ -263,8 +270,8 @@ int fnic_set_intr_mode_msix(struct fnic *fnic) int vec_count = 0; int vecs = fnic->rq_count + fnic->raw_wq_count + fnic->wq_copy_count + 1; - vec_count = pci_alloc_irq_vectors(fnic->pdev, min_irqs, vecs, - PCI_IRQ_MSIX | PCI_IRQ_AFFINITY); + vec_count = pci_alloc_irq_vectors_affinity(fnic->pdev, min_irqs, + vecs, PCI_IRQ_MSIX|PCI_IRQ_AFFINITY, &affd); FNIC_ISR_DBG(KERN_INFO, fnic, "allocated %d MSI-X vectors\n", vec_count); diff --git a/drivers/scsi/fnic/fnic_main.c b/drivers/scsi/fnic/fnic_main.c index 9b3025007075..f13c381a66d7 100644 --- a/drivers/scsi/fnic/fnic_main.c +++ b/drivers/scsi/fnic/fnic_main.c @@ -744,8 +744,19 @@ static int fnic_nvme_drv_init(struct fnic *fnic) return ret; } +static void fnic_mq_init_queue_map(struct fnic *fnic, + struct blk_mq_queue_map *qmap) +{ + unsigned int cpu; + + for_each_possible_cpu(cpu) + qmap->mq_map[cpu] = 0; +} + void fnic_mq_map_queues_cpus(struct Scsi_Host *host) { + const struct cpumask *mask; + unsigned int queue, cpu; struct fnic *fnic = *((struct fnic **) shost_priv(host)); struct pci_dev *l_pdev = fnic->pdev; int intr_mode = fnic->config.intr_mode; @@ -766,7 +777,35 @@ void fnic_mq_map_queues_cpus(struct Scsi_Host *host) return; } - blk_mq_map_hw_queues(qmap, &l_pdev->dev, FNIC_PCI_OFFSET); + fnic_mq_init_queue_map(fnic, qmap); + + /* + * Setup CPU to Queue mapping for all managed MSI-X IRQs. + * Q0 is driver critical and non-managed, hence start from Q1. + */ + for (queue = 1; queue < qmap->nr_queues; queue++) { + int irq_num = pci_irq_vector(fnic->pdev, + queue + FNIC_PCI_OFFSET); + + if (irq_num < 0) + continue; + + mask = pci_irq_get_affinity(fnic->pdev, + queue + FNIC_PCI_OFFSET); + if (!mask) { + shost_printk(KERN_ERR, host, + "failed to get irq_affinity map for queue:%d\n", irq_num); + continue; + } + FNIC_MAIN_DBG(KERN_INFO, fnic, + "got irq_affinity map for %d:\n", irq_num); + for_each_cpu(cpu, mask) { + qmap->mq_map[cpu] = qmap->queue_offset + queue; + FNIC_MAIN_DBG(KERN_INFO, fnic, + "[Q%d] cpu:%d <=> irq:%d\n", + queue, cpu, irq_num); + } + } } static int fnic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) diff --git a/drivers/scsi/fnic/fnic_scsi.c b/drivers/scsi/fnic/fnic_scsi.c index 9607684bc610..afd6bf03b02d 100644 --- a/drivers/scsi/fnic/fnic_scsi.c +++ b/drivers/scsi/fnic/fnic_scsi.c @@ -2641,6 +2641,8 @@ int fnic_device_reset(struct scsi_cmnd *sc) * allocated by mid layer. */ mutex_lock(&fnic->sgreset_mutex); + /* Fake __release() to keep the lock context analyzer happy. */ + __release(&fnic->sgreset_mutex); mqtag = fnic->fnic_max_tag_id; new_sc = 1; } else { @@ -2826,6 +2828,8 @@ int fnic_device_reset(struct scsi_cmnd *sc) if (new_sc) { fnic->sgreset_sc = NULL; + /* Fake __acquire() to keep the lock context analyzer happy. */ + __acquire(&fnic->sgreset_mutex); mutex_unlock(&fnic->sgreset_mutex); } diff --git a/drivers/scsi/gvp11.c b/drivers/scsi/gvp11.c index 79bd64e12adc..a29457f5adfb 100644 --- a/drivers/scsi/gvp11.c +++ b/drivers/scsi/gvp11.c @@ -42,9 +42,9 @@ static irqreturn_t gvp11_intr(int irq, void *data) if (!(status & GVP11_DMAC_INT_PENDING)) return IRQ_NONE; - spin_lock_irqsave(instance->host_lock, flags); + spin_lock_irqsave(&instance->host_lock, flags); wd33c93_intr(instance); - spin_unlock_irqrestore(instance->host_lock, flags); + spin_unlock_irqrestore(&instance->host_lock, flags); return IRQ_HANDLED; } diff --git a/drivers/scsi/hisi_sas/Makefile b/drivers/scsi/hisi_sas/Makefile index 742e732cd51d..8576c78d4afe 100644 --- a/drivers/scsi/hisi_sas/Makefile +++ b/drivers/scsi/hisi_sas/Makefile @@ -1,4 +1,7 @@ # SPDX-License-Identifier: GPL-2.0-only + +CONTEXT_ANALYSIS := y + obj-$(CONFIG_SCSI_HISI_SAS) += hisi_sas_main.o obj-$(CONFIG_SCSI_HISI_SAS) += hisi_sas_v1_hw.o hisi_sas_v2_hw.o obj-$(CONFIG_SCSI_HISI_SAS_PCI) += hisi_sas_v3_hw.o diff --git a/drivers/scsi/hisi_sas/hisi_sas.h b/drivers/scsi/hisi_sas/hisi_sas.h index 1323ed8aa717..d48ba3747b81 100644 --- a/drivers/scsi/hisi_sas/hisi_sas.h +++ b/drivers/scsi/hisi_sas/hisi_sas.h @@ -163,6 +163,7 @@ enum hisi_sas_phy_event { HISI_PHYE_PHY_UP = 0U, HISI_PHYE_LINK_RESET, HISI_PHYE_PHY_UP_PM, + HISI_PHYE_SPINUP_NOTIFY, HISI_PHYES_NUM, }; @@ -689,4 +690,6 @@ extern void hisi_sas_sync_cqs(struct hisi_hba *hisi_hba); extern void hisi_sas_sync_poll_cqs(struct hisi_hba *hisi_hba); extern void hisi_sas_controller_reset_prepare(struct hisi_hba *hisi_hba); extern void hisi_sas_controller_reset_done(struct hisi_hba *hisi_hba); +extern void hisi_sas_spinup_notify(struct hisi_hba *hisi_hba, + struct sas_task *task); #endif diff --git a/drivers/scsi/hisi_sas/hisi_sas_main.c b/drivers/scsi/hisi_sas/hisi_sas_main.c index 944ce19ae2fc..cf7aa0a699cd 100644 --- a/drivers/scsi/hisi_sas/hisi_sas_main.c +++ b/drivers/scsi/hisi_sas/hisi_sas_main.c @@ -996,10 +996,25 @@ static void hisi_sas_phyup_pm_work(struct work_struct *work) pm_runtime_put_sync(dev); } +static void hisi_sas_spinup_notify_work(struct work_struct *work) +{ + struct hisi_sas_phy *phy = + container_of(work, typeof(*phy), works[HISI_PHYE_SPINUP_NOTIFY]); + struct hisi_hba *hisi_hba = phy->hisi_hba; + struct device *dev = hisi_hba->dev; + int phy_no = phy->sas_phy.id; + + hisi_hba->hw->sl_notify_ssp(hisi_hba, phy_no); + dev_info(dev, "spinup notify primitive on phy%d\n", phy_no); + + pm_runtime_put_sync(dev); +} + static const work_func_t hisi_sas_phye_fns[HISI_PHYES_NUM] = { [HISI_PHYE_PHY_UP] = hisi_sas_phyup_work, [HISI_PHYE_LINK_RESET] = hisi_sas_linkreset_work, [HISI_PHYE_PHY_UP_PM] = hisi_sas_phyup_pm_work, + [HISI_PHYE_SPINUP_NOTIFY] = hisi_sas_spinup_notify_work, }; bool hisi_sas_notify_phy_event(struct hisi_sas_phy *phy, @@ -1639,6 +1654,34 @@ void hisi_sas_controller_reset_done(struct hisi_hba *hisi_hba) } EXPORT_SYMBOL_GPL(hisi_sas_controller_reset_done); +void hisi_sas_spinup_notify(struct hisi_hba *hisi_hba, + struct sas_task *task) +{ + struct task_status_struct *ts = &task->task_status; + struct domain_device *dev = task->dev; + struct scsi_sense_hdr sshdr; + struct sas_phy *local_phy; + struct hisi_sas_phy *phy; + + if (!scsi_normalize_sense(ts->buf, ts->buf_valid_size, &sshdr)) + return; + + if (sshdr.sense_key != NOT_READY || + sshdr.sense_code != LU_NOT_READY_NOTIFY_REQUIRED) + return; + + if (!pm_runtime_get_if_active(hisi_hba->dev)) + return; + + local_phy = sas_get_local_phy(dev); + phy = &hisi_hba->phy[local_phy->number]; + if (!hisi_sas_notify_phy_event(phy, HISI_PHYE_SPINUP_NOTIFY)) + pm_runtime_put(hisi_hba->dev); + + sas_put_local_phy(local_phy); +} +EXPORT_SYMBOL_GPL(hisi_sas_spinup_notify); + static int hisi_sas_controller_prereset(struct hisi_hba *hisi_hba) { if (!hisi_hba->hw->soft_reset) diff --git a/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c index fa94d7110714..5fcb8d5002f5 100644 --- a/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c +++ b/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c @@ -1272,6 +1272,10 @@ static void slot_complete_v1_hw(struct hisi_hba *hisi_hba, &status_buffer->iu[0]; sas_ssp_task_response(dev, task, iu); + if (unlikely(ts->stat == SAS_SAM_STAT_CHECK_CONDITION && + !dev_parent_is_expander(device))) + hisi_sas_spinup_notify(hisi_hba, task); + break; } case SAS_PROTOCOL_SMP: diff --git a/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c index f3516a0611dd..f16896e962fd 100644 --- a/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c +++ b/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c @@ -2427,6 +2427,10 @@ static void slot_complete_v2_hw(struct hisi_hba *hisi_hba, &status_buffer->iu[0]; sas_ssp_task_response(dev, task, iu); + if (unlikely(ts->stat == SAS_SAM_STAT_CHECK_CONDITION && + !dev_parent_is_expander(device))) + hisi_sas_spinup_notify(hisi_hba, task); + break; } case SAS_PROTOCOL_SMP: diff --git a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c index 8a2500993e19..9391d031f5df 100644 --- a/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c +++ b/drivers/scsi/hisi_sas/hisi_sas_v3_hw.c @@ -280,6 +280,9 @@ #define CHL_INT2_RX_CODE_ERR_OFF 29 #define CHL_INT2_RX_INVLD_DW_OFF 30 #define CHL_INT2_STP_LINK_TIMEOUT_OFF 31 +#define CHL_INT2_RX_ERR_MSK (BIT(CHL_INT2_RX_DISP_ERR_OFF) | \ + BIT(CHL_INT2_RX_CODE_ERR_OFF) | \ + BIT(CHL_INT2_RX_INVLD_DW_OFF)) #define CHL_INT0_MSK (PORT_BASE + 0x1c0) #define CHL_INT1_MSK (PORT_BASE + 0x1c4) #define CHL_INT2_MSK (PORT_BASE + 0x1c8) @@ -547,6 +550,9 @@ struct hisi_sas_err_record_v3 { #define IRQ_AXI_INDEX 11 #define DELAY_FOR_RESET_HW 100 +#define STOP_PHY_DELAY_US 50 +#define DISABLE_PHY_DELAY_MS 50 +#define DISABLE_HOST_PHY_DELAY_MS 10 #define HDR_SG_MOD 0x2 #define LUN_SIZE 8 #define ATTR_PRIO_REGION 9 @@ -983,7 +989,7 @@ static int reset_hw_v3_hw(struct hisi_hba *hisi_hba) /* Disable all of the PHYs */ hisi_sas_stop_phys(hisi_hba); - udelay(HISI_SAS_DELAY_FOR_PHY_DISABLE); + udelay(STOP_PHY_DELAY_US); /* Ensure axi bus idle */ ret = hisi_sas_read32_poll_timeout(AXI_CFG, val, !val, @@ -1058,21 +1064,36 @@ static void enable_phy_v3_hw(struct hisi_hba *hisi_hba, int phy_no) hisi_sas_phy_write32(hisi_hba, phy_no, PHY_CFG, cfg); } +static void clear_phy_err_cnt_v3_hw(struct hisi_hba *hisi_hba, int phy_no) +{ + u32 irq_msk = hisi_sas_phy_read32(hisi_hba, phy_no, CHL_INT2_MSK); + + hisi_sas_phy_write32(hisi_hba, phy_no, CHL_INT2_MSK, + CHL_INT2_RX_ERR_MSK | irq_msk); + + hisi_sas_phy_read32(hisi_hba, phy_no, ERR_CNT_DWS_LOST); + hisi_sas_phy_read32(hisi_hba, phy_no, ERR_CNT_RESET_PROB); + hisi_sas_phy_read32(hisi_hba, phy_no, ERR_CNT_INVLD_DW); + hisi_sas_phy_read32(hisi_hba, phy_no, ERR_CNT_DISP_ERR); + hisi_sas_phy_read32(hisi_hba, phy_no, ERR_CNT_CODE_ERR); + + hisi_sas_phy_write32(hisi_hba, phy_no, CHL_INT2, CHL_INT2_RX_ERR_MSK); + hisi_sas_phy_write32(hisi_hba, phy_no, CHL_INT2_MSK, irq_msk); +} + static void disable_phy_v3_hw(struct hisi_hba *hisi_hba, int phy_no) { u32 cfg = hisi_sas_phy_read32(hisi_hba, phy_no, PHY_CFG); u32 irq_msk = hisi_sas_phy_read32(hisi_hba, phy_no, CHL_INT2_MSK); - static const u32 msk = BIT(CHL_INT2_RX_DISP_ERR_OFF) | - BIT(CHL_INT2_RX_CODE_ERR_OFF) | - BIT(CHL_INT2_RX_INVLD_DW_OFF); u32 state; - hisi_sas_phy_write32(hisi_hba, phy_no, CHL_INT2_MSK, msk | irq_msk); + hisi_sas_phy_write32(hisi_hba, phy_no, CHL_INT2_MSK, + CHL_INT2_RX_ERR_MSK | irq_msk); cfg &= ~PHY_CFG_ENA_MSK; hisi_sas_phy_write32(hisi_hba, phy_no, PHY_CFG, cfg); - mdelay(HISI_SAS_DELAY_FOR_PHY_DISABLE); + mdelay(DISABLE_PHY_DELAY_MS); state = hisi_sas_read32(hisi_hba, PHY_STATE); if (state & BIT(phy_no)) { @@ -1082,11 +1103,7 @@ static void disable_phy_v3_hw(struct hisi_hba *hisi_hba, int phy_no) udelay(1); - hisi_sas_phy_read32(hisi_hba, phy_no, ERR_CNT_INVLD_DW); - hisi_sas_phy_read32(hisi_hba, phy_no, ERR_CNT_DISP_ERR); - hisi_sas_phy_read32(hisi_hba, phy_no, ERR_CNT_CODE_ERR); - - hisi_sas_phy_write32(hisi_hba, phy_no, CHL_INT2, msk); + clear_phy_err_cnt_v3_hw(hisi_hba, phy_no); hisi_sas_phy_write32(hisi_hba, phy_no, CHL_INT2_MSK, irq_msk); } @@ -1668,6 +1685,7 @@ static irqreturn_t phy_up_v3_hw(int phy_no, struct hisi_hba *hisi_hba) /* Delete timer and set phy_attached atomically */ timer_delete(&phy->timer); phy->phy_attached = 1; + clear_phy_err_cnt_v3_hw(hisi_hba, phy_no); spin_unlock(&phy->lock); /* @@ -1891,9 +1909,6 @@ static void handle_chl_int2_v3_hw(struct hisi_hba *hisi_hba, int phy_no) struct hisi_sas_phy *phy = &hisi_hba->phy[phy_no]; struct pci_dev *pci_dev = hisi_hba->pci_dev; struct device *dev = hisi_hba->dev; - static const u32 msk = BIT(CHL_INT2_RX_DISP_ERR_OFF) | - BIT(CHL_INT2_RX_CODE_ERR_OFF) | - BIT(CHL_INT2_RX_INVLD_DW_OFF); irq_value &= ~irq_msk; if (!irq_value) { @@ -1917,7 +1932,7 @@ static void handle_chl_int2_v3_hw(struct hisi_hba *hisi_hba, int phy_no) hisi_sas_notify_phy_event(phy, HISI_PHYE_LINK_RESET); } - if (pci_dev->revision > 0x20 && (irq_value & msk)) { + if (pci_dev->revision > 0x20 && (irq_value & CHL_INT2_RX_ERR_MSK)) { struct asd_sas_phy *sas_phy = &phy->sas_phy; struct sas_phy *sphy = sas_phy->phy; @@ -2432,6 +2447,10 @@ static void slot_complete_v3_hw(struct hisi_hba *hisi_hba, sizeof(struct hisi_sas_err_record); sas_ssp_task_response(dev, task, iu); + if (unlikely(ts->stat == SAS_SAM_STAT_CHECK_CONDITION && + !dev_parent_is_expander(device))) + hisi_sas_spinup_notify(hisi_hba, task); + break; } case SAS_PROTOCOL_SMP: { @@ -2755,7 +2774,7 @@ static int disable_host_v3_hw(struct hisi_hba *hisi_hba) hisi_sas_stop_phys(hisi_hba); - mdelay(HISI_SAS_DELAY_FOR_PHY_DISABLE); + mdelay(DISABLE_HOST_PHY_DELAY_MS); reg_val = hisi_sas_read32(hisi_hba, AXI_MASTER_CFG_BASE + AM_CTRL_GLOBAL); diff --git a/drivers/scsi/hosts.c b/drivers/scsi/hosts.c index e72055c1ebbb..e8361ba65564 100644 --- a/drivers/scsi/hosts.c +++ b/drivers/scsi/hosts.c @@ -73,7 +73,7 @@ static struct class shost_class = { * transition is illegal. **/ int scsi_host_set_state(struct Scsi_Host *shost, enum scsi_host_state state) - __must_hold(shost->host_lock) + __must_hold(&shost->host_lock) { enum scsi_host_state oldstate = READ_ONCE(shost->shost_state); @@ -168,14 +168,14 @@ void scsi_remove_host(struct Scsi_Host *shost) unsigned long flags; mutex_lock(&shost->scan_mutex); - spin_lock_irqsave(shost->host_lock, flags); + spin_lock_irqsave(&shost->host_lock, flags); if (scsi_host_set_state(shost, SHOST_CANCEL)) if (scsi_host_set_state(shost, SHOST_CANCEL_RECOVERY)) { - spin_unlock_irqrestore(shost->host_lock, flags); + spin_unlock_irqrestore(&shost->host_lock, flags); mutex_unlock(&shost->scan_mutex); return; } - spin_unlock_irqrestore(shost->host_lock, flags); + spin_unlock_irqrestore(&shost->host_lock, flags); scsi_autopm_get_host(shost); flush_workqueue(shost->tmf_work_q); @@ -193,10 +193,10 @@ void scsi_remove_host(struct Scsi_Host *shost) kref_put(&shost->tagset_refcnt, scsi_mq_free_tags); wait_for_completion(&shost->tagset_freed); - spin_lock_irqsave(shost->host_lock, flags); + spin_lock_irqsave(&shost->host_lock, flags); if (scsi_host_set_state(shost, SHOST_DEL)) BUG_ON(scsi_host_set_state(shost, SHOST_DEL_RECOVERY)); - spin_unlock_irqrestore(shost->host_lock, flags); + spin_unlock_irqrestore(&shost->host_lock, flags); transport_unregister_device(&shost->shost_gendev); device_unregister(&shost->shost_dev); @@ -277,7 +277,7 @@ int scsi_add_host_with_dma(struct Scsi_Host *shost, struct device *dev, if (error) goto out_disable_runtime_pm; - scoped_guard(spinlock_irq, shost->host_lock) + scoped_guard(spinlock_irq, &shost->host_lock) scsi_host_set_state(shost, SHOST_RUNNING); get_device(shost->shost_gendev.parent); @@ -414,8 +414,7 @@ struct Scsi_Host *scsi_host_alloc(const struct scsi_host_template *sht, int priv if (!shost) return NULL; - shost->host_lock = &shost->default_lock; - scoped_guard(spinlock_init, shost->host_lock) + scoped_guard(spinlock_init, &shost->host_lock) shost->shost_state = SHOST_CREATED; INIT_LIST_HEAD(&shost->__devices); INIT_LIST_HEAD(&shost->__targets); diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c index 8edad1830abe..187505950b63 100644 --- a/drivers/scsi/hpsa.c +++ b/drivers/scsi/hpsa.c @@ -353,14 +353,13 @@ static inline bool hpsa_is_cmd_idle(struct CommandList *c) /* extract sense key, asc, and ascq from sense data. -1 means invalid. */ static void decode_sense_data(const u8 *sense_data, int sense_data_len, - u8 *sense_key, u8 *asc, u8 *ascq) + u8 *sense_key, u16 *sense_code) { struct scsi_sense_hdr sshdr; bool rc; *sense_key = -1; - *asc = -1; - *ascq = -1; + *sense_code = -1; if (sense_data_len < 1) return; @@ -368,15 +367,15 @@ static void decode_sense_data(const u8 *sense_data, int sense_data_len, rc = scsi_normalize_sense(sense_data, sense_data_len, &sshdr); if (rc) { *sense_key = sshdr.sense_key; - *asc = sshdr.asc; - *ascq = sshdr.ascq; + *sense_code = sshdr.sense_code; } } static int check_for_unit_attention(struct ctlr_info *h, struct CommandList *c) { - u8 sense_key, asc, ascq; + u8 sense_key; + u16 sense_code; int sense_len; if (c->err_info->SenseLen > sizeof(c->err_info->SenseInfo)) @@ -385,34 +384,35 @@ static int check_for_unit_attention(struct ctlr_info *h, sense_len = c->err_info->SenseLen; decode_sense_data(c->err_info->SenseInfo, sense_len, - &sense_key, &asc, &ascq); - if (sense_key != UNIT_ATTENTION || asc == 0xff) + &sense_key, &sense_code); + if (sense_key != UNIT_ATTENTION || + scsi_sense_code_asc(sense_code) == 0xff) return 0; - switch (asc) { - case STATE_CHANGED: + switch (scsi_sense_code_asc(sense_code)) { + case ASC_PARAMETERS_CHANGED: dev_warn(&h->pdev->dev, "%s: a state change detected, command retried\n", h->devname); break; - case LUN_FAILED: + case ASC_LU_HAS_NOT_SELF_CONFIGURED_YET: dev_warn(&h->pdev->dev, "%s: LUN failure detected\n", h->devname); break; - case REPORT_LUNS_CHANGED: + case ASC_TARGET_OPERATING_CONDITIONS_HAVE_CHANGED: dev_warn(&h->pdev->dev, "%s: report LUN data changed\n", h->devname); /* - * Note: this REPORT_LUNS_CHANGED condition only occurs on the external - * target (array) devices. + * Note: this ASC_TARGET_OPERATING_CONDITIONS_HAVE_CHANGED condition + * only occurs on the external target (array) devices. */ break; - case POWER_OR_RESET: + case ASC_POWER_ON_RESET_OR_BUS_DEVICE_RESET_OCCURRED: dev_warn(&h->pdev->dev, "%s: a power on or device reset detected\n", h->devname); break; - case UNIT_ATTENTION_CLEARED: + case ASC_COMMANDS_CLEARED_BY_ANOTHER_INITIATOR: dev_warn(&h->pdev->dev, "%s: unit attention cleared by another initiator\n", h->devname); @@ -2562,10 +2562,8 @@ static void complete_scsi_command(struct CommandList *cp) struct ErrorInfo *ei; struct hpsa_scsi_dev_t *dev; struct io_accel2_cmd *c2; - u8 sense_key; - u8 asc; /* additional sense code */ - u8 ascq; /* additional sense code qualifier */ + u16 sense_code; unsigned long sense_data_size; ei = cp->err_info; @@ -2666,18 +2664,19 @@ static void complete_scsi_command(struct CommandList *cp) memcpy(cmd->sense_buffer, ei->SenseInfo, sense_data_size); if (ei->ScsiStatus) decode_sense_data(ei->SenseInfo, sense_data_size, - &sense_key, &asc, &ascq); + &sense_key, &sense_code); if (ei->ScsiStatus == SAM_STAT_CHECK_CONDITION) { switch (sense_key) { case ABORTED_COMMAND: cmd->result |= DID_SOFT_ERROR << 16; break; case UNIT_ATTENTION: - if (asc == 0x3F && ascq == 0x0E) + if (sense_code == + REPORTED_LUNS_DATA_HAS_CHANGED) h->drv_req_rescan = 1; break; case ILLEGAL_REQUEST: - if (asc == 0x25 && ascq == 0x00) { + if (sense_code == LU_NOT_SUPPORTED) { dev->removed = 1; cmd->result = DID_NO_CONNECT << 16; } @@ -2693,7 +2692,9 @@ static void complete_scsi_command(struct CommandList *cp) "Sense: 0x%x, ASC: 0x%x, ASCQ: 0x%x, " "Returning result: 0x%x\n", cp, ei->ScsiStatus, - sense_key, asc, ascq, + sense_key, + scsi_sense_code_asc(sense_code), + scsi_sense_code_ascq(sense_code), cmd->result); } else { /* scsi status is zero??? How??? */ dev_warn(&h->pdev->dev, "cp %p SCSI status was 0. " @@ -2919,7 +2920,8 @@ static void hpsa_scsi_interpret_error(struct ctlr_info *h, { const struct ErrorInfo *ei = cp->err_info; struct device *d = &cp->h->pdev->dev; - u8 sense_key, asc, ascq; + u8 sense_key; + u16 sense_code; int sense_len; switch (ei->CommandStatus) { @@ -2928,12 +2930,13 @@ static void hpsa_scsi_interpret_error(struct ctlr_info *h, sense_len = sizeof(ei->SenseInfo); else sense_len = ei->SenseLen; - decode_sense_data(ei->SenseInfo, sense_len, - &sense_key, &asc, &ascq); + decode_sense_data(ei->SenseInfo, sense_len, &sense_key, + &sense_code); hpsa_print_cmd(h, "SCSI status", cp); if (ei->ScsiStatus == SAM_STAT_CHECK_CONDITION) dev_warn(d, "SCSI Status = 02, Sense key = 0x%02x, ASC = 0x%02x, ASCQ = 0x%02x\n", - sense_key, asc, ascq); + sense_key, scsi_sense_code_asc(sense_code), + scsi_sense_code_ascq(sense_code)); else dev_warn(d, "SCSI Status = 0x%02x\n", ei->ScsiStatus); if (ei->ScsiStatus == 0) @@ -3163,7 +3166,7 @@ static int hpsa_do_reset(struct ctlr_info *h, struct hpsa_scsi_dev_t *dev, int rc = 0; /* We can really only handle one reset at a time */ - if (mutex_lock_interruptible(&h->reset_mutex) == -EINTR) { + if (mutex_lock_interruptible(&h->reset_mutex)) { dev_warn(&h->pdev->dev, "concurrent reset wait interrupted.\n"); return -EINTR; } @@ -3868,12 +3871,10 @@ static unsigned char hpsa_volume_offline(struct ctlr_info *h, { struct CommandList *c; unsigned char *sense; - u8 sense_key, asc, ascq; + u8 sense_key; + u16 sense_code; int sense_len; int rc, ldstat = 0; -#define ASC_LUN_NOT_READY 0x04 -#define ASCQ_LUN_NOT_READY_FORMAT_IN_PROGRESS 0x04 -#define ASCQ_LUN_NOT_READY_INITIALIZING_CMD_REQ 0x02 c = cmd_alloc(h); @@ -3889,7 +3890,7 @@ static unsigned char hpsa_volume_offline(struct ctlr_info *h, sense_len = sizeof(c->err_info->SenseInfo); else sense_len = c->err_info->SenseLen; - decode_sense_data(sense, sense_len, &sense_key, &asc, &ascq); + decode_sense_data(sense, sense_len, &sense_key, &sense_code); cmd_free(h, c); /* Determine the reason for not ready state */ @@ -3912,8 +3913,8 @@ static unsigned char hpsa_volume_offline(struct ctlr_info *h, /* If VPD status page isn't available, * use ASC/ASCQ to determine state */ - if ((ascq == ASCQ_LUN_NOT_READY_FORMAT_IN_PROGRESS) || - (ascq == ASCQ_LUN_NOT_READY_INITIALIZING_CMD_REQ)) + if (sense_code == LU_NOT_READY_FORMAT_IN_PROGRESS || + sense_code == LU_NOT_READY_INITIALIZING_COMMAND_REQUIRED) return ldstat; break; default: @@ -6499,7 +6500,7 @@ static int hpsa_big_passthru_ioctl(struct ctlr_info *h, return -EINVAL; if (ioc->buf_size > ioc->malloc_size * SG_ENTRIES_IN_CMD) return -EINVAL; - buff = kcalloc(SG_ENTRIES_IN_CMD, sizeof(char *), GFP_KERNEL); + buff = kcalloc(SG_ENTRIES_IN_CMD, sizeof(*buff), GFP_KERNEL); if (!buff) { status = -ENOMEM; goto cleanup1; diff --git a/drivers/scsi/hpsa_cmd.h b/drivers/scsi/hpsa_cmd.h index ba6a3aa8d954..0dbfbec37ce2 100644 --- a/drivers/scsi/hpsa_cmd.h +++ b/drivers/scsi/hpsa_cmd.h @@ -63,29 +63,6 @@ #define CISS_TMF_WRONG_LUN 0x09 #define CISS_TMF_OVERLAPPED_TAG 0x0a -/* Unit Attentions ASC's as defined for the MSA2012sa */ -#define POWER_OR_RESET 0x29 -#define STATE_CHANGED 0x2a -#define UNIT_ATTENTION_CLEARED 0x2f -#define LUN_FAILED 0x3e -#define REPORT_LUNS_CHANGED 0x3f - -/* Unit Attentions ASCQ's as defined for the MSA2012sa */ - - /* These ASCQ's defined for ASC = POWER_OR_RESET */ -#define POWER_ON_RESET 0x00 -#define POWER_ON_REBOOT 0x01 -#define SCSI_BUS_RESET 0x02 -#define MSA_TARGET_RESET 0x03 -#define CONTROLLER_FAILOVER 0x04 -#define TRANSCEIVER_SE 0x05 -#define TRANSCEIVER_LVD 0x06 - - /* These ASCQ's defined for ASC = STATE_CHANGED */ -#define RESERVATION_PREEMPTED 0x03 -#define ASYM_ACCESS_CHANGED 0x06 -#define LUN_CAPACITY_CHANGED 0x09 - /* transfer direction */ #define XFER_NONE 0x00 #define XFER_WRITE 0x01 diff --git a/drivers/scsi/hptiop.c b/drivers/scsi/hptiop.c index 7083c14c5302..a3afb3446bbb 100644 --- a/drivers/scsi/hptiop.c +++ b/drivers/scsi/hptiop.c @@ -385,9 +385,9 @@ static int iop_send_sync_msg(struct hptiop_hba *hba, u32 msg, u32 millisec) hba->ops->post_msg(hba, msg); for (i = 0; i < millisec; i++) { - spin_lock_irq(hba->host->host_lock); + spin_lock_irq(&hba->host->host_lock); hba->ops->iop_intr(hba); - spin_unlock_irq(hba->host->host_lock); + spin_unlock_irq(&hba->host->host_lock); if (hba->msg_done) break; msleep(1); @@ -836,9 +836,9 @@ static irqreturn_t hptiop_intr(int irq, void *dev_id) int handled; unsigned long flags; - spin_lock_irqsave(hba->host->host_lock, flags); + spin_lock_irqsave(&hba->host->host_lock, flags); handled = hba->ops->iop_intr(hba); - spin_unlock_irqrestore(hba->host->host_lock, flags); + spin_unlock_irqrestore(&hba->host->host_lock, flags); return handled; } diff --git a/drivers/scsi/ibmvscsi/Makefile b/drivers/scsi/ibmvscsi/Makefile index 9408c7f4cdee..de6ed9e64b63 100644 --- a/drivers/scsi/ibmvscsi/Makefile +++ b/drivers/scsi/ibmvscsi/Makefile @@ -1,4 +1,7 @@ # SPDX-License-Identifier: GPL-2.0-only + +CONTEXT_ANALYSIS := y + ibmvfc-objs := ibmvfc-core.o ibmvfc-nvme.o obj-$(CONFIG_SCSI_IBMVSCSI) += ibmvscsi.o diff --git a/drivers/scsi/ibmvscsi/ibmvfc-core.c b/drivers/scsi/ibmvscsi/ibmvfc-core.c index 3534ac45e9b8..aa7ae81df41b 100644 --- a/drivers/scsi/ibmvscsi/ibmvfc-core.c +++ b/drivers/scsi/ibmvscsi/ibmvfc-core.c @@ -974,14 +974,14 @@ static int ibmvfc_reenable_crq_queue(struct ibmvfc_host *vhost) if (rc) dev_err(vhost->dev, "Error enabling adapter (rc=%d)\n", rc); - spin_lock_irqsave(vhost->host->host_lock, flags); + spin_lock_irqsave(&vhost->host->host_lock, flags); spin_lock(vhost->crq.q_lock); vhost->do_enquiry = 1; vhost->using_channels = 0; vhost->do_scsi_login = 0; vhost->do_nvme_login = 0; spin_unlock(vhost->crq.q_lock); - spin_unlock_irqrestore(vhost->host->host_lock, flags); + spin_unlock_irqrestore(&vhost->host->host_lock, flags); ibmvfc_reg_sub_crqs(vhost, &vhost->scsi_scrqs); ibmvfc_reg_sub_crqs(vhost, &vhost->nvme_scrqs); @@ -1013,7 +1013,7 @@ static int ibmvfc_reset_crq(struct ibmvfc_host *vhost) rc = plpar_hcall_norets(H_FREE_CRQ, vdev->unit_address); } while (rc == H_BUSY || H_IS_LONG_BUSY(rc)); - spin_lock_irqsave(vhost->host->host_lock, flags); + spin_lock_irqsave(&vhost->host->host_lock, flags); spin_lock(vhost->crq.q_lock); vhost->state = IBMVFC_NO_CRQ; vhost->logged_in = 0; @@ -1037,7 +1037,7 @@ static int ibmvfc_reset_crq(struct ibmvfc_host *vhost) dev_warn(vhost->dev, "Couldn't register crq (rc=%d)\n", rc); spin_unlock(vhost->crq.q_lock); - spin_unlock_irqrestore(vhost->host->host_lock, flags); + spin_unlock_irqrestore(&vhost->host->host_lock, flags); ibmvfc_reg_sub_crqs(vhost, &vhost->scsi_scrqs); ibmvfc_reg_sub_crqs(vhost, &vhost->nvme_scrqs); @@ -1250,9 +1250,9 @@ static void ibmvfc_reset_host(struct ibmvfc_host *vhost) { unsigned long flags; - spin_lock_irqsave(vhost->host->host_lock, flags); + spin_lock_irqsave(&vhost->host->host_lock, flags); __ibmvfc_reset_host(vhost); - spin_unlock_irqrestore(vhost->host->host_lock, flags); + spin_unlock_irqrestore(&vhost->host->host_lock, flags); } /** @@ -1318,9 +1318,9 @@ static struct ibmvfc_target *ibmvfc_get_target(struct scsi_target *starget) struct ibmvfc_target *tgt; unsigned long flags; - spin_lock_irqsave(shost->host_lock, flags); + spin_lock_irqsave(&shost->host_lock, flags); tgt = __ibmvfc_get_target(starget); - spin_unlock_irqrestore(shost->host_lock, flags); + spin_unlock_irqrestore(&shost->host_lock, flags); return tgt; } @@ -1336,7 +1336,7 @@ static void ibmvfc_get_host_speed(struct Scsi_Host *shost) struct ibmvfc_host *vhost = shost_priv(shost); unsigned long flags; - spin_lock_irqsave(shost->host_lock, flags); + spin_lock_irqsave(&shost->host_lock, flags); if (vhost->state == IBMVFC_ACTIVE) { switch (be64_to_cpu(vhost->login_buf->resp.link_speed) / 100) { case 1: @@ -1365,7 +1365,7 @@ static void ibmvfc_get_host_speed(struct Scsi_Host *shost) } } else fc_host_speed(shost) = FC_PORTSPEED_UNKNOWN; - spin_unlock_irqrestore(shost->host_lock, flags); + spin_unlock_irqrestore(&shost->host_lock, flags); } /** @@ -1380,7 +1380,7 @@ static void ibmvfc_get_host_port_state(struct Scsi_Host *shost) struct ibmvfc_host *vhost = shost_priv(shost); unsigned long flags; - spin_lock_irqsave(shost->host_lock, flags); + spin_lock_irqsave(&shost->host_lock, flags); switch (vhost->state) { case IBMVFC_INITIALIZING: case IBMVFC_ACTIVE: @@ -1404,7 +1404,7 @@ static void ibmvfc_get_host_port_state(struct Scsi_Host *shost) fc_host_port_state(shost) = FC_PORTSTATE_UNKNOWN; break; } - spin_unlock_irqrestore(shost->host_lock, flags); + spin_unlock_irqrestore(&shost->host_lock, flags); } /** @@ -1642,9 +1642,9 @@ static void ibmvfc_locked_done(struct ibmvfc_event *evt) { unsigned long flags; - spin_lock_irqsave(evt->vhost->host->host_lock, flags); + spin_lock_irqsave(&evt->vhost->host->host_lock, flags); evt->_done(evt); - spin_unlock_irqrestore(evt->vhost->host->host_lock, flags); + spin_unlock_irqrestore(&evt->vhost->host->host_lock, flags); } /** @@ -1905,7 +1905,7 @@ static void ibmvfc_scsi_relogin(struct scsi_device *sdev) struct ibmvfc_target *tgt; unsigned long flags; - spin_lock_irqsave(vhost->host->host_lock, flags); + spin_lock_irqsave(&vhost->host->host_lock, flags); list_for_each_entry(tgt, &vhost->scsi_scrqs.targets, queue) { if (rport == tgt->rport) { ibmvfc_del_tgt(tgt); @@ -1914,7 +1914,7 @@ static void ibmvfc_scsi_relogin(struct scsi_device *sdev) } ibmvfc_reinit_host(vhost); - spin_unlock_irqrestore(vhost->host->host_lock, flags); + spin_unlock_irqrestore(&vhost->host->host_lock, flags); } /** @@ -2147,17 +2147,17 @@ static int ibmvfc_bsg_timeout(struct bsg_job *job) int rc; ENTER; - spin_lock_irqsave(vhost->host->host_lock, flags); + spin_lock_irqsave(&vhost->host->host_lock, flags); if (vhost->aborting_passthru || vhost->state != IBMVFC_ACTIVE) { __ibmvfc_reset_host(vhost); - spin_unlock_irqrestore(vhost->host->host_lock, flags); + spin_unlock_irqrestore(&vhost->host->host_lock, flags); return 0; } vhost->aborting_passthru = 1; evt = ibmvfc_get_reserved_event(&vhost->crq); if (!evt) { - spin_unlock_irqrestore(vhost->host->host_lock, flags); + spin_unlock_irqrestore(&vhost->host->host_lock, flags); return -ENOMEM; } @@ -2181,7 +2181,7 @@ static int ibmvfc_bsg_timeout(struct bsg_job *job) dev_info(vhost->dev, "Cancelling passthru command to port id 0x%lx\n", port_id); - spin_unlock_irqrestore(vhost->host->host_lock, flags); + spin_unlock_irqrestore(&vhost->host->host_lock, flags); LEAVE; return rc; @@ -2205,7 +2205,7 @@ static int ibmvfc_bsg_plogi(struct ibmvfc_host *vhost, unsigned int port_id) int rc = 0, issue_login = 1; ENTER; - spin_lock_irqsave(vhost->host->host_lock, flags); + spin_lock_irqsave(&vhost->host->host_lock, flags); list_for_each_entry(tgt, &vhost->scsi_scrqs.targets, queue) { if (tgt->scsi_id == port_id) { issue_login = 0; @@ -2234,7 +2234,7 @@ static int ibmvfc_bsg_plogi(struct ibmvfc_host *vhost, unsigned int port_id) init_completion(&evt->comp); rc = ibmvfc_send_event(evt, vhost, default_timeout); - spin_unlock_irqrestore(vhost->host->host_lock, flags); + spin_unlock_irqrestore(&vhost->host->host_lock, flags); if (rc) return -EIO; @@ -2244,10 +2244,10 @@ static int ibmvfc_bsg_plogi(struct ibmvfc_host *vhost, unsigned int port_id) if (rsp_iu.plogi.common.status) rc = -EIO; - spin_lock_irqsave(vhost->host->host_lock, flags); + spin_lock_irqsave(&vhost->host->host_lock, flags); ibmvfc_free_event(evt); unlock_out: - spin_unlock_irqrestore(vhost->host->host_lock, flags); + spin_unlock_irqrestore(&vhost->host->host_lock, flags); LEAVE; return rc; } @@ -2332,17 +2332,17 @@ static int ibmvfc_bsg_request(struct bsg_job *job) if (issue_login) rc = ibmvfc_bsg_plogi(vhost, port_id); - spin_lock_irqsave(vhost->host->host_lock, flags); + spin_lock_irqsave(&vhost->host->host_lock, flags); if (unlikely(rc || (rport && (rc = fc_remote_port_chkready(rport)))) || unlikely((rc = ibmvfc_host_chkready(vhost)))) { - spin_unlock_irqrestore(vhost->host->host_lock, flags); + spin_unlock_irqrestore(&vhost->host->host_lock, flags); goto out; } evt = ibmvfc_get_reserved_event(&vhost->crq); if (!evt) { - spin_unlock_irqrestore(vhost->host->host_lock, flags); + spin_unlock_irqrestore(&vhost->host->host_lock, flags); rc = -ENOMEM; goto out; } @@ -2374,7 +2374,7 @@ static int ibmvfc_bsg_request(struct bsg_job *job) evt->sync_iu = &rsp_iu; init_completion(&evt->comp); rc = ibmvfc_send_event(evt, vhost, 0); - spin_unlock_irqrestore(vhost->host->host_lock, flags); + spin_unlock_irqrestore(&vhost->host->host_lock, flags); if (rc) { rc = -EIO; @@ -2388,9 +2388,9 @@ static int ibmvfc_bsg_request(struct bsg_job *job) else bsg_reply->reply_payload_rcv_len = rsp_len; - spin_lock_irqsave(vhost->host->host_lock, flags); + spin_lock_irqsave(&vhost->host->host_lock, flags); ibmvfc_free_event(evt); - spin_unlock_irqrestore(vhost->host->host_lock, flags); + spin_unlock_irqrestore(&vhost->host->host_lock, flags); bsg_reply->result = rc; bsg_job_done(job, bsg_reply->result, bsg_reply->reply_payload_rcv_len); @@ -2427,7 +2427,7 @@ static int ibmvfc_reset_device(struct scsi_device *sdev, int type, char *desc) unsigned long flags; int rsp_code = 0; - spin_lock_irqsave(vhost->host->host_lock, flags); + spin_lock_irqsave(&vhost->host->host_lock, flags); if (vhost->state == IBMVFC_ACTIVE) { if (vhost->using_channels) evt = ibmvfc_get_event(&vhost->scsi_scrqs.scrqs[0]); @@ -2435,7 +2435,7 @@ static int ibmvfc_reset_device(struct scsi_device *sdev, int type, char *desc) evt = ibmvfc_get_event(&vhost->crq); if (!evt) { - spin_unlock_irqrestore(vhost->host->host_lock, flags); + spin_unlock_irqrestore(&vhost->host->host_lock, flags); return -ENOMEM; } @@ -2452,7 +2452,7 @@ static int ibmvfc_reset_device(struct scsi_device *sdev, int type, char *desc) init_completion(&evt->comp); rsp_rc = ibmvfc_send_event(evt, vhost, default_timeout); } - spin_unlock_irqrestore(vhost->host->host_lock, flags); + spin_unlock_irqrestore(&vhost->host->host_lock, flags); if (rsp_rc != 0) { sdev_printk(KERN_ERR, sdev, "Failed to send %s reset event. rc=%d\n", @@ -2479,9 +2479,9 @@ static int ibmvfc_reset_device(struct scsi_device *sdev, int type, char *desc) } else sdev_printk(KERN_INFO, sdev, "%s reset successful\n", desc); - spin_lock_irqsave(vhost->host->host_lock, flags); + spin_lock_irqsave(&vhost->host->host_lock, flags); ibmvfc_free_event(evt); - spin_unlock_irqrestore(vhost->host->host_lock, flags); + spin_unlock_irqrestore(&vhost->host->host_lock, flags); return rsp_rc; } @@ -2583,7 +2583,7 @@ static int ibmvfc_wait_for_ops(struct ibmvfc_host *vhost, void *device, do { wait = 0; - spin_lock_irqsave(vhost->host->host_lock, flags); + spin_lock_irqsave(&vhost->host->host_lock, flags); for (q_index = 0; q_index < q_size; q_index++) { spin_lock(&queues[q_index].l_lock); for (i = 0; i < queues[q_index].evt_pool.size; i++) { @@ -2597,14 +2597,14 @@ static int ibmvfc_wait_for_ops(struct ibmvfc_host *vhost, void *device, } spin_unlock(&queues[q_index].l_lock); } - spin_unlock_irqrestore(vhost->host->host_lock, flags); + spin_unlock_irqrestore(&vhost->host->host_lock, flags); if (wait) { timeout = wait_for_completion_timeout(&comp, timeout); if (!timeout) { wait = 0; - spin_lock_irqsave(vhost->host->host_lock, flags); + spin_lock_irqsave(&vhost->host->host_lock, flags); for (q_index = 0; q_index < q_size; q_index++) { spin_lock(&queues[q_index].l_lock); for (i = 0; i < queues[q_index].evt_pool.size; i++) { @@ -2618,7 +2618,7 @@ static int ibmvfc_wait_for_ops(struct ibmvfc_host *vhost, void *device, } spin_unlock(&queues[q_index].l_lock); } - spin_unlock_irqrestore(vhost->host->host_lock, flags); + spin_unlock_irqrestore(&vhost->host->host_lock, flags); if (wait) dev_err(vhost->dev, "Timed out waiting for aborted commands\n"); LEAVE; @@ -2684,7 +2684,7 @@ static int ibmvfc_cancel_all_mq(struct scsi_device *sdev, int type) u16 status; ENTER; - spin_lock_irqsave(vhost->host->host_lock, flags); + spin_lock_irqsave(&vhost->host->host_lock, flags); num_hwq = vhost->scsi_scrqs.active_queues; for (i = 0; i < num_hwq; i++) { spin_lock(queues[i].q_lock); @@ -2702,7 +2702,7 @@ static int ibmvfc_cancel_all_mq(struct scsi_device *sdev, int type) evt = ibmvfc_init_tmf(&queues[i], sdev, type); if (!evt) { spin_unlock(queues[i].q_lock); - spin_unlock_irqrestore(vhost->host->host_lock, flags); + spin_unlock_irqrestore(&vhost->host->host_lock, flags); return -ENOMEM; } evt->sync_iu = &queues[i].cancel_rsp; @@ -2712,7 +2712,7 @@ static int ibmvfc_cancel_all_mq(struct scsi_device *sdev, int type) spin_unlock(queues[i].q_lock); } - spin_unlock_irqrestore(vhost->host->host_lock, flags); + spin_unlock_irqrestore(&vhost->host->host_lock, flags); if (list_empty(&cancelq)) { if (vhost->log_level > IBMVFC_DEFAULT_LOG_LEVEL) @@ -2763,7 +2763,7 @@ static int ibmvfc_cancel_all_sq(struct scsi_device *sdev, int type) ENTER; found_evt = NULL; - spin_lock_irqsave(vhost->host->host_lock, flags); + spin_lock_irqsave(&vhost->host->host_lock, flags); spin_lock(&vhost->crq.l_lock); list_for_each_entry(evt, &vhost->crq.sent, queue_list) { if (evt->cmnd && evt->cmnd->device == sdev) { @@ -2776,7 +2776,7 @@ static int ibmvfc_cancel_all_sq(struct scsi_device *sdev, int type) if (!found_evt) { if (vhost->log_level > IBMVFC_DEFAULT_LOG_LEVEL) sdev_printk(KERN_INFO, sdev, "No events found to cancel\n"); - spin_unlock_irqrestore(vhost->host->host_lock, flags); + spin_unlock_irqrestore(&vhost->host->host_lock, flags); return 0; } @@ -2786,7 +2786,7 @@ static int ibmvfc_cancel_all_sq(struct scsi_device *sdev, int type) rsp_rc = ibmvfc_send_event(evt, vhost, default_timeout); } - spin_unlock_irqrestore(vhost->host->host_lock, flags); + spin_unlock_irqrestore(&vhost->host->host_lock, flags); if (rsp_rc != 0) { sdev_printk(KERN_ERR, sdev, "Failed to send cancel event. rc=%d\n", rsp_rc); @@ -2800,9 +2800,9 @@ static int ibmvfc_cancel_all_sq(struct scsi_device *sdev, int type) wait_for_completion(&evt->comp); status = be16_to_cpu(rsp.mad_common.status); - spin_lock_irqsave(vhost->host->host_lock, flags); + spin_lock_irqsave(&vhost->host->host_lock, flags); ibmvfc_free_event(evt); - spin_unlock_irqrestore(vhost->host->host_lock, flags); + spin_unlock_irqrestore(&vhost->host->host_lock, flags); if (status != IBMVFC_MAD_SUCCESS) { sdev_printk(KERN_WARNING, sdev, "Cancel failed with rc=%x\n", status); @@ -2899,7 +2899,7 @@ static int ibmvfc_abort_task_set(struct scsi_device *sdev) int rsp_code = 0; found_evt = NULL; - spin_lock_irqsave(vhost->host->host_lock, flags); + spin_lock_irqsave(&vhost->host->host_lock, flags); spin_lock(&vhost->crq.l_lock); list_for_each_entry(evt, &vhost->crq.sent, queue_list) { if (evt->cmnd && evt->cmnd->device == sdev) { @@ -2912,14 +2912,14 @@ static int ibmvfc_abort_task_set(struct scsi_device *sdev) if (!found_evt) { if (vhost->log_level > IBMVFC_DEFAULT_LOG_LEVEL) sdev_printk(KERN_INFO, sdev, "No events found to abort\n"); - spin_unlock_irqrestore(vhost->host->host_lock, flags); + spin_unlock_irqrestore(&vhost->host->host_lock, flags); return 0; } if (vhost->state == IBMVFC_ACTIVE) { evt = ibmvfc_get_event(&vhost->crq); if (!evt) { - spin_unlock_irqrestore(vhost->host->host_lock, flags); + spin_unlock_irqrestore(&vhost->host->host_lock, flags); return -ENOMEM; } ibmvfc_init_event(evt, ibmvfc_sync_completion, IBMVFC_CMD_FORMAT); @@ -2938,7 +2938,7 @@ static int ibmvfc_abort_task_set(struct scsi_device *sdev) rsp_rc = ibmvfc_send_event(evt, vhost, default_timeout); } - spin_unlock_irqrestore(vhost->host->host_lock, flags); + spin_unlock_irqrestore(&vhost->host->host_lock, flags); if (rsp_rc != 0) { sdev_printk(KERN_ERR, sdev, "Failed to send abort. rc=%d\n", rsp_rc); @@ -2967,9 +2967,9 @@ static int ibmvfc_abort_task_set(struct scsi_device *sdev) rc = ibmvfc_wait_for_ops(vhost, evt, ibmvfc_match_evt); if (rc != SUCCESS) { - spin_lock_irqsave(vhost->host->host_lock, flags); + spin_lock_irqsave(&vhost->host->host_lock, flags); ibmvfc_hard_reset_host(vhost); - spin_unlock_irqrestore(vhost->host->host_lock, flags); + spin_unlock_irqrestore(&vhost->host->host_lock, flags); rsp_rc = 0; } @@ -2994,9 +2994,9 @@ static int ibmvfc_abort_task_set(struct scsi_device *sdev) sdev_printk(KERN_INFO, sdev, "Abort successful\n"); out: - spin_lock_irqsave(vhost->host->host_lock, flags); + spin_lock_irqsave(&vhost->host->host_lock, flags); ibmvfc_free_event(evt); - spin_unlock_irqrestore(vhost->host->host_lock, flags); + spin_unlock_irqrestore(&vhost->host->host_lock, flags); return rsp_rc; } @@ -3176,7 +3176,7 @@ static void ibmvfc_terminate_rport_io(struct fc_rport *rport) if (rc == FAILED) ibmvfc_issue_fc_host_lip(shost); - spin_lock_irqsave(shost->host_lock, flags); + spin_lock_irqsave(&shost->host_lock, flags); found = 0; list_for_each_entry(tgt, &vhost->scsi_scrqs.targets, queue) { if (tgt->scsi_id == rport->port_id) { @@ -3195,7 +3195,7 @@ static void ibmvfc_terminate_rport_io(struct fc_rport *rport) ibmvfc_reinit_host(vhost); } - spin_unlock_irqrestore(shost->host_lock, flags); + spin_unlock_irqrestore(&shost->host_lock, flags); LEAVE; } @@ -3468,7 +3468,7 @@ static int ibmvfc_scan_finished(struct Scsi_Host *shost, unsigned long time) struct ibmvfc_host *vhost = shost_priv(shost); int done = 0; - spin_lock_irqsave(shost->host_lock, flags); + spin_lock_irqsave(&shost->host_lock, flags); if (!vhost->scan_timeout) done = 1; else if (time >= (vhost->scan_timeout * HZ)) { @@ -3481,7 +3481,7 @@ static int ibmvfc_scan_finished(struct Scsi_Host *shost, unsigned long time) vhost->scan_timeout = init_timeout; done = 1; } - spin_unlock_irqrestore(shost->host_lock, flags); + spin_unlock_irqrestore(&shost->host_lock, flags); return done; } @@ -3505,9 +3505,9 @@ static int ibmvfc_sdev_init(struct scsi_device *sdev) if (!rport || fc_remote_port_chkready(rport)) return -ENXIO; - spin_lock_irqsave(shost->host_lock, flags); + spin_lock_irqsave(&shost->host_lock, flags); sdev->hostdata = (void *)(unsigned long)vhost->task_set++; - spin_unlock_irqrestore(shost->host_lock, flags); + spin_unlock_irqrestore(&shost->host_lock, flags); return 0; } @@ -3527,9 +3527,9 @@ static int ibmvfc_target_alloc(struct scsi_target *starget) struct ibmvfc_host *vhost = shost_priv(shost); unsigned long flags = 0; - spin_lock_irqsave(shost->host_lock, flags); + spin_lock_irqsave(&shost->host_lock, flags); starget->hostdata = (void *)(unsigned long)vhost->task_set++; - spin_unlock_irqrestore(shost->host_lock, flags); + spin_unlock_irqrestore(&shost->host_lock, flags); return 0; } @@ -3550,12 +3550,12 @@ static int ibmvfc_sdev_configure(struct scsi_device *sdev, struct Scsi_Host *shost = sdev->host; unsigned long flags = 0; - spin_lock_irqsave(shost->host_lock, flags); + spin_lock_irqsave(&shost->host_lock, flags); if (sdev->type == TYPE_DISK) { sdev->allow_restart = 1; blk_queue_rq_timeout(sdev->request_queue, 120 * HZ); } - spin_unlock_irqrestore(shost->host_lock, flags); + spin_unlock_irqrestore(&shost->host_lock, flags); return 0; } @@ -3646,9 +3646,9 @@ static ssize_t ibmvfc_show_log_level(struct device *dev, unsigned long flags = 0; int len; - spin_lock_irqsave(shost->host_lock, flags); + spin_lock_irqsave(&shost->host_lock, flags); len = sysfs_emit(buf, "%d\n", vhost->log_level); - spin_unlock_irqrestore(shost->host_lock, flags); + spin_unlock_irqrestore(&shost->host_lock, flags); return len; } @@ -3670,9 +3670,9 @@ static ssize_t ibmvfc_store_log_level(struct device *dev, struct ibmvfc_host *vhost = shost_priv(shost); unsigned long flags = 0; - spin_lock_irqsave(shost->host_lock, flags); + spin_lock_irqsave(&shost->host_lock, flags); vhost->log_level = simple_strtoul(buf, NULL, 10); - spin_unlock_irqrestore(shost->host_lock, flags); + spin_unlock_irqrestore(&shost->host_lock, flags); return strlen(buf); } @@ -3685,9 +3685,9 @@ static ssize_t ibmvfc_show_scsi_channels(struct device *dev, unsigned long flags = 0; int len; - spin_lock_irqsave(shost->host_lock, flags); + spin_lock_irqsave(&shost->host_lock, flags); len = sysfs_emit(buf, "%d\n", scsi->desired_queues); - spin_unlock_irqrestore(shost->host_lock, flags); + spin_unlock_irqrestore(&shost->host_lock, flags); return len; } @@ -3701,11 +3701,11 @@ static ssize_t ibmvfc_store_scsi_channels(struct device *dev, unsigned long flags = 0; unsigned int channels; - spin_lock_irqsave(shost->host_lock, flags); + spin_lock_irqsave(&shost->host_lock, flags); channels = simple_strtoul(buf, NULL, 10); scsi->desired_queues = min(channels, shost->nr_hw_queues); ibmvfc_hard_reset_host(vhost); - spin_unlock_irqrestore(shost->host_lock, flags); + spin_unlock_irqrestore(&shost->host_lock, flags); return strlen(buf); } @@ -3751,9 +3751,9 @@ static ssize_t ibmvfc_read_trace(struct file *filp, struct kobject *kobj, count = size; } - spin_lock_irqsave(shost->host_lock, flags); + spin_lock_irqsave(&shost->host_lock, flags); memcpy(buf, &src[off], count); - spin_unlock_irqrestore(shost->host_lock, flags); + spin_unlock_irqrestore(&shost->host_lock, flags); return count; } @@ -3864,10 +3864,10 @@ static irqreturn_t ibmvfc_interrupt(int irq, void *dev_instance) struct ibmvfc_host *vhost = (struct ibmvfc_host *)dev_instance; unsigned long flags; - spin_lock_irqsave(vhost->host->host_lock, flags); + spin_lock_irqsave(&vhost->host->host_lock, flags); vio_disable_interrupts(to_vio_dev(vhost->dev)); tasklet_schedule(&vhost->tasklet); - spin_unlock_irqrestore(vhost->host->host_lock, flags); + spin_unlock_irqrestore(&vhost->host->host_lock, flags); return IRQ_HANDLED; } @@ -3889,7 +3889,7 @@ static void ibmvfc_tasklet(void *data) int done = 0; LIST_HEAD(evt_doneq); - spin_lock_irqsave(vhost->host->host_lock, flags); + spin_lock_irqsave(&vhost->host->host_lock, flags); spin_lock(vhost->crq.q_lock); while (!done) { /* Pull all the valid messages off the async CRQ */ @@ -3922,7 +3922,7 @@ static void ibmvfc_tasklet(void *data) } spin_unlock(vhost->crq.q_lock); - spin_unlock_irqrestore(vhost->host->host_lock, flags); + spin_unlock_irqrestore(&vhost->host->host_lock, flags); list_for_each_entry_safe(evt, temp, &evt_doneq, queue_list) { timer_delete(&evt->timer); @@ -4776,12 +4776,12 @@ static void ibmvfc_adisc_timeout(struct timer_list *t) int rc; tgt_dbg(tgt, "ADISC timeout\n"); - spin_lock_irqsave(vhost->host->host_lock, flags); + spin_lock_irqsave(&vhost->host->host_lock, flags); if (vhost->abort_threads >= disc_threads || tgt->action != IBMVFC_TGT_ACTION_INIT_WAIT || vhost->state != IBMVFC_INITIALIZING || vhost->action != IBMVFC_HOST_ACTION_QUERY_TGTS) { - spin_unlock_irqrestore(vhost->host->host_lock, flags); + spin_unlock_irqrestore(&vhost->host->host_lock, flags); return; } @@ -4793,7 +4793,7 @@ static void ibmvfc_adisc_timeout(struct timer_list *t) vhost->abort_threads--; kref_put(&tgt->kref, ibmvfc_release_tgt); __ibmvfc_reset_host(vhost); - spin_unlock_irqrestore(vhost->host->host_lock, flags); + spin_unlock_irqrestore(&vhost->host->host_lock, flags); return; } ibmvfc_init_event(evt, ibmvfc_tgt_adisc_cancel_done, IBMVFC_MAD_FORMAT); @@ -4821,7 +4821,7 @@ static void ibmvfc_adisc_timeout(struct timer_list *t) __ibmvfc_reset_host(vhost); } else tgt_dbg(tgt, "Attempting to cancel ADISC\n"); - spin_unlock_irqrestore(vhost->host->host_lock, flags); + spin_unlock_irqrestore(&vhost->host->host_lock, flags); } /** @@ -5010,7 +5010,7 @@ static int ibmvfc_alloc_target(struct ibmvfc_host *vhost, channels = &vhost->nvme_scrqs; /* Look to see if we already have a target allocated for this SCSI ID or WWPN */ - spin_lock_irqsave(vhost->host->host_lock, flags); + spin_lock_irqsave(&vhost->host->host_lock, flags); list_for_each_entry(tgt, &channels->targets, queue) { if (tgt->wwpn == wwpn) { wtgt = tgt; @@ -5062,7 +5062,7 @@ static int ibmvfc_alloc_target(struct ibmvfc_host *vhost, ibmvfc_init_tgt(tgt, ibmvfc_tgt_implicit_logout); goto unlock_out; } - spin_unlock_irqrestore(vhost->host->host_lock, flags); + spin_unlock_irqrestore(&vhost->host->host_lock, flags); tgt = mempool_alloc(vhost->tgt_pool, GFP_NOIO); memset(tgt, 0, sizeof(*tgt)); @@ -5074,12 +5074,12 @@ static int ibmvfc_alloc_target(struct ibmvfc_host *vhost, timer_setup(&tgt->timer, ibmvfc_adisc_timeout, 0); kref_init(&tgt->kref); ibmvfc_init_tgt(tgt, ibmvfc_tgt_implicit_logout); - spin_lock_irqsave(vhost->host->host_lock, flags); + spin_lock_irqsave(&vhost->host->host_lock, flags); tgt->cancel_key = vhost->task_set++; list_add_tail(&tgt->queue, &channels->targets); unlock_out: - spin_unlock_irqrestore(vhost->host->host_lock, flags); + spin_unlock_irqrestore(&vhost->host->host_lock, flags); return 0; } @@ -5853,9 +5853,9 @@ static int ibmvfc_work_to_do(struct ibmvfc_host *vhost) unsigned long flags; int rc; - spin_lock_irqsave(vhost->host->host_lock, flags); + spin_lock_irqsave(&vhost->host->host_lock, flags); rc = __ibmvfc_work_to_do(vhost); - spin_unlock_irqrestore(vhost->host->host_lock, flags); + spin_unlock_irqrestore(&vhost->host->host_lock, flags); return rc; } @@ -5890,14 +5890,14 @@ static void ibmvfc_tgt_add_nvme_rport(struct ibmvfc_target *tgt) tgt_dbg(tgt, "Adding NVMe rport\n"); ibmvfc_nvme_register_remoteport(tgt); - spin_lock_irqsave(vhost->host->host_lock, flags); + spin_lock_irqsave(&vhost->host->host_lock, flags); rport = tgt->nvme_remote_port; if (rport && tgt->action == IBMVFC_TGT_ACTION_DEL_RPORT) { tgt_dbg(tgt, "Deleting NVMe rport\n"); list_del(&tgt->queue); ibmvfc_set_tgt_action(tgt, IBMVFC_TGT_ACTION_DELETED_RPORT); - spin_unlock_irqrestore(vhost->host->host_lock, flags); + spin_unlock_irqrestore(&vhost->host->host_lock, flags); ibmvfc_nvme_unregister_remoteport(tgt); timer_delete_sync(&tgt->timer); kref_put(&tgt->kref, ibmvfc_release_tgt); @@ -5906,11 +5906,11 @@ static void ibmvfc_tgt_add_nvme_rport(struct ibmvfc_target *tgt) tgt_dbg(tgt, "Deleting NVMe rport with outstanding I/O\n"); ibmvfc_set_tgt_action(tgt, IBMVFC_TGT_ACTION_LOGOUT_DELETED_RPORT); tgt->init_retries = 0; - spin_unlock_irqrestore(vhost->host->host_lock, flags); + spin_unlock_irqrestore(&vhost->host->host_lock, flags); ibmvfc_nvme_unregister_remoteport(tgt); return; } else if (rport && tgt->action == IBMVFC_TGT_ACTION_DELETED_RPORT) { - spin_unlock_irqrestore(vhost->host->host_lock, flags); + spin_unlock_irqrestore(&vhost->host->host_lock, flags); return; } @@ -5919,7 +5919,7 @@ static void ibmvfc_tgt_add_nvme_rport(struct ibmvfc_target *tgt) tgt->target_id = tgt->nvme_remote_port->port_id; } else tgt_dbg(tgt, "NVMe rport add failed\n"); - spin_unlock_irqrestore(vhost->host->host_lock, flags); + spin_unlock_irqrestore(&vhost->host->host_lock, flags); } /** @@ -5935,13 +5935,13 @@ static void ibmvfc_tgt_add_rport(struct ibmvfc_target *tgt) tgt_dbg(tgt, "Adding rport\n"); rport = fc_remote_port_add(vhost->host, 0, &tgt->ids); - spin_lock_irqsave(vhost->host->host_lock, flags); + spin_lock_irqsave(&vhost->host->host_lock, flags); if (rport && tgt->action == IBMVFC_TGT_ACTION_DEL_RPORT) { tgt_dbg(tgt, "Deleting rport\n"); list_del(&tgt->queue); ibmvfc_set_tgt_action(tgt, IBMVFC_TGT_ACTION_DELETED_RPORT); - spin_unlock_irqrestore(vhost->host->host_lock, flags); + spin_unlock_irqrestore(&vhost->host->host_lock, flags); fc_remote_port_delete(rport); timer_delete_sync(&tgt->timer); kref_put(&tgt->kref, ibmvfc_release_tgt); @@ -5951,11 +5951,11 @@ static void ibmvfc_tgt_add_rport(struct ibmvfc_target *tgt) ibmvfc_set_tgt_action(tgt, IBMVFC_TGT_ACTION_LOGOUT_DELETED_RPORT); tgt->rport = NULL; tgt->init_retries = 0; - spin_unlock_irqrestore(vhost->host->host_lock, flags); + spin_unlock_irqrestore(&vhost->host->host_lock, flags); fc_remote_port_delete(rport); return; } else if (rport && tgt->action == IBMVFC_TGT_ACTION_DELETED_RPORT) { - spin_unlock_irqrestore(vhost->host->host_lock, flags); + spin_unlock_irqrestore(&vhost->host->host_lock, flags); return; } @@ -5973,7 +5973,7 @@ static void ibmvfc_tgt_add_rport(struct ibmvfc_target *tgt) rport->supported_classes |= FC_COS_CLASS3; } else tgt_dbg(tgt, "rport add failed\n"); - spin_unlock_irqrestore(vhost->host->host_lock, flags); + spin_unlock_irqrestore(&vhost->host->host_lock, flags); } /** @@ -5991,7 +5991,7 @@ static void ibmvfc_do_work(struct ibmvfc_host *vhost) int rc; ibmvfc_log_ae(vhost, vhost->events_to_log); - spin_lock_irqsave(vhost->host->host_lock, flags); + spin_lock_irqsave(&vhost->host->host_lock, flags); vhost->events_to_log = 0; switch (vhost->action) { case IBMVFC_HOST_ACTION_NONE: @@ -6000,12 +6000,12 @@ static void ibmvfc_do_work(struct ibmvfc_host *vhost) break; case IBMVFC_HOST_ACTION_RESET: list_splice_init(&vhost->purge, &purge); - spin_unlock_irqrestore(vhost->host->host_lock, flags); + spin_unlock_irqrestore(&vhost->host->host_lock, flags); ibmvfc_complete_purge(&purge); ibmvfc_nvme_unregister(vhost); rc = ibmvfc_reset_crq(vhost); - spin_lock_irqsave(vhost->host->host_lock, flags); + spin_lock_irqsave(&vhost->host->host_lock, flags); if (!rc || rc == H_CLOSED) vio_enable_interrupts(to_vio_dev(vhost->dev)); if (vhost->action == IBMVFC_HOST_ACTION_RESET) { @@ -6026,11 +6026,11 @@ static void ibmvfc_do_work(struct ibmvfc_host *vhost) break; case IBMVFC_HOST_ACTION_REENABLE: list_splice_init(&vhost->purge, &purge); - spin_unlock_irqrestore(vhost->host->host_lock, flags); + spin_unlock_irqrestore(&vhost->host->host_lock, flags); ibmvfc_complete_purge(&purge); rc = ibmvfc_reenable_crq_queue(vhost); - spin_lock_irqsave(vhost->host->host_lock, flags); + spin_lock_irqsave(&vhost->host->host_lock, flags); if (vhost->action == IBMVFC_HOST_ACTION_REENABLE) { /* * The only action we could have changed to would have @@ -6052,7 +6052,7 @@ static void ibmvfc_do_work(struct ibmvfc_host *vhost) BUG_ON(vhost->state != IBMVFC_INITIALIZING); if (vhost->delay_init) { vhost->delay_init = 0; - spin_unlock_irqrestore(vhost->host->host_lock, flags); + spin_unlock_irqrestore(&vhost->host->host_lock, flags); ssleep(15); return; } else @@ -6098,7 +6098,7 @@ static void ibmvfc_do_work(struct ibmvfc_host *vhost) } if (ibmvfc_dev_logo_to_do(vhost)) { - spin_unlock_irqrestore(vhost->host->host_lock, flags); + spin_unlock_irqrestore(&vhost->host->host_lock, flags); return; } @@ -6109,7 +6109,7 @@ static void ibmvfc_do_work(struct ibmvfc_host *vhost) tgt->rport = NULL; list_del(&tgt->queue); ibmvfc_set_tgt_action(tgt, IBMVFC_TGT_ACTION_DELETED_RPORT); - spin_unlock_irqrestore(vhost->host->host_lock, flags); + spin_unlock_irqrestore(&vhost->host->host_lock, flags); if (rport) fc_remote_port_delete(rport); timer_delete_sync(&tgt->timer); @@ -6133,7 +6133,7 @@ static void ibmvfc_do_work(struct ibmvfc_host *vhost) */ if (rport && rport->fast_io_fail_tmo == -1) tgt->move_login = 1; - spin_unlock_irqrestore(vhost->host->host_lock, flags); + spin_unlock_irqrestore(&vhost->host->host_lock, flags); if (rport) fc_remote_port_delete(rport); return; @@ -6146,7 +6146,7 @@ static void ibmvfc_do_work(struct ibmvfc_host *vhost) nvme_rport = tgt->nvme_remote_port; list_del(&tgt->queue); ibmvfc_set_tgt_action(tgt, IBMVFC_TGT_ACTION_DELETED_RPORT); - spin_unlock_irqrestore(vhost->host->host_lock, flags); + spin_unlock_irqrestore(&vhost->host->host_lock, flags); if (nvme_rport) ibmvfc_nvme_unregister_remoteport(tgt); timer_delete_sync(&tgt->timer); @@ -6157,7 +6157,7 @@ static void ibmvfc_do_work(struct ibmvfc_host *vhost) nvme_rport = tgt->nvme_remote_port; ibmvfc_set_tgt_action(tgt, IBMVFC_TGT_ACTION_LOGOUT_DELETED_RPORT); tgt->init_retries = 0; - spin_unlock_irqrestore(vhost->host->host_lock, flags); + spin_unlock_irqrestore(&vhost->host->host_lock, flags); if (nvme_rport) ibmvfc_nvme_unregister_remoteport(tgt); return; @@ -6170,14 +6170,14 @@ static void ibmvfc_do_work(struct ibmvfc_host *vhost) vhost->reinit = 0; scsi_block_requests(vhost->host); ibmvfc_set_host_action(vhost, IBMVFC_HOST_ACTION_QUERY); - spin_unlock_irqrestore(vhost->host->host_lock, flags); + spin_unlock_irqrestore(&vhost->host->host_lock, flags); } else { ibmvfc_set_host_state(vhost, IBMVFC_ACTIVE); ibmvfc_set_host_action(vhost, IBMVFC_HOST_ACTION_NONE); wake_up(&vhost->init_wait_q); schedule_work(&vhost->rport_add_work_q); vhost->init_retries = 0; - spin_unlock_irqrestore(vhost->host->host_lock, flags); + spin_unlock_irqrestore(&vhost->host->host_lock, flags); scsi_unblock_requests(vhost->host); } @@ -6188,7 +6188,7 @@ static void ibmvfc_do_work(struct ibmvfc_host *vhost) } } else { ibmvfc_set_host_action(vhost, IBMVFC_HOST_ACTION_NONE); - spin_unlock_irqrestore(vhost->host->host_lock, flags); + spin_unlock_irqrestore(&vhost->host->host_lock, flags); scsi_unblock_requests(vhost->host); wake_up(&vhost->init_wait_q); return; @@ -6196,9 +6196,9 @@ static void ibmvfc_do_work(struct ibmvfc_host *vhost) break; case IBMVFC_HOST_ACTION_ALLOC_TGTS: ibmvfc_set_host_action(vhost, IBMVFC_HOST_ACTION_TGT_INIT); - spin_unlock_irqrestore(vhost->host->host_lock, flags); + spin_unlock_irqrestore(&vhost->host->host_lock, flags); ibmvfc_alloc_targets(vhost); - spin_lock_irqsave(vhost->host->host_lock, flags); + spin_lock_irqsave(&vhost->host->host_lock, flags); break; case IBMVFC_HOST_ACTION_TGT_INIT: list_for_each_entry(tgt, &vhost->scsi_scrqs.targets, queue) { @@ -6221,7 +6221,7 @@ static void ibmvfc_do_work(struct ibmvfc_host *vhost) break; } - spin_unlock_irqrestore(vhost->host->host_lock, flags); + spin_unlock_irqrestore(&vhost->host->host_lock, flags); } /** @@ -6754,7 +6754,7 @@ static void ibmvfc_rport_add_thread(struct work_struct *work) int did_work; ENTER; - spin_lock_irqsave(vhost->host->host_lock, flags); + spin_lock_irqsave(&vhost->host->host_lock, flags); do { did_work = 0; if (vhost->state != IBMVFC_ACTIVE) @@ -6767,19 +6767,19 @@ static void ibmvfc_rport_add_thread(struct work_struct *work) kref_get(&tgt->kref); rport = tgt->rport; if (!rport) { - spin_unlock_irqrestore(vhost->host->host_lock, flags); + spin_unlock_irqrestore(&vhost->host->host_lock, flags); ibmvfc_tgt_add_rport(tgt); } else if (get_device(&rport->dev)) { - spin_unlock_irqrestore(vhost->host->host_lock, flags); + spin_unlock_irqrestore(&vhost->host->host_lock, flags); tgt_dbg(tgt, "Setting rport roles\n"); fc_remote_port_rolechg(rport, tgt->ids.roles); put_device(&rport->dev); } else { - spin_unlock_irqrestore(vhost->host->host_lock, flags); + spin_unlock_irqrestore(&vhost->host->host_lock, flags); } kref_put(&tgt->kref, ibmvfc_release_tgt); - spin_lock_irqsave(vhost->host->host_lock, flags); + spin_lock_irqsave(&vhost->host->host_lock, flags); break; } } @@ -6791,16 +6791,16 @@ static void ibmvfc_rport_add_thread(struct work_struct *work) kref_get(&tgt->kref); nvme_rport = tgt->nvme_remote_port; if (!nvme_rport) { - spin_unlock_irqrestore(vhost->host->host_lock, flags); + spin_unlock_irqrestore(&vhost->host->host_lock, flags); ibmvfc_tgt_add_nvme_rport(tgt); } else { - spin_unlock_irqrestore(vhost->host->host_lock, flags); + spin_unlock_irqrestore(&vhost->host->host_lock, flags); if (IS_ENABLED(CONFIG_NVME_FC)) nvme_fc_rescan_remoteport(nvme_rport); } kref_put(&tgt->kref, ibmvfc_release_tgt); - spin_lock_irqsave(vhost->host->host_lock, flags); + spin_lock_irqsave(&vhost->host->host_lock, flags); break; } } @@ -6808,7 +6808,7 @@ static void ibmvfc_rport_add_thread(struct work_struct *work) if (vhost->state == IBMVFC_ACTIVE) vhost->scan_complete = 1; - spin_unlock_irqrestore(vhost->host->host_lock, flags); + spin_unlock_irqrestore(&vhost->host->host_lock, flags); LEAVE; } @@ -6946,9 +6946,9 @@ static void ibmvfc_remove(struct vio_dev *vdev) ENTER; ibmvfc_remove_trace_file(&vhost->host->shost_dev.kobj, &ibmvfc_trace_attr); - spin_lock_irqsave(vhost->host->host_lock, flags); + spin_lock_irqsave(&vhost->host->host_lock, flags); ibmvfc_link_down(vhost, IBMVFC_HOST_OFFLINE); - spin_unlock_irqrestore(vhost->host->host_lock, flags); + spin_unlock_irqrestore(&vhost->host->host_lock, flags); ibmvfc_wait_while_resetting(vhost); kthread_stop(vhost->work_thread); @@ -6956,10 +6956,10 @@ static void ibmvfc_remove(struct vio_dev *vdev) fc_remove_host(vhost->host); scsi_remove_host(vhost->host); - spin_lock_irqsave(vhost->host->host_lock, flags); + spin_lock_irqsave(&vhost->host->host_lock, flags); ibmvfc_purge_requests(vhost, DID_ERROR); list_splice_init(&vhost->purge, &purge); - spin_unlock_irqrestore(vhost->host->host_lock, flags); + spin_unlock_irqrestore(&vhost->host->host_lock, flags); ibmvfc_complete_purge(&purge); ibmvfc_release_sub_crqs(vhost); ibmvfc_release_crq_queue(vhost); @@ -6986,10 +6986,10 @@ static int ibmvfc_resume(struct device *dev) struct ibmvfc_host *vhost = dev_get_drvdata(dev); struct vio_dev *vdev = to_vio_dev(dev); - spin_lock_irqsave(vhost->host->host_lock, flags); + spin_lock_irqsave(&vhost->host->host_lock, flags); vio_disable_interrupts(vdev); tasklet_schedule(&vhost->tasklet); - spin_unlock_irqrestore(vhost->host->host_lock, flags); + spin_unlock_irqrestore(&vhost->host->host_lock, flags); return 0; } diff --git a/drivers/scsi/ibmvscsi/ibmvfc-nvme.c b/drivers/scsi/ibmvscsi/ibmvfc-nvme.c index 54f80b6265d4..9ac2671a3567 100644 --- a/drivers/scsi/ibmvscsi/ibmvfc-nvme.c +++ b/drivers/scsi/ibmvscsi/ibmvfc-nvme.c @@ -208,7 +208,7 @@ static void ibmvfc_nvme_ls_abort(struct nvme_fc_local_port *lport, if (!vhost->logged_in || !evt) return; - spin_lock_irqsave(vhost->host->host_lock, flags); + spin_lock_irqsave(&vhost->host->host_lock, flags); kref_get(&tgt->kref); ibmvfc_init_event(evt, ibmvfc_sync_nvme_completion, IBMVFC_MAD_FORMAT); ibmvfc_init_ls_abort(evt, ls_abort); @@ -217,14 +217,14 @@ static void ibmvfc_nvme_ls_abort(struct nvme_fc_local_port *lport, if (ibmvfc_send_event(evt, vhost, default_timeout)) goto out; - spin_unlock_irqrestore(vhost->host->host_lock, flags); + spin_unlock_irqrestore(&vhost->host->host_lock, flags); wait_for_completion(&evt->comp); status = be16_to_cpu(rsp.mad_common.status); - spin_lock_irqsave(vhost->host->host_lock, flags); + spin_lock_irqsave(&vhost->host->host_lock, flags); ibmvfc_free_event(evt); out: - spin_unlock_irqrestore(vhost->host->host_lock, flags); + spin_unlock_irqrestore(&vhost->host->host_lock, flags); ibmvfc_dbg(vhost, "ls_abort: cancel failed with rc=%x\n", status); kref_put(&tgt->kref, ibmvfc_release_tgt); } diff --git a/drivers/scsi/ibmvscsi/ibmvscsi.c b/drivers/scsi/ibmvscsi/ibmvscsi.c index 609bda730b3a..4ecd3db08875 100644 --- a/drivers/scsi/ibmvscsi/ibmvscsi.c +++ b/drivers/scsi/ibmvscsi/ibmvscsi.c @@ -785,13 +785,13 @@ static void purge_requests(struct ibmvscsi_host_data *hostdata, int error_code) struct srp_event_struct *evt; unsigned long flags; - spin_lock_irqsave(hostdata->host->host_lock, flags); + spin_lock_irqsave(&hostdata->host->host_lock, flags); while (!list_empty(&hostdata->sent)) { evt = list_first_entry(&hostdata->sent, struct srp_event_struct, list); list_del(&evt->list); timer_delete(&evt->timer); - spin_unlock_irqrestore(hostdata->host->host_lock, flags); + spin_unlock_irqrestore(&hostdata->host->host_lock, flags); if (evt->cmnd) { evt->cmnd->result = (error_code << 16); unmap_cmd_data(&evt->iu.srp.cmd, evt, @@ -802,9 +802,9 @@ static void purge_requests(struct ibmvscsi_host_data *hostdata, int error_code) evt->iu.srp.login_req.opcode != SRP_LOGIN_REQ) evt->done(evt); free_event_struct(&evt->hostdata->pool, evt); - spin_lock_irqsave(hostdata->host->host_lock, flags); + spin_lock_irqsave(&hostdata->host->host_lock, flags); } - spin_unlock_irqrestore(hostdata->host->host_lock, flags); + spin_unlock_irqrestore(&hostdata->host->host_lock, flags); } /** @@ -818,9 +818,9 @@ static void ibmvscsi_set_request_limit(struct ibmvscsi_host_data *hostdata, int { unsigned long flags; - spin_lock_irqsave(hostdata->host->host_lock, flags); + spin_lock_irqsave(&hostdata->host->host_lock, flags); atomic_set(&hostdata->request_limit, limit); - spin_unlock_irqrestore(hostdata->host->host_lock, flags); + spin_unlock_irqrestore(&hostdata->host->host_lock, flags); } /** @@ -1221,9 +1221,9 @@ static int send_srp_login(struct ibmvscsi_host_data *hostdata) */ ibmvscsi_set_request_limit(hostdata, 0); - spin_lock_irqsave(hostdata->host->host_lock, flags); + spin_lock_irqsave(&hostdata->host->host_lock, flags); rc = ibmvscsi_send_srp_event(evt_struct, hostdata, login_timeout * 2); - spin_unlock_irqrestore(hostdata->host->host_lock, flags); + spin_unlock_irqrestore(&hostdata->host->host_lock, flags); dev_info(hostdata->dev, "sent SRP login\n"); return rc; }; @@ -1317,10 +1317,10 @@ static void send_mad_capabilities(struct ibmvscsi_host_data *hostdata) req->common.length = cpu_to_be16(sizeof(hostdata->caps) - sizeof(hostdata->caps.reserve)); - spin_lock_irqsave(hostdata->host->host_lock, flags); + spin_lock_irqsave(&hostdata->host->host_lock, flags); if (ibmvscsi_send_srp_event(evt_struct, hostdata, info_timeout * 2)) dev_err(hostdata->dev, "couldn't send CAPABILITIES_REQ!\n"); - spin_unlock_irqrestore(hostdata->host->host_lock, flags); + spin_unlock_irqrestore(&hostdata->host->host_lock, flags); }; /** @@ -1373,9 +1373,9 @@ static int enable_fast_fail(struct ibmvscsi_host_data *hostdata) fast_fail_mad->common.type = cpu_to_be32(VIOSRP_ENABLE_FAST_FAIL); fast_fail_mad->common.length = cpu_to_be16(sizeof(*fast_fail_mad)); - spin_lock_irqsave(hostdata->host->host_lock, flags); + spin_lock_irqsave(&hostdata->host->host_lock, flags); rc = ibmvscsi_send_srp_event(evt_struct, hostdata, info_timeout * 2); - spin_unlock_irqrestore(hostdata->host->host_lock, flags); + spin_unlock_irqrestore(&hostdata->host->host_lock, flags); return rc; } @@ -1454,10 +1454,10 @@ static void send_mad_adapter_info(struct ibmvscsi_host_data *hostdata) req->common.length = cpu_to_be16(sizeof(hostdata->madapter_info)); req->buffer = cpu_to_be64(hostdata->adapter_info_addr); - spin_lock_irqsave(hostdata->host->host_lock, flags); + spin_lock_irqsave(&hostdata->host->host_lock, flags); if (ibmvscsi_send_srp_event(evt_struct, hostdata, info_timeout * 2)) dev_err(hostdata->dev, "couldn't send ADAPTER_INFO_REQ!\n"); - spin_unlock_irqrestore(hostdata->host->host_lock, flags); + spin_unlock_irqrestore(&hostdata->host->host_lock, flags); }; /* @@ -1502,7 +1502,7 @@ static int ibmvscsi_eh_abort_handler(struct scsi_cmnd *cmd) /* First, find this command in our sent list so we can figure * out the correct tag */ - spin_lock_irqsave(hostdata->host->host_lock, flags); + spin_lock_irqsave(&hostdata->host->host_lock, flags); wait_switch = jiffies + (init_timeout * HZ); do { found_evt = NULL; @@ -1514,13 +1514,13 @@ static int ibmvscsi_eh_abort_handler(struct scsi_cmnd *cmd) } if (!found_evt) { - spin_unlock_irqrestore(hostdata->host->host_lock, flags); + spin_unlock_irqrestore(&hostdata->host->host_lock, flags); return SUCCESS; } evt = get_event_struct(&hostdata->pool); if (evt == NULL) { - spin_unlock_irqrestore(hostdata->host->host_lock, flags); + spin_unlock_irqrestore(&hostdata->host->host_lock, flags); sdev_printk(KERN_ERR, cmd->device, "failed to allocate abort event\n"); return FAILED; @@ -1548,12 +1548,12 @@ static int ibmvscsi_eh_abort_handler(struct scsi_cmnd *cmd) if (rsp_rc != SCSI_MLQUEUE_HOST_BUSY) break; - spin_unlock_irqrestore(hostdata->host->host_lock, flags); + spin_unlock_irqrestore(&hostdata->host->host_lock, flags); msleep(10); - spin_lock_irqsave(hostdata->host->host_lock, flags); + spin_lock_irqsave(&hostdata->host->host_lock, flags); } while (time_before(jiffies, wait_switch)); - spin_unlock_irqrestore(hostdata->host->host_lock, flags); + spin_unlock_irqrestore(&hostdata->host->host_lock, flags); if (rsp_rc != 0) { sdev_printk(KERN_ERR, cmd->device, @@ -1592,7 +1592,7 @@ static int ibmvscsi_eh_abort_handler(struct scsi_cmnd *cmd) * The event is no longer in our list. Make sure it didn't * complete while we were aborting */ - spin_lock_irqsave(hostdata->host->host_lock, flags); + spin_lock_irqsave(&hostdata->host->host_lock, flags); found_evt = NULL; list_for_each_entry(tmp_evt, &hostdata->sent, list) { if (tmp_evt->cmnd == cmd) { @@ -1602,7 +1602,7 @@ static int ibmvscsi_eh_abort_handler(struct scsi_cmnd *cmd) } if (found_evt == NULL) { - spin_unlock_irqrestore(hostdata->host->host_lock, flags); + spin_unlock_irqrestore(&hostdata->host->host_lock, flags); sdev_printk(KERN_INFO, cmd->device, "aborted task tag 0x%llx completed\n", tsk_mgmt->task_tag); return SUCCESS; @@ -1616,7 +1616,7 @@ static int ibmvscsi_eh_abort_handler(struct scsi_cmnd *cmd) unmap_cmd_data(&found_evt->iu.srp.cmd, found_evt, found_evt->hostdata->dev); free_event_struct(&found_evt->hostdata->pool, found_evt); - spin_unlock_irqrestore(hostdata->host->host_lock, flags); + spin_unlock_irqrestore(&hostdata->host->host_lock, flags); atomic_inc(&hostdata->request_limit); return SUCCESS; } @@ -1638,12 +1638,12 @@ static int ibmvscsi_eh_device_reset_handler(struct scsi_cmnd *cmd) u16 lun = lun_from_dev(cmd->device); unsigned long wait_switch = 0; - spin_lock_irqsave(hostdata->host->host_lock, flags); + spin_lock_irqsave(&hostdata->host->host_lock, flags); wait_switch = jiffies + (init_timeout * HZ); do { evt = get_event_struct(&hostdata->pool); if (evt == NULL) { - spin_unlock_irqrestore(hostdata->host->host_lock, flags); + spin_unlock_irqrestore(&hostdata->host->host_lock, flags); sdev_printk(KERN_ERR, cmd->device, "failed to allocate reset event\n"); return FAILED; @@ -1670,12 +1670,12 @@ static int ibmvscsi_eh_device_reset_handler(struct scsi_cmnd *cmd) if (rsp_rc != SCSI_MLQUEUE_HOST_BUSY) break; - spin_unlock_irqrestore(hostdata->host->host_lock, flags); + spin_unlock_irqrestore(&hostdata->host->host_lock, flags); msleep(10); - spin_lock_irqsave(hostdata->host->host_lock, flags); + spin_lock_irqsave(&hostdata->host->host_lock, flags); } while (time_before(jiffies, wait_switch)); - spin_unlock_irqrestore(hostdata->host->host_lock, flags); + spin_unlock_irqrestore(&hostdata->host->host_lock, flags); if (rsp_rc != 0) { sdev_printk(KERN_ERR, cmd->device, @@ -1712,7 +1712,7 @@ static int ibmvscsi_eh_device_reset_handler(struct scsi_cmnd *cmd) /* We need to find all commands for this LUN that have not yet been * responded to, and fail them with DID_RESET */ - spin_lock_irqsave(hostdata->host->host_lock, flags); + spin_lock_irqsave(&hostdata->host->host_lock, flags); list_for_each_entry_safe(tmp_evt, pos, &hostdata->sent, list) { if ((tmp_evt->cmnd) && (tmp_evt->cmnd->device == cmd->device)) { if (tmp_evt->cmnd) @@ -1729,7 +1729,7 @@ static int ibmvscsi_eh_device_reset_handler(struct scsi_cmnd *cmd) tmp_evt->done(tmp_evt); } } - spin_unlock_irqrestore(hostdata->host->host_lock, flags); + spin_unlock_irqrestore(&hostdata->host->host_lock, flags); return SUCCESS; } @@ -1855,10 +1855,10 @@ static void ibmvscsi_handle_crq(struct viosrp_crq *crq, * Lock the host_lock before messing with these structures, since we * are running in a task context */ - spin_lock_irqsave(evt_struct->hostdata->host->host_lock, flags); + spin_lock_irqsave(&evt_struct->hostdata->host->host_lock, flags); list_del(&evt_struct->list); free_event_struct(&evt_struct->hostdata->pool, evt_struct); - spin_unlock_irqrestore(evt_struct->hostdata->host->host_lock, flags); + spin_unlock_irqrestore(&evt_struct->hostdata->host->host_lock, flags); } /** @@ -1876,12 +1876,12 @@ static int ibmvscsi_sdev_configure(struct scsi_device *sdev, struct Scsi_Host *shost = sdev->host; unsigned long lock_flags = 0; - spin_lock_irqsave(shost->host_lock, lock_flags); + spin_lock_irqsave(&shost->host_lock, lock_flags); if (sdev->type == TYPE_DISK) { sdev->allow_restart = 1; blk_queue_rq_timeout(sdev->request_queue, 120 * HZ); } - spin_unlock_irqrestore(shost->host_lock, lock_flags); + spin_unlock_irqrestore(&shost->host_lock, lock_flags); return 0; } @@ -2131,35 +2131,35 @@ static void ibmvscsi_do_work(struct ibmvscsi_host_data *hostdata) int rc; char *action = "reset"; - spin_lock_irqsave(hostdata->host->host_lock, flags); + spin_lock_irqsave(&hostdata->host->host_lock, flags); switch (hostdata->action) { case IBMVSCSI_HOST_ACTION_UNBLOCK: rc = 0; break; case IBMVSCSI_HOST_ACTION_RESET: - spin_unlock_irqrestore(hostdata->host->host_lock, flags); + spin_unlock_irqrestore(&hostdata->host->host_lock, flags); rc = ibmvscsi_reset_crq_queue(&hostdata->queue, hostdata); - spin_lock_irqsave(hostdata->host->host_lock, flags); + spin_lock_irqsave(&hostdata->host->host_lock, flags); if (!rc) rc = ibmvscsi_send_crq(hostdata, 0xC001000000000000LL, 0); vio_enable_interrupts(to_vio_dev(hostdata->dev)); break; case IBMVSCSI_HOST_ACTION_REENABLE: action = "enable"; - spin_unlock_irqrestore(hostdata->host->host_lock, flags); + spin_unlock_irqrestore(&hostdata->host->host_lock, flags); rc = ibmvscsi_reenable_crq_queue(&hostdata->queue, hostdata); - spin_lock_irqsave(hostdata->host->host_lock, flags); + spin_lock_irqsave(&hostdata->host->host_lock, flags); if (!rc) rc = ibmvscsi_send_crq(hostdata, 0xC001000000000000LL, 0); break; case IBMVSCSI_HOST_ACTION_NONE: default: - spin_unlock_irqrestore(hostdata->host->host_lock, flags); + spin_unlock_irqrestore(&hostdata->host->host_lock, flags); return; } hostdata->action = IBMVSCSI_HOST_ACTION_NONE; - spin_unlock_irqrestore(hostdata->host->host_lock, flags); + spin_unlock_irqrestore(&hostdata->host->host_lock, flags); if (rc) { ibmvscsi_set_request_limit(hostdata, -1); @@ -2191,9 +2191,9 @@ static int ibmvscsi_work_to_do(struct ibmvscsi_host_data *hostdata) unsigned long flags; int rc; - spin_lock_irqsave(hostdata->host->host_lock, flags); + spin_lock_irqsave(&hostdata->host->host_lock, flags); rc = __ibmvscsi_work_to_do(hostdata); - spin_unlock_irqrestore(hostdata->host->host_lock, flags); + spin_unlock_irqrestore(&hostdata->host->host_lock, flags); return rc; } diff --git a/drivers/scsi/ibmvscsi_tgt/Makefile b/drivers/scsi/ibmvscsi_tgt/Makefile index cc7a8256dcf8..7ae12ee9a347 100644 --- a/drivers/scsi/ibmvscsi_tgt/Makefile +++ b/drivers/scsi/ibmvscsi_tgt/Makefile @@ -1,4 +1,7 @@ # SPDX-License-Identifier: GPL-2.0-only + +CONTEXT_ANALYSIS := y + obj-$(CONFIG_SCSI_IBMVSCSIS) += ibmvscsis.o ibmvscsis-y := libsrp.o ibmvscsi_tgt.o diff --git a/drivers/scsi/ibmvscsi_tgt/ibmvscsi_tgt.c b/drivers/scsi/ibmvscsi_tgt/ibmvscsi_tgt.c index 61f682800765..92b26f7fec50 100644 --- a/drivers/scsi/ibmvscsi_tgt/ibmvscsi_tgt.c +++ b/drivers/scsi/ibmvscsi_tgt/ibmvscsi_tgt.c @@ -219,6 +219,7 @@ static long ibmvscsis_unregister_command_q(struct scsi_info *vscsi) */ static void ibmvscsis_delete_client_info(struct scsi_info *vscsi, bool client_closed) + __must_hold(&vscsi->intr_lock) { vscsi->client_cap = 0; @@ -251,6 +252,7 @@ static void ibmvscsis_delete_client_info(struct scsi_info *vscsi, * Process level, interrupt lock is held */ static long ibmvscsis_free_command_q(struct scsi_info *vscsi) + __must_hold(&vscsi->intr_lock) { int bytes; u32 flags_under_lock; @@ -329,6 +331,7 @@ static struct viosrp_crq *ibmvscsis_cmd_q_dequeue(uint mask, * Interrupt environment interrupt lock held */ static long ibmvscsis_send_init_message(struct scsi_info *vscsi, u8 format) + __must_hold(&vscsi->intr_lock) { struct viosrp_crq *crq; u64 buffer[2] = { 0, 0 }; @@ -356,6 +359,7 @@ static long ibmvscsis_send_init_message(struct scsi_info *vscsi, u8 format) * Process level only, interrupt lock held */ static long ibmvscsis_check_init_msg(struct scsi_info *vscsi, uint *format) + __must_hold(&vscsi->intr_lock) { struct viosrp_crq *crq; long rc = ADAPT_SUCCESS; @@ -571,6 +575,7 @@ static void ibmvscsis_disconnect(struct work_struct *work) */ static void ibmvscsis_post_disconnect(struct scsi_info *vscsi, uint new_state, uint flag_bits) + __must_hold(&vscsi->intr_lock) { uint state; @@ -652,6 +657,7 @@ static void ibmvscsis_post_disconnect(struct scsi_info *vscsi, uint new_state, * Must be called with interrupt lock held. */ static long ibmvscsis_handle_init_compl_msg(struct scsi_info *vscsi) + __must_hold(&vscsi->intr_lock) { long rc = ADAPT_SUCCESS; @@ -691,6 +697,7 @@ static long ibmvscsis_handle_init_compl_msg(struct scsi_info *vscsi) * Must be called with interrupt lock held. */ static long ibmvscsis_handle_init_msg(struct scsi_info *vscsi) + __must_hold(&vscsi->intr_lock) { long rc = ADAPT_SUCCESS; @@ -759,6 +766,7 @@ static long ibmvscsis_handle_init_msg(struct scsi_info *vscsi) * Interrupt, interrupt lock held */ static long ibmvscsis_init_msg(struct scsi_info *vscsi, struct viosrp_crq *crq) + __must_hold(&vscsi->intr_lock) { long rc = ADAPT_SUCCESS; @@ -798,6 +806,7 @@ static long ibmvscsis_init_msg(struct scsi_info *vscsi, struct viosrp_crq *crq) * Must be called with interrupt lock held. */ static long ibmvscsis_establish_new_q(struct scsi_info *vscsi) + __must_hold(&vscsi->intr_lock) { long rc = ADAPT_SUCCESS; uint format; @@ -874,6 +883,7 @@ static long ibmvscsis_establish_new_q(struct scsi_info *vscsi) * Process environment, called with interrupt lock held */ static void ibmvscsis_reset_queue(struct scsi_info *vscsi) + __must_hold(&vscsi->intr_lock) { int bytes; long rc = ADAPT_SUCCESS; @@ -924,6 +934,7 @@ static void ibmvscsis_reset_queue(struct scsi_info *vscsi) */ static void ibmvscsis_free_cmd_resources(struct scsi_info *vscsi, struct ibmvscsis_cmd *cmd) + __must_hold(&vscsi->intr_lock) { struct iu_entry *iue = cmd->iue; @@ -974,6 +985,7 @@ static void ibmvscsis_free_cmd_resources(struct scsi_info *vscsi, * Process or interrupt environment called with interrupt lock held */ static long ibmvscsis_ready_for_suspend(struct scsi_info *vscsi, bool idle) + __must_hold(&vscsi->intr_lock) { long rc = 0; struct viosrp_crq *crq; @@ -1030,6 +1042,7 @@ static long ibmvscsis_ready_for_suspend(struct scsi_info *vscsi, bool idle) */ static long ibmvscsis_trans_event(struct scsi_info *vscsi, struct viosrp_crq *crq) + __must_hold(&vscsi->intr_lock) { long rc = ADAPT_SUCCESS; @@ -1166,6 +1179,7 @@ static long ibmvscsis_trans_event(struct scsi_info *vscsi, * intr_lock must be held */ static void ibmvscsis_poll_cmd_q(struct scsi_info *vscsi) + __must_hold(&vscsi->intr_lock) { struct viosrp_crq *crq; long rc; @@ -1252,6 +1266,7 @@ static void ibmvscsis_poll_cmd_q(struct scsi_info *vscsi) * Called with interrupt lock held */ static void ibmvscsis_free_cmd_qs(struct scsi_info *vscsi) + __must_hold(&vscsi->intr_lock) { struct ibmvscsis_cmd *cmd, *nxt; @@ -1272,6 +1287,7 @@ static void ibmvscsis_free_cmd_qs(struct scsi_info *vscsi) * Must be called with interrupt lock held. */ static struct ibmvscsis_cmd *ibmvscsis_get_free_cmd(struct scsi_info *vscsi) + __must_hold(&vscsi->intr_lock) { struct ibmvscsis_cmd *cmd = NULL; struct iu_entry *iue; @@ -1310,6 +1326,7 @@ static struct ibmvscsis_cmd *ibmvscsis_get_free_cmd(struct scsi_info *vscsi) * Process environment called with interrupt lock held */ static void ibmvscsis_adapter_idle(struct scsi_info *vscsi) + __must_hold(&vscsi->intr_lock) { int free_qs = false; long rc = 0; @@ -1441,6 +1458,7 @@ static void ibmvscsis_adapter_idle(struct scsi_info *vscsi) static long ibmvscsis_copy_crq_packet(struct scsi_info *vscsi, struct ibmvscsis_cmd *cmd, struct viosrp_crq *crq) + __must_hold(&vscsi->intr_lock) { struct iu_entry *iue = cmd->iue; long rc = 0; @@ -1500,6 +1518,7 @@ static long ibmvscsis_copy_crq_packet(struct scsi_info *vscsi, */ static long ibmvscsis_adapter_info(struct scsi_info *vscsi, struct iu_entry *iue) + __must_hold(&vscsi->intr_lock) { struct viosrp_adapter_info *mad = &vio_iu(iue)->mad.adapter_info; struct mad_adapter_info_data *info; @@ -1611,6 +1630,7 @@ static long ibmvscsis_adapter_info(struct scsi_info *vscsi, * Interrupt called with adapter lock held */ static int ibmvscsis_cap_mad(struct scsi_info *vscsi, struct iu_entry *iue) + __must_hold(&vscsi->intr_lock) { struct viosrp_capabilities *mad = &vio_iu(iue)->mad.capabilities; struct capabilities *cap; @@ -1725,6 +1745,7 @@ static int ibmvscsis_cap_mad(struct scsi_info *vscsi, struct iu_entry *iue) * Must be called with interrupt lock held. */ static long ibmvscsis_process_mad(struct scsi_info *vscsi, struct iu_entry *iue) + __must_hold(&vscsi->intr_lock) { struct mad_common *mad = (struct mad_common *)&vio_iu(iue)->mad; struct viosrp_empty_iu *empty; @@ -1768,6 +1789,7 @@ static long ibmvscsis_process_mad(struct scsi_info *vscsi, struct iu_entry *iue) * Must be called with interrupt lock held. */ static void srp_snd_msg_failed(struct scsi_info *vscsi, long rc) + __must_hold(&vscsi->intr_lock) { ktime_t kt; @@ -1871,6 +1893,7 @@ static void srp_snd_msg_failed(struct scsi_info *vscsi, long rc) * Called with interrupt lock held */ static void ibmvscsis_send_messages(struct scsi_info *vscsi) + __must_hold(&vscsi->intr_lock) { struct viosrp_crq empty_crq = { }; struct viosrp_crq *crq = &empty_crq; @@ -1979,6 +2002,7 @@ static void ibmvscsis_send_messages(struct scsi_info *vscsi) static void ibmvscsis_send_mad_resp(struct scsi_info *vscsi, struct ibmvscsis_cmd *cmd, struct viosrp_crq *crq) + __must_hold(&vscsi->intr_lock) { struct iu_entry *iue = cmd->iue; struct mad_common *mad = (struct mad_common *)&vio_iu(iue)->mad; @@ -2021,6 +2045,7 @@ static void ibmvscsis_send_mad_resp(struct scsi_info *vscsi, * Interrupt, called with adapter lock held */ static long ibmvscsis_mad(struct scsi_info *vscsi, struct viosrp_crq *crq) + __must_hold(&vscsi->intr_lock) { struct iu_entry *iue; struct ibmvscsis_cmd *cmd; @@ -2097,6 +2122,7 @@ static long ibmvscsis_mad(struct scsi_info *vscsi, struct viosrp_crq *crq) */ static long ibmvscsis_login_rsp(struct scsi_info *vscsi, struct ibmvscsis_cmd *cmd) + __must_hold(&vscsi->intr_lock) { struct iu_entry *iue = cmd->iue; struct srp_login_rsp *rsp = &vio_iu(iue)->srp.login_rsp; @@ -2157,6 +2183,7 @@ static long ibmvscsis_login_rsp(struct scsi_info *vscsi, */ static long ibmvscsis_srp_login_rej(struct scsi_info *vscsi, struct ibmvscsis_cmd *cmd, u32 reason) + __must_hold(&vscsi->intr_lock) { struct iu_entry *iue = cmd->iue; struct srp_login_rej *rej = &vio_iu(iue)->srp.login_rej; @@ -2272,6 +2299,7 @@ static int ibmvscsis_drop_nexus(struct ibmvscsis_tport *tport) static long ibmvscsis_srp_login(struct scsi_info *vscsi, struct ibmvscsis_cmd *cmd, struct viosrp_crq *crq) + __must_hold(&vscsi->intr_lock) { struct iu_entry *iue = cmd->iue; struct srp_login_req *req = &vio_iu(iue)->srp.login_req; @@ -2346,6 +2374,7 @@ static long ibmvscsis_srp_login(struct scsi_info *vscsi, static long ibmvscsis_srp_i_logout(struct scsi_info *vscsi, struct ibmvscsis_cmd *cmd, struct viosrp_crq *crq) + __must_hold(&vscsi->intr_lock) { struct iu_entry *iue = cmd->iue; struct srp_i_logout *log_out = &vio_iu(iue)->srp.i_logout; @@ -2367,8 +2396,8 @@ static long ibmvscsis_srp_i_logout(struct scsi_info *vscsi, return ADAPT_SUCCESS; } -/* Called with intr lock held */ static void ibmvscsis_srp_cmd(struct scsi_info *vscsi, struct viosrp_crq *crq) + __must_hold(&vscsi->intr_lock) { struct ibmvscsis_cmd *cmd; struct iu_entry *iue; @@ -2469,6 +2498,7 @@ static void ibmvscsis_srp_cmd(struct scsi_info *vscsi, struct viosrp_crq *crq) * Interrupt, interrupt lock held */ static long ibmvscsis_ping_response(struct scsi_info *vscsi) + __must_hold(&vscsi->intr_lock) { struct viosrp_crq *crq; u64 buffer[2] = { 0, 0 }; @@ -2520,6 +2550,7 @@ static long ibmvscsis_ping_response(struct scsi_info *vscsi) */ static long ibmvscsis_parse_command(struct scsi_info *vscsi, struct viosrp_crq *crq) + __must_hold(&vscsi->intr_lock) { long rc = ADAPT_SUCCESS; @@ -2961,6 +2992,7 @@ static irqreturn_t ibmvscsis_interrupt(int dummy, void *data) * Must be called with interrupt lock held. */ static long ibmvscsis_enable_change_state(struct scsi_info *vscsi) + __must_hold(&vscsi->intr_lock) { int bytes; long rc = ADAPT_SUCCESS; @@ -3757,9 +3789,8 @@ static int ibmvscsis_queue_data_in(struct se_cmd *se_cmd) dev_err(&vscsi->dev, "srp_transfer_data failed: %d\n", rc); se_cmd->scsi_sense_length = 18; memset(se_cmd->sense_buffer, 0, se_cmd->scsi_sense_length); - /* Logical Unit Communication Time-out asc/ascq = 0x0801 */ - scsi_build_sense_buffer(0, se_cmd->sense_buffer, MEDIUM_ERROR, - 0x08, 0x01); + scsi_set_sense_buffer(0, se_cmd->sense_buffer, MEDIUM_ERROR, + LU_COMMUNICATION_TIMEOUT); } srp_build_response(vscsi, cmd, &len); diff --git a/drivers/scsi/imm.c b/drivers/scsi/imm.c index 0535252e77e3..680399bc866d 100644 --- a/drivers/scsi/imm.c +++ b/drivers/scsi/imm.c @@ -781,10 +781,10 @@ static void imm_interrupt(struct work_struct *work) imm_pb_dismiss(dev); - spin_lock_irqsave(host->host_lock, flags); + spin_lock_irqsave(&host->host_lock, flags); dev->cur_cmd = NULL; scsi_done(cmd); - spin_unlock_irqrestore(host->host_lock, flags); + spin_unlock_irqrestore(&host->host_lock, flags); return; } diff --git a/drivers/scsi/initio.c b/drivers/scsi/initio.c index 06fbe85dccfa..da2670cd7edf 100644 --- a/drivers/scsi/initio.c +++ b/drivers/scsi/initio.c @@ -2507,9 +2507,9 @@ static irqreturn_t i91u_intr(int irqno, void *dev_id) unsigned long flags; int r; - spin_lock_irqsave(dev->host_lock, flags); + spin_lock_irqsave(&dev->host_lock, flags); r = initio_isr((struct initio_host *)dev->hostdata); - spin_unlock_irqrestore(dev->host_lock, flags); + spin_unlock_irqrestore(&dev->host_lock, flags); if (r) return IRQ_HANDLED; else @@ -2635,9 +2635,9 @@ static int i91u_bus_reset(struct scsi_cmnd * cmnd) host = (struct initio_host *) cmnd->device->host->hostdata; - spin_lock_irq(cmnd->device->host->host_lock); + spin_lock_irq(&cmnd->device->host->host_lock); initio_reset_scsi(host, 0); - spin_unlock_irq(cmnd->device->host->host_lock); + spin_unlock_irq(&cmnd->device->host->host_lock); return SUCCESS; } diff --git a/drivers/scsi/ipr.c b/drivers/scsi/ipr.c index d207e5e81afe..665fc54fcbb3 100644 --- a/drivers/scsi/ipr.c +++ b/drivers/scsi/ipr.c @@ -612,9 +612,9 @@ static void ipr_lock_and_done(struct ipr_cmnd *ipr_cmd) unsigned long lock_flags; struct ipr_ioa_cfg *ioa_cfg = ipr_cmd->ioa_cfg; - spin_lock_irqsave(ioa_cfg->host->host_lock, lock_flags); + spin_lock_irqsave(&ioa_cfg->host->host_lock, lock_flags); ipr_cmd->done(ipr_cmd); - spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags); + spin_unlock_irqrestore(&ioa_cfg->host->host_lock, lock_flags); } /** @@ -1006,6 +1006,7 @@ static void ipr_init_ioadl(struct ipr_cmnd *ipr_cmd, dma_addr_t dma_addr, /** * ipr_send_blocking_cmd - Send command and sleep on its completion. + * @host: SCSI host * @ipr_cmd: ipr command struct * @timeout_func: function to invoke if command times out * @timeout: timeout @@ -1013,18 +1014,17 @@ static void ipr_init_ioadl(struct ipr_cmnd *ipr_cmd, dma_addr_t dma_addr, * Return value: * none **/ -static void ipr_send_blocking_cmd(struct ipr_cmnd *ipr_cmd, +static void ipr_send_blocking_cmd(struct Scsi_Host *host, struct ipr_cmnd *ipr_cmd, void (*timeout_func) (struct timer_list *), u32 timeout) + __must_hold(&host->host_lock) { - struct ipr_ioa_cfg *ioa_cfg = ipr_cmd->ioa_cfg; - init_completion(&ipr_cmd->completion); ipr_do_req(ipr_cmd, ipr_internal_cmd_done, timeout_func, timeout); - spin_unlock_irq(ioa_cfg->host->host_lock); + spin_unlock_irq(&host->host_lock); wait_for_completion(&ipr_cmd->completion); - spin_lock_irq(ioa_cfg->host->host_lock); + spin_lock_irq(&host->host_lock); } static int ipr_get_hrrq_index(struct ipr_ioa_cfg *ioa_cfg) @@ -2594,7 +2594,7 @@ static void ipr_timeout(struct timer_list *t) struct ipr_ioa_cfg *ioa_cfg = ipr_cmd->ioa_cfg; ENTER; - spin_lock_irqsave(ioa_cfg->host->host_lock, lock_flags); + spin_lock_irqsave(&ioa_cfg->host->host_lock, lock_flags); ioa_cfg->errors_logged++; dev_err(&ioa_cfg->pdev->dev, @@ -2606,7 +2606,7 @@ static void ipr_timeout(struct timer_list *t) if (!ioa_cfg->in_reset_reload || ioa_cfg->reset_cmd == ipr_cmd) ipr_initiate_ioa_reset(ioa_cfg, IPR_SHUTDOWN_NONE); - spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags); + spin_unlock_irqrestore(&ioa_cfg->host->host_lock, lock_flags); LEAVE; } @@ -2627,7 +2627,7 @@ static void ipr_oper_timeout(struct timer_list *t) struct ipr_ioa_cfg *ioa_cfg = ipr_cmd->ioa_cfg; ENTER; - spin_lock_irqsave(ioa_cfg->host->host_lock, lock_flags); + spin_lock_irqsave(&ioa_cfg->host->host_lock, lock_flags); ioa_cfg->errors_logged++; dev_err(&ioa_cfg->pdev->dev, @@ -2642,7 +2642,7 @@ static void ipr_oper_timeout(struct timer_list *t) ipr_initiate_ioa_reset(ioa_cfg, IPR_SHUTDOWN_NONE); } - spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags); + spin_unlock_irqrestore(&ioa_cfg->host->host_lock, lock_flags); LEAVE; } @@ -2893,7 +2893,7 @@ static int ipr_sdt_copy(struct ipr_ioa_cfg *ioa_cfg, (ioa_dump->hdr.len + bytes_copied) < max_dump_size) { if (ioa_dump->page_offset >= PAGE_SIZE || ioa_dump->page_offset == 0) { - page = (__be32 *)__get_free_page(GFP_ATOMIC); + page = kmalloc(PAGE_SIZE, GFP_NOIO); if (!page) { ipr_trace; @@ -2910,7 +2910,7 @@ static int ipr_sdt_copy(struct ipr_ioa_cfg *ioa_cfg, rem_page_len = PAGE_SIZE - ioa_dump->page_offset; cur_len = min(rem_len, rem_page_len); - spin_lock_irqsave(ioa_cfg->host->host_lock, lock_flags); + spin_lock_irqsave(&ioa_cfg->host->host_lock, lock_flags); if (ioa_cfg->sdt_state == ABORT_DUMP) { rc = -EIO; } else { @@ -2919,7 +2919,7 @@ static int ipr_sdt_copy(struct ipr_ioa_cfg *ioa_cfg, &page[ioa_dump->page_offset / 4], (cur_len / sizeof(u32))); } - spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags); + spin_unlock_irqrestore(&ioa_cfg->host->host_lock, lock_flags); if (!rc) { ioa_dump->page_offset += cur_len; @@ -3060,17 +3060,17 @@ static void ipr_get_ioa_dump(struct ipr_ioa_cfg *ioa_cfg, struct ipr_dump *dump) ENTER; - spin_lock_irqsave(ioa_cfg->host->host_lock, lock_flags); + spin_lock_irqsave(&ioa_cfg->host->host_lock, lock_flags); if (ioa_cfg->sdt_state != READ_DUMP) { - spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags); + spin_unlock_irqrestore(&ioa_cfg->host->host_lock, lock_flags); return; } if (ioa_cfg->sis64) { - spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags); + spin_unlock_irqrestore(&ioa_cfg->host->host_lock, lock_flags); ssleep(IPR_DUMP_DELAY_SECONDS); - spin_lock_irqsave(ioa_cfg->host->host_lock, lock_flags); + spin_lock_irqsave(&ioa_cfg->host->host_lock, lock_flags); } start_addr = readl(ioa_cfg->ioa_mailbox); @@ -3078,7 +3078,7 @@ static void ipr_get_ioa_dump(struct ipr_ioa_cfg *ioa_cfg, struct ipr_dump *dump) if (!ioa_cfg->sis64 && !ipr_sdt_is_fmt2(start_addr)) { dev_err(&ioa_cfg->pdev->dev, "Invalid dump table format: %lx\n", start_addr); - spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags); + spin_unlock_irqrestore(&ioa_cfg->host->host_lock, lock_flags); return; } @@ -3135,7 +3135,7 @@ static void ipr_get_ioa_dump(struct ipr_ioa_cfg *ioa_cfg, struct ipr_dump *dump) rc, be32_to_cpu(sdt->hdr.state)); driver_dump->hdr.status = IPR_DUMP_STATUS_FAILED; ioa_cfg->sdt_state = DUMP_OBTAINED; - spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags); + spin_unlock_irqrestore(&ioa_cfg->host->host_lock, lock_flags); return; } @@ -3151,7 +3151,7 @@ static void ipr_get_ioa_dump(struct ipr_ioa_cfg *ioa_cfg, struct ipr_dump *dump) else dump->driver_dump.hdr.len += max_num_entries * sizeof(struct ipr_sdt_entry); - spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags); + spin_unlock_irqrestore(&ioa_cfg->host->host_lock, lock_flags); for (i = 0; i < num_entries; i++) { if (ioa_dump->hdr.len > max_dump_size) { @@ -3220,13 +3220,13 @@ static void ipr_release_dump(struct kref *kref) int i; ENTER; - spin_lock_irqsave(ioa_cfg->host->host_lock, lock_flags); + spin_lock_irqsave(&ioa_cfg->host->host_lock, lock_flags); ioa_cfg->dump = NULL; ioa_cfg->sdt_state = INACTIVE; - spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags); + spin_unlock_irqrestore(&ioa_cfg->host->host_lock, lock_flags); for (i = 0; i < dump->ioa_dump.next_page_index; i++) - free_page((unsigned long) dump->ioa_dump.ioa_data[i]); + kfree(dump->ioa_dump.ioa_data[i]); vfree(dump->ioa_dump.ioa_data); kfree(dump); @@ -3244,13 +3244,13 @@ static void ipr_add_remove_thread(struct work_struct *work) int did_work; ENTER; - spin_lock_irqsave(ioa_cfg->host->host_lock, lock_flags); + spin_lock_irqsave(&ioa_cfg->host->host_lock, lock_flags); restart: do { did_work = 0; if (!ioa_cfg->hrrq[IPR_INIT_HRRQ].allow_cmds) { - spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags); + spin_unlock_irqrestore(&ioa_cfg->host->host_lock, lock_flags); return; } @@ -3263,10 +3263,10 @@ static void ipr_add_remove_thread(struct work_struct *work) list_move_tail(&res->queue, &ioa_cfg->free_res_q); else res->del_from_ml = 0; - spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags); + spin_unlock_irqrestore(&ioa_cfg->host->host_lock, lock_flags); scsi_remove_device(sdev); scsi_device_put(sdev); - spin_lock_irqsave(ioa_cfg->host->host_lock, lock_flags); + spin_lock_irqsave(&ioa_cfg->host->host_lock, lock_flags); } break; } @@ -3279,15 +3279,15 @@ static void ipr_add_remove_thread(struct work_struct *work) target = res->target; lun = res->lun; res->add_to_ml = 0; - spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags); + spin_unlock_irqrestore(&ioa_cfg->host->host_lock, lock_flags); scsi_add_device(ioa_cfg->host, bus, target, lun); - spin_lock_irqsave(ioa_cfg->host->host_lock, lock_flags); + spin_lock_irqsave(&ioa_cfg->host->host_lock, lock_flags); goto restart; } } ioa_cfg->scan_done = 1; - spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags); + spin_unlock_irqrestore(&ioa_cfg->host->host_lock, lock_flags); kobject_uevent(&ioa_cfg->host->shost_dev.kobj, KOBJ_CHANGE); LEAVE; } @@ -3311,44 +3311,44 @@ static void ipr_worker_thread(struct work_struct *work) container_of(work, struct ipr_ioa_cfg, work_q); ENTER; - spin_lock_irqsave(ioa_cfg->host->host_lock, lock_flags); + spin_lock_irqsave(&ioa_cfg->host->host_lock, lock_flags); if (ioa_cfg->sdt_state == READ_DUMP) { dump = ioa_cfg->dump; if (!dump) { - spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags); + spin_unlock_irqrestore(&ioa_cfg->host->host_lock, lock_flags); return; } kref_get(&dump->kref); - spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags); + spin_unlock_irqrestore(&ioa_cfg->host->host_lock, lock_flags); ipr_get_ioa_dump(ioa_cfg, dump); kref_put(&dump->kref, ipr_release_dump); - spin_lock_irqsave(ioa_cfg->host->host_lock, lock_flags); + spin_lock_irqsave(&ioa_cfg->host->host_lock, lock_flags); if (ioa_cfg->sdt_state == DUMP_OBTAINED && !ioa_cfg->dump_timeout) ipr_initiate_ioa_reset(ioa_cfg, IPR_SHUTDOWN_NONE); - spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags); + spin_unlock_irqrestore(&ioa_cfg->host->host_lock, lock_flags); return; } if (ioa_cfg->scsi_unblock) { ioa_cfg->scsi_unblock = 0; ioa_cfg->scsi_blocked = 0; - spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags); + spin_unlock_irqrestore(&ioa_cfg->host->host_lock, lock_flags); scsi_unblock_requests(ioa_cfg->host); - spin_lock_irqsave(ioa_cfg->host->host_lock, lock_flags); + spin_lock_irqsave(&ioa_cfg->host->host_lock, lock_flags); if (ioa_cfg->scsi_blocked) scsi_block_requests(ioa_cfg->host); } if (!ioa_cfg->scan_enabled) { - spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags); + spin_unlock_irqrestore(&ioa_cfg->host->host_lock, lock_flags); return; } schedule_work(&ioa_cfg->scsi_add_work_q); - spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags); + spin_unlock_irqrestore(&ioa_cfg->host->host_lock, lock_flags); LEAVE; } @@ -3375,10 +3375,10 @@ static ssize_t ipr_read_trace(struct file *filp, struct kobject *kobj, unsigned long lock_flags = 0; ssize_t ret; - spin_lock_irqsave(ioa_cfg->host->host_lock, lock_flags); + spin_lock_irqsave(&ioa_cfg->host->host_lock, lock_flags); ret = memory_read_from_buffer(buf, count, &off, ioa_cfg->trace, IPR_TRACE_SIZE); - spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags); + spin_unlock_irqrestore(&ioa_cfg->host->host_lock, lock_flags); return ret; } @@ -3411,12 +3411,12 @@ static ssize_t ipr_show_fw_version(struct device *dev, unsigned long lock_flags = 0; int len; - spin_lock_irqsave(ioa_cfg->host->host_lock, lock_flags); + spin_lock_irqsave(&ioa_cfg->host->host_lock, lock_flags); len = snprintf(buf, PAGE_SIZE, "%02X%02X%02X%02X\n", ucode_vpd->major_release, ucode_vpd->card_type, ucode_vpd->minor_release[0], ucode_vpd->minor_release[1]); - spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags); + spin_unlock_irqrestore(&ioa_cfg->host->host_lock, lock_flags); return len; } @@ -3445,9 +3445,9 @@ static ssize_t ipr_show_log_level(struct device *dev, unsigned long lock_flags = 0; int len; - spin_lock_irqsave(ioa_cfg->host->host_lock, lock_flags); + spin_lock_irqsave(&ioa_cfg->host->host_lock, lock_flags); len = snprintf(buf, PAGE_SIZE, "%d\n", ioa_cfg->log_level); - spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags); + spin_unlock_irqrestore(&ioa_cfg->host->host_lock, lock_flags); return len; } @@ -3469,9 +3469,9 @@ static ssize_t ipr_store_log_level(struct device *dev, struct ipr_ioa_cfg *ioa_cfg = (struct ipr_ioa_cfg *)shost->hostdata; unsigned long lock_flags = 0; - spin_lock_irqsave(ioa_cfg->host->host_lock, lock_flags); + spin_lock_irqsave(&ioa_cfg->host->host_lock, lock_flags); ioa_cfg->log_level = simple_strtoul(buf, NULL, 10); - spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags); + spin_unlock_irqrestore(&ioa_cfg->host->host_lock, lock_flags); return strlen(buf); } @@ -3509,31 +3509,31 @@ static ssize_t ipr_store_diagnostics(struct device *dev, if (!capable(CAP_SYS_ADMIN)) return -EACCES; - spin_lock_irqsave(ioa_cfg->host->host_lock, lock_flags); + spin_lock_irqsave(&ioa_cfg->host->host_lock, lock_flags); while (ioa_cfg->in_reset_reload) { - spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags); + spin_unlock_irqrestore(&ioa_cfg->host->host_lock, lock_flags); wait_event(ioa_cfg->reset_wait_q, !ioa_cfg->in_reset_reload); - spin_lock_irqsave(ioa_cfg->host->host_lock, lock_flags); + spin_lock_irqsave(&ioa_cfg->host->host_lock, lock_flags); } ioa_cfg->errors_logged = 0; ipr_initiate_ioa_reset(ioa_cfg, IPR_SHUTDOWN_NORMAL); if (ioa_cfg->in_reset_reload) { - spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags); + spin_unlock_irqrestore(&ioa_cfg->host->host_lock, lock_flags); wait_event(ioa_cfg->reset_wait_q, !ioa_cfg->in_reset_reload); /* Wait for a second for any errors to be logged */ msleep(1000); } else { - spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags); + spin_unlock_irqrestore(&ioa_cfg->host->host_lock, lock_flags); return -EIO; } - spin_lock_irqsave(ioa_cfg->host->host_lock, lock_flags); + spin_lock_irqsave(&ioa_cfg->host->host_lock, lock_flags); if (ioa_cfg->in_reset_reload || ioa_cfg->errors_logged) rc = -EIO; - spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags); + spin_unlock_irqrestore(&ioa_cfg->host->host_lock, lock_flags); return rc; } @@ -3563,12 +3563,12 @@ static ssize_t ipr_show_adapter_state(struct device *dev, unsigned long lock_flags = 0; int len; - spin_lock_irqsave(ioa_cfg->host->host_lock, lock_flags); + spin_lock_irqsave(&ioa_cfg->host->host_lock, lock_flags); if (ioa_cfg->hrrq[IPR_INIT_HRRQ].ioa_is_dead) len = snprintf(buf, PAGE_SIZE, "offline\n"); else len = snprintf(buf, PAGE_SIZE, "online\n"); - spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags); + spin_unlock_irqrestore(&ioa_cfg->host->host_lock, lock_flags); return len; } @@ -3596,7 +3596,7 @@ static ssize_t ipr_store_adapter_state(struct device *dev, if (!capable(CAP_SYS_ADMIN)) return -EACCES; - spin_lock_irqsave(ioa_cfg->host->host_lock, lock_flags); + spin_lock_irqsave(&ioa_cfg->host->host_lock, lock_flags); if (ioa_cfg->hrrq[IPR_INIT_HRRQ].ioa_is_dead && !strncmp(buf, "online", 6)) { for (i = 0; i < ioa_cfg->hrrq_num; i++) { @@ -3609,7 +3609,7 @@ static ssize_t ipr_store_adapter_state(struct device *dev, ioa_cfg->in_ioa_bringdown = 0; ipr_initiate_ioa_reset(ioa_cfg, IPR_SHUTDOWN_NONE); } - spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags); + spin_unlock_irqrestore(&ioa_cfg->host->host_lock, lock_flags); wait_event(ioa_cfg->reset_wait_q, !ioa_cfg->in_reset_reload); return result; @@ -3648,10 +3648,10 @@ static ssize_t ipr_store_reset_adapter(struct device *dev, if (!capable(CAP_SYS_ADMIN)) return -EACCES; - spin_lock_irqsave(ioa_cfg->host->host_lock, lock_flags); + spin_lock_irqsave(&ioa_cfg->host->host_lock, lock_flags); if (!ioa_cfg->in_reset_reload) ipr_initiate_ioa_reset(ioa_cfg, IPR_SHUTDOWN_NORMAL); - spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags); + spin_unlock_irqrestore(&ioa_cfg->host->host_lock, lock_flags); wait_event(ioa_cfg->reset_wait_q, !ioa_cfg->in_reset_reload); return result; @@ -3683,9 +3683,9 @@ static ssize_t ipr_show_iopoll_weight(struct device *dev, unsigned long lock_flags = 0; int len; - spin_lock_irqsave(shost->host_lock, lock_flags); + spin_lock_irqsave(&shost->host_lock, lock_flags); len = snprintf(buf, PAGE_SIZE, "%d\n", ioa_cfg->iopoll_weight); - spin_unlock_irqrestore(shost->host_lock, lock_flags); + spin_unlock_irqrestore(&shost->host_lock, lock_flags); return len; } @@ -3732,7 +3732,7 @@ static ssize_t ipr_store_iopoll_weight(struct device *dev, irq_poll_disable(&ioa_cfg->hrrq[i].iopoll); } - spin_lock_irqsave(shost->host_lock, lock_flags); + spin_lock_irqsave(&shost->host_lock, lock_flags); ioa_cfg->iopoll_weight = user_iopoll_weight; if (ioa_cfg->iopoll_weight && ioa_cfg->sis64 && ioa_cfg->nvectors > 1) { for (i = 1; i < ioa_cfg->hrrq_num; i++) { @@ -3740,7 +3740,7 @@ static ssize_t ipr_store_iopoll_weight(struct device *dev, ioa_cfg->iopoll_weight, ipr_iopoll); } } - spin_unlock_irqrestore(shost->host_lock, lock_flags); + spin_unlock_irqrestore(&shost->host_lock, lock_flags); return strlen(buf); } @@ -3939,15 +3939,15 @@ static int ipr_update_ioa_ucode(struct ipr_ioa_cfg *ioa_cfg, { unsigned long lock_flags; - spin_lock_irqsave(ioa_cfg->host->host_lock, lock_flags); + spin_lock_irqsave(&ioa_cfg->host->host_lock, lock_flags); while (ioa_cfg->in_reset_reload) { - spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags); + spin_unlock_irqrestore(&ioa_cfg->host->host_lock, lock_flags); wait_event(ioa_cfg->reset_wait_q, !ioa_cfg->in_reset_reload); - spin_lock_irqsave(ioa_cfg->host->host_lock, lock_flags); + spin_lock_irqsave(&ioa_cfg->host->host_lock, lock_flags); } if (ioa_cfg->ucode_sglist) { - spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags); + spin_unlock_irqrestore(&ioa_cfg->host->host_lock, lock_flags); dev_err(&ioa_cfg->pdev->dev, "Microcode download already in progress\n"); return -EIO; @@ -3958,7 +3958,7 @@ static int ipr_update_ioa_ucode(struct ipr_ioa_cfg *ioa_cfg, DMA_TO_DEVICE); if (!sglist->num_dma_sg) { - spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags); + spin_unlock_irqrestore(&ioa_cfg->host->host_lock, lock_flags); dev_err(&ioa_cfg->pdev->dev, "Failed to map microcode download buffer!\n"); return -EIO; @@ -3966,12 +3966,12 @@ static int ipr_update_ioa_ucode(struct ipr_ioa_cfg *ioa_cfg, ioa_cfg->ucode_sglist = sglist; ipr_initiate_ioa_reset(ioa_cfg, IPR_SHUTDOWN_NORMAL); - spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags); + spin_unlock_irqrestore(&ioa_cfg->host->host_lock, lock_flags); wait_event(ioa_cfg->reset_wait_q, !ioa_cfg->in_reset_reload); - spin_lock_irqsave(ioa_cfg->host->host_lock, lock_flags); + spin_lock_irqsave(&ioa_cfg->host->host_lock, lock_flags); ioa_cfg->ucode_sglist = NULL; - spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags); + spin_unlock_irqrestore(&ioa_cfg->host->host_lock, lock_flags); return 0; } @@ -4072,9 +4072,9 @@ static ssize_t ipr_show_fw_type(struct device *dev, unsigned long lock_flags = 0; int len; - spin_lock_irqsave(ioa_cfg->host->host_lock, lock_flags); + spin_lock_irqsave(&ioa_cfg->host->host_lock, lock_flags); len = snprintf(buf, PAGE_SIZE, "%d\n", ioa_cfg->sis64); - spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags); + spin_unlock_irqrestore(&ioa_cfg->host->host_lock, lock_flags); return len; } @@ -4097,16 +4097,16 @@ static ssize_t ipr_read_async_err_log(struct file *filep, struct kobject *kobj, unsigned long lock_flags = 0; int ret; - spin_lock_irqsave(ioa_cfg->host->host_lock, lock_flags); + spin_lock_irqsave(&ioa_cfg->host->host_lock, lock_flags); hostrcb = list_first_entry_or_null(&ioa_cfg->hostrcb_report_q, struct ipr_hostrcb, queue); if (!hostrcb) { - spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags); + spin_unlock_irqrestore(&ioa_cfg->host->host_lock, lock_flags); return 0; } ret = memory_read_from_buffer(buf, count, &off, &hostrcb->hcam, sizeof(hostrcb->hcam)); - spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags); + spin_unlock_irqrestore(&ioa_cfg->host->host_lock, lock_flags); return ret; } @@ -4120,17 +4120,17 @@ static ssize_t ipr_next_async_err_log(struct file *filep, struct kobject *kobj, struct ipr_hostrcb *hostrcb; unsigned long lock_flags = 0; - spin_lock_irqsave(ioa_cfg->host->host_lock, lock_flags); + spin_lock_irqsave(&ioa_cfg->host->host_lock, lock_flags); hostrcb = list_first_entry_or_null(&ioa_cfg->hostrcb_report_q, struct ipr_hostrcb, queue); if (!hostrcb) { - spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags); + spin_unlock_irqrestore(&ioa_cfg->host->host_lock, lock_flags); return count; } /* Reclaim hostrcb before exit */ list_move_tail(&hostrcb->queue, &ioa_cfg->hostrcb_free_q); - spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags); + spin_unlock_irqrestore(&ioa_cfg->host->host_lock, lock_flags); return count; } @@ -4187,15 +4187,15 @@ static ssize_t ipr_read_dump(struct file *filp, struct kobject *kobj, if (!capable(CAP_SYS_ADMIN)) return -EACCES; - spin_lock_irqsave(ioa_cfg->host->host_lock, lock_flags); + spin_lock_irqsave(&ioa_cfg->host->host_lock, lock_flags); dump = ioa_cfg->dump; if (ioa_cfg->sdt_state != DUMP_OBTAINED || !dump) { - spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags); + spin_unlock_irqrestore(&ioa_cfg->host->host_lock, lock_flags); return 0; } kref_get(&dump->kref); - spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags); + spin_unlock_irqrestore(&ioa_cfg->host->host_lock, lock_flags); if (off > dump->driver_dump.hdr.len) { kref_put(&dump->kref, ipr_release_dump); @@ -4298,10 +4298,10 @@ static int ipr_alloc_dump(struct ipr_ioa_cfg *ioa_cfg) kref_init(&dump->kref); dump->ioa_cfg = ioa_cfg; - spin_lock_irqsave(ioa_cfg->host->host_lock, lock_flags); + spin_lock_irqsave(&ioa_cfg->host->host_lock, lock_flags); if (INACTIVE != ioa_cfg->sdt_state) { - spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags); + spin_unlock_irqrestore(&ioa_cfg->host->host_lock, lock_flags); vfree(dump->ioa_dump.ioa_data); kfree(dump); return 0; @@ -4313,7 +4313,7 @@ static int ipr_alloc_dump(struct ipr_ioa_cfg *ioa_cfg) ioa_cfg->dump_taken = 1; schedule_work(&ioa_cfg->work_q); } - spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags); + spin_unlock_irqrestore(&ioa_cfg->host->host_lock, lock_flags); return 0; } @@ -4332,15 +4332,15 @@ static int ipr_free_dump(struct ipr_ioa_cfg *ioa_cfg) ENTER; - spin_lock_irqsave(ioa_cfg->host->host_lock, lock_flags); + spin_lock_irqsave(&ioa_cfg->host->host_lock, lock_flags); dump = ioa_cfg->dump; if (!dump) { - spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags); + spin_unlock_irqrestore(&ioa_cfg->host->host_lock, lock_flags); return 0; } ioa_cfg->dump = NULL; - spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags); + spin_unlock_irqrestore(&ioa_cfg->host->host_lock, lock_flags); kref_put(&dump->kref, ipr_release_dump); @@ -4429,11 +4429,11 @@ static ssize_t ipr_show_adapter_handle(struct device *dev, struct device_attribu unsigned long lock_flags = 0; ssize_t len = -ENXIO; - spin_lock_irqsave(ioa_cfg->host->host_lock, lock_flags); + spin_lock_irqsave(&ioa_cfg->host->host_lock, lock_flags); res = (struct ipr_resource_entry *)sdev->hostdata; if (res) len = snprintf(buf, PAGE_SIZE, "%08X\n", res->res_handle); - spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags); + spin_unlock_irqrestore(&ioa_cfg->host->host_lock, lock_flags); return len; } @@ -4464,7 +4464,7 @@ static ssize_t ipr_show_resource_path(struct device *dev, struct device_attribut ssize_t len = -ENXIO; char buffer[IPR_MAX_RES_PATH_LENGTH]; - spin_lock_irqsave(ioa_cfg->host->host_lock, lock_flags); + spin_lock_irqsave(&ioa_cfg->host->host_lock, lock_flags); res = (struct ipr_resource_entry *)sdev->hostdata; if (res && ioa_cfg->sis64) len = snprintf(buf, PAGE_SIZE, "%s\n", @@ -4474,7 +4474,7 @@ static ssize_t ipr_show_resource_path(struct device *dev, struct device_attribut len = snprintf(buf, PAGE_SIZE, "%d:%d:%d:%d\n", ioa_cfg->host->host_no, res->bus, res->target, res->lun); - spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags); + spin_unlock_irqrestore(&ioa_cfg->host->host_lock, lock_flags); return len; } @@ -4503,14 +4503,14 @@ static ssize_t ipr_show_device_id(struct device *dev, struct device_attribute *a unsigned long lock_flags = 0; ssize_t len = -ENXIO; - spin_lock_irqsave(ioa_cfg->host->host_lock, lock_flags); + spin_lock_irqsave(&ioa_cfg->host->host_lock, lock_flags); res = (struct ipr_resource_entry *)sdev->hostdata; if (res && ioa_cfg->sis64) len = snprintf(buf, PAGE_SIZE, "0x%llx\n", be64_to_cpu(res->dev_id)); else if (res) len = snprintf(buf, PAGE_SIZE, "0x%llx\n", res->lun_wwn); - spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags); + spin_unlock_irqrestore(&ioa_cfg->host->host_lock, lock_flags); return len; } @@ -4539,13 +4539,13 @@ static ssize_t ipr_show_resource_type(struct device *dev, struct device_attribut unsigned long lock_flags = 0; ssize_t len = -ENXIO; - spin_lock_irqsave(ioa_cfg->host->host_lock, lock_flags); + spin_lock_irqsave(&ioa_cfg->host->host_lock, lock_flags); res = (struct ipr_resource_entry *)sdev->hostdata; if (res) len = snprintf(buf, PAGE_SIZE, "%x\n", res->type); - spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags); + spin_unlock_irqrestore(&ioa_cfg->host->host_lock, lock_flags); return len; } @@ -4575,13 +4575,13 @@ static ssize_t ipr_show_raw_mode(struct device *dev, unsigned long lock_flags = 0; ssize_t len; - spin_lock_irqsave(ioa_cfg->host->host_lock, lock_flags); + spin_lock_irqsave(&ioa_cfg->host->host_lock, lock_flags); res = (struct ipr_resource_entry *)sdev->hostdata; if (res) len = snprintf(buf, PAGE_SIZE, "%d\n", res->raw_mode); else len = -ENXIO; - spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags); + spin_unlock_irqrestore(&ioa_cfg->host->host_lock, lock_flags); return len; } @@ -4605,7 +4605,7 @@ static ssize_t ipr_store_raw_mode(struct device *dev, unsigned long lock_flags = 0; ssize_t len; - spin_lock_irqsave(ioa_cfg->host->host_lock, lock_flags); + spin_lock_irqsave(&ioa_cfg->host->host_lock, lock_flags); res = (struct ipr_resource_entry *)sdev->hostdata; if (res) { if (ipr_is_af_dasd_device(res)) { @@ -4618,7 +4618,7 @@ static ssize_t ipr_store_raw_mode(struct device *dev, len = -EINVAL; } else len = -ENXIO; - spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags); + spin_unlock_irqrestore(&ioa_cfg->host->host_lock, lock_flags); return len; } @@ -4759,13 +4759,13 @@ static void ipr_sdev_destroy(struct scsi_device *sdev) ioa_cfg = (struct ipr_ioa_cfg *) sdev->host->hostdata; - spin_lock_irqsave(ioa_cfg->host->host_lock, lock_flags); + spin_lock_irqsave(&ioa_cfg->host->host_lock, lock_flags); res = (struct ipr_resource_entry *) sdev->hostdata; if (res) { sdev->hostdata = NULL; res->sdev = NULL; } - spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags); + spin_unlock_irqrestore(&ioa_cfg->host->host_lock, lock_flags); } /** @@ -4786,7 +4786,7 @@ static int ipr_sdev_configure(struct scsi_device *sdev, unsigned long lock_flags = 0; char buffer[IPR_MAX_RES_PATH_LENGTH]; - spin_lock_irqsave(ioa_cfg->host->host_lock, lock_flags); + spin_lock_irqsave(&ioa_cfg->host->host_lock, lock_flags); res = sdev->hostdata; if (res) { if (ipr_is_af_dasd_device(res)) @@ -4802,7 +4802,7 @@ static int ipr_sdev_configure(struct scsi_device *sdev, IPR_VSET_RW_TIMEOUT); lim->max_hw_sectors = IPR_VSET_MAX_SECTORS; } - spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags); + spin_unlock_irqrestore(&ioa_cfg->host->host_lock, lock_flags); if (ioa_cfg->sis64) sdev_printk(KERN_INFO, sdev, "Resource path: %s\n", @@ -4810,7 +4810,7 @@ static int ipr_sdev_configure(struct scsi_device *sdev, res->res_path, buffer, sizeof(buffer))); return 0; } - spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags); + spin_unlock_irqrestore(&ioa_cfg->host->host_lock, lock_flags); return 0; } @@ -4835,7 +4835,7 @@ static int ipr_sdev_init(struct scsi_device *sdev) sdev->hostdata = NULL; - spin_lock_irqsave(ioa_cfg->host->host_lock, lock_flags); + spin_lock_irqsave(&ioa_cfg->host->host_lock, lock_flags); res = ipr_find_sdev(sdev); if (res) { @@ -4849,12 +4849,12 @@ static int ipr_sdev_init(struct scsi_device *sdev) if (ipr_is_gata(res)) { sdev_printk(KERN_ERR, sdev, "SATA devices are no longer " "supported by this driver. Skipping device.\n"); - spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags); + spin_unlock_irqrestore(&ioa_cfg->host->host_lock, lock_flags); return -ENXIO; } } - spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags); + spin_unlock_irqrestore(&ioa_cfg->host->host_lock, lock_flags); return rc; } @@ -4970,7 +4970,7 @@ static int ipr_eh_host_reset(struct scsi_cmnd *cmd) ENTER; ioa_cfg = (struct ipr_ioa_cfg *) cmd->device->host->hostdata; - spin_lock_irqsave(ioa_cfg->host->host_lock, lock_flags); + spin_lock_irqsave(&ioa_cfg->host->host_lock, lock_flags); if (!ioa_cfg->in_reset_reload && !ioa_cfg->hrrq[IPR_INIT_HRRQ].ioa_is_dead) { ipr_initiate_ioa_reset(ioa_cfg, IPR_SHUTDOWN_ABBREV); @@ -4981,9 +4981,9 @@ static int ipr_eh_host_reset(struct scsi_cmnd *cmd) ioa_cfg->sdt_state = GET_DUMP; } - spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags); + spin_unlock_irqrestore(&ioa_cfg->host->host_lock, lock_flags); wait_event(ioa_cfg->reset_wait_q, !ioa_cfg->in_reset_reload); - spin_lock_irqsave(ioa_cfg->host->host_lock, lock_flags); + spin_lock_irqsave(&ioa_cfg->host->host_lock, lock_flags); /* If we got hit with a host reset while we were already resetting the adapter for some reason, and the reset failed. */ @@ -4992,7 +4992,7 @@ static int ipr_eh_host_reset(struct scsi_cmnd *cmd) rc = FAILED; } - spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags); + spin_unlock_irqrestore(&ioa_cfg->host->host_lock, lock_flags); LEAVE; return rc; } @@ -5011,7 +5011,9 @@ static int ipr_eh_host_reset(struct scsi_cmnd *cmd) * 0 on success / non-zero on failure **/ static int ipr_device_reset(struct ipr_ioa_cfg *ioa_cfg, + struct Scsi_Host *host, struct ipr_resource_entry *res) + __must_hold(&host->host_lock) { struct ipr_cmnd *ipr_cmd; struct ipr_ioarcb *ioarcb; @@ -5030,7 +5032,8 @@ static int ipr_device_reset(struct ipr_ioa_cfg *ioa_cfg, cmd_pkt->request_type = IPR_RQTYPE_IOACMD; cmd_pkt->cdb[0] = IPR_RESET_DEVICE; - ipr_send_blocking_cmd(ipr_cmd, ipr_timeout, IPR_DEVICE_RESET_TIMEOUT); + ipr_send_blocking_cmd(host, ipr_cmd, ipr_timeout, + IPR_DEVICE_RESET_TIMEOUT); ioasc = be32_to_cpu(ipr_cmd->s.ioasa.hdr.ioasc); list_add_tail(&ipr_cmd->queue, &ipr_cmd->hrrq->hrrq_free_q); @@ -5049,14 +5052,15 @@ static int ipr_device_reset(struct ipr_ioa_cfg *ioa_cfg, * Return value: * SUCCESS / FAILED **/ -static int __ipr_eh_dev_reset(struct scsi_cmnd *scsi_cmd) +static int __ipr_eh_dev_reset(struct Scsi_Host *host, struct scsi_cmnd *scsi_cmd) + __must_hold(&host->host_lock) { struct ipr_ioa_cfg *ioa_cfg; struct ipr_resource_entry *res; int rc = 0; ENTER; - ioa_cfg = (struct ipr_ioa_cfg *) scsi_cmd->device->host->hostdata; + ioa_cfg = (struct ipr_ioa_cfg *) host->hostdata; res = scsi_cmd->device->hostdata; /* @@ -5072,7 +5076,7 @@ static int __ipr_eh_dev_reset(struct scsi_cmnd *scsi_cmd) res->resetting_device = 1; scmd_printk(KERN_ERR, scsi_cmd, "Resetting device\n"); - rc = ipr_device_reset(ioa_cfg, res); + rc = ipr_device_reset(ioa_cfg, host, res); res->resetting_device = 0; res->reset_occurred = 1; @@ -5085,16 +5089,17 @@ static int ipr_eh_dev_reset(struct scsi_cmnd *cmd) int rc; struct ipr_ioa_cfg *ioa_cfg; struct ipr_resource_entry *res; + struct Scsi_Host *host = cmd->device->host; - ioa_cfg = (struct ipr_ioa_cfg *) cmd->device->host->hostdata; + ioa_cfg = (struct ipr_ioa_cfg *) host->hostdata; res = cmd->device->hostdata; if (!res) return FAILED; - spin_lock_irq(cmd->device->host->host_lock); - rc = __ipr_eh_dev_reset(cmd); - spin_unlock_irq(cmd->device->host->host_lock); + spin_lock_irq(&host->host_lock); + rc = __ipr_eh_dev_reset(host, cmd); + spin_unlock_irq(&host->host_lock); if (rc == SUCCESS) rc = ipr_wait_for_ops(ioa_cfg, cmd->device, ipr_match_lun); @@ -5158,9 +5163,9 @@ static void ipr_abort_timeout(struct timer_list *t) unsigned long lock_flags = 0; ENTER; - spin_lock_irqsave(ioa_cfg->host->host_lock, lock_flags); + spin_lock_irqsave(&ioa_cfg->host->host_lock, lock_flags); if (ipr_cmd->completion.done || ioa_cfg->in_reset_reload) { - spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags); + spin_unlock_irqrestore(&ioa_cfg->host->host_lock, lock_flags); return; } @@ -5175,7 +5180,7 @@ static void ipr_abort_timeout(struct timer_list *t) cmd_pkt->cdb[2] = IPR_RESET_TYPE_SELECT | IPR_BUS_RESET; ipr_do_req(reset_cmd, ipr_bus_reset_done, ipr_timeout, IPR_DEVICE_RESET_TIMEOUT); - spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags); + spin_unlock_irqrestore(&ioa_cfg->host->host_lock, lock_flags); LEAVE; } @@ -5189,7 +5194,9 @@ static void ipr_abort_timeout(struct timer_list *t) * SUCCESS / FAILED **/ static int ipr_cancel_op(struct scsi_cmnd *scsi_cmd) + __must_hold(&scsi_cmd->device->host->host_lock) { + struct Scsi_Host *host = scsi_cmd->device->host; struct ipr_cmnd *ipr_cmd; struct ipr_ioa_cfg *ioa_cfg; struct ipr_resource_entry *res; @@ -5199,7 +5206,7 @@ static int ipr_cancel_op(struct scsi_cmnd *scsi_cmd) struct ipr_hrr_queue *hrrq; ENTER; - ioa_cfg = (struct ipr_ioa_cfg *)scsi_cmd->device->host->hostdata; + ioa_cfg = (struct ipr_ioa_cfg *)host->hostdata; res = scsi_cmd->device->hostdata; /* If we are currently going through reset/reload, return failed. @@ -5247,7 +5254,8 @@ static int ipr_cancel_op(struct scsi_cmnd *scsi_cmd) scmd_printk(KERN_ERR, scsi_cmd, "Aborting command: %02X\n", scsi_cmd->cmnd[0]); - ipr_send_blocking_cmd(ipr_cmd, ipr_abort_timeout, IPR_CANCEL_ALL_TIMEOUT); + ipr_send_blocking_cmd(host, ipr_cmd, ipr_abort_timeout, + IPR_CANCEL_ALL_TIMEOUT); ioasc = be32_to_cpu(ipr_cmd->s.ioasa.hdr.ioasc); /* @@ -5281,12 +5289,12 @@ static int ipr_scan_finished(struct Scsi_Host *shost, unsigned long elapsed_time struct ipr_ioa_cfg *ioa_cfg = (struct ipr_ioa_cfg *) shost->hostdata; int rc = 0; - spin_lock_irqsave(shost->host_lock, lock_flags); + spin_lock_irqsave(&shost->host_lock, lock_flags); if (ioa_cfg->hrrq[IPR_INIT_HRRQ].ioa_is_dead || ioa_cfg->scan_done) rc = 1; if ((elapsed_time/HZ) > (ioa_cfg->transop_timeout * 2)) rc = 1; - spin_unlock_irqrestore(shost->host_lock, lock_flags); + spin_unlock_irqrestore(&shost->host_lock, lock_flags); return rc; } @@ -5299,17 +5307,17 @@ static int ipr_scan_finished(struct Scsi_Host *shost, unsigned long elapsed_time **/ static int ipr_eh_abort(struct scsi_cmnd *scsi_cmd) { + struct Scsi_Host *host = scsi_cmd->device->host; + struct ipr_ioa_cfg *ioa_cfg = (void *)host->hostdata; unsigned long flags; int rc; - struct ipr_ioa_cfg *ioa_cfg; ENTER; - ioa_cfg = (struct ipr_ioa_cfg *) scsi_cmd->device->host->hostdata; - spin_lock_irqsave(scsi_cmd->device->host->host_lock, flags); + spin_lock_irqsave(&host->host_lock, flags); rc = ipr_cancel_op(scsi_cmd); - spin_unlock_irqrestore(scsi_cmd->device->host->host_lock, flags); + spin_unlock_irqrestore(&host->host_lock, flags); if (rc == SUCCESS) rc = ipr_wait_for_ops(ioa_cfg, scsi_cmd->device, ipr_match_lun); @@ -6222,11 +6230,11 @@ static void ipr_scsi_done(struct ipr_cmnd *ipr_cmd) list_add_tail(&ipr_cmd->queue, &ipr_cmd->hrrq->hrrq_free_q); spin_unlock_irqrestore(ipr_cmd->hrrq->lock, lock_flags); } else { - spin_lock_irqsave(ioa_cfg->host->host_lock, lock_flags); + spin_lock_irqsave(&ioa_cfg->host->host_lock, lock_flags); spin_lock(&ipr_cmd->hrrq->_lock); ipr_erp_start(ioa_cfg, ipr_cmd); spin_unlock(&ipr_cmd->hrrq->_lock); - spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags); + spin_unlock_irqrestore(&ioa_cfg->host->host_lock, lock_flags); } } @@ -6383,9 +6391,9 @@ static const char *ipr_ioa_info(struct Scsi_Host *host) ioa_cfg = (struct ipr_ioa_cfg *) host->hostdata; - spin_lock_irqsave(host->host_lock, lock_flags); + spin_lock_irqsave(&host->host_lock, lock_flags); sprintf(buffer, "IBM %X Storage Adapter", ioa_cfg->type); - spin_unlock_irqrestore(host->host_lock, lock_flags); + spin_unlock_irqrestore(&host->host_lock, lock_flags); return buffer; } @@ -7480,14 +7488,14 @@ static void ipr_reset_timer_done(struct timer_list *t) struct ipr_ioa_cfg *ioa_cfg = ipr_cmd->ioa_cfg; unsigned long lock_flags = 0; - spin_lock_irqsave(ioa_cfg->host->host_lock, lock_flags); + spin_lock_irqsave(&ioa_cfg->host->host_lock, lock_flags); if (ioa_cfg->reset_cmd == ipr_cmd) { list_del(&ipr_cmd->queue); ipr_cmd->done(ipr_cmd); } - spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags); + spin_unlock_irqrestore(&ioa_cfg->host->host_lock, lock_flags); } /** @@ -8023,10 +8031,10 @@ static void ipr_reset_reset_work(struct work_struct *work) msleep(jiffies_to_msecs(IPR_PCI_RESET_TIMEOUT)); pci_set_pcie_reset_state(pdev, pcie_deassert_reset); - spin_lock_irqsave(ioa_cfg->host->host_lock, lock_flags); + spin_lock_irqsave(&ioa_cfg->host->host_lock, lock_flags); if (ioa_cfg->reset_cmd == ipr_cmd) ipr_reset_ioa_job(ipr_cmd); - spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags); + spin_unlock_irqrestore(&ioa_cfg->host->host_lock, lock_flags); LEAVE; } @@ -8588,10 +8596,10 @@ static pci_ers_result_t ipr_pci_mmio_enabled(struct pci_dev *pdev) unsigned long flags = 0; struct ipr_ioa_cfg *ioa_cfg = pci_get_drvdata(pdev); - spin_lock_irqsave(ioa_cfg->host->host_lock, flags); + spin_lock_irqsave(&ioa_cfg->host->host_lock, flags); if (!ioa_cfg->probe_done) pci_save_state(pdev); - spin_unlock_irqrestore(ioa_cfg->host->host_lock, flags); + spin_unlock_irqrestore(&ioa_cfg->host->host_lock, flags); return PCI_ERS_RESULT_NEED_RESET; } @@ -8608,10 +8616,10 @@ static void ipr_pci_frozen(struct pci_dev *pdev) unsigned long flags = 0; struct ipr_ioa_cfg *ioa_cfg = pci_get_drvdata(pdev); - spin_lock_irqsave(ioa_cfg->host->host_lock, flags); + spin_lock_irqsave(&ioa_cfg->host->host_lock, flags); if (ioa_cfg->probe_done) _ipr_initiate_ioa_reset(ioa_cfg, ipr_reset_freeze, IPR_SHUTDOWN_NONE); - spin_unlock_irqrestore(ioa_cfg->host->host_lock, flags); + spin_unlock_irqrestore(&ioa_cfg->host->host_lock, flags); } /** @@ -8627,7 +8635,7 @@ static pci_ers_result_t ipr_pci_slot_reset(struct pci_dev *pdev) unsigned long flags = 0; struct ipr_ioa_cfg *ioa_cfg = pci_get_drvdata(pdev); - spin_lock_irqsave(ioa_cfg->host->host_lock, flags); + spin_lock_irqsave(&ioa_cfg->host->host_lock, flags); if (ioa_cfg->probe_done) { if (ioa_cfg->needs_warm_reset) ipr_initiate_ioa_reset(ioa_cfg, IPR_SHUTDOWN_NONE); @@ -8636,7 +8644,7 @@ static pci_ers_result_t ipr_pci_slot_reset(struct pci_dev *pdev) IPR_SHUTDOWN_NONE); } else wake_up_all(&ioa_cfg->eeh_wait_q); - spin_unlock_irqrestore(ioa_cfg->host->host_lock, flags); + spin_unlock_irqrestore(&ioa_cfg->host->host_lock, flags); return PCI_ERS_RESULT_RECOVERED; } @@ -8653,7 +8661,7 @@ static void ipr_pci_perm_failure(struct pci_dev *pdev) struct ipr_ioa_cfg *ioa_cfg = pci_get_drvdata(pdev); int i; - spin_lock_irqsave(ioa_cfg->host->host_lock, flags); + spin_lock_irqsave(&ioa_cfg->host->host_lock, flags); if (ioa_cfg->probe_done) { if (ioa_cfg->sdt_state == WAIT_FOR_DUMP) ioa_cfg->sdt_state = ABORT_DUMP; @@ -8668,7 +8676,7 @@ static void ipr_pci_perm_failure(struct pci_dev *pdev) ipr_initiate_ioa_reset(ioa_cfg, IPR_SHUTDOWN_NONE); } else wake_up_all(&ioa_cfg->eeh_wait_q); - spin_unlock_irqrestore(ioa_cfg->host->host_lock, flags); + spin_unlock_irqrestore(&ioa_cfg->host->host_lock, flags); } /** @@ -8712,7 +8720,7 @@ static void ipr_probe_ioa_part2(struct ipr_ioa_cfg *ioa_cfg) unsigned long host_lock_flags = 0; ENTER; - spin_lock_irqsave(ioa_cfg->host->host_lock, host_lock_flags); + spin_lock_irqsave(&ioa_cfg->host->host_lock, host_lock_flags); dev_dbg(&ioa_cfg->pdev->dev, "ioa_cfg adx: 0x%p\n", ioa_cfg); ioa_cfg->probe_done = 1; if (ioa_cfg->needs_hard_reset) { @@ -8721,7 +8729,7 @@ static void ipr_probe_ioa_part2(struct ipr_ioa_cfg *ioa_cfg) } else _ipr_initiate_ioa_reset(ioa_cfg, ipr_reset_enable_ioa, IPR_SHUTDOWN_NONE); - spin_unlock_irqrestore(ioa_cfg->host->host_lock, host_lock_flags); + spin_unlock_irqrestore(&ioa_cfg->host->host_lock, host_lock_flags); LEAVE; } @@ -9196,7 +9204,7 @@ static void ipr_init_ioa_cfg(struct ipr_ioa_cfg *ioa_cfg, INIT_LIST_HEAD(&ioa_cfg->hrrq[i].hrrq_pending_q); spin_lock_init(&ioa_cfg->hrrq[i]._lock); if (i == 0) - ioa_cfg->hrrq[i].lock = ioa_cfg->host->host_lock; + ioa_cfg->hrrq[i].lock = &ioa_cfg->host->host_lock; else ioa_cfg->hrrq[i].lock = &ioa_cfg->hrrq[i]._lock; } @@ -9291,12 +9299,12 @@ static irqreturn_t ipr_test_intr(int irq, void *devp) unsigned long lock_flags = 0; dev_info(&ioa_cfg->pdev->dev, "Received IRQ : %d\n", irq); - spin_lock_irqsave(ioa_cfg->host->host_lock, lock_flags); + spin_lock_irqsave(&ioa_cfg->host->host_lock, lock_flags); ioa_cfg->msi_received = 1; wake_up(&ioa_cfg->msi_wait_q); - spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags); + spin_unlock_irqrestore(&ioa_cfg->host->host_lock, lock_flags); return IRQ_HANDLED; } @@ -9320,13 +9328,13 @@ static int ipr_test_msi(struct ipr_ioa_cfg *ioa_cfg, struct pci_dev *pdev) ENTER; - spin_lock_irqsave(ioa_cfg->host->host_lock, lock_flags); + spin_lock_irqsave(&ioa_cfg->host->host_lock, lock_flags); init_waitqueue_head(&ioa_cfg->msi_wait_q); ioa_cfg->msi_received = 0; ipr_mask_and_clear_interrupts(ioa_cfg, ~IPR_PCII_IOA_TRANS_TO_OPER); writel(IPR_PCII_IO_DEBUG_ACKNOWLEDGE, ioa_cfg->regs.clr_interrupt_mask_reg32); readl(ioa_cfg->regs.sense_interrupt_mask_reg); - spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags); + spin_unlock_irqrestore(&ioa_cfg->host->host_lock, lock_flags); rc = request_irq(irq, ipr_test_intr, 0, IPR_NAME, ioa_cfg); if (rc) { @@ -9338,7 +9346,7 @@ static int ipr_test_msi(struct ipr_ioa_cfg *ioa_cfg, struct pci_dev *pdev) writel(IPR_PCII_IO_DEBUG_ACKNOWLEDGE, ioa_cfg->regs.sense_interrupt_reg32); readl(ioa_cfg->regs.sense_interrupt_reg); wait_event_timeout(ioa_cfg->msi_wait_q, ioa_cfg->msi_received, HZ); - spin_lock_irqsave(ioa_cfg->host->host_lock, lock_flags); + spin_lock_irqsave(&ioa_cfg->host->host_lock, lock_flags); ipr_mask_and_clear_interrupts(ioa_cfg, ~IPR_PCII_IOA_TRANS_TO_OPER); if (!ioa_cfg->msi_received) { @@ -9348,7 +9356,7 @@ static int ipr_test_msi(struct ipr_ioa_cfg *ioa_cfg, struct pci_dev *pdev) } else if (ipr_debug) dev_info(&pdev->dev, "MSI test succeeded.\n"); - spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags); + spin_unlock_irqrestore(&ioa_cfg->host->host_lock, lock_flags); free_irq(irq, ioa_cfg); @@ -9573,9 +9581,9 @@ static int ipr_probe_ioa(struct pci_dev *pdev, if (interrupts & IPR_PCII_IOA_UNIT_CHECKED) ioa_cfg->ioa_unit_checked = 1; - spin_lock_irqsave(ioa_cfg->host->host_lock, lock_flags); + spin_lock_irqsave(&ioa_cfg->host->host_lock, lock_flags); ipr_mask_and_clear_interrupts(ioa_cfg, ~IPR_PCII_IOA_TRANS_TO_OPER); - spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags); + spin_unlock_irqrestore(&ioa_cfg->host->host_lock, lock_flags); if (pdev->msi_enabled || pdev->msix_enabled) { name_msi_vectors(ioa_cfg); @@ -9680,11 +9688,11 @@ static void __ipr_remove(struct pci_dev *pdev) unsigned long driver_lock_flags; ENTER; - spin_lock_irqsave(ioa_cfg->host->host_lock, host_lock_flags); + spin_lock_irqsave(&ioa_cfg->host->host_lock, host_lock_flags); while (ioa_cfg->in_reset_reload) { - spin_unlock_irqrestore(ioa_cfg->host->host_lock, host_lock_flags); + spin_unlock_irqrestore(&ioa_cfg->host->host_lock, host_lock_flags); wait_event(ioa_cfg->reset_wait_q, !ioa_cfg->in_reset_reload); - spin_lock_irqsave(ioa_cfg->host->host_lock, host_lock_flags); + spin_lock_irqsave(&ioa_cfg->host->host_lock, host_lock_flags); } for (i = 0; i < ioa_cfg->hrrq_num; i++) { @@ -9695,13 +9703,13 @@ static void __ipr_remove(struct pci_dev *pdev) wmb(); ipr_initiate_ioa_bringdown(ioa_cfg, IPR_SHUTDOWN_NORMAL); - spin_unlock_irqrestore(ioa_cfg->host->host_lock, host_lock_flags); + spin_unlock_irqrestore(&ioa_cfg->host->host_lock, host_lock_flags); wait_event(ioa_cfg->reset_wait_q, !ioa_cfg->in_reset_reload); flush_work(&ioa_cfg->work_q); if (ioa_cfg->reset_work_q) flush_workqueue(ioa_cfg->reset_work_q); INIT_LIST_HEAD(&ioa_cfg->used_res_q); - spin_lock_irqsave(ioa_cfg->host->host_lock, host_lock_flags); + spin_lock_irqsave(&ioa_cfg->host->host_lock, host_lock_flags); spin_lock_irqsave(&ipr_driver_lock, driver_lock_flags); list_del(&ioa_cfg->queue); @@ -9709,7 +9717,7 @@ static void __ipr_remove(struct pci_dev *pdev) if (ioa_cfg->sdt_state == ABORT_DUMP) ioa_cfg->sdt_state = WAIT_FOR_DUMP; - spin_unlock_irqrestore(ioa_cfg->host->host_lock, host_lock_flags); + spin_unlock_irqrestore(&ioa_cfg->host->host_lock, host_lock_flags); ipr_free_all_resources(ioa_cfg); @@ -9807,10 +9815,10 @@ static int ipr_probe(struct pci_dev *pdev, const struct pci_device_id *dev_id) __ipr_remove(pdev); return rc; } - spin_lock_irqsave(ioa_cfg->host->host_lock, flags); + spin_lock_irqsave(&ioa_cfg->host->host_lock, flags); ioa_cfg->scan_enabled = 1; schedule_work(&ioa_cfg->work_q); - spin_unlock_irqrestore(ioa_cfg->host->host_lock, flags); + spin_unlock_irqrestore(&ioa_cfg->host->host_lock, flags); ioa_cfg->iopoll_weight = ioa_cfg->chip_cfg->iopoll_weight; @@ -9843,7 +9851,7 @@ static void ipr_shutdown(struct pci_dev *pdev) enum ipr_shutdown_type shutdown_type = IPR_SHUTDOWN_NORMAL; int i; - spin_lock_irqsave(ioa_cfg->host->host_lock, lock_flags); + spin_lock_irqsave(&ioa_cfg->host->host_lock, lock_flags); if (ioa_cfg->iopoll_weight && ioa_cfg->sis64 && ioa_cfg->nvectors > 1) { ioa_cfg->iopoll_weight = 0; for (i = 1; i < ioa_cfg->hrrq_num; i++) @@ -9851,16 +9859,16 @@ static void ipr_shutdown(struct pci_dev *pdev) } while (ioa_cfg->in_reset_reload) { - spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags); + spin_unlock_irqrestore(&ioa_cfg->host->host_lock, lock_flags); wait_event(ioa_cfg->reset_wait_q, !ioa_cfg->in_reset_reload); - spin_lock_irqsave(ioa_cfg->host->host_lock, lock_flags); + spin_lock_irqsave(&ioa_cfg->host->host_lock, lock_flags); } if (ipr_fast_reboot && system_state == SYSTEM_RESTART && ioa_cfg->sis64) shutdown_type = IPR_SHUTDOWN_QUIESCE; ipr_initiate_ioa_bringdown(ioa_cfg, shutdown_type); - spin_unlock_irqrestore(ioa_cfg->host->host_lock, lock_flags); + spin_unlock_irqrestore(&ioa_cfg->host->host_lock, lock_flags); wait_event(ioa_cfg->reset_wait_q, !ioa_cfg->in_reset_reload); if (ipr_fast_reboot && system_state == SYSTEM_RESTART && ioa_cfg->sis64) { ipr_free_irqs(ioa_cfg); @@ -10030,10 +10038,10 @@ static int ipr_halt(struct notifier_block *nb, ulong event, void *buf) spin_lock_irqsave(&ipr_driver_lock, driver_lock_flags); list_for_each_entry(ioa_cfg, &ipr_ioa_head, queue) { - spin_lock_irqsave(ioa_cfg->host->host_lock, flags); + spin_lock_irqsave(&ioa_cfg->host->host_lock, flags); if (!ioa_cfg->hrrq[IPR_INIT_HRRQ].allow_cmds || (ipr_fast_reboot && event == SYS_RESTART && ioa_cfg->sis64)) { - spin_unlock_irqrestore(ioa_cfg->host->host_lock, flags); + spin_unlock_irqrestore(&ioa_cfg->host->host_lock, flags); continue; } @@ -10044,7 +10052,7 @@ static int ipr_halt(struct notifier_block *nb, ulong event, void *buf) ipr_cmd->ioarcb.cmd_pkt.cdb[1] = IPR_SHUTDOWN_PREPARE_FOR_NORMAL; ipr_do_req(ipr_cmd, ipr_halt_done, ipr_timeout, IPR_DEVICE_RESET_TIMEOUT); - spin_unlock_irqrestore(ioa_cfg->host->host_lock, flags); + spin_unlock_irqrestore(&ioa_cfg->host->host_lock, flags); } spin_unlock_irqrestore(&ipr_driver_lock, driver_lock_flags); diff --git a/drivers/scsi/ips.c b/drivers/scsi/ips.c index 41ed73966a48..c7d6c5aae340 100644 --- a/drivers/scsi/ips.c +++ b/drivers/scsi/ips.c @@ -794,7 +794,7 @@ int ips_eh_abort(struct scsi_cmnd *SC) if (!ha->active) return (FAILED); - spin_lock(host->host_lock); + spin_lock(&host->host_lock); /* See if the command is on the copp queue */ item = ha->copp_waitlist.head; @@ -815,7 +815,7 @@ int ips_eh_abort(struct scsi_cmnd *SC) ret = (FAILED); } - spin_unlock(host->host_lock); + spin_unlock(&host->host_lock); return ret; } @@ -999,9 +999,9 @@ static int ips_eh_reset(struct scsi_cmnd *SC) { int rc; - spin_lock_irq(SC->device->host->host_lock); + spin_lock_irq(&SC->device->host->host_lock); rc = __ips_eh_reset(SC); - spin_unlock_irq(SC->device->host->host_lock); + spin_unlock_irq(&SC->device->host->host_lock); return rc; } @@ -1221,16 +1221,16 @@ do_ipsintr(int irq, void *dev_id) return IRQ_HANDLED; } - spin_lock(host->host_lock); + spin_lock(&host->host_lock); if (!ha->active) { - spin_unlock(host->host_lock); + spin_unlock(&host->host_lock); return IRQ_HANDLED; } irqstatus = (*ha->func.intr) (ha); - spin_unlock(host->host_lock); + spin_unlock(&host->host_lock); /* start the next command */ ips_next(ha, IPS_INTR_ON); @@ -2506,6 +2506,7 @@ ips_hainit(ips_ha_t * ha) /****************************************************************************/ static void ips_next(ips_ha_t * ha, int intr) + __context_unsafe(/*conditional locking*/) { ips_scb_t *scb; struct scsi_cmnd *SC; @@ -2524,7 +2525,7 @@ ips_next(ips_ha_t * ha, int intr) * this command won't time out */ if (intr == IPS_INTR_ON) - spin_lock(host->host_lock); + spin_lock(&host->host_lock); if ((ha->subsys->param[3] & 0x300000) && (ha->scb_activelist.count == 0)) { @@ -2548,14 +2549,14 @@ ips_next(ips_ha_t * ha, int intr) item = ips_removeq_copp_head(&ha->copp_waitlist); ha->num_ioctl++; if (intr == IPS_INTR_ON) - spin_unlock(host->host_lock); + spin_unlock(&host->host_lock); scb->scsi_cmd = item->scsi_cmd; kfree(item); ret = ips_make_passthru(ha, scb->scsi_cmd, scb, intr); if (intr == IPS_INTR_ON) - spin_lock(host->host_lock); + spin_lock(&host->host_lock); switch (ret) { case IPS_FAILURE: if (scb->scsi_cmd) { @@ -2625,7 +2626,7 @@ ips_next(ips_ha_t * ha, int intr) SC = ips_removeq_wait(&ha->scb_waitlist, q); if (intr == IPS_INTR_ON) - spin_unlock(host->host_lock); /* Unlock HA after command is taken off queue */ + spin_unlock(&host->host_lock); /* Unlock HA after command is taken off queue */ SC->result = DID_OK; SC->host_scribble = NULL; @@ -2682,7 +2683,7 @@ ips_next(ips_ha_t * ha, int intr) scb->dcdb.transfer_length = 0; } if (intr == IPS_INTR_ON) - spin_lock(host->host_lock); + spin_lock(&host->host_lock); ret = ips_send_cmd(ha, scb); @@ -2721,7 +2722,7 @@ ips_next(ips_ha_t * ha, int intr) } /* end while */ if (intr == IPS_INTR_ON) - spin_unlock(host->host_lock); + spin_unlock(&host->host_lock); } /****************************************************************************/ diff --git a/drivers/scsi/isci/Makefile b/drivers/scsi/isci/Makefile index da6f04cae272..00fd5c1a8d39 100644 --- a/drivers/scsi/isci/Makefile +++ b/drivers/scsi/isci/Makefile @@ -1,4 +1,7 @@ # SPDX-License-Identifier: GPL-2.0 + +CONTEXT_ANALYSIS := y + obj-$(CONFIG_SCSI_ISCI) += isci.o isci-objs := init.o phy.o request.o \ remote_device.o port.o \ diff --git a/drivers/scsi/leapraid/leapraid_func.h b/drivers/scsi/leapraid/leapraid_func.h index 4c0b9ca728d8..a16390a71662 100644 --- a/drivers/scsi/leapraid/leapraid_func.h +++ b/drivers/scsi/leapraid/leapraid_func.h @@ -113,7 +113,6 @@ #define DESC_FORMAT_THRESHOLD 0x72 #define SENSE_KEY_MASK 0x0F #define SCSI_SENSE_RESPONSE_CODE_MASK 0x7F -#define ASC_FAILURE_PREDICTION_THRESHOLD_EXCEEDED 0x5D #define LEAPRAID_LARGE_DISK_THRESHOLD 0x200000UL #define LEAPRAID_LARGE_DISK_HEADS 255 #define LEAPRAID_LARGE_DISK_SECTORS 63 @@ -126,12 +125,6 @@ #define LEAPRAID_SCSI_HOST_SHIFT 16 #define LEAPRAID_SCSI_DRIVER_SHIFT 24 -/* SCSI ASC/ASCQ definitions. */ -#define LEAPRAID_SCSI_ASCQ_DEFAULT 0x00 -#define LEAPRAID_SCSI_ASC_POWER_ON_RESET 0x29 -#define LEAPRAID_SCSI_ASC_INVALID_CMD_CODE 0x20 -#define LEAPRAID_SCSI_ASCQ_POWER_ON_RESET 0x07 - /* VPD Page 0x89 (ATA Information). */ #define LEAPRAID_VPD_PAGE_ATA_INFO 0x89 #define LEAPRAID_VPD_PG89_MAX_LEN 255 @@ -554,7 +547,6 @@ struct leapraid_fw_evt_work { /** * struct leapraid_fw_evt_struct - Firmware event handling structure * - * @fw_evt_name: Name of the firmware event. * @fw_evt_thread: Workqueue used for processing firmware events. * @fw_evt_lock: Spinlock protecting access to the firmware event list. * @fw_evt_list: Linked list of pending firmware events. @@ -565,7 +557,6 @@ struct leapraid_fw_evt_work { */ struct leapraid_fw_evt_struct { u32 leapraid_evt_masks[4]; - char fw_evt_name[48]; struct workqueue_struct *fw_evt_thread; spinlock_t fw_evt_lock; /* protects firmware event */ struct list_head fw_evt_list; diff --git a/drivers/scsi/leapraid/leapraid_os.c b/drivers/scsi/leapraid/leapraid_os.c index ee3242779dfd..da597eb99377 100644 --- a/drivers/scsi/leapraid/leapraid_os.c +++ b/drivers/scsi/leapraid/leapraid_os.c @@ -382,9 +382,8 @@ static void leapraid_handle_data_underrun( } else if (!xfer_cnt && scmd->cmnd[0] == REPORT_LUNS) { scsiio_rep->scsi_state = LEAPRAID_SCSI_STATE_AUTOSENSE_VALID; scsiio_rep->scsi_status = SAM_STAT_CHECK_CONDITION; - scsi_build_sense(scmd, 0, ILLEGAL_REQUEST, - LEAPRAID_SCSI_ASC_INVALID_CMD_CODE, - LEAPRAID_SCSI_ASCQ_DEFAULT); + scsi_set_sense(scmd, 0, ILLEGAL_REQUEST, + INVALID_COMMAND_OP_CODE); } } @@ -515,8 +514,9 @@ static void leapraid_scsiio_done_dispatch( &sshdr)) dev_warn(&adapter->pdev->dev, "Sense: key=0x%x asc=0x%x ascq=0x%x\n", - sshdr.sense_key, sshdr.asc, - sshdr.ascq); + sshdr.sense_key, + scsi_sense_asc(&sshdr), + scsi_sense_ascq(&sshdr)); else dev_warn(&adapter->pdev->dev, "Sense: Invalid sense data\n"); @@ -810,9 +810,8 @@ static bool leapraid_should_queuecommand(struct leapraid_adapter *adapter, if (sdev_priv->block && scsi_get_host_state(scmd->device->host) == SHOST_RECOVERY && scmd->cmnd[0] == TEST_UNIT_READY) { - scsi_build_sense(scmd, 0, UNIT_ATTENTION, - LEAPRAID_SCSI_ASC_POWER_ON_RESET, - LEAPRAID_SCSI_ASCQ_POWER_ON_RESET); + scsi_set_sense(scmd, 0, UNIT_ATTENTION, + I_T_NEXUS_LOSS_OCCURRED); goto scsiio_done; } @@ -2054,12 +2053,10 @@ static int leapraid_probe(struct pci_dev *pdev, const struct pci_device_id *id) shost->transportt = leapraid_transport_template; shost->unique_id = adapter->adapter_attr.id; - snprintf(adapter->fw_evt_s.fw_evt_name, - sizeof(adapter->fw_evt_s.fw_evt_name), - "fw_event_%s%d", LEAPRAID_DRIVER_NAME, - adapter->adapter_attr.id); adapter->fw_evt_s.fw_evt_thread = - alloc_ordered_workqueue(adapter->fw_evt_s.fw_evt_name, 0); + alloc_ordered_workqueue("fw_event_%s%d", 0, + LEAPRAID_DRIVER_NAME, + adapter->adapter_attr.id); if (!adapter->fw_evt_s.fw_evt_thread) { dev_err(&adapter->pdev->dev, "%s: Failed to create fw event workqueue\n", __func__); diff --git a/drivers/scsi/libfc/Makefile b/drivers/scsi/libfc/Makefile index 65396f86c307..b265cf2a84a2 100644 --- a/drivers/scsi/libfc/Makefile +++ b/drivers/scsi/libfc/Makefile @@ -1,6 +1,8 @@ # SPDX-License-Identifier: GPL-2.0 # $Id: Makefile +CONTEXT_ANALYSIS := y + obj-$(CONFIG_LIBFC) += libfc.o libfc-objs := \ diff --git a/drivers/scsi/libfc/fc_disc.c b/drivers/scsi/libfc/fc_disc.c index 7792724d5b97..ce230a67a082 100644 --- a/drivers/scsi/libfc/fc_disc.c +++ b/drivers/scsi/libfc/fc_disc.c @@ -37,7 +37,7 @@ #define FC_DISC_RETRY_LIMIT 3 /* max retries */ #define FC_DISC_RETRY_DELAY 500UL /* (msecs) delay */ -static void fc_disc_gpn_ft_req(struct fc_disc *); +static void fc_disc_gpn_ft_req(struct fc_disc *disc) __must_hold(&disc->disc_mutex); static void fc_disc_gpn_ft_resp(struct fc_seq *, struct fc_frame *, void *); static void fc_disc_done(struct fc_disc *, enum fc_disc_event); static void fc_disc_timeout(struct work_struct *); @@ -68,6 +68,7 @@ static void fc_disc_stop_rports(struct fc_disc *disc) * @fp: The RSCN frame */ static void fc_disc_recv_rscn_req(struct fc_disc *disc, struct fc_frame *fp) + __must_hold(&disc->disc_mutex) { struct fc_lport *lport; struct fc_els_rscn *rp; @@ -200,6 +201,7 @@ static void fc_disc_recv_req(struct fc_lport *lport, struct fc_frame *fp) * @disc: The discovery object to be restarted */ static void fc_disc_restart(struct fc_disc *disc) + __must_hold(&disc->disc_mutex) { lockdep_assert_held(&disc->disc_mutex); @@ -250,6 +252,7 @@ static void fc_disc_start(void (*disc_callback)(struct fc_lport *, * @event: The discovery completion status */ static void fc_disc_done(struct fc_disc *disc, enum fc_disc_event event) + __must_hold(&disc->disc_mutex) { struct fc_lport *lport = fc_disc_lport(disc); struct fc_rport_priv *rdata; @@ -294,6 +297,7 @@ static void fc_disc_done(struct fc_disc *disc, enum fc_disc_event event) * @fp: The error code encoded as a frame pointer */ static void fc_disc_error(struct fc_disc *disc, struct fc_frame *fp) + __must_hold(&disc->disc_mutex) { struct fc_lport *lport = fc_disc_lport(disc); unsigned long delay = 0; @@ -374,6 +378,7 @@ static void fc_disc_gpn_ft_req(struct fc_disc *disc) * Goes through the list of IDs and names resulting from a request. */ static int fc_disc_gpn_ft_parse(struct fc_disc *disc, void *buf, size_t len) + __must_hold(&disc->disc_mutex) { struct fc_lport *lport; struct fc_gpn_ft_resp *np; diff --git a/drivers/scsi/libfc/fc_exch.c b/drivers/scsi/libfc/fc_exch.c index 9183a0e9568a..ba2530386f97 100644 --- a/drivers/scsi/libfc/fc_exch.c +++ b/drivers/scsi/libfc/fc_exch.c @@ -811,6 +811,7 @@ static void fc_exch_timeout(struct work_struct *work) */ static struct fc_exch *fc_exch_em_alloc(struct fc_lport *lport, struct fc_exch_mgr *mp) + __context_unsafe(/*conditionally acquires &_res->ex_lock*/) { struct fc_exch *ep; unsigned int cpu; @@ -904,6 +905,7 @@ static struct fc_exch *fc_exch_em_alloc(struct fc_lport *lport, */ static struct fc_exch *fc_exch_alloc(struct fc_lport *lport, struct fc_frame *fp) + __context_unsafe(/*conditionally acquires &_res->ex_lock*/) { struct fc_exch_mgr_anchor *ema; struct fc_exch *ep; @@ -996,6 +998,8 @@ static struct fc_exch *fc_exch_resp(struct fc_lport *lport, ep = fc_exch_alloc(lport, fp); if (ep) { + /* Acquired by fc_exch_alloc(). */ + __acquire(&ep->ex_lock); ep->class = fc_frame_class(fp); /* @@ -2191,6 +2195,8 @@ struct fc_seq *fc_exch_seq_send(struct fc_lport *lport, fc_frame_free(fp); return NULL; } + /* Acquired by fc_exch_alloc(). */ + __acquire(&ep->ex_lock); ep->esb_stat |= ESB_ST_SEQ_INIT; fh = fc_frame_header_get(fp); fc_exch_set_addr(ep, ntoh24(fh->fh_s_id), ntoh24(fh->fh_d_id)); diff --git a/drivers/scsi/libfc/fc_fcp.c b/drivers/scsi/libfc/fc_fcp.c index a5139e43ca4c..dbd5673e2885 100644 --- a/drivers/scsi/libfc/fc_fcp.c +++ b/drivers/scsi/libfc/fc_fcp.c @@ -77,7 +77,8 @@ struct fc_fcp_internal { static void fc_fcp_recv_data(struct fc_fcp_pkt *, struct fc_frame *); static void fc_fcp_recv(struct fc_seq *, struct fc_frame *, void *); static void fc_fcp_resp(struct fc_fcp_pkt *, struct fc_frame *); -static void fc_fcp_complete_locked(struct fc_fcp_pkt *); +static void fc_fcp_complete_locked(struct fc_fcp_pkt *fsp) + __must_hold(&fsp->scsi_pkt_lock); static void fc_tm_done(struct fc_seq *, struct fc_frame *, void *); static void fc_fcp_error(struct fc_fcp_pkt *, struct fc_frame *); static void fc_fcp_recovery(struct fc_fcp_pkt *, u8 code); @@ -207,6 +208,7 @@ static void fc_fcp_pkt_destroy(struct fc_seq *seq, void *fsp) * needed. */ static inline int fc_fcp_lock_pkt(struct fc_fcp_pkt *fsp) + __cond_acquires(0, &fsp->scsi_pkt_lock) { spin_lock_bh(&fsp->scsi_pkt_lock); if (fsp->state & FC_SRB_COMPL) { @@ -224,6 +226,7 @@ static inline int fc_fcp_lock_pkt(struct fc_fcp_pkt *fsp) * @fsp: The FCP packet to be unlocked and decremented */ static inline void fc_fcp_unlock_pkt(struct fc_fcp_pkt *fsp) + __releases(&fsp->scsi_pkt_lock) { spin_unlock_bh(&fsp->scsi_pkt_lock); fc_fcp_pkt_release(fsp); @@ -243,6 +246,7 @@ static void fc_fcp_timer_set(struct fc_fcp_pkt *fsp, unsigned long delay) } static void fc_fcp_abort_done(struct fc_fcp_pkt *fsp) + __must_hold(&fsp->scsi_pkt_lock) { fsp->state |= FC_SRB_ABORTED; fsp->state &= ~FC_SRB_ABORT_PENDING; @@ -259,6 +263,7 @@ static void fc_fcp_abort_done(struct fc_fcp_pkt *fsp) * @fsp: The FCP packet to abort exchanges on */ static int fc_fcp_send_abort(struct fc_fcp_pkt *fsp) + __must_hold(&fsp->scsi_pkt_lock) { int rc; @@ -296,6 +301,7 @@ static int fc_fcp_send_abort(struct fc_fcp_pkt *fsp) * The SCSI-ml will retry the command. */ static void fc_fcp_retry_cmd(struct fc_fcp_pkt *fsp, int status_code) + __must_hold(&fsp->scsi_pkt_lock) { if (fsp->seq_ptr) { fc_exch_done(fsp->seq_ptr); @@ -358,7 +364,7 @@ static void fc_fcp_can_queue_ramp_up(struct fc_lport *lport) unsigned long flags; int can_queue; - spin_lock_irqsave(lport->host->host_lock, flags); + spin_lock_irqsave(&lport->host->host_lock, flags); if (si->last_can_queue_ramp_up_time && (time_before(jiffies, si->last_can_queue_ramp_up_time + @@ -381,7 +387,7 @@ static void fc_fcp_can_queue_ramp_up(struct fc_lport *lport) "can_queue to %d.\n", can_queue); unlock: - spin_unlock_irqrestore(lport->host->host_lock, flags); + spin_unlock_irqrestore(&lport->host->host_lock, flags); } /** @@ -401,7 +407,7 @@ static bool fc_fcp_can_queue_ramp_down(struct fc_lport *lport) int can_queue; bool changed = false; - spin_lock_irqsave(lport->host->host_lock, flags); + spin_lock_irqsave(&lport->host->host_lock, flags); if (si->last_can_queue_ramp_down_time && (time_before(jiffies, si->last_can_queue_ramp_down_time + @@ -418,7 +424,7 @@ static bool fc_fcp_can_queue_ramp_down(struct fc_lport *lport) changed = true; unlock: - spin_unlock_irqrestore(lport->host->host_lock, flags); + spin_unlock_irqrestore(&lport->host->host_lock, flags); return changed; } @@ -470,6 +476,7 @@ static inline unsigned int get_fsp_rec_tov(struct fc_fcp_pkt *fsp) * @fp: The data frame */ static void fc_fcp_recv_data(struct fc_fcp_pkt *fsp, struct fc_frame *fp) + __must_hold(&fsp->scsi_pkt_lock) { struct scsi_cmnd *sc = fsp->cmd; struct fc_lport *lport = fsp->lp; @@ -588,6 +595,7 @@ static void fc_fcp_recv_data(struct fc_fcp_pkt *fsp, struct fc_frame *fp) */ static int fc_fcp_send_data(struct fc_fcp_pkt *fsp, struct fc_seq *seq, size_t offset, size_t seq_blen) + __must_hold(&fsp->scsi_pkt_lock) { struct fc_exch *ep; struct scsi_cmnd *sc; @@ -734,6 +742,7 @@ static int fc_fcp_send_data(struct fc_fcp_pkt *fsp, struct fc_seq *seq, * @fp: The response frame */ static void fc_fcp_abts_resp(struct fc_fcp_pkt *fsp, struct fc_frame *fp) + __must_hold(&fsp->scsi_pkt_lock) { int ba_done = 1; struct fc_ba_rjt *brp; @@ -846,6 +855,7 @@ static void fc_fcp_recv(struct fc_seq *seq, struct fc_frame *fp, void *arg) * @fp: The response frame */ static void fc_fcp_resp(struct fc_fcp_pkt *fsp, struct fc_frame *fp) + __must_hold(&fsp->scsi_pkt_lock) { struct fc_frame_header *fh; struct fcp_resp *fc_rp; @@ -1242,6 +1252,7 @@ static void fc_fcp_error(struct fc_fcp_pkt *fsp, struct fc_frame *fp) * Called to send an abort and then wait for abort completion */ static int fc_fcp_pkt_abort(struct fc_fcp_pkt *fsp) + __must_hold(&fsp->scsi_pkt_lock) { int rc = FAILED; unsigned long ticks_left; @@ -1453,6 +1464,7 @@ static void fc_fcp_timeout(struct timer_list *t) * @fsp: The FCP packet to send the REC request on */ static void fc_fcp_rec(struct fc_fcp_pkt *fsp) + __must_hold(&fsp->scsi_pkt_lock) { struct fc_lport *lport; struct fc_frame *fp; @@ -1690,6 +1702,7 @@ static void fc_fcp_rec_error(struct fc_fcp_pkt *fsp, struct fc_frame *fp) * @code: The FCP status code to set */ static void fc_fcp_recovery(struct fc_fcp_pkt *fsp, u8 code) + __must_hold(&fsp->scsi_pkt_lock) { FC_FCP_DBG(fsp, "start recovery code %x\n", code); fsp->status_code = code; @@ -1712,6 +1725,7 @@ static void fc_fcp_recovery(struct fc_fcp_pkt *fsp, u8 code) * when expecting status but the request has timed out. */ static void fc_fcp_srr(struct fc_fcp_pkt *fsp, enum fc_rctl r_ctl, u32 offset) + __must_hold(&fsp->scsi_pkt_lock) { struct fc_lport *lport = fsp->lp; struct fc_rport *rport; @@ -1950,6 +1964,7 @@ EXPORT_SYMBOL(fc_queuecommand); * The fcp packet lock must be held when calling. */ static void fc_io_compl(struct fc_fcp_pkt *fsp) + __must_hold(&fsp->scsi_pkt_lock) { struct fc_fcp_internal *si; struct scsi_cmnd *sc_cmd; diff --git a/drivers/scsi/libiscsi.c b/drivers/scsi/libiscsi.c index 5cbc51899de0..2d04448432a7 100644 --- a/drivers/scsi/libiscsi.c +++ b/drivers/scsi/libiscsi.c @@ -445,16 +445,18 @@ static int iscsi_prep_scsi_cmd_pdu(struct iscsi_task *task) /** * iscsi_free_task - free a task + * @session: iscsi session * @task: iscsi cmd task * * Must be called with session back_lock. * This function returns the scsi command to scsi-ml or cleans * up mgmt tasks then returns the task to the pool. */ -static void iscsi_free_task(struct iscsi_task *task) +static void iscsi_free_task(struct iscsi_session *session, + struct iscsi_task *task) + __must_hold(&session->back_lock) { struct iscsi_conn *conn = task->conn; - struct iscsi_session *session = conn->session; struct scsi_cmnd *sc = task->sc; int oldstate = task->state; @@ -492,14 +494,16 @@ EXPORT_SYMBOL_GPL(iscsi_get_task); /** * __iscsi_put_task - drop the refcount on a task + * @session: iscsi session * @task: iscsi_task to drop the refcount on * * The back_lock must be held when calling in case it frees the task. */ -void __iscsi_put_task(struct iscsi_task *task) +void __iscsi_put_task(struct iscsi_session *session, struct iscsi_task *task) + __must_hold(&session->back_lock) { if (refcount_dec_and_test(&task->refcount)) - iscsi_free_task(task); + iscsi_free_task(session, task); } EXPORT_SYMBOL_GPL(__iscsi_put_task); @@ -509,7 +513,7 @@ void iscsi_put_task(struct iscsi_task *task) if (refcount_dec_and_test(&task->refcount)) { spin_lock_bh(&session->back_lock); - iscsi_free_task(task); + iscsi_free_task(session, task); spin_unlock_bh(&session->back_lock); } } @@ -517,17 +521,19 @@ EXPORT_SYMBOL_GPL(iscsi_put_task); /** * iscsi_complete_task - finish a task + * @session: iscsi session * @task: iscsi cmd task * @state: state to complete task with * * Must be called with session back_lock. */ -static void iscsi_complete_task(struct iscsi_task *task, int state) +static void iscsi_complete_task(struct iscsi_session *session, + struct iscsi_task *task, int state) + __must_hold(&session->back_lock) { struct iscsi_conn *conn = task->conn; - ISCSI_DBG_SESSION(conn->session, - "complete task itt 0x%x state %d sc %p\n", + ISCSI_DBG_SESSION(session, "complete task itt 0x%x state %d sc %p\n", task->itt, task->state, task->sc); if (task->state == ISCSI_TASK_COMPLETED || task->state == ISCSI_TASK_ABRT_TMF || @@ -541,11 +547,12 @@ static void iscsi_complete_task(struct iscsi_task *task, int state) WRITE_ONCE(conn->ping_task, NULL); /* release get from queueing */ - __iscsi_put_task(task); + __iscsi_put_task(session, task); } /** * iscsi_complete_scsi_task - finish scsi task normally + * @session: iscsi session * @task: iscsi task for scsi cmd * @exp_cmdsn: expected cmd sn in cpu format * @max_cmdsn: max cmd sn in cpu format @@ -555,23 +562,28 @@ static void iscsi_complete_task(struct iscsi_task *task, int state) * * Called with session back_lock */ -void iscsi_complete_scsi_task(struct iscsi_task *task, +void iscsi_complete_scsi_task(struct iscsi_session *session, + struct iscsi_task *task, uint32_t exp_cmdsn, uint32_t max_cmdsn) + __must_hold(&session->back_lock) { struct iscsi_conn *conn = task->conn; - ISCSI_DBG_SESSION(conn->session, "[itt 0x%x]\n", task->itt); + ISCSI_DBG_SESSION(session, "[itt 0x%x]\n", task->itt); conn->last_recv = jiffies; - __iscsi_update_cmdsn(conn->session, exp_cmdsn, max_cmdsn); - iscsi_complete_task(task, ISCSI_TASK_COMPLETED); + __iscsi_update_cmdsn(session, exp_cmdsn, max_cmdsn); + iscsi_complete_task(session, task, ISCSI_TASK_COMPLETED); } EXPORT_SYMBOL_GPL(iscsi_complete_scsi_task); /* * Must be called with back and frwd lock */ -static bool cleanup_queued_task(struct iscsi_task *task) +static bool cleanup_queued_task(struct iscsi_session *session, + struct iscsi_task *task) + __must_hold(&session->frwd_lock) + __must_hold(&session->back_lock) { struct iscsi_conn *conn = task->conn; bool early_complete = false; @@ -592,17 +604,17 @@ static bool cleanup_queued_task(struct iscsi_task *task) */ if (task->state == ISCSI_TASK_RUNNING || task->state == ISCSI_TASK_COMPLETED) - __iscsi_put_task(task); + __iscsi_put_task(session, task); } - if (conn->session->running_aborted_task == task) { - conn->session->running_aborted_task = NULL; - __iscsi_put_task(task); + if (session->running_aborted_task == task) { + session->running_aborted_task = NULL; + __iscsi_put_task(session, task); } if (conn->task == task) { conn->task = NULL; - __iscsi_put_task(task); + __iscsi_put_task(session, task); } return early_complete; @@ -612,13 +624,15 @@ static bool cleanup_queued_task(struct iscsi_task *task) * session back and frwd lock must be held and if not called for a task that * is still pending or from the xmit thread, then xmit thread must be suspended */ -static void __fail_scsi_task(struct iscsi_task *task, int err) +static void __fail_scsi_task(struct iscsi_session *session, + struct iscsi_task *task, int err) + __must_hold(&session->frwd_lock) + __must_hold(&session->back_lock) { - struct iscsi_conn *conn = task->conn; struct scsi_cmnd *sc; int state; - if (cleanup_queued_task(task)) + if (cleanup_queued_task(session, task)) return; if (task->state == ISCSI_TASK_PENDING) { @@ -626,7 +640,7 @@ static void __fail_scsi_task(struct iscsi_task *task, int err) * cmd never made it to the xmit thread, so we should not count * the cmd in the sequencing */ - conn->session->queued_cmdsn--; + session->queued_cmdsn--; /* it was never sent so just complete like normal */ state = ISCSI_TASK_COMPLETED; } else if (err == DID_TRANSPORT_DISRUPTED) @@ -637,15 +651,15 @@ static void __fail_scsi_task(struct iscsi_task *task, int err) sc = task->sc; sc->result = err << 16; scsi_set_resid(sc, scsi_bufflen(sc)); - iscsi_complete_task(task, state); + iscsi_complete_task(session, task, state); } -static void fail_scsi_task(struct iscsi_task *task, int err) +static void fail_scsi_task(struct iscsi_session *session, + struct iscsi_task *task, int err) + __must_hold(&session->frwd_lock) { - struct iscsi_session *session = task->conn->session; - spin_lock_bh(&session->back_lock); - __fail_scsi_task(task, err); + __fail_scsi_task(session, task, err); spin_unlock_bh(&session->back_lock); } @@ -857,6 +871,7 @@ EXPORT_SYMBOL_GPL(iscsi_conn_send_pdu); /** * iscsi_scsi_cmd_rsp - SCSI Command Response processing + * @session: iscsi session * @conn: iscsi connection * @hdr: iscsi header * @task: scsi command task @@ -866,12 +881,13 @@ EXPORT_SYMBOL_GPL(iscsi_conn_send_pdu); * iscsi_cmd_rsp sets up the scsi_cmnd fields based on the PDU and * then completes the command and task. called under back_lock **/ -static void iscsi_scsi_cmd_rsp(struct iscsi_conn *conn, struct iscsi_hdr *hdr, +static void iscsi_scsi_cmd_rsp(struct iscsi_session *session, + struct iscsi_conn *conn, struct iscsi_hdr *hdr, struct iscsi_task *task, char *data, int datalen) + __must_hold(&session->back_lock) { struct iscsi_scsi_rsp *rhdr = (struct iscsi_scsi_rsp *)hdr; - struct iscsi_session *session = conn->session; struct scsi_cmnd *sc = task->sc; iscsi_update_cmdsn(session, (struct iscsi_nopin*)rhdr); @@ -892,7 +908,8 @@ static void iscsi_scsi_cmd_rsp(struct iscsi_conn *conn, struct iscsi_hdr *hdr, ascq = session->tt->check_protection(task, §or); if (ascq) { - scsi_build_sense(sc, 1, ILLEGAL_REQUEST, 0x10, ascq); + scsi_set_sense(sc, 1, ILLEGAL_REQUEST, + scsi_sense_code(ASC_ID_CRC_OR_ECC_ERROR, ascq)); scsi_set_sense_information(sc->sense_buffer, SCSI_SENSE_BUFFERSIZE, sector); @@ -949,11 +966,12 @@ static void iscsi_scsi_cmd_rsp(struct iscsi_conn *conn, struct iscsi_hdr *hdr, ISCSI_DBG_SESSION(session, "cmd rsp done [sc %p res %d itt 0x%x]\n", sc, sc->result, task->itt); conn->scsirsp_pdus_cnt++; - iscsi_complete_task(task, ISCSI_TASK_COMPLETED); + iscsi_complete_task(session, task, ISCSI_TASK_COMPLETED); } /** * iscsi_data_in_rsp - SCSI Data-In Response processing + * @session: iscsi session * @conn: iscsi connection * @hdr: iscsi pdu * @task: scsi command task @@ -962,8 +980,9 @@ static void iscsi_scsi_cmd_rsp(struct iscsi_conn *conn, struct iscsi_hdr *hdr, * then completes the command and task. called under back_lock **/ static void -iscsi_data_in_rsp(struct iscsi_conn *conn, struct iscsi_hdr *hdr, - struct iscsi_task *task) +iscsi_data_in_rsp(struct iscsi_session *session, struct iscsi_conn *conn, + struct iscsi_hdr *hdr, struct iscsi_task *task) + __must_hold(&session->back_lock) { struct iscsi_data_rsp *rhdr = (struct iscsi_data_rsp *)hdr; struct scsi_cmnd *sc = task->sc; @@ -971,7 +990,7 @@ iscsi_data_in_rsp(struct iscsi_conn *conn, struct iscsi_hdr *hdr, if (!(rhdr->flags & ISCSI_FLAG_DATA_STATUS)) return; - iscsi_update_cmdsn(conn->session, (struct iscsi_nopin *)hdr); + iscsi_update_cmdsn(session, (struct iscsi_nopin *)hdr); sc->result = (DID_OK << 16) | rhdr->cmd_status; conn->exp_statsn = be32_to_cpu(rhdr->statsn) + 1; if (rhdr->flags & (ISCSI_FLAG_DATA_UNDERFLOW | @@ -986,11 +1005,11 @@ iscsi_data_in_rsp(struct iscsi_conn *conn, struct iscsi_hdr *hdr, sc->result = (DID_BAD_TARGET << 16) | rhdr->cmd_status; } - ISCSI_DBG_SESSION(conn->session, "data in with status done " + ISCSI_DBG_SESSION(session, "data in with status done " "[sc %p res %d itt 0x%x]\n", sc, sc->result, task->itt); conn->scsirsp_pdus_cnt++; - iscsi_complete_task(task, ISCSI_TASK_COMPLETED); + iscsi_complete_task(session, task, ISCSI_TASK_COMPLETED); } static void iscsi_tmf_rsp(struct iscsi_conn *conn, struct iscsi_hdr *hdr) @@ -1058,6 +1077,7 @@ static int iscsi_send_nopout(struct iscsi_conn *conn, struct iscsi_nopin *rhdr) /** * iscsi_nop_out_rsp - SCSI NOP Response processing + * @session: iscsi session * @task: scsi command task * @nop: the nop structure * @data: where to put the data @@ -1066,8 +1086,10 @@ static int iscsi_send_nopout(struct iscsi_conn *conn, struct iscsi_nopin *rhdr) * iscsi_nop_out_rsp handles nop response from use or * from user space. called under back_lock **/ -static int iscsi_nop_out_rsp(struct iscsi_task *task, +static int iscsi_nop_out_rsp(struct iscsi_session *session, + struct iscsi_task *task, struct iscsi_nopin *nop, char *data, int datalen) + __must_hold(&session->back_lock) { struct iscsi_conn *conn = task->conn; int rc = 0; @@ -1082,12 +1104,14 @@ static int iscsi_nop_out_rsp(struct iscsi_task *task, rc = ISCSI_ERR_CONN_FAILED; } else mod_timer(&conn->transport_timer, jiffies + conn->recv_timeout); - iscsi_complete_task(task, ISCSI_TASK_COMPLETED); + iscsi_complete_task(session, task, ISCSI_TASK_COMPLETED); return rc; } -static int iscsi_handle_reject(struct iscsi_conn *conn, struct iscsi_hdr *hdr, +static int iscsi_handle_reject(struct iscsi_session *session, + struct iscsi_conn *conn, struct iscsi_hdr *hdr, char *data, int datalen) + __must_hold(&session->back_lock) { struct iscsi_reject *reject = (struct iscsi_reject *)hdr; struct iscsi_hdr rejected_pdu; @@ -1135,26 +1159,29 @@ static int iscsi_handle_reject(struct iscsi_conn *conn, struct iscsi_hdr *hdr, * Just resend. */ /* In RX path we are under back lock */ - spin_unlock(&conn->session->back_lock); - spin_lock(&conn->session->frwd_lock); + spin_unlock(&session->back_lock); + spin_lock(&session->frwd_lock); iscsi_send_nopout(conn, (struct iscsi_nopin*)&rejected_pdu); - spin_unlock(&conn->session->frwd_lock); - spin_lock(&conn->session->back_lock); + spin_unlock(&session->frwd_lock); + spin_lock(&session->back_lock); } else { - struct iscsi_task *task; + struct iscsi_task *task = NULL; /* * Our nop as ping got dropped. We know the target * and transport are ok so just clean up */ - task = iscsi_itt_to_task(conn, rejected_pdu.itt); - if (!task) { + if (!iscsi_verify_itt(conn, rejected_pdu.itt)) + task = iscsi_itt_to_task(session, conn, + rejected_pdu.itt); + if (!task || task->state == ISCSI_TASK_FREE || + task->sc) { iscsi_conn_printk(KERN_ERR, conn, "Invalid pdu reject. Could " "not lookup rejected task.\n"); rc = ISCSI_ERR_BAD_ITT; } else - rc = iscsi_nop_out_rsp(task, + rc = iscsi_nop_out_rsp(session, task, (struct iscsi_nopin*)&rejected_pdu, NULL, 0); } @@ -1171,6 +1198,7 @@ static int iscsi_handle_reject(struct iscsi_conn *conn, struct iscsi_hdr *hdr, /** * iscsi_itt_to_task - look up task by itt + * @session: iscsi session * @conn: iscsi connection * @itt: itt * @@ -1179,9 +1207,10 @@ static int iscsi_handle_reject(struct iscsi_conn *conn, struct iscsi_hdr *hdr, * * The session back_lock must be held. */ -struct iscsi_task *iscsi_itt_to_task(struct iscsi_conn *conn, itt_t itt) +struct iscsi_task *iscsi_itt_to_task(struct iscsi_session *session, + struct iscsi_conn *conn, itt_t itt) + __must_hold(&session->back_lock) { - struct iscsi_session *session = conn->session; int i; if (itt == RESERVED_ITT) @@ -1191,7 +1220,7 @@ struct iscsi_task *iscsi_itt_to_task(struct iscsi_conn *conn, itt_t itt) session->tt->parse_pdu_itt(conn, itt, &i, NULL); else i = get_itt(itt); - if (i >= session->cmds_max) + if (i < 0 || i >= session->cmds_max) return NULL; return session->cmds[i]; @@ -1200,6 +1229,7 @@ EXPORT_SYMBOL_GPL(iscsi_itt_to_task); /** * __iscsi_complete_pdu - complete pdu + * @session: iscsi session * @conn: iscsi conn * @hdr: iscsi header * @data: data buffer @@ -1209,10 +1239,10 @@ EXPORT_SYMBOL_GPL(iscsi_itt_to_task); * queuecommand or send generic. session back_lock must be held and verify * itt must have been called. */ -int __iscsi_complete_pdu(struct iscsi_conn *conn, struct iscsi_hdr *hdr, - char *data, int datalen) +int __iscsi_complete_pdu(struct iscsi_session *session, struct iscsi_conn *conn, + struct iscsi_hdr *hdr, char *data, int datalen) + __must_hold(&session->back_lock) { - struct iscsi_session *session = conn->session; int opcode = hdr->opcode & ISCSI_OPCODE_MASK, rc = 0; struct iscsi_task *task; uint32_t itt; @@ -1251,7 +1281,7 @@ int __iscsi_complete_pdu(struct iscsi_conn *conn, struct iscsi_hdr *hdr, spin_lock(&session->back_lock); break; case ISCSI_OP_REJECT: - rc = iscsi_handle_reject(conn, hdr, data, datalen); + rc = iscsi_handle_reject(session, conn, hdr, data, datalen); break; case ISCSI_OP_ASYNC_EVENT: conn->exp_statsn = be32_to_cpu(hdr->statsn) + 1; @@ -1268,7 +1298,7 @@ int __iscsi_complete_pdu(struct iscsi_conn *conn, struct iscsi_hdr *hdr, switch(opcode) { case ISCSI_OP_SCSI_CMD_RSP: case ISCSI_OP_SCSI_DATA_IN: - task = iscsi_itt_to_ctask(conn, hdr->itt); + task = iscsi_itt_to_ctask(session, conn, hdr->itt); if (!task) return ISCSI_ERR_BAD_ITT; task->last_xfer = jiffies; @@ -1283,8 +1313,8 @@ int __iscsi_complete_pdu(struct iscsi_conn *conn, struct iscsi_hdr *hdr, case ISCSI_OP_TEXT_RSP: case ISCSI_OP_SCSI_TMFUNC_RSP: case ISCSI_OP_NOOP_IN: - task = iscsi_itt_to_task(conn, hdr->itt); - if (!task) + task = iscsi_itt_to_task(session, conn, hdr->itt); + if (!task || task->state == ISCSI_TASK_FREE || task->sc) return ISCSI_ERR_BAD_ITT; break; default: @@ -1293,10 +1323,10 @@ int __iscsi_complete_pdu(struct iscsi_conn *conn, struct iscsi_hdr *hdr, switch(opcode) { case ISCSI_OP_SCSI_CMD_RSP: - iscsi_scsi_cmd_rsp(conn, hdr, task, data, datalen); + iscsi_scsi_cmd_rsp(session, conn, hdr, task, data, datalen); break; case ISCSI_OP_SCSI_DATA_IN: - iscsi_data_in_rsp(conn, hdr, task); + iscsi_data_in_rsp(session, conn, hdr, task); break; case ISCSI_OP_LOGOUT_RSP: iscsi_update_cmdsn(session, (struct iscsi_nopin*)hdr); @@ -1322,7 +1352,7 @@ int __iscsi_complete_pdu(struct iscsi_conn *conn, struct iscsi_hdr *hdr, } iscsi_tmf_rsp(conn, hdr); - iscsi_complete_task(task, ISCSI_TASK_COMPLETED); + iscsi_complete_task(session, task, ISCSI_TASK_COMPLETED); break; case ISCSI_OP_NOOP_IN: iscsi_update_cmdsn(session, (struct iscsi_nopin*)hdr); @@ -1332,7 +1362,7 @@ int __iscsi_complete_pdu(struct iscsi_conn *conn, struct iscsi_hdr *hdr, } conn->exp_statsn = be32_to_cpu(hdr->statsn) + 1; - rc = iscsi_nop_out_rsp(task, (struct iscsi_nopin*)hdr, + rc = iscsi_nop_out_rsp(session, task, (struct iscsi_nopin*)hdr, data, datalen); break; default: @@ -1345,7 +1375,7 @@ int __iscsi_complete_pdu(struct iscsi_conn *conn, struct iscsi_hdr *hdr, recv_pdu: if (iscsi_recv_pdu(conn->cls_conn, hdr, data, datalen)) rc = ISCSI_ERR_CONN_FAILED; - iscsi_complete_task(task, ISCSI_TASK_COMPLETED); + iscsi_complete_task(session, task, ISCSI_TASK_COMPLETED); return rc; } EXPORT_SYMBOL_GPL(__iscsi_complete_pdu); @@ -1353,11 +1383,12 @@ EXPORT_SYMBOL_GPL(__iscsi_complete_pdu); int iscsi_complete_pdu(struct iscsi_conn *conn, struct iscsi_hdr *hdr, char *data, int datalen) { + struct iscsi_session *session = conn->session; int rc; - spin_lock(&conn->session->back_lock); - rc = __iscsi_complete_pdu(conn, hdr, data, datalen); - spin_unlock(&conn->session->back_lock); + spin_lock(&session->back_lock); + rc = __iscsi_complete_pdu(session, conn, hdr, data, datalen); + spin_unlock(&session->back_lock); return rc; } EXPORT_SYMBOL_GPL(iscsi_complete_pdu); @@ -1384,7 +1415,7 @@ int iscsi_verify_itt(struct iscsi_conn *conn, itt_t itt) return ISCSI_ERR_BAD_ITT; } - if (i >= session->cmds_max) { + if (i < 0 || i >= session->cmds_max) { iscsi_conn_printk(KERN_ERR, conn, "received invalid itt index %u (max cmds " "%u.\n", i, session->cmds_max); @@ -1396,6 +1427,7 @@ EXPORT_SYMBOL_GPL(iscsi_verify_itt); /** * iscsi_itt_to_ctask - look up ctask by itt + * @session: iscsi session * @conn: iscsi connection * @itt: itt * @@ -1403,21 +1435,23 @@ EXPORT_SYMBOL_GPL(iscsi_verify_itt); * * The session back_lock must be held. */ -struct iscsi_task *iscsi_itt_to_ctask(struct iscsi_conn *conn, itt_t itt) +struct iscsi_task *iscsi_itt_to_ctask(struct iscsi_session *session, + struct iscsi_conn *conn, itt_t itt) + __must_hold(&session->back_lock) { struct iscsi_task *task; if (iscsi_verify_itt(conn, itt)) return NULL; - task = iscsi_itt_to_task(conn, itt); + task = iscsi_itt_to_task(session, conn, itt); if (!task || !task->sc) return NULL; - if (iscsi_cmd(task->sc)->age != conn->session->age) { - iscsi_session_printk(KERN_ERR, conn->session, + if (iscsi_cmd(task->sc)->age != session->age) { + iscsi_session_printk(KERN_ERR, session, "task's session age %d, expected %d\n", - iscsi_cmd(task->sc)->age, conn->session->age); + iscsi_cmd(task->sc)->age, session->age); return NULL; } @@ -1481,10 +1515,10 @@ void iscsi_conn_failure(struct iscsi_conn *conn, enum iscsi_err err) } EXPORT_SYMBOL_GPL(iscsi_conn_failure); -static int iscsi_check_cmdsn_window_closed(struct iscsi_conn *conn) +static int iscsi_check_cmdsn_window_closed(struct iscsi_session *session, + struct iscsi_conn *conn) + __must_hold(&session->frwd_lock) { - struct iscsi_session *session = conn->session; - /* * Check for iSCSI window and take care of CmdSN wrap-around */ @@ -1498,8 +1532,9 @@ static int iscsi_check_cmdsn_window_closed(struct iscsi_conn *conn) return 0; } -static int iscsi_xmit_task(struct iscsi_conn *conn, struct iscsi_task *task, - bool was_requeue) +static int iscsi_xmit_task(struct iscsi_session *session, struct iscsi_conn *conn, + struct iscsi_task *task, bool was_requeue) + __must_hold(&session->frwd_lock) { int rc; @@ -1539,9 +1574,9 @@ static int iscsi_xmit_task(struct iscsi_conn *conn, struct iscsi_task *task, return -ENODATA; } - spin_unlock_bh(&conn->session->frwd_lock); - rc = conn->session->tt->xmit_task(task); - spin_lock_bh(&conn->session->frwd_lock); + spin_unlock_bh(&session->frwd_lock); + rc = session->tt->xmit_task(task); + spin_lock_bh(&session->frwd_lock); if (!rc) { /* done with this task */ task->last_xfer = jiffies; @@ -1598,18 +1633,19 @@ EXPORT_SYMBOL_GPL(iscsi_requeue_task); **/ static int iscsi_data_xmit(struct iscsi_conn *conn) { + struct iscsi_session *session = conn->session; struct iscsi_task *task; int rc = 0; - spin_lock_bh(&conn->session->frwd_lock); + spin_lock_bh(&session->frwd_lock); if (test_bit(ISCSI_CONN_FLAG_SUSPEND_TX, &conn->flags)) { - ISCSI_DBG_SESSION(conn->session, "Tx suspended!\n"); - spin_unlock_bh(&conn->session->frwd_lock); + ISCSI_DBG_SESSION(session, "Tx suspended!\n"); + spin_unlock_bh(&session->frwd_lock); return -ENODATA; } if (conn->task) { - rc = iscsi_xmit_task(conn, conn->task, false); + rc = iscsi_xmit_task(session, conn, conn->task, false); if (rc) goto done; } @@ -1626,12 +1662,12 @@ static int iscsi_data_xmit(struct iscsi_conn *conn) list_del_init(&task->running); if (iscsi_prep_mgmt_task(conn, task)) { /* regular RX path uses back_lock */ - spin_lock_bh(&conn->session->back_lock); - __iscsi_put_task(task); - spin_unlock_bh(&conn->session->back_lock); + spin_lock_bh(&session->back_lock); + __iscsi_put_task(session, task); + spin_unlock_bh(&session->back_lock); continue; } - rc = iscsi_xmit_task(conn, task, false); + rc = iscsi_xmit_task(session, conn, task, false); if (rc) goto done; } @@ -1641,7 +1677,7 @@ static int iscsi_data_xmit(struct iscsi_conn *conn) /* * we always do fastlogout - conn stop code will clean up. */ - if (conn->session->state == ISCSI_STATE_LOGGING_OUT) + if (session->state == ISCSI_STATE_LOGGING_OUT) break; task = list_entry(conn->requeue.next, struct iscsi_task, @@ -1651,7 +1687,7 @@ static int iscsi_data_xmit(struct iscsi_conn *conn) break; list_del_init(&task->running); - rc = iscsi_xmit_task(conn, task, true); + rc = iscsi_xmit_task(session, conn, task, true); if (rc) goto done; if (!list_empty(&conn->mgmtqueue)) @@ -1663,19 +1699,19 @@ static int iscsi_data_xmit(struct iscsi_conn *conn) task = list_entry(conn->cmdqueue.next, struct iscsi_task, running); list_del_init(&task->running); - if (conn->session->state == ISCSI_STATE_LOGGING_OUT) { - fail_scsi_task(task, DID_IMM_RETRY); + if (session->state == ISCSI_STATE_LOGGING_OUT) { + fail_scsi_task(session, task, DID_IMM_RETRY); continue; } rc = iscsi_prep_scsi_cmd_pdu(task); if (rc) { if (rc == -ENOMEM || rc == -EACCES) - fail_scsi_task(task, DID_IMM_RETRY); + fail_scsi_task(session, task, DID_IMM_RETRY); else - fail_scsi_task(task, DID_ABORT); + fail_scsi_task(session, task, DID_ABORT); continue; } - rc = iscsi_xmit_task(conn, task, false); + rc = iscsi_xmit_task(session, conn, task, false); if (rc) goto done; /* @@ -1689,11 +1725,11 @@ static int iscsi_data_xmit(struct iscsi_conn *conn) goto check_requeue; } - spin_unlock_bh(&conn->session->frwd_lock); + spin_unlock_bh(&session->frwd_lock); return -ENODATA; done: - spin_unlock_bh(&conn->session->frwd_lock); + spin_unlock_bh(&session->frwd_lock); return rc; } @@ -1827,7 +1863,7 @@ enum scsi_qc_status iscsi_queuecommand(struct Scsi_Host *host, goto fault; } - if (iscsi_check_cmdsn_window_closed(conn)) { + if (iscsi_check_cmdsn_window_closed(session, conn)) { reason = FAILURE_WINDOW_CLOSED; goto reject; } @@ -1865,7 +1901,7 @@ enum scsi_qc_status iscsi_queuecommand(struct Scsi_Host *host, prepd_reject: spin_lock_bh(&session->back_lock); - iscsi_complete_task(task, ISCSI_TASK_REQUEUE_SCSIQ); + iscsi_complete_task(session, task, ISCSI_TASK_REQUEUE_SCSIQ); spin_unlock_bh(&session->back_lock); reject: spin_unlock_bh(&session->frwd_lock); @@ -1875,7 +1911,7 @@ enum scsi_qc_status iscsi_queuecommand(struct Scsi_Host *host, prepd_fault: spin_lock_bh(&session->back_lock); - iscsi_complete_task(task, ISCSI_TASK_REQUEUE_SCSIQ); + iscsi_complete_task(session, task, ISCSI_TASK_REQUEUE_SCSIQ); spin_unlock_bh(&session->back_lock); fault: spin_unlock_bh(&session->frwd_lock); @@ -1912,13 +1948,13 @@ static void iscsi_tmf_timedout(struct timer_list *t) spin_unlock(&session->frwd_lock); } -static int iscsi_exec_task_mgmt_fn(struct iscsi_conn *conn, +static int iscsi_exec_task_mgmt_fn(struct iscsi_session *session, + struct iscsi_conn *conn, struct iscsi_tm *hdr, int age, int timeout) + __must_hold(&session->eh_mutex) __must_hold(&session->frwd_lock) { - struct iscsi_session *session = conn->session; - if (__iscsi_conn_send_pdu(conn, (struct iscsi_hdr *)hdr, NULL, 0)) { spin_unlock_bh(&session->frwd_lock); iscsi_conn_printk(KERN_ERR, conn, "Could not send TMF.\n"); @@ -1961,9 +1997,10 @@ static int iscsi_exec_task_mgmt_fn(struct iscsi_conn *conn, /* * Fail commands. session frwd lock held and xmit thread flushed. */ -static void fail_scsi_tasks(struct iscsi_conn *conn, u64 lun, int error) +static void fail_scsi_tasks(struct iscsi_session *session, struct iscsi_conn *conn, + u64 lun, int error) + __must_hold(&session->frwd_lock) { - struct iscsi_session *session = conn->session; struct iscsi_task *task; int i; @@ -1992,8 +2029,8 @@ static void fail_scsi_tasks(struct iscsi_conn *conn, u64 lun, int error) ISCSI_DBG_SESSION(session, "failing sc %p itt 0x%x state %d\n", task->sc, task->itt, task->state); - __fail_scsi_task(task, error); - __iscsi_put_task(task); + __fail_scsi_task(session, task, error); + __iscsi_put_task(session, task); } spin_unlock_bh(&session->back_lock); } @@ -2414,7 +2451,7 @@ int iscsi_eh_abort(struct scsi_cmnd *sc) spin_unlock(&session->back_lock); if (task->state == ISCSI_TASK_PENDING) { - fail_scsi_task(task, DID_ABORT); + fail_scsi_task(session, task, DID_ABORT); goto success; } @@ -2426,7 +2463,8 @@ int iscsi_eh_abort(struct scsi_cmnd *sc) hdr = &session->tmhdr; iscsi_prep_abort_task_pdu(task, hdr); - if (iscsi_exec_task_mgmt_fn(conn, hdr, age, session->abort_timeout)) + if (iscsi_exec_task_mgmt_fn(session, conn, hdr, age, + session->abort_timeout)) goto failed; switch (session->tmf_state) { @@ -2443,7 +2481,7 @@ int iscsi_eh_abort(struct scsi_cmnd *sc) * then sent more data for the cmd. */ spin_lock_bh(&session->frwd_lock); - fail_scsi_task(task, DID_ABORT); + fail_scsi_task(session, task, DID_ABORT); session->tmf_state = TMF_INITIAL; memset(hdr, 0, sizeof(*hdr)); spin_unlock_bh(&session->frwd_lock); @@ -2540,7 +2578,7 @@ int iscsi_eh_device_reset(struct scsi_cmnd *sc) hdr = &session->tmhdr; iscsi_prep_lun_reset_pdu(sc, hdr); - if (iscsi_exec_task_mgmt_fn(conn, hdr, session->age, + if (iscsi_exec_task_mgmt_fn(session, conn, hdr, session->age, session->lu_reset_timeout)) { rc = FAILED; goto unlock; @@ -2565,7 +2603,7 @@ int iscsi_eh_device_reset(struct scsi_cmnd *sc) spin_lock_bh(&session->frwd_lock); memset(hdr, 0, sizeof(*hdr)); - fail_scsi_tasks(conn, sc->device->lun, DID_ERROR); + fail_scsi_tasks(session, conn, sc->device->lun, DID_ERROR); session->tmf_state = TMF_INITIAL; spin_unlock_bh(&session->frwd_lock); @@ -2702,7 +2740,7 @@ static int iscsi_eh_target_reset(struct scsi_cmnd *sc) hdr = &session->tmhdr; iscsi_prep_tgt_reset_pdu(sc, hdr); - if (iscsi_exec_task_mgmt_fn(conn, hdr, session->age, + if (iscsi_exec_task_mgmt_fn(session, conn, hdr, session->age, session->tgt_reset_timeout)) { rc = FAILED; goto unlock; @@ -2727,7 +2765,7 @@ static int iscsi_eh_target_reset(struct scsi_cmnd *sc) spin_lock_bh(&session->frwd_lock); memset(hdr, 0, sizeof(*hdr)); - fail_scsi_tasks(conn, -1, DID_ERROR); + fail_scsi_tasks(session, conn, -1, DID_ERROR); session->tmf_state = TMF_INITIAL; spin_unlock_bh(&session->frwd_lock); @@ -3356,6 +3394,7 @@ EXPORT_SYMBOL_GPL(iscsi_conn_start); static void fail_mgmt_tasks(struct iscsi_session *session, struct iscsi_conn *conn) + __must_hold(&session->frwd_lock) { struct iscsi_task *task; int i, state; @@ -3373,7 +3412,7 @@ fail_mgmt_tasks(struct iscsi_session *session, struct iscsi_conn *conn) task->itt, task->state); spin_lock_bh(&session->back_lock); - if (cleanup_queued_task(task)) { + if (cleanup_queued_task(session, task)) { spin_unlock_bh(&session->back_lock); continue; } @@ -3381,7 +3420,7 @@ fail_mgmt_tasks(struct iscsi_session *session, struct iscsi_conn *conn) state = ISCSI_TASK_ABRT_SESS_RECOV; if (task->state == ISCSI_TASK_PENDING) state = ISCSI_TASK_COMPLETED; - iscsi_complete_task(task, state); + iscsi_complete_task(session, task, state); spin_unlock_bh(&session->back_lock); } } @@ -3441,7 +3480,7 @@ void iscsi_conn_stop(struct iscsi_cls_conn *cls_conn, int flag) * flush queues. */ spin_lock_bh(&session->frwd_lock); - fail_scsi_tasks(conn, -1, DID_TRANSPORT_DISRUPTED); + fail_scsi_tasks(session, conn, -1, DID_TRANSPORT_DISRUPTED); fail_mgmt_tasks(session, conn); memset(&session->tmhdr, 0, sizeof(session->tmhdr)); spin_unlock_bh(&session->frwd_lock); diff --git a/drivers/scsi/libiscsi_tcp.c b/drivers/scsi/libiscsi_tcp.c index 7223bb18b048..1cfa68b01e10 100644 --- a/drivers/scsi/libiscsi_tcp.c +++ b/drivers/scsi/libiscsi_tcp.c @@ -480,6 +480,9 @@ static int iscsi_tcp_data_in(struct iscsi_conn *conn, struct iscsi_task *task) int datasn = be32_to_cpu(rhdr->datasn); unsigned total_in_length = task->sc->sdb.length; + if (task->sc->sc_data_direction != DMA_FROM_DEVICE) + return ISCSI_ERR_PROTO; + /* * lib iscsi will update this in the completion handling if there * is status. @@ -529,7 +532,7 @@ static int iscsi_tcp_r2t_rsp(struct iscsi_conn *conn, struct iscsi_hdr *hdr) int rc; spin_lock(&session->back_lock); - task = iscsi_itt_to_ctask(conn, hdr->itt); + task = iscsi_itt_to_ctask(session, conn, hdr->itt); if (!task) { spin_unlock(&session->back_lock); return ISCSI_ERR_BAD_ITT; @@ -677,6 +680,7 @@ iscsi_tcp_process_data_in(struct iscsi_tcp_conn *tcp_conn, static int iscsi_tcp_hdr_dissect(struct iscsi_conn *conn, struct iscsi_hdr *hdr) { + struct iscsi_session *session = conn->session; int rc = 0, opcode, ahslen; struct iscsi_tcp_conn *tcp_conn = conn->dd_data; struct iscsi_task *task; @@ -706,14 +710,14 @@ iscsi_tcp_hdr_dissect(struct iscsi_conn *conn, struct iscsi_hdr *hdr) switch(opcode) { case ISCSI_OP_SCSI_DATA_IN: - spin_lock(&conn->session->back_lock); - task = iscsi_itt_to_ctask(conn, hdr->itt); + spin_lock(&session->back_lock); + task = iscsi_itt_to_ctask(session, conn, hdr->itt); if (!task) rc = ISCSI_ERR_BAD_ITT; else rc = iscsi_tcp_data_in(conn, task); if (rc) { - spin_unlock(&conn->session->back_lock); + spin_unlock(&session->back_lock); break; } @@ -731,7 +735,7 @@ iscsi_tcp_hdr_dissect(struct iscsi_conn *conn, struct iscsi_hdr *hdr) * update the digest per-entry. */ if (conn->datadgst_en && - !(conn->session->tt->caps & CAP_DIGEST_OFFLOAD)) + !(session->tt->caps & CAP_DIGEST_OFFLOAD)) rx_crcp = tcp_conn->rx_crcp; ISCSI_DBG_TCP(conn, "iscsi_tcp_begin_data_in( " @@ -746,11 +750,11 @@ iscsi_tcp_hdr_dissect(struct iscsi_conn *conn, struct iscsi_hdr *hdr) tcp_conn->in.datalen, iscsi_tcp_process_data_in, rx_crcp); - spin_unlock(&conn->session->back_lock); + spin_unlock(&session->back_lock); return rc; } - rc = __iscsi_complete_pdu(conn, hdr, NULL, 0); - spin_unlock(&conn->session->back_lock); + rc = __iscsi_complete_pdu(session, conn, hdr, NULL, 0); + spin_unlock(&session->back_lock); break; case ISCSI_OP_R2T: if (ahslen) { diff --git a/drivers/scsi/libsas/Makefile b/drivers/scsi/libsas/Makefile index 9dc32736cf21..6f6f1336b438 100644 --- a/drivers/scsi/libsas/Makefile +++ b/drivers/scsi/libsas/Makefile @@ -6,6 +6,8 @@ # Copyright (C) 2005 Luben Tuikov # +CONTEXT_ANALYSIS := y + obj-$(CONFIG_SCSI_SAS_LIBSAS) += libsas.o libsas-y += sas_init.o \ sas_phy.o \ diff --git a/drivers/scsi/libsas/sas_ata.c b/drivers/scsi/libsas/sas_ata.c index 61368e55bf86..2340790c9f6b 100644 --- a/drivers/scsi/libsas/sas_ata.c +++ b/drivers/scsi/libsas/sas_ata.c @@ -153,7 +153,7 @@ static void sas_ata_task_done(struct sas_task *task) } static unsigned int sas_ata_qc_issue(struct ata_queued_cmd *qc) - __must_hold(ap->lock) + __must_hold(qc->ap->lock) { struct sas_task *task; struct scatterlist *sg; diff --git a/drivers/scsi/libsas/sas_expander.c b/drivers/scsi/libsas/sas_expander.c index 811c9eb4fef1..26c2099c28b9 100644 --- a/drivers/scsi/libsas/sas_expander.c +++ b/drivers/scsi/libsas/sas_expander.c @@ -62,7 +62,11 @@ static int smp_execute_task_sg(struct domain_device *dev, to_sas_internal(dev->port->ha->shost->transportt); struct sas_ha_struct *ha = dev->port->ha; - pm_runtime_get_sync(ha->dev); + /* + * Non-blocking: a sync resume here would deadlock against + * sas_drain_work() during HA resume. + */ + pm_runtime_get_noresume(ha->dev); mutex_lock(&dev->ex_dev.cmd_mutex); for (retry = 0; retry < 3; retry++) { if (test_bit(SAS_DEV_GONE, &dev->state)) { @@ -135,7 +139,7 @@ static int smp_execute_task_sg(struct domain_device *dev, } } mutex_unlock(&dev->ex_dev.cmd_mutex); - pm_runtime_put_sync(ha->dev); + pm_runtime_put(ha->dev); BUG_ON(retry == 3 && task != NULL); sas_free_task(task); @@ -2222,6 +2226,11 @@ void sas_smp_handler(struct bsg_job *job, struct Scsi_Host *shost, goto out; } + /* The host may have autosuspended, resume it here. */ + ret = pm_runtime_resume_and_get(dev->port->ha->dev); + if (ret) + goto out; + ret = smp_execute_task_sg(dev, job->request_payload.sg_list, job->reply_payload.sg_list); if (ret >= 0) { @@ -2229,6 +2238,7 @@ void sas_smp_handler(struct bsg_job *job, struct Scsi_Host *shost, rcvlen = job->reply_payload.payload_len - ret; ret = 0; } + pm_runtime_put(dev->port->ha->dev); out: bsg_job_done(job, ret, rcvlen); diff --git a/drivers/scsi/libsas/sas_scsi_host.c b/drivers/scsi/libsas/sas_scsi_host.c index 97ac3db5dccb..76517c8f0684 100644 --- a/drivers/scsi/libsas/sas_scsi_host.c +++ b/drivers/scsi/libsas/sas_scsi_host.c @@ -436,13 +436,13 @@ int sas_eh_abort_handler(struct scsi_cmnd *cmd) if (!i->dft->lldd_abort_task) return FAILED; - spin_lock_irqsave(host->host_lock, flags); + spin_lock_irqsave(&host->host_lock, flags); /* We cannot do async aborts for SATA devices */ if (dev_is_sata(dev) && !host->host_eh_scheduled) { - spin_unlock_irqrestore(host->host_lock, flags); + spin_unlock_irqrestore(&host->host_lock, flags); return FAILED; } - spin_unlock_irqrestore(host->host_lock, flags); + spin_unlock_irqrestore(&host->host_lock, flags); if (task) res = i->dft->lldd_abort_task(task); @@ -714,9 +714,9 @@ void sas_scsi_recover_host(struct Scsi_Host *shost) retry: tries++; retry = true; - spin_lock_irq(shost->host_lock); + spin_lock_irq(&shost->host_lock); list_splice_init(&shost->eh_cmd_q, &eh_work_q); - spin_unlock_irq(shost->host_lock); + spin_unlock_irq(&shost->host_lock); pr_notice("Enter %s busy: %d failed: %d\n", __func__, scsi_host_busy(shost), shost->host_failed); diff --git a/drivers/scsi/libsas/sas_task.c b/drivers/scsi/libsas/sas_task.c index e9d291007817..2080e5836179 100644 --- a/drivers/scsi/libsas/sas_task.c +++ b/drivers/scsi/libsas/sas_task.c @@ -25,7 +25,7 @@ void sas_ssp_task_response(struct device *dev, struct sas_task *task, case SAS_DATAPRES_SENSE_DATA: tstat->stat = SAS_SAM_STAT_CHECK_CONDITION; tstat->buf_valid_size = - min_t(int, SAS_STATUS_BUF_SIZE, + min_t(u32, SAS_STATUS_BUF_SIZE, be32_to_cpu(iu->sense_data_len)); memcpy(tstat->buf, iu->sense_data, tstat->buf_valid_size); diff --git a/drivers/scsi/lpfc/lpfc_ct.c b/drivers/scsi/lpfc/lpfc_ct.c index 0734ab3be3e3..f709e5087577 100644 --- a/drivers/scsi/lpfc/lpfc_ct.c +++ b/drivers/scsi/lpfc/lpfc_ct.c @@ -3576,8 +3576,6 @@ lpfc_cmpl_ct_cmd_vmid(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, int i; cmd = be16_to_cpu(ctcmd->CommandResponse.bits.CmdRsp); - if (cmd == SLI_CTAS_DALLAPP_ID) - lpfc_ct_free_iocb(phba, cmdiocb); if (lpfc_els_chk_latt(vport) || get_job_ulpstatus(phba, rspiocb)) { if (cmd != SLI_CTAS_DALLAPP_ID) diff --git a/drivers/scsi/lpfc/lpfc_els.c b/drivers/scsi/lpfc/lpfc_els.c index 52fc5058976d..804aa7509b69 100644 --- a/drivers/scsi/lpfc/lpfc_els.c +++ b/drivers/scsi/lpfc/lpfc_els.c @@ -5952,11 +5952,12 @@ lpfc_els_rsp_reject(struct lpfc_vport *vport, uint32_t rejectError, /* Xmit ELS RJT response tag */ lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS, "0129 Xmit ELS RJT x%x response tag x%x " - "xri x%x, did x%x, nlp_flag x%lx, nlp_state x%x, " - "rpi x%x\n", + "xri x%x, ndlp x%px, did x%x, nlp_flag x%lx, " + "nlp_state x%x, rpi x%x ref_cnt %d\n", rejectError, elsiocb->iotag, - get_job_ulpcontext(phba, elsiocb), ndlp->nlp_DID, - ndlp->nlp_flag, ndlp->nlp_state, ndlp->nlp_rpi); + get_job_ulpcontext(phba, elsiocb), ndlp, + ndlp->nlp_DID, ndlp->nlp_flag, ndlp->nlp_state, + ndlp->nlp_rpi, kref_read(&ndlp->kref)); lpfc_debugfs_disc_trc(vport, LPFC_DISC_TRC_ELS_RSP, "Issue LS_RJT: did:x%x flg:x%lx err:x%x", ndlp->nlp_DID, ndlp->nlp_flag, rejectError); @@ -7917,15 +7918,15 @@ lpfc_els_flush_rscn(struct lpfc_vport *vport) struct lpfc_hba *phba = vport->phba; int i; - spin_lock_irq(shost->host_lock); + spin_lock_irq(&shost->host_lock); if (vport->fc_rscn_flush) { /* Another thread is walking fc_rscn_id_list on this vport */ - spin_unlock_irq(shost->host_lock); + spin_unlock_irq(&shost->host_lock); return; } /* Indicate we are walking lpfc_els_flush_rscn on this vport */ vport->fc_rscn_flush = 1; - spin_unlock_irq(shost->host_lock); + spin_unlock_irq(&shost->host_lock); for (i = 0; i < vport->fc_rscn_id_cnt; i++) { lpfc_in_buf_free(phba, vport->fc_rscn_id_list[i]); @@ -7933,9 +7934,9 @@ lpfc_els_flush_rscn(struct lpfc_vport *vport) } clear_bit(FC_RSCN_MODE, &vport->fc_flag); clear_bit(FC_RSCN_DISCOVERY, &vport->fc_flag); - spin_lock_irq(shost->host_lock); + spin_lock_irq(&shost->host_lock); vport->fc_rscn_id_cnt = 0; - spin_unlock_irq(shost->host_lock); + spin_unlock_irq(&shost->host_lock); lpfc_can_disctmo(vport); /* Indicate we are done walking this fc_rscn_id_list */ vport->fc_rscn_flush = 0; @@ -7972,15 +7973,15 @@ lpfc_rscn_payload_check(struct lpfc_vport *vport, uint32_t did) if (test_bit(FC_RSCN_DISCOVERY, &vport->fc_flag)) return did; - spin_lock_irq(shost->host_lock); + spin_lock_irq(&shost->host_lock); if (vport->fc_rscn_flush) { /* Another thread is walking fc_rscn_id_list on this vport */ - spin_unlock_irq(shost->host_lock); + spin_unlock_irq(&shost->host_lock); return 0; } /* Indicate we are walking fc_rscn_id_list on this vport */ vport->fc_rscn_flush = 1; - spin_unlock_irq(shost->host_lock); + spin_unlock_irq(&shost->host_lock); for (i = 0; i < vport->fc_rscn_id_cnt; i++) { lp = vport->fc_rscn_id_list[i]->virt; payload_len = be32_to_cpu(*lp++ & ~ELS_CMD_MASK); @@ -8146,7 +8147,7 @@ lpfc_els_rcv_rscn(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb, uint32_t payload_len, length, nportid, *cmd; int rscn_cnt; int rscn_id = 0, hba_id = 0; - int i, tmo; + int i; pcmd = cmdiocb->cmd_dmabuf; lp = (uint32_t *) pcmd->virt; @@ -8225,19 +8226,16 @@ lpfc_els_rcv_rscn(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb, lpfc_els_rsp_acc(vport, ELS_CMD_ACC, cmdiocb, ndlp, NULL); /* Restart disctmo if its already running */ - if (test_bit(FC_DISC_TMO, &vport->fc_flag)) { - tmo = ((phba->fc_ratov * 3) + 3); - mod_timer(&vport->fc_disctmo, - jiffies + secs_to_jiffies(tmo)); - } + if (test_bit(FC_DISC_TMO, &vport->fc_flag)) + lpfc_set_disctmo(vport); return 0; } } - spin_lock_irq(shost->host_lock); + spin_lock_irq(&shost->host_lock); if (vport->fc_rscn_flush) { /* Another thread is walking fc_rscn_id_list on this vport */ - spin_unlock_irq(shost->host_lock); + spin_unlock_irq(&shost->host_lock); set_bit(FC_RSCN_DISCOVERY, &vport->fc_flag); /* Send back ACC */ lpfc_els_rsp_acc(vport, ELS_CMD_ACC, cmdiocb, ndlp, NULL); @@ -8245,7 +8243,7 @@ lpfc_els_rcv_rscn(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb, } /* Indicate we are walking fc_rscn_id_list on this vport */ vport->fc_rscn_flush = 1; - spin_unlock_irq(shost->host_lock); + spin_unlock_irq(&shost->host_lock); /* Get the array count after successfully have the token */ rscn_cnt = vport->fc_rscn_id_cnt; /* If we are already processing an RSCN, save the received @@ -8260,11 +8258,9 @@ lpfc_els_rcv_rscn(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb, set_bit(FC_RSCN_DEFERRED, &vport->fc_flag); /* Restart disctmo if its already running */ - if (test_bit(FC_DISC_TMO, &vport->fc_flag)) { - tmo = ((phba->fc_ratov * 3) + 3); - mod_timer(&vport->fc_disctmo, - jiffies + secs_to_jiffies(tmo)); - } + if (test_bit(FC_DISC_TMO, &vport->fc_flag)) + lpfc_set_disctmo(vport); + if ((rscn_cnt < FC_MAX_HOLD_RSCN) && !test_bit(FC_RSCN_DISCOVERY, &vport->fc_flag)) { set_bit(FC_RSCN_MODE, &vport->fc_flag); @@ -8538,14 +8534,14 @@ lpfc_els_rcv_flogi(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb, * The vport state should go to LPFC_FLOGI only * AFTER we issue a FLOGI, not receive one. */ - spin_lock_irq(shost->host_lock); + spin_lock_irq(&shost->host_lock); fc_flag = vport->fc_flag; port_state = vport->port_state; /* Acking an unsol FLOGI. Count 1 for link bounce * work-around. */ vport->rcv_flogi_cnt++; - spin_unlock_irq(shost->host_lock); + spin_unlock_irq(&shost->host_lock); set_bit(FC_PT2PT, &vport->fc_flag); clear_bit(FC_FABRIC, &vport->fc_flag); clear_bit(FC_PUBLIC_LOOP, &vport->fc_flag); @@ -9597,6 +9593,7 @@ lpfc_els_timeout(struct timer_list *t) **/ void lpfc_els_timeout_handler(struct lpfc_vport *vport) + __context_unsafe(/*conditional locking*/) { struct lpfc_hba *phba = vport->phba; struct lpfc_sli_ring *pring; @@ -9719,6 +9716,7 @@ lpfc_els_timeout_handler(struct lpfc_vport *vport) **/ void lpfc_els_flush_cmd(struct lpfc_vport *vport) + __context_unsafe(/*conditional locking*/) { LIST_HEAD(abort_list); LIST_HEAD(cancel_list); @@ -10462,6 +10460,7 @@ lpfc_els_unsol_buffer(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, struct lpfc_vport *vport, struct lpfc_iocbq *elsiocb) { struct lpfc_nodelist *ndlp; + struct lpfc_nodelist *alloc_ndlp = NULL; struct ls_rjt stat; u32 *payload, payload_len; u32 cmd = 0, did = 0, newnode, status = 0; @@ -10560,7 +10559,9 @@ lpfc_els_unsol_buffer(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, did, vport->port_state, ndlp->nlp_flag); phba->fc_stat.elsRcvPLOGI++; + alloc_ndlp = ndlp; ndlp = lpfc_plogi_confirm_nport(phba, payload, ndlp); + if (phba->sli_rev == LPFC_SLI_REV4 && test_bit(FC_PT2PT, &phba->pport->fc_flag)) { vport->fc_prevDID = vport->fc_myDID; @@ -10876,13 +10877,28 @@ lpfc_els_unsol_buffer(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, stat.un.b.lsRjtRsnCodeExp = rjt_exp; lpfc_els_rsp_reject(vport, stat.un.lsRjtError, elsiocb, ndlp, NULL); - /* Remove the reference from above for new nodes. */ - if (newnode) - lpfc_disc_state_machine(vport, ndlp, NULL, - NLP_EVT_DEVICE_RM); + + /* Remove the safety reference from routine start. */ + if (newnode) { + /* alloc_ndlp is assigned for an unsolicited PLOGI from + * the ndlp allocated by this routine. The routine + * lpfc_plogi_confirm_nport may have swapped the initial + * ndlp to an existing ndlp. In that case, alloc_ndlp + * is the pre-swap ndlp that needs a DEVICE_RM because + * it is the newnode. For all other paths to lsrjt + * (non-PLOGI ELS) that were rejected by the early + * port_state check, alloc_ndlp is NULL and ndlp is + * still the originally allocated node. + */ + lpfc_disc_state_machine(vport, + alloc_ndlp ? alloc_ndlp : ndlp, + NULL, NLP_EVT_DEVICE_RM); + } } - /* Release the reference on this elsiocb, not the ndlp. */ + /* This elsiocb is not the IOCB issued for a response. Remove + * the safety reference allocated earlier. + */ lpfc_nlp_put(elsiocb->ndlp); elsiocb->ndlp = NULL; @@ -11190,9 +11206,9 @@ lpfc_cmpl_reg_new_vport(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) break; } } else { - spin_lock_irq(shost->host_lock); + spin_lock_irq(&shost->host_lock); vport->vpi_state |= LPFC_VPI_REGISTERED; - spin_unlock_irq(shost->host_lock); + spin_unlock_irq(&shost->host_lock); if (vport == phba->pport) { if (phba->sli_rev < LPFC_SLI_REV4) lpfc_issue_fabric_reglogin(vport); @@ -11395,6 +11411,7 @@ lpfc_cmpl_els_fdisc(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, struct serv_parm *sp; uint8_t fabric_param_changed; u32 ulp_status, ulp_word4; + unsigned long flags; ulp_status = get_job_ulpstatus(phba, rspiocb); ulp_word4 = get_job_word4(phba, rspiocb); @@ -11416,7 +11433,6 @@ lpfc_cmpl_els_fdisc(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, ulp_status, ulp_word4, vport->fc_prevDID); if (ulp_status) { - if (lpfc_fabric_login_reqd(phba, cmdiocb, rspiocb)) { lpfc_retry_pport_discovery(phba); goto out; @@ -11427,12 +11443,28 @@ lpfc_cmpl_els_fdisc(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, goto out; /* Warn FDISC status */ lpfc_vlog_msg(vport, KERN_WARNING, LOG_ELS, - "0126 FDISC cmpl status: x%x/x%x)\n", - ulp_status, ulp_word4); + "0126 FDISC cmpl status: (x%x/x%x) ndlp x%px " + "Data: x%lx x%x x%x x%x x%x x%x x%x x%x x%x\n", + ulp_status, ulp_word4, ndlp, ndlp->nlp_flag, + ndlp->nlp_DID, ndlp->nlp_last_elscmd, + ndlp->nlp_type, ndlp->nlp_rpi, ndlp->nlp_state, + ndlp->nlp_prev_state, ndlp->fc4_xpt_flags, + kref_read(&ndlp->kref)); - /* drop initial reference */ - if (!test_and_set_bit(NLP_DROPPED, &ndlp->nlp_flag)) + /* If have not previously registered with transport layer and no + * LPFC_EVT_DEV_LOSS work pending, then drop initial reference. + * Otherwise, let the dev_loss_tmo_callbk drop the initial + * reference. + */ + spin_lock_irqsave(&ndlp->lock, flags); + if (!(ndlp->fc4_xpt_flags & (SCSI_XPT_REGD | NVME_XPT_REGD)) && + !test_bit(NLP_IN_DEV_LOSS, &ndlp->nlp_flag) && + !test_and_set_bit(NLP_DROPPED, &ndlp->nlp_flag)) { + spin_unlock_irqrestore(&ndlp->lock, flags); lpfc_nlp_put(ndlp); + } else { + spin_unlock_irqrestore(&ndlp->lock, flags); + } goto fdisc_failed; } diff --git a/drivers/scsi/lpfc/lpfc_hbadisc.c b/drivers/scsi/lpfc/lpfc_hbadisc.c index c9b02d2c6305..57cdd669928c 100644 --- a/drivers/scsi/lpfc/lpfc_hbadisc.c +++ b/drivers/scsi/lpfc/lpfc_hbadisc.c @@ -1340,9 +1340,9 @@ lpfc_linkdown(struct lpfc_hba *phba) } clear_bit(FC_PT2PT, &phba->pport->fc_flag); clear_bit(FC_PT2PT_PLOGI, &phba->pport->fc_flag); - spin_lock_irq(shost->host_lock); + spin_lock_irq(&shost->host_lock); phba->pport->rcv_flogi_cnt = 0; - spin_unlock_irq(shost->host_lock); + spin_unlock_irq(&shost->host_lock); } return 0; } @@ -1406,9 +1406,9 @@ lpfc_linkup_port(struct lpfc_vport *vport) } set_bit(FC_NDISC_ACTIVE, &vport->fc_flag); - spin_lock_irq(shost->host_lock); + spin_lock_irq(&shost->host_lock); vport->fc_ns_retry = 0; - spin_unlock_irq(shost->host_lock); + spin_unlock_irq(&shost->host_lock); lpfc_setup_fdmi_mask(vport); lpfc_linkup_cleanup_nodes(vport); @@ -1437,9 +1437,9 @@ lpfc_linkup(struct lpfc_hba *phba) * absorbed without an ACQE. No lock here - in worker thread * and discovery is synchronized. */ - spin_lock_irq(shost->host_lock); + spin_lock_irq(&shost->host_lock); phba->pport->rcv_flogi_cnt = 0; - spin_unlock_irq(shost->host_lock); + spin_unlock_irq(&shost->host_lock); return 0; } @@ -3400,9 +3400,9 @@ lpfc_mbx_cmpl_reg_vfi(struct lpfc_hba *phba, LPFC_MBOXQ_t *mboxq) set_bit(FC_VFI_REGISTERED, &vport->fc_flag); clear_bit(FC_VPORT_NEEDS_REG_VPI, &vport->fc_flag); clear_bit(FC_VPORT_NEEDS_INIT_VPI, &vport->fc_flag); - spin_lock_irq(shost->host_lock); + spin_lock_irq(&shost->host_lock); vport->vpi_state |= LPFC_VPI_REGISTERED; - spin_unlock_irq(shost->host_lock); + spin_unlock_irq(&shost->host_lock); /* In case SLI4 FC loopback test, we are ready */ if ((phba->sli_rev == LPFC_SLI_REV4) && @@ -3943,9 +3943,9 @@ lpfc_mbx_cmpl_unreg_vpi(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) } set_bit(FC_VPORT_NEEDS_REG_VPI, &vport->fc_flag); - spin_lock_irq(shost->host_lock); + spin_lock_irq(&shost->host_lock); vport->vpi_state &= ~LPFC_VPI_REGISTERED; - spin_unlock_irq(shost->host_lock); + spin_unlock_irq(&shost->host_lock); mempool_free(pmb, phba->mbox_mem_pool); lpfc_cleanup_vports_rrqs(vport, NULL); /* @@ -4010,9 +4010,9 @@ lpfc_mbx_cmpl_reg_vpi(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) } clear_bit(FC_VPORT_NEEDS_REG_VPI, &vport->fc_flag); - spin_lock_irq(shost->host_lock); + spin_lock_irq(&shost->host_lock); vport->vpi_state |= LPFC_VPI_REGISTERED; - spin_unlock_irq(shost->host_lock); + spin_unlock_irq(&shost->host_lock); vport->num_disc_nodes = 0; /* go thru NPR list and issue ELS PLOGIs */ if (atomic_read(&vport->fc_npr_cnt)) @@ -4951,6 +4951,13 @@ lpfc_drop_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp) */ if (ndlp->nlp_state == NLP_STE_UNUSED_NODE) return; + + lpfc_printf_vlog(vport, KERN_INFO, LOG_NODE | LOG_ELS | LOG_DISCOVERY, + "3421 Mark ndlp x%px Dropped. DID x%06x, nflags x%lx " + "xflags x%x ref_cnt %d\n", + ndlp, ndlp->nlp_DID, ndlp->nlp_flag, + ndlp->fc4_xpt_flags, kref_read(&ndlp->kref)); + lpfc_nlp_set_state(vport, ndlp, NLP_STE_UNUSED_NODE); if (vport->phba->sli_rev == LPFC_SLI_REV4) { lpfc_cleanup_vports_rrqs(vport, ndlp); @@ -5620,9 +5627,9 @@ lpfc_findnode_did(struct lpfc_vport *vport, uint32_t did) struct lpfc_nodelist *ndlp; unsigned long iflags; - spin_lock_irqsave(shost->host_lock, iflags); + spin_lock_irqsave(&shost->host_lock, iflags); ndlp = __lpfc_findnode_did(vport, did); - spin_unlock_irqrestore(shost->host_lock, iflags); + spin_unlock_irqrestore(&shost->host_lock, iflags); return ndlp; } @@ -6426,9 +6433,9 @@ lpfc_findnode_wwpn(struct lpfc_vport *vport, struct lpfc_name *wwpn) struct Scsi_Host *shost = lpfc_shost_from_vport(vport); struct lpfc_nodelist *ndlp; - spin_lock_irq(shost->host_lock); + spin_lock_irq(&shost->host_lock); ndlp = __lpfc_find_node(vport, lpfc_filter_by_wwpn, wwpn); - spin_unlock_irq(shost->host_lock); + spin_unlock_irq(&shost->host_lock); return ndlp; } @@ -6444,9 +6451,9 @@ lpfc_findnode_rpi(struct lpfc_vport *vport, uint16_t rpi) struct lpfc_nodelist *ndlp; unsigned long flags; - spin_lock_irqsave(shost->host_lock, flags); + spin_lock_irqsave(&shost->host_lock, flags); ndlp = __lpfc_findnode_rpi(vport, rpi); - spin_unlock_irqrestore(shost->host_lock, flags); + spin_unlock_irqrestore(&shost->host_lock, flags); return ndlp; } @@ -6786,9 +6793,9 @@ lpfc_unregister_fcf_prep(struct lpfc_hba *phba) lpfc_sli4_unreg_all_rpis(vports[i]); lpfc_mbx_unreg_vpi(vports[i]); shost = lpfc_shost_from_vport(vports[i]); - spin_lock_irq(shost->host_lock); + spin_lock_irq(&shost->host_lock); vports[i]->vpi_state &= ~LPFC_VPI_REGISTERED; - spin_unlock_irq(shost->host_lock); + spin_unlock_irq(&shost->host_lock); set_bit(FC_VPORT_NEEDS_INIT_VPI, &vports[i]->fc_flag); } lpfc_destroy_vport_work_array(phba, vports); @@ -6801,9 +6808,9 @@ lpfc_unregister_fcf_prep(struct lpfc_hba *phba) lpfc_sli4_unreg_all_rpis(phba->pport); lpfc_mbx_unreg_vpi(phba->pport); shost = lpfc_shost_from_vport(phba->pport); - spin_lock_irq(shost->host_lock); + spin_lock_irq(&shost->host_lock); phba->pport->vpi_state &= ~LPFC_VPI_REGISTERED; - spin_unlock_irq(shost->host_lock); + spin_unlock_irq(&shost->host_lock); set_bit(FC_VPORT_NEEDS_INIT_VPI, &phba->pport->fc_flag); } diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c index 23355f12fbff..7352cb6e584b 100644 --- a/drivers/scsi/lpfc/lpfc_init.c +++ b/drivers/scsi/lpfc/lpfc_init.c @@ -3833,9 +3833,9 @@ lpfc_offline_prep(struct lpfc_hba *phba, int mbx_action) if (test_bit(FC_UNLOADING, &vports[i]->load_flag)) continue; shost = lpfc_shost_from_vport(vports[i]); - spin_lock_irq(shost->host_lock); + spin_lock_irq(&shost->host_lock); vports[i]->vpi_state &= ~LPFC_VPI_REGISTERED; - spin_unlock_irq(shost->host_lock); + spin_unlock_irq(&shost->host_lock); set_bit(FC_VPORT_NEEDS_REG_VPI, &vports[i]->fc_flag); clear_bit(FC_VFI_REGISTERED, &vports[i]->fc_flag); @@ -3926,9 +3926,9 @@ lpfc_offline(struct lpfc_hba *phba) if (vports != NULL) for (i = 0; i <= phba->max_vports && vports[i] != NULL; i++) { shost = lpfc_shost_from_vport(vports[i]); - spin_lock_irq(shost->host_lock); + spin_lock_irq(&shost->host_lock); vports[i]->work_port_events = 0; - spin_unlock_irq(shost->host_lock); + spin_unlock_irq(&shost->host_lock); set_bit(FC_OFFLINE_MODE, &vports[i]->fc_flag); } lpfc_destroy_vport_work_array(phba, vports); @@ -4930,7 +4930,7 @@ int lpfc_scan_finished(struct Scsi_Host *shost, unsigned long time) struct lpfc_hba *phba = vport->phba; int stat = 0; - spin_lock_irq(shost->host_lock); + spin_lock_irq(&shost->host_lock); if (test_bit(FC_UNLOADING, &vport->load_flag)) { stat = 1; @@ -4965,7 +4965,7 @@ int lpfc_scan_finished(struct Scsi_Host *shost, unsigned long time) stat = 1; finished: - spin_unlock_irq(shost->host_lock); + spin_unlock_irq(&shost->host_lock); return stat; } @@ -9226,9 +9226,9 @@ lpfc_post_init_setup(struct lpfc_hba *phba) lpfc_host_attrib_init(shost); if (phba->cfg_poll & DISABLE_FCP_RING_INT) { - spin_lock_irq(shost->host_lock); + spin_lock_irq(&shost->host_lock); lpfc_poll_start_timer(phba); - spin_unlock_irq(shost->host_lock); + spin_unlock_irq(&shost->host_lock); } lpfc_printf_log(phba, KERN_INFO, LOG_INIT, @@ -13514,6 +13514,9 @@ lpfc_sli4_hba_unset(struct lpfc_hba *phba) /* Stop the SLI4 device port */ if (phba->pport) phba->pport->work_port_events = 0; + + /* All IO completed and queues released. Free the IOCBs. */ + lpfc_free_iocb_list(phba); } /* @@ -14948,11 +14951,20 @@ lpfc_pci_remove_one_s4(struct pci_dev *pdev) /* Perform scsi free before driver resource_unset since scsi * buffers are released to their corresponding pools here. + * lpfc_sli4_hba_unset() issues aborts via lpfc_sli_hba_iocb_abort(), + * which allocates abort IOCBs from phba->lpfc_iocb_list; the pool + * must still exist, so lpfc_free_iocb_list() runs only after unset. */ lpfc_io_free(phba); - lpfc_free_iocb_list(phba); - lpfc_sli4_hba_unset(phba); + /* Flush the PHBA WQ - there could be a race with ELS IOs while lpfc + * is unloading. This stops a race between completions, aborts and + * resource recovery. + */ + if (phba->wq) + flush_workqueue(phba->wq); + + lpfc_sli4_hba_unset(phba); lpfc_unset_driver_resource_phase2(phba); lpfc_sli4_driver_resource_unset(phba); diff --git a/drivers/scsi/lpfc/lpfc_nportdisc.c b/drivers/scsi/lpfc/lpfc_nportdisc.c index 9c449055a55e..fb8844c69491 100644 --- a/drivers/scsi/lpfc/lpfc_nportdisc.c +++ b/drivers/scsi/lpfc/lpfc_nportdisc.c @@ -220,6 +220,7 @@ lpfc_check_elscmpl_iocb(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb, */ void lpfc_els_abort(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp) + __context_unsafe(/*conditional locking*/) { LIST_HEAD(abort_list); LIST_HEAD(drv_cmpl_list); @@ -227,6 +228,11 @@ lpfc_els_abort(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp) struct lpfc_iocbq *iocb, *next_iocb; int retval = 0; + /* Exit early to prevent race with queue teardown. */ + if (unlikely(phba->sli_rev == LPFC_SLI_REV4 && + !test_bit(HBA_SETUP, &phba->hba_flag))) + return; + pring = lpfc_phba_elsring(phba); /* In case of error recovery path, we might have a NULL pring here */ @@ -250,8 +256,9 @@ lpfc_els_abort(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp) spin_lock_irq(&phba->hbalock); if (phba->sli_rev == LPFC_SLI_REV4) spin_lock(&pring->ring_lock); + list_for_each_entry_safe(iocb, next_iocb, &pring->txcmplq, list) { - /* Add to abort_list on on NDLP match. */ + /* Add to abort_list on NDLP match. */ if (lpfc_check_sli_ndlp(phba, pring, iocb, ndlp)) list_add_tail(&iocb->dlist, &abort_list); } @@ -266,7 +273,13 @@ lpfc_els_abort(struct lpfc_hba *phba, struct lpfc_nodelist *ndlp) retval = lpfc_sli_issue_abort_iotag(phba, pring, iocb, NULL); spin_unlock_irq(&phba->hbalock); - if (retval && test_bit(FC_UNLOADING, &phba->pport->load_flag)) { + /* An abort that fails here is just cancelled when the driver is + * going offline. However, if the abort failure is because the + * IOCB is already getting aborted, don't cancel. Just let it + * complete. + */ + if (test_bit(FC_UNLOADING, &phba->pport->load_flag) && + retval && retval != IOCB_ABORTING) { list_del_init(&iocb->list); list_add_tail(&iocb->list, &drv_cmpl_list); } @@ -2866,6 +2879,20 @@ lpfc_device_rm_npr_node(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, set_bit(NLP_NODEV_REMOVE, &ndlp->nlp_flag); return ndlp->nlp_state; } + + /* It is an error to drop a node while either of its transport + * registrations have not completed. + */ + if (ndlp->fc4_xpt_flags & (SCSI_XPT_REGD | NVME_XPT_REGD)) { + lpfc_printf_vlog(vport, KERN_WARNING, + LOG_ELS | LOG_NODE | LOG_DISCOVERY, + "3423 Not dropping ndlp x%px, DID x%x xflags x%x " + "with dev_loss pending. ref_cnt %d\n", + ndlp, ndlp->nlp_DID, ndlp->fc4_xpt_flags, + kref_read(&ndlp->kref)); + return ndlp->nlp_state; + } + lpfc_drop_node(vport, ndlp); return NLP_STE_FREED_NODE; } diff --git a/drivers/scsi/lpfc/lpfc_scsi.c b/drivers/scsi/lpfc/lpfc_scsi.c index 8a795c65e3c3..3f39cc065029 100644 --- a/drivers/scsi/lpfc/lpfc_scsi.c +++ b/drivers/scsi/lpfc/lpfc_scsi.c @@ -2848,7 +2848,8 @@ lpfc_calc_bg_err(struct lpfc_hba *phba, struct lpfc_io_buf *lpfc_cmd) } out: if (err_type == BGS_GUARD_ERR_MASK) { - scsi_build_sense(cmd, 1, ILLEGAL_REQUEST, 0x10, 0x1); + scsi_set_sense(cmd, 1, ILLEGAL_REQUEST, + LOGICAL_BLOCK_GUARD_CHECK_FAILED); set_host_byte(cmd, DID_ABORT); phba->bg_guard_err_cnt++; lpfc_printf_log(phba, KERN_WARNING, LOG_FCP | LOG_BG, @@ -2857,7 +2858,8 @@ lpfc_calc_bg_err(struct lpfc_hba *phba, struct lpfc_io_buf *lpfc_cmd) sum, guard_tag); } else if (err_type == BGS_REFTAG_ERR_MASK) { - scsi_build_sense(cmd, 1, ILLEGAL_REQUEST, 0x10, 0x3); + scsi_set_sense(cmd, 1, ILLEGAL_REQUEST, + LOGICAL_BLOCK_REFERENCE_TAG_CHECK_FAILED); set_host_byte(cmd, DID_ABORT); phba->bg_reftag_err_cnt++; @@ -2867,7 +2869,8 @@ lpfc_calc_bg_err(struct lpfc_hba *phba, struct lpfc_io_buf *lpfc_cmd) ref_tag, start_ref_tag); } else if (err_type == BGS_APPTAG_ERR_MASK) { - scsi_build_sense(cmd, 1, ILLEGAL_REQUEST, 0x10, 0x2); + scsi_set_sense(cmd, 1, ILLEGAL_REQUEST, + LOGICAL_BLOCK_APPLICATION_TAG_CHECK_FAILED); set_host_byte(cmd, DID_ABORT); phba->bg_apptag_err_cnt++; @@ -2970,7 +2973,8 @@ lpfc_parse_bg_err(struct lpfc_hba *phba, struct lpfc_io_buf *lpfc_cmd, if (lpfc_bgs_get_guard_err(bgstat)) { ret = 1; - scsi_build_sense(cmd, 1, ILLEGAL_REQUEST, 0x10, 0x1); + scsi_set_sense(cmd, 1, ILLEGAL_REQUEST, + LOGICAL_BLOCK_GUARD_CHECK_FAILED); set_host_byte(cmd, DID_ABORT); phba->bg_guard_err_cnt++; lpfc_printf_log(phba, KERN_WARNING, LOG_FCP | LOG_BG, @@ -2983,7 +2987,8 @@ lpfc_parse_bg_err(struct lpfc_hba *phba, struct lpfc_io_buf *lpfc_cmd, if (lpfc_bgs_get_reftag_err(bgstat)) { ret = 1; - scsi_build_sense(cmd, 1, ILLEGAL_REQUEST, 0x10, 0x3); + scsi_set_sense(cmd, 1, ILLEGAL_REQUEST, + LOGICAL_BLOCK_REFERENCE_TAG_CHECK_FAILED); set_host_byte(cmd, DID_ABORT); phba->bg_reftag_err_cnt++; lpfc_printf_log(phba, KERN_WARNING, LOG_FCP | LOG_BG, @@ -2996,7 +3001,8 @@ lpfc_parse_bg_err(struct lpfc_hba *phba, struct lpfc_io_buf *lpfc_cmd, if (lpfc_bgs_get_apptag_err(bgstat)) { ret = 1; - scsi_build_sense(cmd, 1, ILLEGAL_REQUEST, 0x10, 0x2); + scsi_set_sense(cmd, 1, ILLEGAL_REQUEST, + LOGICAL_BLOCK_APPLICATION_TAG_CHECK_FAILED); set_host_byte(cmd, DID_ABORT); phba->bg_apptag_err_cnt++; lpfc_printf_log(phba, KERN_WARNING, LOG_FCP | LOG_BG, @@ -4272,7 +4278,7 @@ lpfc_fcp_io_cmd_wqe_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *pwqeIn, if (vport->cfg_max_scsicmpl_time && time_after(jiffies, lpfc_cmd->start_time + msecs_to_jiffies(vport->cfg_max_scsicmpl_time))) { - spin_lock_irqsave(shost->host_lock, flags); + spin_lock_irqsave(&shost->host_lock, flags); if (ndlp) { if (ndlp->cmd_qdepth > atomic_read(&ndlp->cmd_pending) && @@ -4285,7 +4291,7 @@ lpfc_fcp_io_cmd_wqe_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *pwqeIn, ndlp->last_change_time = jiffies; } - spin_unlock_irqrestore(shost->host_lock, flags); + spin_unlock_irqrestore(&shost->host_lock, flags); } lpfc_scsi_unprep_dma_buf(phba, lpfc_cmd); @@ -4552,7 +4558,7 @@ lpfc_scsi_cmd_iocb_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *pIocbIn, if (vport->cfg_max_scsicmpl_time && time_after(jiffies, lpfc_cmd->start_time + msecs_to_jiffies(vport->cfg_max_scsicmpl_time))) { - spin_lock_irqsave(shost->host_lock, flags); + spin_lock_irqsave(&shost->host_lock, flags); if (pnode) { if (pnode->cmd_qdepth > atomic_read(&pnode->cmd_pending) && @@ -4565,7 +4571,7 @@ lpfc_scsi_cmd_iocb_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *pIocbIn, pnode->last_change_time = jiffies; } - spin_unlock_irqrestore(shost->host_lock, flags); + spin_unlock_irqrestore(&shost->host_lock, flags); } lpfc_scsi_unprep_dma_buf(phba, lpfc_cmd); @@ -5501,6 +5507,7 @@ void lpfc_vmid_vport_cleanup(struct lpfc_vport *vport) **/ static int lpfc_abort_handler(struct scsi_cmnd *cmnd) + __context_unsafe(/*conditional locking*/) { struct Scsi_Host *shost = cmnd->device->host; struct fc_rport *rport = starget_to_rport(scsi_target(cmnd->device)); diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c index cfa4371169f1..84fb317a34ed 100644 --- a/drivers/scsi/lpfc/lpfc_sli.c +++ b/drivers/scsi/lpfc/lpfc_sli.c @@ -2886,9 +2886,9 @@ lpfc_sli_def_mbox_cmpl(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb) !test_bit(FC_UNLOADING, &phba->pport->load_flag) && !pmb->u.mb.mbxStatus) { shost = lpfc_shost_from_vport(vport); - spin_lock_irq(shost->host_lock); + spin_lock_irq(&shost->host_lock); vport->vpi_state |= LPFC_VPI_REGISTERED; - spin_unlock_irq(shost->host_lock); + spin_unlock_irq(&shost->host_lock); clear_bit(FC_VPORT_NEEDS_REG_VPI, &vport->fc_flag); } @@ -3722,6 +3722,7 @@ lpfc_sli_iocbq_lookup_by_tag(struct lpfc_hba *phba, static int lpfc_sli_process_sol_iocb(struct lpfc_hba *phba, struct lpfc_sli_ring *pring, struct lpfc_iocbq *saveq) + __context_unsafe(/*conditional locking*/) { struct lpfc_iocbq *cmdiocbp; unsigned long iflag; @@ -12730,8 +12731,12 @@ lpfc_sli_sum_iocb(struct lpfc_vport *vport, uint16_t tgt_id, uint64_t lun_id, if (!iocbq || iocbq->vport != vport) continue; - if (!(iocbq->cmd_flag & LPFC_IO_FCP) || - !(iocbq->cmd_flag & LPFC_IO_ON_TXCMPLQ)) + /* Only count FCP i/o */ + if (!(iocbq->cmd_flag & LPFC_IO_FCP)) + continue; + /* Count i/o whilst LLDD retains an interest in the scsi_cmnd */ + if (!(iocbq->cmd_flag & + (LPFC_IO_ON_TXCMPLQ | LPFC_DRIVER_ABORTED))) continue; /* Include counting outstanding aborts */ @@ -12876,6 +12881,7 @@ lpfc_sli_abort_iocb(struct lpfc_vport *vport, u16 tgt_id, u64 lun_id, int lpfc_sli_abort_taskmgmt(struct lpfc_vport *vport, struct lpfc_sli_ring *pring, uint16_t tgt_id, uint64_t lun_id, lpfc_ctx_cmd cmd) + __context_unsafe(/*conditional locking*/) { struct lpfc_hba *phba = vport->phba; struct lpfc_io_buf *lpfc_cmd; diff --git a/drivers/scsi/lpfc/lpfc_version.h b/drivers/scsi/lpfc/lpfc_version.h index d6e6e436fbfc..7df63d118234 100644 --- a/drivers/scsi/lpfc/lpfc_version.h +++ b/drivers/scsi/lpfc/lpfc_version.h @@ -20,7 +20,7 @@ * included with this package. * *******************************************************************/ -#define LPFC_DRIVER_VERSION "15.0.0.0" +#define LPFC_DRIVER_VERSION "15.0.0.1" #define LPFC_DRIVER_NAME "lpfc" /* Used for SLI 2/3 */ diff --git a/drivers/scsi/mac53c94.c b/drivers/scsi/mac53c94.c index de2bd860b9d7..613bb204b6af 100644 --- a/drivers/scsi/mac53c94.c +++ b/drivers/scsi/mac53c94.c @@ -107,7 +107,7 @@ static int mac53c94_host_reset(struct scsi_cmnd *cmd) struct dbdma_regs __iomem *dma = state->dma; unsigned long flags; - spin_lock_irqsave(cmd->device->host->host_lock, flags); + spin_lock_irqsave(&cmd->device->host->host_lock, flags); writel((RUN|PAUSE|FLUSH|WAKE) << 16, &dma->control); writeb(CMD_SCSI_RESET, ®s->command); /* assert RST */ @@ -117,7 +117,7 @@ static int mac53c94_host_reset(struct scsi_cmnd *cmd) mac53c94_init(state); writeb(CMD_NOP, ®s->command); - spin_unlock_irqrestore(cmd->device->host->host_lock, flags); + spin_unlock_irqrestore(&cmd->device->host->host_lock, flags); return SUCCESS; } @@ -182,9 +182,9 @@ static irqreturn_t do_mac53c94_interrupt(int irq, void *dev_id) unsigned long flags; struct Scsi_Host *dev = ((struct fsc_state *) dev_id)->current_req->device->host; - spin_lock_irqsave(dev->host_lock, flags); + spin_lock_irqsave(&dev->host_lock, flags); mac53c94_interrupt(irq, dev_id); - spin_unlock_irqrestore(dev->host_lock, flags); + spin_unlock_irqrestore(&dev->host_lock, flags); return IRQ_HANDLED; } diff --git a/drivers/scsi/megaraid.c b/drivers/scsi/megaraid.c index 9476a0d2c72d..a4079866f747 100644 --- a/drivers/scsi/megaraid.c +++ b/drivers/scsi/megaraid.c @@ -1592,9 +1592,11 @@ mega_cmd_done(adapter_t *adapter, u8 completed[], int nstatus, int status) epthru->reqsensearea, 14); cmd->result = SAM_STAT_CHECK_CONDITION; - } else - scsi_build_sense(cmd, 0, - ABORTED_COMMAND, 0, 0); + } else { + scsi_set_sense(cmd, 0, + ABORTED_COMMAND, + NO_ADDITIONAL_SENSE_INFORMATION); + } } break; diff --git a/drivers/scsi/megaraid/mega_common.h b/drivers/scsi/megaraid/mega_common.h index 2ad0aa2f837d..8e58599d5685 100644 --- a/drivers/scsi/megaraid/mega_common.h +++ b/drivers/scsi/megaraid/mega_common.h @@ -37,8 +37,6 @@ #define PCI_CONF_AMISIG64 0xa4 #define MEGA_SCSI_INQ_EVPD 1 -#define MEGA_INVALID_FIELD_IN_CDB 0x24 - /** * scb_t - scsi command control block diff --git a/drivers/scsi/megaraid/megaraid_mbox.c b/drivers/scsi/megaraid/megaraid_mbox.c index ce89032a5a74..b7319282e3c5 100644 --- a/drivers/scsi/megaraid/megaraid_mbox.c +++ b/drivers/scsi/megaraid/megaraid_mbox.c @@ -1577,8 +1577,8 @@ megaraid_mbox_build_cmd(adapter_t *adapter, struct scsi_cmnd *scp, } if (scp->cmnd[1] & MEGA_SCSI_INQ_EVPD) { - scsi_build_sense(scp, 0, ILLEGAL_REQUEST, - MEGA_INVALID_FIELD_IN_CDB, 0); + scsi_set_sense(scp, 0, ILLEGAL_REQUEST, + INVALID_FIELD_IN_CDB); return NULL; } @@ -2311,9 +2311,11 @@ megaraid_mbox_dpc(unsigned long devp) epthru->reqsensearea, 14); scp->result = SAM_STAT_CHECK_CONDITION; - } else - scsi_build_sense(scp, 0, - ABORTED_COMMAND, 0, 0); + } else { + scsi_set_sense(scp, 0, + ABORTED_COMMAND, + NO_ADDITIONAL_SENSE_INFORMATION); + } } break; diff --git a/drivers/scsi/megaraid/megaraid_sas_base.c b/drivers/scsi/megaraid/megaraid_sas_base.c index b95f187297ae..1064c5baae8e 100644 --- a/drivers/scsi/megaraid/megaraid_sas_base.c +++ b/drivers/scsi/megaraid/megaraid_sas_base.c @@ -2274,11 +2274,11 @@ megasas_check_and_restore_queue_depth(struct megasas_instance *instance) && atomic_read(&instance->fw_outstanding) < instance->throttlequeuedepth + 1) { - spin_lock_irqsave(instance->host->host_lock, flags); + spin_lock_irqsave(&instance->host->host_lock, flags); instance->flag &= ~MEGASAS_FW_BUSY; instance->host->can_queue = instance->cur_can_queue; - spin_unlock_irqrestore(instance->host->host_lock, flags); + spin_unlock_irqrestore(&instance->host->host_lock, flags); } } @@ -2955,13 +2955,13 @@ static enum scsi_timeout_action megasas_reset_timer(struct scsi_cmnd *scmd) instance = (struct megasas_instance *)scmd->device->host->hostdata; if (!(instance->flag & MEGASAS_FW_BUSY)) { /* FW is busy, throttle IO */ - spin_lock_irqsave(instance->host->host_lock, flags); + spin_lock_irqsave(&instance->host->host_lock, flags); instance->host->can_queue = instance->throttlequeuedepth; instance->last_time = jiffies; instance->flag |= MEGASAS_FW_BUSY; - spin_unlock_irqrestore(instance->host->host_lock, flags); + spin_unlock_irqrestore(&instance->host->host_lock, flags); } return SCSI_EH_RESET_TIMER; } @@ -3727,7 +3727,7 @@ megasas_complete_cmd(struct megasas_instance *instance, struct megasas_cmd *cmd, if ((opcode == MR_DCMD_LD_MAP_GET_INFO) && (cmd->frame->dcmd.mbox.b[1] == 1)) { fusion->fast_path_io = 0; - spin_lock_irqsave(instance->host->host_lock, flags); + spin_lock_irqsave(&instance->host->host_lock, flags); status = cmd->frame->hdr.cmd_status; instance->map_update_cmd = NULL; if (status != MFI_STAT_OK) { @@ -3737,7 +3737,7 @@ megasas_complete_cmd(struct megasas_instance *instance, struct megasas_cmd *cmd, else { megasas_return_cmd(instance, cmd); spin_unlock_irqrestore( - instance->host->host_lock, + &instance->host->host_lock, flags); break; } @@ -3762,7 +3762,7 @@ megasas_complete_cmd(struct megasas_instance *instance, struct megasas_cmd *cmd, megasas_set_ld_removed_by_fw(instance); megasas_sync_map_info(instance); - spin_unlock_irqrestore(instance->host->host_lock, + spin_unlock_irqrestore(&instance->host->host_lock, flags); break; @@ -3778,7 +3778,7 @@ megasas_complete_cmd(struct megasas_instance *instance, struct megasas_cmd *cmd, if ((opcode == MR_DCMD_SYSTEM_PD_MAP_GET_INFO) && (cmd->frame->dcmd.mbox.b[0] == 1)) { - spin_lock_irqsave(instance->host->host_lock, flags); + spin_lock_irqsave(&instance->host->host_lock, flags); status = cmd->frame->hdr.cmd_status; instance->jbod_seq_cmd = NULL; megasas_return_cmd(instance, cmd); @@ -3791,7 +3791,7 @@ megasas_complete_cmd(struct megasas_instance *instance, struct megasas_cmd *cmd, } else instance->use_seqnum_jbod_fp = false; - spin_unlock_irqrestore(instance->host->host_lock, flags); + spin_unlock_irqrestore(&instance->host->host_lock, flags); break; } @@ -7886,7 +7886,9 @@ megasas_resume(struct device *dev) goto fail_init_mfi; } - if (megasas_get_ctrl_info(instance) != DCMD_SUCCESS) + scoped_guard(mutex, &instance->reset_mutex) + rval = megasas_get_ctrl_info(instance); + if (rval != DCMD_SUCCESS) goto fail_init_mfi; tasklet_init(&instance->isr_tasklet, instance->instancet->tasklet, diff --git a/drivers/scsi/mesh.c b/drivers/scsi/mesh.c index dc1402b321da..1883ba08af7d 100644 --- a/drivers/scsi/mesh.c +++ b/drivers/scsi/mesh.c @@ -1016,9 +1016,9 @@ static irqreturn_t do_mesh_interrupt(int irq, void *dev_id) struct mesh_state *ms = dev_id; struct Scsi_Host *dev = ms->host; - spin_lock_irqsave(dev->host_lock, flags); + spin_lock_irqsave(&dev->host_lock, flags); mesh_interrupt(ms); - spin_unlock_irqrestore(dev->host_lock, flags); + spin_unlock_irqrestore(&dev->host_lock, flags); return IRQ_HANDLED; } @@ -1708,7 +1708,7 @@ static int mesh_host_reset(struct scsi_cmnd *cmd) printk(KERN_DEBUG "mesh_host_reset\n"); - spin_lock_irqsave(ms->host->host_lock, flags); + spin_lock_irqsave(&ms->host->host_lock, flags); if (ms->dma_started) halt_dma(ms); @@ -1734,7 +1734,7 @@ static int mesh_host_reset(struct scsi_cmnd *cmd) /* Complete pending commands */ handle_reset(ms); - spin_unlock_irqrestore(ms->host->host_lock, flags); + spin_unlock_irqrestore(&ms->host->host_lock, flags); return SUCCESS; } @@ -1771,14 +1771,14 @@ static int mesh_suspend(struct macio_dev *mdev, pm_message_t mesg) return 0; scsi_block_requests(ms->host); - spin_lock_irqsave(ms->host->host_lock, flags); + spin_lock_irqsave(&ms->host->host_lock, flags); while(ms->phase != idle) { - spin_unlock_irqrestore(ms->host->host_lock, flags); + spin_unlock_irqrestore(&ms->host->host_lock, flags); msleep(10); - spin_lock_irqsave(ms->host->host_lock, flags); + spin_lock_irqsave(&ms->host->host_lock, flags); } ms->phase = sleeping; - spin_unlock_irqrestore(ms->host->host_lock, flags); + spin_unlock_irqrestore(&ms->host->host_lock, flags); disable_irq(ms->meshintr); set_mesh_power(ms, 0); @@ -1795,9 +1795,9 @@ static int mesh_resume(struct macio_dev *mdev) set_mesh_power(ms, 1); mesh_init(ms); - spin_lock_irqsave(ms->host->host_lock, flags); + spin_lock_irqsave(&ms->host->host_lock, flags); mesh_start(ms); - spin_unlock_irqrestore(ms->host->host_lock, flags); + spin_unlock_irqrestore(&ms->host->host_lock, flags); enable_irq(ms->meshintr); scsi_unblock_requests(ms->host); @@ -1818,7 +1818,7 @@ static int mesh_shutdown(struct macio_dev *mdev) unsigned long flags; printk(KERN_INFO "resetting MESH scsi bus(es)\n"); - spin_lock_irqsave(ms->host->host_lock, flags); + spin_lock_irqsave(&ms->host->host_lock, flags); mr = ms->mesh; out_8(&mr->intr_mask, 0); out_8(&mr->interrupt, INT_ERROR | INT_EXCEPTION | INT_CMDDONE); @@ -1826,7 +1826,7 @@ static int mesh_shutdown(struct macio_dev *mdev) mesh_flush_io(mr); udelay(30); out_8(&mr->bus_status1, 0); - spin_unlock_irqrestore(ms->host->host_lock, flags); + spin_unlock_irqrestore(&ms->host->host_lock, flags); return 0; } diff --git a/drivers/scsi/mpi3mr/mpi/mpi30_cnfg.h b/drivers/scsi/mpi3mr/mpi/mpi30_cnfg.h index 33dd303c97bb..7cf16a5c15b7 100644 --- a/drivers/scsi/mpi3mr/mpi/mpi30_cnfg.h +++ b/drivers/scsi/mpi3mr/mpi/mpi30_cnfg.h @@ -72,6 +72,12 @@ #define MPI3_SECURITY_PGAD_SLOT_GROUP_SHIFT (8) #define MPI3_SECURITY_PGAD_SLOT_MASK (0x000000ff) #define MPI3_INSTANCE_PGAD_INSTANCE_MASK (0x0000ffff) +#define MPI3_INSTANCE_PGAD_INSTANCE_SHIFT (0) +#define MPI3_INTERFACE_PGAD_INTERFACE_MASK (0x0000000f) +#define MPI3_INTERFACE_PGAD_INTERFACE_SHIFT (0) +#define MPI3_INTERFACE_PGAD_INTERFACE_MPI (0) +#define MPI3_INTERFACE_PGAD_INTERFACE_NVME_VD (1) +#define MPI3_INTERFACE_PGAD_INTERFACE_NVME_PD (2) struct mpi3_config_request { __le16 host_tag; u8 ioc_use_only02; @@ -492,10 +498,31 @@ struct mpi3_man10_istwi_ctrlr_entry { }; #define MPI3_MAN10_ISTWI_CTRLR_FLAGS_BUS_SPEED_MASK (0x000c) -#define MPI3_MAN10_ISTWI_CTRLR_FLAGS_BUS_SPEED_100K (0x0000) -#define MPI3_MAN10_ISTWI_CTRLR_FLAGS_BUS_SPEED_400K (0x0004) +#define MPI3_MAN10_ISTWI_CTRLR_FLAGS_BUS_SPEED_100_KHZ (0x0000) +#define MPI3_MAN10_ISTWI_CTRLR_FLAGS_BUS_SPEED_400_KHZ (0x0004) #define MPI3_MAN10_ISTWI_CTRLR_FLAGS_TARGET_ENABLED (0x0002) #define MPI3_MAN10_ISTWI_CTRLR_FLAGS_INITIATOR_ENABLED (0x0001) +#define MPI3_MAN10_ISTWI_CTRLR_FLAGS_I2C_GLITCH_FLTR_MASK (0xc000) +#define MPI3_MAN10_ISTWI_CTRLR_FLAGS_I2C_GLITCH_FLTR_SHIFT (14) +#define MPI3_MAN10_ISTWI_CTRLR_FLAGS_I2C_GLITCH_FLTR_50_NS (0x0000) +#define MPI3_MAN10_ISTWI_CTRLR_FLAGS_I2C_GLITCH_FLTR_10_NS (0x4000) +#define MPI3_MAN10_ISTWI_CTRLR_FLAGS_I2C_GLITCH_FLTR_5_NS (0x8000) +#define MPI3_MAN10_ISTWI_CTRLR_FLAGS_I2C_GLITCH_FLTR_0_NS (0xc000) +#define MPI3_MAN10_ISTWI_CTRLR_FLAGS_BUS_TYPE_MASK (0x3000) +#define MPI3_MAN10_ISTWI_CTRLR_FLAGS_BUS_TYPE_SHIFT (12) +#define MPI3_MAN10_ISTWI_CTRLR_FLAGS_BUS_TYPE_I2C (0x0000) +#define MPI3_MAN10_ISTWI_CTRLR_FLAGS_BUS_TYPE_I3C (0x1000) +#define MPI3_MAN10_ISTWI_CTRLR_FLAGS_BUS_TYPE_AUTO (0x2000) +#define MPI3_MAN10_ISTWI_CTRLR_FLAGS_I3C_MAX_DATA_RATE_MASK (0x0e00) +#define MPI3_MAN10_ISTWI_CTRLR_FLAGS_I3C_MAX_DATA_RATE_SHIFT (9) +#define MPI3_MAN10_ISTWI_CTRLR_FLAGS_I3C_MAX_DATA_RATE_12_5_MHZ (0x0000) +#define MPI3_MAN10_ISTWI_CTRLR_FLAGS_I3C_MAX_DATA_RATE_8_MHZ (0x0200) +#define MPI3_MAN10_ISTWI_CTRLR_FLAGS_I3C_MAX_DATA_RATE_6_MHZ (0x0400) +#define MPI3_MAN10_ISTWI_CTRLR_FLAGS_I3C_MAX_DATA_RATE_4_MHZ (0x0600) +#define MPI3_MAN10_ISTWI_CTRLR_FLAGS_I3C_MAX_DATA_RATE_2_MHZ (0x0800) +#define MPI3_MAN10_ISTWI_CTRLR_FLAGS_BUS_SPEED_MASK (0x000c) +#define MPI3_MAN10_ISTWI_CTRLR_FLAGS_BUS_SPEED_SHIFT (0) + #ifndef MPI3_MAN10_ISTWI_CTRLR_MAX #define MPI3_MAN10_ISTWI_CTRLR_MAX (1) #endif @@ -1027,6 +1054,16 @@ struct mpi3_io_unit_page5 { #define MPI3_IOUNIT5_DEVICE_SHUTDOWN_SWITCH_ATTACHED (0x02) #define MPI3_IOUNIT5_DEVICE_SHUTDOWN_DIRECT_AND_EXPANDER (0x03) #define MPI3_IOUNIT5_DEVICE_SHUTDOWN_DIRECT_AND_SWITCH (0x03) +#define MPI3_IOUNIT5_DEVICE_SHUTDOWN_HDD_SPINDOWN_MASK (0xc000) +#define MPI3_IOUNIT5_DEVICE_SHUTDOWN_HDD_SPINDOWN_NONE (0x0000) +#define MPI3_IOUNIT5_DEVICE_SHUTDOWN_HDD_SPINDOWN_ALL (0x4000) +#define MPI3_IOUNIT5_DEVICE_SHUTDOWN_HDD_SPINDOWN_FILTERED (0x8000) +#define MPI3_IOUNIT5_DEVICE_SHUTDOWN_HDD_SPINDOWN_RESERVED (0xc000) +#define MPI3_IOUNIT5_DEVICE_SHUTDOWN_SYNC_CACHE_MASK (0x3000) +#define MPI3_IOUNIT5_DEVICE_SHUTDOWN_SYNC_CACHE_ALL (0x0000) +#define MPI3_IOUNIT5_DEVICE_SHUTDOWN_SYNC_CACHE_FILTERED (0x1000) +#define MPI3_IOUNIT5_DEVICE_SHUTDOWN_SYNC_CACHE_NONE (0x2000) +#define MPI3_IOUNIT5_DEVICE_SHUTDOWN_SYNC_CACHE_RESERVED (0x3000) #define MPI3_IOUNIT5_DEVICE_SHUTDOWN_SATA_HDD_MASK (0x0300) #define MPI3_IOUNIT5_DEVICE_SHUTDOWN_SATA_HDD_SHIFT (8) #define MPI3_IOUNIT5_DEVICE_SHUTDOWN_SAS_HDD_MASK (0x00c0) @@ -1069,7 +1106,8 @@ struct mpi3_io_unit_page8 { struct mpi3_config_page_header header; u8 sb_mode; u8 sb_state; - __le16 reserved0a; + u8 flags; + u8 reserved0b; u8 num_slots; u8 slots_available; u8 current_key_encryption_algo; @@ -1088,6 +1126,8 @@ struct mpi3_io_unit_page8 { #define MPI3_IOUNIT8_SBSTATE_SVN_UPDATE_PENDING (0x04) #define MPI3_IOUNIT8_SBSTATE_KEY_UPDATE_PENDING (0x02) #define MPI3_IOUNIT8_SBSTATE_SECURE_BOOT_ENABLED (0x01) +#define MPI3_IOUNIT8_FLAGS_FWQR_CAPABLE (0x80) +#define MPI3_IOUNIT8_FLAGS_FWQR_SECURED (0x40) #define MPI3_IOUNIT8_SBMODE_CURRENT_KEY_IOUNIT17 (0x10) #define MPI3_IOUNIT8_SBMODE_HARD_SECURE_RECERTIFIED (0x08) struct mpi3_io_unit_page9 { @@ -1174,10 +1214,16 @@ struct mpi3_io_unit_page12 { #define MPI3_IOUNIT12_FLAGS_NUMPASSES_32 (0x00000200) #define MPI3_IOUNIT12_FLAGS_NUMPASSES_64 (0x00000300) #define MPI3_IOUNIT12_FLAGS_PASSPERIOD_MASK (0x00000003) +#define MPI3_IOUNIT12_FLAGS_PASSPERIOD_SHIFT (0) #define MPI3_IOUNIT12_FLAGS_PASSPERIOD_DISABLED (0x00000000) #define MPI3_IOUNIT12_FLAGS_PASSPERIOD_500US (0x00000001) #define MPI3_IOUNIT12_FLAGS_PASSPERIOD_1MS (0x00000002) #define MPI3_IOUNIT12_FLAGS_PASSPERIOD_2MS (0x00000003) +#define MPI3_IOUNIT12_FLAGS_INTERFACE_MASK (0x0000000c) +#define MPI3_IOUNIT12_FLAGS_INTERFACE_SHIFT (2) +#define MPI3_IOUNIT12_FLAGS_INTERFACE_MPI (0x00000000) +#define MPI3_IOUNIT12_FLAGS_INTERFACE_NVME_VD (0x00000004) +#define MPI3_IOUNIT12_FLAGS_INTERFACE_NVME_PD (0x00000008) #ifndef MPI3_IOUNIT13_FUNC_MAX #define MPI3_IOUNIT13_FUNC_MAX (1) #endif @@ -1238,6 +1284,7 @@ struct mpi3_io_unit_page15 { #define MPI3_IOUNIT15_PAGEVERSION (0x00) #define MPI3_IOUNIT15_FLAGS_EPRINIT_INITREQUIRED (0x04) #define MPI3_IOUNIT15_FLAGS_EPRSUPPORT_MASK (0x03) +#define MPI3_IOUNIT15_FLAGS_EPRSUPPORT_SHIFT (0) #define MPI3_IOUNIT15_FLAGS_EPRSUPPORT_NOT_SUPPORTED (0x00) #define MPI3_IOUNIT15_FLAGS_EPRSUPPORT_WITHOUT_POWER_BRAKE_GPIO (0x01) #define MPI3_IOUNIT15_FLAGS_EPRSUPPORT_WITH_POWER_BRAKE_GPIO (0x02) @@ -1255,6 +1302,9 @@ struct mpi3_io_unit_page17 { __le32 current_key[]; }; #define MPI3_IOUNIT17_PAGEVERSION (0x00) +#define MPI3_IOUNIT17_FLAGS_KEYROOT_MASK (0x01) +#define MPI3_IOUNIT17_FLAGS_KEYROOT_HW (0x00) +#define MPI3_IOUNIT17_FLAGS_KEYROOT_FW (0x01) struct mpi3_io_unit_page18 { struct mpi3_config_page_header header; u8 flags; @@ -1640,11 +1690,28 @@ struct mpi3_security_page3 { }; #define MPI3_SECURITY3_PAGEVERSION (0x00) -#define MPI3_SECURITY3_FLAGS_TYPE_MASK (0x0f) +#define MPI3_SECURITY3_FLAGS_TYPE_MASK (0x1f) #define MPI3_SECURITY3_FLAGS_TYPE_SHIFT (0) #define MPI3_SECURITY3_FLAGS_TYPE_NOT_VALID (0) #define MPI3_SECURITY3_FLAGS_TYPE_MLDSA_PRIVATE (1) #define MPI3_SECURITY3_FLAGS_TYPE_MLDSA_PUBLIC (2) +union mpi3_security_digest { + __le32 dword[16]; + __le16 word[32]; + u8 byte[64]; +}; +struct mpi3_security_page4 { + struct mpi3_config_page_header header; + __le32 reserved08[2]; + union mpi3_security_mac mac; + union mpi3_security_nonce nonce; + u8 num_digests; + u8 hash_algorithm; + __le16 reserved92; + __le32 reserved94[3]; + union mpi3_security_digest digest[]; +}; +#define MPI3_SECURITY4_PAGEVERSION (0x00) struct mpi3_security_page10 { struct mpi3_config_page_header header; __le32 reserved08[2]; @@ -2074,7 +2141,7 @@ struct mpi3_sas_phy3_phy_event_config { #define MPI3_SASPHY3_EVENT_CODE_LCCONN_TIME (0xd5) #define MPI3_SASPHY3_EVENT_CODE_SSP_TX_START_TRANSMIT (0xd6) #define MPI3_SASPHY3_EVENT_CODE_SATA_TX_START (0xd7) -#define MPI3_SASPHY3_EVENT_CODE_SMP_TX_START_TRANSMT (0xd8) +#define MPI3_SASPHY3_EVENT_CODE_SMP_TX_START_TRANSMIT (0xd8) #define MPI3_SASPHY3_EVENT_CODE_TX_SMP_BREAK_CONN (0xd9) #define MPI3_SASPHY3_EVENT_CODE_SSP_RX_START_RECEIVE (0xda) #define MPI3_SASPHY3_EVENT_CODE_SATA_RX_START_RECEIVE (0xdb) diff --git a/drivers/scsi/mpi3mr/mpi/mpi30_image.h b/drivers/scsi/mpi3mr/mpi/mpi30_image.h index 62ddf094d46c..5fa09fa79358 100644 --- a/drivers/scsi/mpi3mr/mpi/mpi30_image.h +++ b/drivers/scsi/mpi3mr/mpi/mpi30_image.h @@ -18,7 +18,7 @@ struct mpi3_hash_exclusion_format { __le32 size; }; -#define MPI3_IMAGE_HASH_EXCUSION_NUM (4) +#define MPI3_IMAGE_HASH_EXCLUSION_NUM (4) struct mpi3_component_image_header { __le32 signature0; __le32 load_address; @@ -42,7 +42,7 @@ struct mpi3_component_image_header { union mpi3_version_union rmc_interface_version; union mpi3_version_union etp_interface_version; struct mpi3_comp_image_version component_image_version; - struct mpi3_hash_exclusion_format hash_exclusion[MPI3_IMAGE_HASH_EXCUSION_NUM]; + struct mpi3_hash_exclusion_format hash_exclusion[MPI3_IMAGE_HASH_EXCLUSION_NUM]; __le32 next_image_header_offset; union mpi3_version_union security_version; __le32 reserved84[31]; @@ -347,7 +347,8 @@ struct mpi3_encrypted_hash_entry { struct mpi3_encrypted_hash_data { u8 image_version; u8 num_hash; - __le16 reserved02; + u8 fw_num_hash; + u8 reserved03; __le32 reserved04; struct mpi3_encrypted_hash_entry encrypted_hash_entry[MPI3_ENCRYPTED_HASH_ENTRY_MAX]; }; diff --git a/drivers/scsi/mpi3mr/mpi/mpi30_ioc.h b/drivers/scsi/mpi3mr/mpi/mpi30_ioc.h index 68efa0d51345..aa42fba7f930 100644 --- a/drivers/scsi/mpi3mr/mpi/mpi30_ioc.h +++ b/drivers/scsi/mpi3mr/mpi/mpi30_ioc.h @@ -428,10 +428,10 @@ struct mpi3_event_data_sas_discovery { #define MPI3_EVENT_SAS_DISC_FLAGS_IN_PROGRESS (0x01) #define MPI3_EVENT_SAS_DISC_RC_STARTED (0x01) #define MPI3_EVENT_SAS_DISC_RC_COMPLETED (0x02) -#define MPI3_SAS_DISC_STATUS_MAX_ENCLOSURES_EXCEED (0x80000000) -#define MPI3_SAS_DISC_STATUS_MAX_EXPANDERS_EXCEED (0x40000000) -#define MPI3_SAS_DISC_STATUS_MAX_DEVICES_EXCEED (0x20000000) -#define MPI3_SAS_DISC_STATUS_MAX_TOPO_PHYS_EXCEED (0x10000000) +#define MPI3_SAS_DISC_STATUS_MAX_ENCLOSURES_EXCEEDED (0x80000000) +#define MPI3_SAS_DISC_STATUS_MAX_EXPANDERS_EXCEEDED (0x40000000) +#define MPI3_SAS_DISC_STATUS_MAX_DEVICES_EXCEEDED (0x20000000) +#define MPI3_SAS_DISC_STATUS_MAX_TOPO_PHYS_EXCEEDED (0x10000000) #define MPI3_SAS_DISC_STATUS_INVALID_CEI (0x00010000) #define MPI3_SAS_DISC_STATUS_FECEI_MISMATCH (0x00008000) #define MPI3_SAS_DISC_STATUS_MULTIPLE_DEVICES_IN_SLOT (0x00004000) @@ -965,7 +965,7 @@ struct mpi3_ci_download_reply { u8 flags; u8 cache_dirty; u8 pending_count; - u8 reserved13; + u8 additional_flags; }; #define MPI3_CI_DOWNLOAD_FLAGS_DOWNLOAD_IN_PROGRESS (0x80) @@ -979,6 +979,11 @@ struct mpi3_ci_download_reply { #define MPI3_CI_DOWNLOAD_FLAGS_ACTIVATION_STATUS_ONLINE_PENDING (0x04) #define MPI3_CI_DOWNLOAD_FLAGS_ACTIVATION_STATUS_OFFLINE_PENDING (0x06) #define MPI3_CI_DOWNLOAD_FLAGS_COMPATIBLE (0x01) +#define MPI3_CI_DOWNLOAD_ADDITIONALFLAGS_REDUNDANCYRESTORATION_MASK (0x03) +#define MPI3_CI_DOWNLOAD_ADDITIONALFLAGS_REDUNDANCYRESTORATION_SHIFT (0) +#define MPI3_CI_DOWNLOAD_ADDITIONALFLAGS_REDUNDANCYRESTORATION_NONE (0x00) +#define MPI3_CI_DOWNLOAD_ADDITIONALFLAGS_REDUNDANCYRESTORATION_PRIMARY (0x01) +#define MPI3_CI_DOWNLOAD_ADDITIONALFLAGS_REDUNDANCYRESTORATION_SECONDARY (0x02) struct mpi3_ci_upload_request { __le16 host_tag; u8 ioc_use_only02; diff --git a/drivers/scsi/mpi3mr/mpi/mpi30_transport.h b/drivers/scsi/mpi3mr/mpi/mpi30_transport.h index 290a1f5c2924..794ecc778945 100644 --- a/drivers/scsi/mpi3mr/mpi/mpi30_transport.h +++ b/drivers/scsi/mpi3mr/mpi/mpi30_transport.h @@ -18,7 +18,7 @@ union mpi3_version_union { #define MPI3_VERSION_MAJOR (3) #define MPI3_VERSION_MINOR (0) -#define MPI3_VERSION_UNIT (39) +#define MPI3_VERSION_UNIT (41) #define MPI3_VERSION_DEV (0) #define MPI3_DEVHANDLE_INVALID (0xffff) struct mpi3_sysif_oper_queue_indexes { diff --git a/drivers/scsi/mpi3mr/mpi3mr.h b/drivers/scsi/mpi3mr/mpi3mr.h index c25525fe0671..d6e16707fd97 100644 --- a/drivers/scsi/mpi3mr/mpi3mr.h +++ b/drivers/scsi/mpi3mr/mpi3mr.h @@ -56,8 +56,8 @@ extern struct list_head mrioc_list; extern int prot_mask; extern atomic64_t event_counter; -#define MPI3MR_DRIVER_VERSION "8.17.0.3.50" -#define MPI3MR_DRIVER_RELDATE "09-January-2026" +#define MPI3MR_DRIVER_VERSION "8.18.0.8.50" +#define MPI3MR_DRIVER_RELDATE "26-June-2026" #define MPI3MR_DRIVER_NAME "mpi3mr" #define MPI3MR_DRIVER_LICENSE "GPL" @@ -125,6 +125,7 @@ extern atomic64_t event_counter; #define MPI3MR_RESETTM_TIMEOUT 60 #define MPI3MR_RESET_HOST_IOWAIT_TIMEOUT 5 #define MPI3MR_TSUPDATE_INTERVAL 900 +#define MPI3MR_EARLY_TSUPDATE_SECONDS 60 #define MPI3MR_DEFAULT_SHUTDOWN_TIME 120 #define MPI3MR_RAID_ERRREC_RESET_TIMEOUT 180 #define MPI3MR_PREPARE_FOR_RESET_TIMEOUT 180 @@ -168,6 +169,7 @@ extern atomic64_t event_counter; #define MPI3MR_DEFAULT_MDTS (128 * 1024) #define MPI3MR_DEFAULT_PGSZEXP (12) +#define MPI3MR_MAX_PGSZEXP (27) /* Command retry count definitions */ #define MPI3MR_DEV_RMHS_RETRY_COUNT 3 @@ -177,7 +179,7 @@ extern atomic64_t event_counter; #define MPI3MR_DEFAULT_SDEV_QD 32 /* Definitions for Threaded IRQ poll*/ -#define MPI3MR_IRQ_POLL_SLEEP 20 +#define MPI3MR_IRQ_POLL_SLEEP 2 #define MPI3MR_IRQ_POLL_TRIGGER_IOCOUNT 8 /* Definitions for the controller security status*/ @@ -1118,6 +1120,7 @@ struct scmd_priv { * @evtack_cmds_bitmap: Event Ack bitmap * @delayed_evtack_cmds_list: Delayed event acknowledgment list * @ts_update_counter: Timestamp update counter + * @early_ts_sync_done: Early (1 min) timestamp sync completed after load * @ts_update_interval: Timestamp update interval * @reset_in_progress: Reset in progress flag * @unrecoverable: Controller unrecoverable flag @@ -1318,6 +1321,7 @@ struct mpi3mr_ioc { struct list_head delayed_evtack_cmds_list; u16 ts_update_counter; + u8 early_ts_sync_done; u16 ts_update_interval; u8 reset_in_progress; u8 unrecoverable; @@ -1410,6 +1414,9 @@ struct mpi3mr_ioc { struct dma_pool *trace_buf_pool; struct segments *trace_buf; u8 invalid_io_comp; + bool is_unload; + bool skip_dev_shutdown_on_unload; + }; diff --git a/drivers/scsi/mpi3mr/mpi3mr_app.c b/drivers/scsi/mpi3mr/mpi3mr_app.c index 1353a8ff9c85..eadad89bfcfb 100644 --- a/drivers/scsi/mpi3mr/mpi3mr_app.c +++ b/drivers/scsi/mpi3mr/mpi3mr_app.c @@ -141,25 +141,27 @@ void mpi3mr_alloc_diag_bufs(struct mpi3mr_ioc *mrioc) trace_min_size = fw_min_size = MPI3MR_DEFAULT_HDB_MIN_SZ; } else { - trace_size = driver_pg1.host_diag_trace_max_size * 1024; - trace_dec_size = driver_pg1.host_diag_trace_decrement_size + trace_size = le16_to_cpu(driver_pg1.host_diag_trace_max_size) * 1024; + trace_dec_size = le16_to_cpu(driver_pg1.host_diag_trace_decrement_size) * 1024; - trace_min_size = driver_pg1.host_diag_trace_min_size * 1024; - fw_size = driver_pg1.host_diag_fw_max_size * 1024; - fw_dec_size = driver_pg1.host_diag_fw_decrement_size * 1024; - fw_min_size = driver_pg1.host_diag_fw_min_size * 1024; + trace_min_size = le16_to_cpu(driver_pg1.host_diag_trace_min_size) * 1024; + fw_size = le16_to_cpu(driver_pg1.host_diag_fw_max_size) * 1024; + fw_dec_size = le16_to_cpu(driver_pg1.host_diag_fw_decrement_size) * 1024; + fw_min_size = le16_to_cpu(driver_pg1.host_diag_fw_min_size) * 1024; dprint_init(mrioc, "%s:trace diag buffer sizes read from driver\n" "page1: maximum size = %dKB, decrement size = %dKB\n" - ", minimum size = %dKB\n", __func__, driver_pg1.host_diag_trace_max_size, - driver_pg1.host_diag_trace_decrement_size, - driver_pg1.host_diag_trace_min_size); + ", minimum size = %dKB\n", __func__, + le16_to_cpu(driver_pg1.host_diag_trace_max_size), + le16_to_cpu(driver_pg1.host_diag_trace_decrement_size), + le16_to_cpu(driver_pg1.host_diag_trace_min_size)); dprint_init(mrioc, "%s:firmware diag buffer sizes read from driver\n" "page1: maximum size = %dKB, decrement size = %dKB\n" - ", minimum size = %dKB\n", __func__, driver_pg1.host_diag_fw_max_size, - driver_pg1.host_diag_fw_decrement_size, - driver_pg1.host_diag_fw_min_size); + ", minimum size = %dKB\n", __func__, + le16_to_cpu(driver_pg1.host_diag_fw_max_size), + le16_to_cpu(driver_pg1.host_diag_fw_decrement_size), + le16_to_cpu(driver_pg1.host_diag_fw_min_size)); if ((trace_size == 0) && (fw_size == 0)) return; } @@ -179,6 +181,12 @@ void mpi3mr_alloc_diag_bufs(struct mpi3mr_ioc *mrioc) mpi3mr_alloc_trace_buffer(mrioc, trace_size)) { retry = true; + + if (!trace_dec_size || trace_dec_size > trace_size) { + retry = false; + goto retry_fw; + } + trace_size -= trace_dec_size; dprint_init(mrioc, "trace diag buffer allocation failed\n" "retrying smaller size %dKB\n", trace_size / 1024); @@ -211,11 +219,13 @@ void mpi3mr_alloc_diag_bufs(struct mpi3mr_ioc *mrioc) diag_buffer->size = fw_size; } else { retry = true; - fw_size -= fw_dec_size; - dprint_init(mrioc, "%s:trace diag buffer allocation failed,\n" - "retrying smaller size %dKB\n", - __func__, fw_size / 1024); - goto retry_fw; + if (fw_dec_size && fw_dec_size <= fw_size) { + fw_size -= fw_dec_size; + dprint_init(mrioc, "%s:trace diag buffer allocation failed,\n" + "retrying smaller size %dKB\n", + __func__, fw_size / 1024); + goto retry_fw; + } } } } @@ -1244,7 +1254,7 @@ static long mpi3mr_bsg_query_hdb(struct mpi3mr_ioc *mrioc, length = (sizeof(*hbd_status) + ((MPI3MR_MAX_NUM_HDB - 1) * sizeof(*hbd_status_entry))); - hbd_status = kmalloc(length, GFP_KERNEL); + hbd_status = kzalloc(length, GFP_KERNEL); if (!hbd_status) return -ENOMEM; hbd_status_entry = &hbd_status->entry[0]; @@ -1466,7 +1476,8 @@ static long mpi3mr_bsg_pel_enable(struct mpi3mr_ioc *mrioc, static long mpi3mr_get_all_tgt_info(struct mpi3mr_ioc *mrioc, struct bsg_job *job) { - u16 num_devices = 0, i = 0, size; + u16 num_devices = 0, i = 0; + size_t size; unsigned long flags; struct mpi3mr_tgt_dev *tgtdev; struct mpi3mr_device_map_info *devmap_info = NULL; @@ -1492,8 +1503,8 @@ static long mpi3mr_get_all_tgt_info(struct mpi3mr_ioc *mrioc, return 0; } - kern_entrylen = num_devices * sizeof(*devmap_info); - size = sizeof(u64) + kern_entrylen; + kern_entrylen = (uint32_t)num_devices * sizeof(*devmap_info); + size = sizeof(u64) + (size_t)kern_entrylen; alltgt_info = kzalloc(size, GFP_KERNEL); if (!alltgt_info) return -ENOMEM; @@ -2384,7 +2395,7 @@ static long mpi3mr_bsg_process_mpt_cmds(struct bsg_job *job) long rval = -EINVAL; struct mpi3mr_ioc *mrioc = NULL; u8 *mpi_req = NULL, *sense_buff_k = NULL; - u8 mpi_msg_size = 0; + u32 mpi_msg_size = 0; struct mpi3mr_bsg_packet *bsg_req = NULL; struct mpi3mr_bsg_mptcmd *karg; struct mpi3mr_buf_entry *buf_entries = NULL; @@ -2538,7 +2549,15 @@ static long mpi3mr_bsg_process_mpt_cmds(struct bsg_job *job) rval = -EINVAL; goto out; } - memcpy(mpi_req, sgl_iter, buf_entries->buf_len); + if (sgl_iter + mpi_msg_size > + dout_buf + job->request_payload.payload_len) { + dprint_bsg_err(mrioc, "%s: MPI request buf exceeds dout_buf\n", + __func__); + mutex_unlock(&mrioc->bsg_cmds.mutex); + rval = -EINVAL; + goto out; + } + memcpy(mpi_req, sgl_iter, mpi_msg_size); break; default: invalid_be = 1; @@ -2737,10 +2756,12 @@ static long mpi3mr_bsg_process_mpt_cmds(struct bsg_job *job) } if (block_io) { tgtdev = mpi3mr_get_tgtdev_by_handle(mrioc, dev_handle); - if (tgtdev && tgtdev->starget && tgtdev->starget->hostdata) { - stgt_priv = (struct mpi3mr_stgt_priv_data *) - tgtdev->starget->hostdata; - atomic_inc(&stgt_priv->block_io); + if (tgtdev) { + if (tgtdev->starget && tgtdev->starget->hostdata) { + stgt_priv = (struct mpi3mr_stgt_priv_data *) + tgtdev->starget->hostdata; + atomic_inc(&stgt_priv->block_io); + } mpi3mr_tgtdev_put(tgtdev); } } @@ -2774,6 +2795,8 @@ static long mpi3mr_bsg_process_mpt_cmds(struct bsg_job *job) dprint_bsg_err(mrioc, "%s: posting bsg request is failed\n", __func__); rval = -EAGAIN; + if (block_io && stgt_priv) + atomic_dec(&stgt_priv->block_io); goto out_unlock; } wait_for_completion_timeout(&mrioc->bsg_cmds.done, @@ -2935,7 +2958,8 @@ static long mpi3mr_bsg_process_mpt_cmds(struct bsg_job *job) void mpi3mr_app_save_logdata_th(struct mpi3mr_ioc *mrioc, char *event_data, u16 event_data_size) { - u32 index = mrioc->logdata_buf_idx, sz; + u32 index = mrioc->logdata_buf_idx; + size_t entry_payload_len, sz; struct mpi3mr_logdata_entry *entry; if (!(mrioc->logdata_buf)) @@ -2944,7 +2968,12 @@ void mpi3mr_app_save_logdata_th(struct mpi3mr_ioc *mrioc, char *event_data, entry = (struct mpi3mr_logdata_entry *) (mrioc->logdata_buf + (index * mrioc->logdata_entry_sz)); entry->valid_entry = 1; - sz = min(mrioc->logdata_entry_sz, event_data_size); + if (mrioc->logdata_entry_sz > MPI3MR_BSG_LOGDATA_ENTRY_HEADER_SZ) + entry_payload_len = (size_t)mrioc->logdata_entry_sz - + MPI3MR_BSG_LOGDATA_ENTRY_HEADER_SZ; + else + entry_payload_len = 0; + sz = min_t(size_t, entry_payload_len, event_data_size); memcpy(entry->data, event_data, sz); mrioc->logdata_buf_idx = ((++index) % MPI3MR_BSG_LOGDATA_MAX_ENTRIES); @@ -3053,7 +3082,7 @@ void mpi3mr_bsg_init(struct mpi3mr_ioc *mrioc) } q = bsg_setup_queue(bsg_dev, dev_name(bsg_dev), &lim, - mpi3mr_bsg_request, NULL, 0); + mpi3mr_bsg_request, NULL, 0, SCSI_SENSE_BUFFERSIZE); if (IS_ERR(q)) { ioc_err(mrioc, "%s: bsg registration failed\n", dev_name(bsg_dev)); diff --git a/drivers/scsi/mpi3mr/mpi3mr_fw.c b/drivers/scsi/mpi3mr/mpi3mr_fw.c index 681868716ebd..f0d3cd398dd0 100644 --- a/drivers/scsi/mpi3mr/mpi3mr_fw.c +++ b/drivers/scsi/mpi3mr/mpi3mr_fw.c @@ -124,11 +124,16 @@ void mpi3mr_build_zero_len_sge(void *paddr) void *mpi3mr_get_reply_virt_addr(struct mpi3mr_ioc *mrioc, dma_addr_t phys_addr) { + u64 offset; + if (!phys_addr) return NULL; + offset = phys_addr - mrioc->reply_buf_dma; + if ((phys_addr < mrioc->reply_buf_dma) || - (phys_addr > mrioc->reply_buf_dma_max_address)) + (phys_addr > mrioc->reply_buf_dma_max_address - mrioc->reply_sz) || + do_div(offset, mrioc->reply_sz)) return NULL; return mrioc->reply_buf + (phys_addr - mrioc->reply_buf_dma); @@ -137,9 +142,19 @@ void *mpi3mr_get_reply_virt_addr(struct mpi3mr_ioc *mrioc, void *mpi3mr_get_sensebuf_virt_addr(struct mpi3mr_ioc *mrioc, dma_addr_t phys_addr) { + u64 offset; + if (!phys_addr) return NULL; + offset = phys_addr - mrioc->sense_buf_dma; + + if (phys_addr < mrioc->sense_buf_dma || + (phys_addr > mrioc->sense_buf_dma + + (mrioc->num_sense_bufs * MPI3MR_SENSE_BUF_SZ) - MPI3MR_SENSE_BUF_SZ) || + do_div(offset, MPI3MR_SENSE_BUF_SZ)) + return NULL; + return mrioc->sense_buf + (phys_addr - mrioc->sense_buf_dma); } @@ -404,7 +419,8 @@ static void mpi3mr_process_admin_reply_desc(struct mpi3mr_ioc *mrioc, scsi_normalize_sense(sense_buf, sense_count, &sshdr); mpi3mr_scsisense_trigger(mrioc, sshdr.sense_key, - sshdr.asc, sshdr.ascq); + scsi_sense_asc(&sshdr), + scsi_sense_ascq(&sshdr)); } } mpi3mr_reply_trigger(mrioc, masked_ioc_status, ioc_loginfo); @@ -474,6 +490,12 @@ int mpi3mr_process_admin_reply_q(struct mpi3mr_ioc *mrioc) return 0; } + /* + * Ensure that the descriptor payload is read only after + * the phase bit check is complete. + */ + dma_rmb(); + do { if (mrioc->unrecoverable || mrioc->io_admin_reset_sync) break; @@ -494,6 +516,13 @@ int mpi3mr_process_admin_reply_q(struct mpi3mr_ioc *mrioc) if ((le16_to_cpu(reply_desc->reply_flags) & MPI3_REPLY_DESCRIPT_FLAGS_PHASE_MASK) != exp_phase) break; + + /* + * Ensure that the descriptor payload is read only after + * the phase bit check is complete. + */ + dma_rmb(); + if (threshold_comps == MPI3MR_THRESHOLD_REPLY_COUNT) { writel(admin_reply_ci, &mrioc->sysif_regs->admin_reply_queue_ci); @@ -554,6 +583,9 @@ int mpi3mr_process_op_reply_q(struct mpi3mr_ioc *mrioc, struct mpi3_default_reply_descriptor *reply_desc; u16 req_q_idx = 0, reply_qidx, threshold_comps = 0; + if (!op_reply_q) + return 0; + reply_qidx = op_reply_q->qid - 1; if (!atomic_add_unless(&op_reply_q->in_use, 1, 1)) @@ -565,15 +597,33 @@ int mpi3mr_process_op_reply_q(struct mpi3mr_ioc *mrioc, reply_desc = mpi3mr_get_reply_desc(op_reply_q, reply_ci); if ((le16_to_cpu(reply_desc->reply_flags) & MPI3_REPLY_DESCRIPT_FLAGS_PHASE_MASK) != exp_phase) { + /* Recheck under in_use before releasing, to avoid a reclaim race */ + dma_rmb(); + if ((le16_to_cpu(reply_desc->reply_flags) & + MPI3_REPLY_DESCRIPT_FLAGS_PHASE_MASK) == exp_phase) + goto process_desc; atomic_dec(&op_reply_q->in_use); return 0; } +process_desc: + /* + * Ensure that the descriptor payload is read only after + * the phase bit check is complete. + */ + dma_rmb(); do { if (mrioc->unrecoverable || mrioc->io_admin_reset_sync) break; req_q_idx = le16_to_cpu(reply_desc->request_queue_id) - 1; + + if (unlikely(req_q_idx >= mrioc->num_op_req_q)) { + ioc_err(mrioc, "Invalid request queue id %d, skipping reply\n", + req_q_idx + 1); + goto next_reply; + } + op_req_q = &mrioc->req_qinfo[req_q_idx]; WRITE_ONCE(op_req_q->ci, le16_to_cpu(reply_desc->request_queue_ci)); @@ -582,8 +632,9 @@ int mpi3mr_process_op_reply_q(struct mpi3mr_ioc *mrioc, if (reply_dma) mpi3mr_repost_reply_buf(mrioc, reply_dma); - num_op_reply++; threshold_comps++; +next_reply: + num_op_reply++; if (++reply_ci == op_reply_q->num_replies) { reply_ci = 0; @@ -593,8 +644,19 @@ int mpi3mr_process_op_reply_q(struct mpi3mr_ioc *mrioc, reply_desc = mpi3mr_get_reply_desc(op_reply_q, reply_ci); if ((le16_to_cpu(reply_desc->reply_flags) & - MPI3_REPLY_DESCRIPT_FLAGS_PHASE_MASK) != exp_phase) + MPI3_REPLY_DESCRIPT_FLAGS_PHASE_MASK) != exp_phase) { + dma_rmb(); + if ((le16_to_cpu(reply_desc->reply_flags) & + MPI3_REPLY_DESCRIPT_FLAGS_PHASE_MASK) == exp_phase) + goto reply_ready; break; + } +reply_ready: + /* + * Ensure that the descriptor payload is read only after + * the phase bit check is complete. + */ + dma_rmb(); #ifndef CONFIG_PREEMPT_RT /* * Exit completion loop to avoid CPU lockup @@ -656,6 +718,7 @@ static irqreturn_t mpi3mr_isr_primary(int irq, void *privdata) { struct mpi3mr_intr_info *intr_info = privdata; struct mpi3mr_ioc *mrioc; + struct op_reply_qinfo *op_reply_q; u16 midx; u32 num_admin_replies = 0, num_op_reply = 0; @@ -671,9 +734,9 @@ static irqreturn_t mpi3mr_isr_primary(int irq, void *privdata) if (!midx) num_admin_replies = mpi3mr_process_admin_reply_q(mrioc); - if (intr_info->op_reply_q) - num_op_reply = mpi3mr_process_op_reply_q(mrioc, - intr_info->op_reply_q); + op_reply_q = READ_ONCE(intr_info->op_reply_q); + if (op_reply_q) + num_op_reply = mpi3mr_process_op_reply_q(mrioc, op_reply_q); if (num_admin_replies || num_op_reply) return IRQ_HANDLED; @@ -686,6 +749,7 @@ static irqreturn_t mpi3mr_isr_primary(int irq, void *privdata) static irqreturn_t mpi3mr_isr(int irq, void *privdata) { struct mpi3mr_intr_info *intr_info = privdata; + struct op_reply_qinfo *op_reply_q; int ret; if (!intr_info) @@ -698,11 +762,12 @@ static irqreturn_t mpi3mr_isr(int irq, void *privdata) * If more IOs are expected, schedule IRQ polling thread. * Otherwise exit from ISR. */ - if ((threaded_isr_poll == false) || !intr_info->op_reply_q) + op_reply_q = READ_ONCE(intr_info->op_reply_q); + if ((threaded_isr_poll == false) || !op_reply_q) return ret; - if (!intr_info->op_reply_q->enable_irq_poll || - !atomic_read(&intr_info->op_reply_q->pend_ios)) + if (!op_reply_q->enable_irq_poll || + !atomic_read(&op_reply_q->pend_ios)) return ret; disable_irq_nosync(intr_info->os_irq); @@ -724,12 +789,19 @@ static irqreturn_t mpi3mr_isr_poll(int irq, void *privdata) { struct mpi3mr_intr_info *intr_info = privdata; struct mpi3mr_ioc *mrioc; + struct op_reply_qinfo *op_reply_q; u16 midx; u32 num_op_reply = 0; - if (!intr_info || !intr_info->op_reply_q) + if (!intr_info) return IRQ_NONE; + op_reply_q = READ_ONCE(intr_info->op_reply_q); + if (!op_reply_q) { + enable_irq(intr_info->os_irq); + return IRQ_HANDLED; + } + mrioc = intr_info->mrioc; midx = intr_info->msix_index; @@ -738,19 +810,23 @@ static irqreturn_t mpi3mr_isr_poll(int irq, void *privdata) if (!mrioc->intr_enabled || mrioc->unrecoverable) break; + op_reply_q = READ_ONCE(intr_info->op_reply_q); + if (!op_reply_q) + break; + if (!midx) mpi3mr_process_admin_reply_q(mrioc); - if (intr_info->op_reply_q) - num_op_reply += - mpi3mr_process_op_reply_q(mrioc, - intr_info->op_reply_q); + num_op_reply += + mpi3mr_process_op_reply_q(mrioc, op_reply_q); + if (!atomic_read(&op_reply_q->pend_ios)) + break; - usleep_range(MPI3MR_IRQ_POLL_SLEEP, MPI3MR_IRQ_POLL_SLEEP + 1); + usleep_range(MPI3MR_IRQ_POLL_SLEEP, 10 * MPI3MR_IRQ_POLL_SLEEP); - } while (atomic_read(&intr_info->op_reply_q->pend_ios) && - (num_op_reply < mrioc->max_host_ios)); + } while (num_op_reply < mrioc->max_host_ios); - intr_info->op_reply_q->enable_irq_poll = false; + if (op_reply_q) + op_reply_q->enable_irq_poll = false; enable_irq(intr_info->os_irq); return IRQ_HANDLED; @@ -1934,10 +2010,6 @@ static void mpi3mr_free_op_req_q_segments(struct mpi3mr_ioc *mrioc, u16 q_idx) int size; struct segments *segments; - segments = mrioc->req_qinfo[q_idx].q_segments; - if (!segments) - return; - if (mrioc->enable_segqueue) { size = MPI3MR_OP_REQ_Q_SEG_SIZE; if (mrioc->req_qinfo[q_idx].q_segment_list) { @@ -1951,6 +2023,10 @@ static void mpi3mr_free_op_req_q_segments(struct mpi3mr_ioc *mrioc, u16 q_idx) size = mrioc->req_qinfo[q_idx].segment_qd * mrioc->facts.op_req_sz; + segments = mrioc->req_qinfo[q_idx].q_segments; + if (!segments) + return; + for (j = 0; j < mrioc->req_qinfo[q_idx].num_segments; j++) { if (!segments[j].segment) continue; @@ -1977,10 +2053,17 @@ static void mpi3mr_free_op_reply_q_segments(struct mpi3mr_ioc *mrioc, u16 q_idx) u16 j; int size; struct segments *segments; + u16 midx = REPLY_QUEUE_IDX_TO_MSIX_IDX(q_idx, mrioc->op_reply_q_offset); - segments = mrioc->op_reply_qinfo[q_idx].q_segments; - if (!segments) - return; + /* + * Stop the ISR/poll thread from picking up this queue before its + * segments are freed below, and wait for any in-flight handler + * that already has the old pointer to finish using it. + */ + if (midx < mrioc->intr_info_count) { + WRITE_ONCE(mrioc->intr_info[midx].op_reply_q, NULL); + synchronize_irq(pci_irq_vector(mrioc->pdev, midx)); + } if (mrioc->enable_segqueue) { size = MPI3MR_OP_REP_Q_SEG_SIZE; @@ -1995,6 +2078,10 @@ static void mpi3mr_free_op_reply_q_segments(struct mpi3mr_ioc *mrioc, u16 q_idx) size = mrioc->op_reply_qinfo[q_idx].segment_qd * mrioc->op_reply_desc_sz; + segments = mrioc->op_reply_qinfo[q_idx].q_segments; + if (!segments) + return; + for (j = 0; j < mrioc->op_reply_qinfo[q_idx].num_segments; j++) { if (!segments[j].segment) continue; @@ -2461,7 +2548,7 @@ static int mpi3mr_create_op_req_q(struct mpi3mr_ioc *mrioc, u16 idx, static int mpi3mr_create_op_queues(struct mpi3mr_ioc *mrioc) { int retval = 0; - u16 num_queues = 0, i = 0, msix_count_op_q = 1; + u16 num_queues = 0, i = 0, j = 0, msix_count_op_q = 1; u32 ioc_status; enum mpi3mr_iocstate ioc_state; @@ -2513,6 +2600,13 @@ static int mpi3mr_create_op_queues(struct mpi3mr_ioc *mrioc) } } + if (i < num_queues) { + for (j = i; j < num_queues; j++) { + mpi3mr_free_op_req_q_segments(mrioc, j); + mpi3mr_free_op_reply_q_segments(mrioc, j); + } + } + if (i == 0) { /* Not even one queue is created successfully*/ retval = -1; @@ -2534,11 +2628,19 @@ static int mpi3mr_create_op_queues(struct mpi3mr_ioc *mrioc) return retval; out_failed: - kfree(mrioc->req_qinfo); - mrioc->req_qinfo = NULL; + if (mrioc->req_qinfo) { + for (j = 0; j < i; j++) { + mpi3mr_free_op_req_q_segments(mrioc, j); + mpi3mr_free_op_reply_q_segments(mrioc, j); + } + kfree(mrioc->req_qinfo); + mrioc->req_qinfo = NULL; + } + mrioc->num_op_req_q = 0; kfree(mrioc->op_reply_qinfo); mrioc->op_reply_qinfo = NULL; + mrioc->num_op_reply_q = 0; return retval; } @@ -2582,7 +2684,8 @@ int mpi3mr_op_request_post(struct mpi3mr_ioc *mrioc, if (mpi3mr_check_req_qfull(op_req_q)) { midx = REPLY_QUEUE_IDX_TO_MSIX_IDX( reply_qidx, mrioc->op_reply_q_offset); - mpi3mr_process_op_reply_q(mrioc, mrioc->intr_info[midx].op_reply_q); + mpi3mr_process_op_reply_q(mrioc, + READ_ONCE(mrioc->intr_info[midx].op_reply_q)); if (mpi3mr_check_req_qfull(op_req_q)) { @@ -2875,8 +2978,9 @@ static int mpi3mr_print_pkg_ver(struct mpi3mr_ioc *mrioc) * @work: work struct * * Watch dog work periodically executed (1 second interval) to - * monitor firmware fault and to issue periodic timer sync to - * the firmware. + * monitor firmware fault and perform timestamp synchronization + * to firmware, with an early sync 1 minute after load followed + * by periodic updates at ts_update_interval seconds (default 15 minutes). * * Return: Nothing. */ @@ -2922,11 +3026,23 @@ static void mpi3mr_watchdog_work(struct work_struct *work) } if (!(mrioc->facts.ioc_capabilities & - MPI3_IOCFACTS_CAPABILITY_NON_SUPERVISOR_IOC) && - (mrioc->ts_update_counter++ >= mrioc->ts_update_interval)) { + MPI3_IOCFACTS_CAPABILITY_NON_SUPERVISOR_IOC)) { + if (!mrioc->early_ts_sync_done) { + /* + * Send time sync 1 min after load + */ + if (mrioc->ts_update_counter++ >= + MPI3MR_EARLY_TSUPDATE_SECONDS) { + mrioc->early_ts_sync_done = 1; + mrioc->ts_update_counter = 0; + mpi3mr_sync_timestamp(mrioc); + } + } else if (mrioc->ts_update_counter++ >= + mrioc->ts_update_interval) { + mrioc->ts_update_counter = 0; + mpi3mr_sync_timestamp(mrioc); + } - mrioc->ts_update_counter = 0; - mpi3mr_sync_timestamp(mrioc); } if ((mrioc->prepare_for_reset) && @@ -4112,26 +4228,35 @@ static int mpi3mr_repost_diag_bufs(struct mpi3mr_ioc *mrioc) } /** - * mpi3mr_read_tsu_interval - Update time stamp interval + * mpi3mr_read_driver_page1 - Read Driver Page 1 parameters * @mrioc: Adapter instance reference * - * Update time stamp interval if its defined in driver page 1, - * otherwise use default value. + * Reads and caches Driver Page 1 parameters such as + * timestamp update interval and driver behavior flags. * * Return: Nothing */ static void -mpi3mr_read_tsu_interval(struct mpi3mr_ioc *mrioc) +mpi3mr_read_driver_page1(struct mpi3mr_ioc *mrioc) { struct mpi3_driver_page1 driver_pg1; u16 pg_sz = sizeof(driver_pg1); int retval = 0; mrioc->ts_update_interval = MPI3MR_TSUPDATE_INTERVAL; + mrioc->skip_dev_shutdown_on_unload = 0; retval = mpi3mr_cfg_get_driver_pg1(mrioc, &driver_pg1, pg_sz); - if (!retval && driver_pg1.time_stamp_update) + + if (retval) + return; + + if (driver_pg1.time_stamp_update) mrioc->ts_update_interval = (driver_pg1.time_stamp_update * 60); + + mrioc->skip_dev_shutdown_on_unload = + (le32_to_cpu(driver_pg1.flags) & + MPI3_DRIVER1_FLAGS_DEVICE_SHUTDOWN_ON_UNLOAD_DISABLE) ? 1 : 0; } /** @@ -4437,7 +4562,7 @@ int mpi3mr_init_ioc(struct mpi3mr_ioc *mrioc) goto out_failed_noretry; } - mpi3mr_read_tsu_interval(mrioc); + mpi3mr_read_driver_page1(mrioc); mpi3mr_print_ioc_info(mrioc); dprint_init(mrioc, "allocating host diag buffers\n"); @@ -4609,7 +4734,7 @@ int mpi3mr_reinit_ioc(struct mpi3mr_ioc *mrioc, u8 is_resume) goto out_failed_noretry; } - mpi3mr_read_tsu_interval(mrioc); + mpi3mr_read_driver_page1(mrioc); mpi3mr_print_ioc_info(mrioc); if (is_resume) { @@ -5094,8 +5219,16 @@ static void mpi3mr_issue_ioc_shutdown(struct mpi3mr_ioc *mrioc) return; } - shutdown_action = MPI3_SYSIF_IOC_CONFIG_SHUTDOWN_NORMAL | - MPI3_SYSIF_IOC_CONFIG_DEVICE_SHUTDOWN_SEND_REQ; + shutdown_action = MPI3_SYSIF_IOC_CONFIG_SHUTDOWN_NORMAL; + + if (!(mrioc->is_unload && mrioc->skip_dev_shutdown_on_unload)) + shutdown_action |= + MPI3_SYSIF_IOC_CONFIG_DEVICE_SHUTDOWN_SEND_REQ; + else + ioc_info(mrioc, + "The shutdown request is issued without the device shutdown bit set\n" + "as indicated by the controller configuration\n"); + ioc_config = readl(&mrioc->sysif_regs->ioc_configuration); ioc_config |= shutdown_action; diff --git a/drivers/scsi/mpi3mr/mpi3mr_os.c b/drivers/scsi/mpi3mr/mpi3mr_os.c index 0f7380448718..6b0156e54d45 100644 --- a/drivers/scsi/mpi3mr/mpi3mr_os.c +++ b/drivers/scsi/mpi3mr/mpi3mr_os.c @@ -233,10 +233,11 @@ static void mpi3mr_fwevt_add_to_list(struct mpi3mr_ioc *mrioc, { unsigned long flags; - if (!mrioc->fwevt_worker_thread) - return; - spin_lock_irqsave(&mrioc->fwevt_lock, flags); + if (!mrioc->fwevt_worker_thread) { + spin_unlock_irqrestore(&mrioc->fwevt_lock, flags); + return; + } /* get fwevt reference count while adding it to fwevt_list */ mpi3mr_fwevt_get(fwevt); INIT_LIST_HEAD(&fwevt->list); @@ -282,32 +283,6 @@ void mpi3mr_hdb_trigger_data_event(struct mpi3mr_ioc *mrioc, mpi3mr_fwevt_add_to_list(mrioc, fwevt); } -/** - * mpi3mr_fwevt_del_from_list - Delete firmware event from list - * @mrioc: Adapter instance reference - * @fwevt: Firmware event reference - * - * Delete the given firmware event from the firmware event list. - * - * Return: Nothing. - */ -static void mpi3mr_fwevt_del_from_list(struct mpi3mr_ioc *mrioc, - struct mpi3mr_fwevt *fwevt) -{ - unsigned long flags; - - spin_lock_irqsave(&mrioc->fwevt_lock, flags); - if (!list_empty(&fwevt->list)) { - list_del_init(&fwevt->list); - /* - * Put fwevt reference count after - * removing it from fwevt_list - */ - mpi3mr_fwevt_put(fwevt); - } - spin_unlock_irqrestore(&mrioc->fwevt_lock, flags); -} - /** * mpi3mr_dequeue_fwevt - Dequeue firmware event from the list * @mrioc: Adapter instance reference @@ -327,11 +302,7 @@ static struct mpi3mr_fwevt *mpi3mr_dequeue_fwevt( fwevt = list_first_entry(&mrioc->fwevt_list, struct mpi3mr_fwevt, list); list_del_init(&fwevt->list); - /* - * Put fwevt reference count after - * removing it from fwevt_list - */ - mpi3mr_fwevt_put(fwevt); + } spin_unlock_irqrestore(&mrioc->fwevt_lock, flags); @@ -365,6 +336,11 @@ static void mpi3mr_cancel_work(struct mpi3mr_fwevt *fwevt) */ mpi3mr_fwevt_put(fwevt); } + + /* + * Drop the reference count that was acquired by the caller. + */ + mpi3mr_fwevt_put(fwevt); } /** @@ -379,17 +355,44 @@ static void mpi3mr_cancel_work(struct mpi3mr_fwevt *fwevt) void mpi3mr_cleanup_fwevt_list(struct mpi3mr_ioc *mrioc) { struct mpi3mr_fwevt *fwevt = NULL; + unsigned long flags; + /* + * Safely read current_event under lock to prevent TOCTOU race + * with the firmware event worker thread. + */ + spin_lock_irqsave(&mrioc->fwevt_lock, flags); if ((list_empty(&mrioc->fwevt_list) && !mrioc->current_event) || - !mrioc->fwevt_worker_thread) + !mrioc->fwevt_worker_thread) { + spin_unlock_irqrestore(&mrioc->fwevt_lock, flags); return; + } + spin_unlock_irqrestore(&mrioc->fwevt_lock, flags); while ((fwevt = mpi3mr_dequeue_fwevt(mrioc))) mpi3mr_cancel_work(fwevt); - if (mrioc->current_event) { - fwevt = mrioc->current_event; + /* + * Safely read current_event under lock to prevent TOCTOU race + * with the firmware event worker thread. + */ + spin_lock_irqsave(&mrioc->fwevt_lock, flags); + fwevt = mrioc->current_event; + if (fwevt) { + /* + * Take a reference to ensure the event is not freed by the + * worker thread while we are evaluating or cancelling it. + */ + mpi3mr_fwevt_get(fwevt); + } + spin_unlock_irqrestore(&mrioc->fwevt_lock, flags); + + if (fwevt) { + bool pending_at_sml; + /* + * Read pending_at_sml under lock to avoid a stale value. + * * Don't call cancel_work_sync() API for the * fwevt work if the controller reset is * get called as part of processing the @@ -397,8 +400,13 @@ void mpi3mr_cleanup_fwevt_list(struct mpi3mr_ioc *mrioc) * waiting for device add/remove APIs to complete. * Otherwise we will see deadlock. */ - if (current_work() == &fwevt->work || fwevt->pending_at_sml) { + spin_lock_irqsave(&mrioc->fwevt_lock, flags); + pending_at_sml = fwevt->pending_at_sml; + spin_unlock_irqrestore(&mrioc->fwevt_lock, flags); + + if (current_work() == &fwevt->work || pending_at_sml) { fwevt->discard = 1; + mpi3mr_fwevt_put(fwevt); return; } @@ -912,6 +920,8 @@ void mpi3mr_remove_tgtdev_from_host(struct mpi3mr_ioc *mrioc, struct mpi3mr_tgt_dev *tgtdev) { struct mpi3mr_stgt_priv_data *tgt_priv; + unsigned long flags; + bool discard = false; ioc_info(mrioc, "%s :Removing handle(0x%04x), wwid(0x%016llx)\n", __func__, tgtdev->dev_handle, (unsigned long long)tgtdev->wwid); @@ -924,17 +934,27 @@ void mpi3mr_remove_tgtdev_from_host(struct mpi3mr_ioc *mrioc, if (!mrioc->sas_transport_enabled || (tgtdev->dev_type != MPI3_DEVICE_DEVFORM_SAS_SATA) || tgtdev->non_stl) { if (tgtdev->starget) { + spin_lock_irqsave(&mrioc->fwevt_lock, flags); + if (mrioc->stop_drv_processing || + mrioc->reset_in_progress) { + spin_unlock_irqrestore(&mrioc->fwevt_lock, flags); + return; + } if (mrioc->current_event) mrioc->current_event->pending_at_sml = 1; + spin_unlock_irqrestore(&mrioc->fwevt_lock, flags); scsi_remove_target(&tgtdev->starget->dev); tgtdev->host_exposed = 0; + spin_lock_irqsave(&mrioc->fwevt_lock, flags); if (mrioc->current_event) { mrioc->current_event->pending_at_sml = 0; - if (mrioc->current_event->discard) { - mpi3mr_print_device_event_notice(mrioc, - false); - return; - } + discard = mrioc->current_event->discard; + } + spin_unlock_irqrestore(&mrioc->fwevt_lock, flags); + if (discard) { + mpi3mr_print_device_event_notice(mrioc, + false); + return; } } } else @@ -962,6 +982,8 @@ static int mpi3mr_report_tgtdev_to_host(struct mpi3mr_ioc *mrioc, { int retval = 0; struct mpi3mr_tgt_dev *tgtdev; + unsigned long flags; + bool discard = false; if (mrioc->reset_in_progress || mrioc->pci_err_recovery) return -1; @@ -978,19 +1000,29 @@ static int mpi3mr_report_tgtdev_to_host(struct mpi3mr_ioc *mrioc, if (!mrioc->sas_transport_enabled || (tgtdev->dev_type != MPI3_DEVICE_DEVFORM_SAS_SATA) || tgtdev->non_stl){ tgtdev->host_exposed = 1; + spin_lock_irqsave(&mrioc->fwevt_lock, flags); + if (mrioc->stop_drv_processing || mrioc->reset_in_progress) { + spin_unlock_irqrestore(&mrioc->fwevt_lock, flags); + tgtdev->host_exposed = 0; + goto out; + } if (mrioc->current_event) mrioc->current_event->pending_at_sml = 1; + spin_unlock_irqrestore(&mrioc->fwevt_lock, flags); scsi_scan_target(&mrioc->shost->shost_gendev, mrioc->scsi_device_channel, tgtdev->perst_id, SCAN_WILD_CARD, SCSI_SCAN_INITIAL); if (!tgtdev->starget) tgtdev->host_exposed = 0; + spin_lock_irqsave(&mrioc->fwevt_lock, flags); if (mrioc->current_event) { mrioc->current_event->pending_at_sml = 0; - if (mrioc->current_event->discard) { - mpi3mr_print_device_event_notice(mrioc, true); - goto out; - } + discard = mrioc->current_event->discard; + } + spin_unlock_irqrestore(&mrioc->fwevt_lock, flags); + if (discard) { + mpi3mr_print_device_event_notice(mrioc, true); + goto out; } dprint_event_bh(mrioc, "exposed target device with handle(0x%04x), perst_id(%d)\n", @@ -1363,24 +1395,32 @@ static void mpi3mr_update_tgtdev(struct mpi3mr_ioc *mrioc, struct mpi3_device0_pcie_format *pcieinf = &dev_pg0->device_specific.pcie_format; u16 dev_info = le16_to_cpu(pcieinf->device_info); + u8 pgsz = MPI3MR_DEFAULT_PGSZEXP; + u8 reset_to = MPI3MR_INTADMCMD_TIMEOUT; + u8 abort_to = MPI3MR_INTADMCMD_TIMEOUT; + u8 fw_pgsz = READ_ONCE(pcieinf->page_size); tgtdev->dev_spec.pcie_inf.dev_info = dev_info; tgtdev->dev_spec.pcie_inf.capb = le32_to_cpu(pcieinf->capabilities); tgtdev->dev_spec.pcie_inf.mdts = MPI3MR_DEFAULT_MDTS; - /* 2^12 = 4096 */ - tgtdev->dev_spec.pcie_inf.pgsz = 12; + /* Validate firmware page size to prevent undefined shift behavior */ + if (fw_pgsz >= MPI3MR_DEFAULT_PGSZEXP && fw_pgsz <= MPI3MR_MAX_PGSZEXP) + pgsz = fw_pgsz; + if (dev_pg0->access_status == MPI3_DEVICE0_ASTATUS_NO_ERRORS) { tgtdev->dev_spec.pcie_inf.mdts = le32_to_cpu(pcieinf->maximum_data_transfer_size); - tgtdev->dev_spec.pcie_inf.pgsz = pcieinf->page_size; - tgtdev->dev_spec.pcie_inf.reset_to = - max_t(u8, pcieinf->controller_reset_to, - MPI3MR_INTADMCMD_TIMEOUT); - tgtdev->dev_spec.pcie_inf.abort_to = - max_t(u8, pcieinf->nvme_abort_to, + reset_to = max_t(u8, pcieinf->controller_reset_to, + MPI3MR_INTADMCMD_TIMEOUT); + abort_to = max_t(u8, pcieinf->nvme_abort_to, MPI3MR_INTADMCMD_TIMEOUT); } + + tgtdev->dev_spec.pcie_inf.pgsz = pgsz; + tgtdev->dev_spec.pcie_inf.reset_to = reset_to; + tgtdev->dev_spec.pcie_inf.abort_to = abort_to; + if (tgtdev->dev_spec.pcie_inf.mdts > (1024 * 1024)) tgtdev->dev_spec.pcie_inf.mdts = (1024 * 1024); if (((dev_info & MPI3_DEVICE0_PCIE_DEVICE_INFO_TYPE_MASK) != @@ -2150,13 +2190,25 @@ static void mpi3mr_fwevt_bh(struct mpi3mr_ioc *mrioc, u16 perst_id, handle, dev_info; struct mpi3_device0_sas_sata_format *sasinf = NULL; unsigned int timeout; + unsigned long flags; - mpi3mr_fwevt_del_from_list(mrioc, fwevt); + spin_lock_irqsave(&mrioc->fwevt_lock, flags); + if (!list_empty(&fwevt->list)) { + list_del_init(&fwevt->list); + /* + * Put fwevt reference count after + * removing it from fwevt_list + */ + mpi3mr_fwevt_put(fwevt); + } mrioc->current_event = fwevt; + spin_unlock_irqrestore(&mrioc->fwevt_lock, flags); - if (mrioc->stop_drv_processing) { - dprint_event_bh(mrioc, "ignoring event(0x%02x) in the bottom half handler\n" - "due to stop_drv_processing\n", fwevt->event_id); + if (mrioc->stop_drv_processing || mrioc->pci_err_recovery) { + dprint_event_bh(mrioc, + "ignoring event(0x%02x) in the bottom half handler\n" + "due to stop_drv_processing or pci_err_recovery\n", + fwevt->event_id); goto out; } @@ -2285,9 +2337,12 @@ static void mpi3mr_fwevt_bh(struct mpi3mr_ioc *mrioc, mpi3mr_process_event_ack(mrioc, fwevt->event_id, fwevt->evt_ctx); out: + spin_lock_irqsave(&mrioc->fwevt_lock, flags); + mrioc->current_event = NULL; + spin_unlock_irqrestore(&mrioc->fwevt_lock, flags); + /* Put fwevt reference count to neutralize kref_init increment */ mpi3mr_fwevt_put(fwevt); - mrioc->current_event = NULL; } /** @@ -2426,7 +2481,8 @@ static void mpi3mr_dev_rmhs_complete_iou(struct mpi3mr_ioc *mrioc, ioc_info(mrioc, "%s :dev removal handshake completed successfully: handle(0x%04x)\n", __func__, drv_cmd->dev_handle); - clear_bit(drv_cmd->dev_handle, mrioc->removepend_bitmap); + if (drv_cmd->dev_handle < mrioc->facts.max_devhandle) + clear_bit(drv_cmd->dev_handle, mrioc->removepend_bitmap); } if (!list_empty(&mrioc->delayed_rmhs_list)) { @@ -2540,12 +2596,29 @@ static void mpi3mr_dev_rmhs_send_tm(struct mpi3mr_ioc *mrioc, u16 handle, struct mpi3mr_tgt_dev *tgtdev = NULL; unsigned long flags; + if (handle >= mrioc->facts.max_devhandle) { + ioc_err(mrioc, "dev_remove_hs: handle(0x%04x) >= max_devhandle(0x%04x)\n", + handle, mrioc->facts.max_devhandle); + if (drv_cmd) { + cmd_idx = drv_cmd->host_tag - MPI3MR_HOSTTAG_DEVRMCMD_MIN; + drv_cmd->state = MPI3MR_CMD_NOTUSED; + drv_cmd->callback = NULL; + drv_cmd->dev_handle = MPI3MR_INVALID_DEV_HANDLE; + drv_cmd->retry_count = 0; + clear_bit(cmd_idx, mrioc->devrem_bitmap); + } + return; + } + spin_lock_irqsave(&mrioc->tgtdev_lock, flags); tgtdev = __mpi3mr_get_tgtdev_by_handle(mrioc, handle); if (tgtdev && (iou_rc == MPI3_CTRL_OP_REMOVE_DEVICE)) tgtdev->state = MPI3MR_DEV_REMOVE_HS_STARTED; spin_unlock_irqrestore(&mrioc->tgtdev_lock, flags); + if (tgtdev) + mpi3mr_tgtdev_put(tgtdev); + if (drv_cmd) goto issue_cmd; do { @@ -2768,12 +2841,28 @@ static void mpi3mr_pcietopochg_evt_th(struct mpi3mr_ioc *mrioc, struct mpi3_event_data_pcie_topology_change_list *topo_evt = (struct mpi3_event_data_pcie_topology_change_list *)event_reply->event_data; int i; - u16 handle; - u8 reason_code; + u16 handle, avail_len; + u8 reason_code, max_entries, num_entries; struct mpi3mr_tgt_dev *tgtdev = NULL; struct mpi3mr_stgt_priv_data *scsi_tgt_priv_data = NULL; - for (i = 0; i < topo_evt->num_entries; i++) { + avail_len = event_reply->event_data_length * 4; + if (avail_len < offsetof(struct mpi3_event_data_pcie_topology_change_list, port_entry)) { + ioc_err(mrioc, "PCIe topology event: event data too small (%u bytes)\n", + avail_len); + return; + } + max_entries = (avail_len - + offsetof(struct mpi3_event_data_pcie_topology_change_list, port_entry)) / + sizeof(struct mpi3_event_pcie_topo_port_entry); + num_entries = topo_evt->num_entries; + if (num_entries > max_entries) { + ioc_err(mrioc, "PCIe topology event: num_entries(%d) exceeds max(%d)\n", + num_entries, max_entries); + return; + } + + for (i = 0; i < num_entries; i++) { handle = le16_to_cpu(topo_evt->port_entry[i].attached_dev_handle); if (!handle) continue; @@ -2834,12 +2923,28 @@ static void mpi3mr_sastopochg_evt_th(struct mpi3mr_ioc *mrioc, struct mpi3_event_data_sas_topology_change_list *topo_evt = (struct mpi3_event_data_sas_topology_change_list *)event_reply->event_data; int i; - u16 handle; - u8 reason_code; + u16 handle, avail_len; + u8 reason_code, max_entries, num_entries; struct mpi3mr_tgt_dev *tgtdev = NULL; struct mpi3mr_stgt_priv_data *scsi_tgt_priv_data = NULL; - for (i = 0; i < topo_evt->num_entries; i++) { + avail_len = event_reply->event_data_length * 4; + if (avail_len < offsetof(struct mpi3_event_data_sas_topology_change_list, phy_entry)) { + ioc_err(mrioc, "SAS topology event: event data too small (%u bytes)\n", + avail_len); + return; + } + max_entries = (avail_len - + offsetof(struct mpi3_event_data_sas_topology_change_list, phy_entry)) / + sizeof(struct mpi3_event_sas_topo_phy_entry); + num_entries = topo_evt->num_entries; + if (num_entries > max_entries) { + ioc_err(mrioc, "SAS topology event: num_entries(%d) exceeds max(%d)\n", + num_entries, max_entries); + return; + } + + for (i = 0; i < num_entries; i++) { handle = le16_to_cpu(topo_evt->phy_entry[i].attached_dev_handle); if (!handle) continue; @@ -3109,7 +3214,7 @@ void mpi3mr_add_event_wait_for_device_refresh(struct mpi3mr_ioc *mrioc) void mpi3mr_os_handle_events(struct mpi3mr_ioc *mrioc, struct mpi3_event_notification_reply *event_reply) { - u16 evt_type, sz; + u16 evt_type, sz, avail_reply_room; struct mpi3mr_fwevt *fwevt = NULL; bool ack_req = 0, process_evt_bh = 0; @@ -3170,7 +3275,12 @@ void mpi3mr_os_handle_events(struct mpi3mr_ioc *mrioc, case MPI3_EVENT_DEVICE_INFO_CHANGED: case MPI3_EVENT_LOG_DATA: - sz = event_reply->event_data_length * 4; + if (mrioc->reply_sz > offsetof(struct mpi3_event_notification_reply, event_data)) + avail_reply_room = mrioc->reply_sz - + offsetof(struct mpi3_event_notification_reply, event_data); + else + avail_reply_room = 0; + sz = min_t(u16, event_reply->event_data_length * 4, avail_reply_room); mpi3mr_app_save_logdata_th(mrioc, (char *)event_reply->event_data, sz); break; @@ -3204,7 +3314,12 @@ void mpi3mr_os_handle_events(struct mpi3mr_ioc *mrioc, dprint_event_th(mrioc, "scheduling bottom half handler for event(0x%02x) - (0x%08x), ack_required=%d\n", evt_type, le32_to_cpu(event_reply->event_context), ack_req); - sz = event_reply->event_data_length * 4; + if (mrioc->reply_sz > offsetof(struct mpi3_event_notification_reply, event_data)) + avail_reply_room = mrioc->reply_sz - + offsetof(struct mpi3_event_notification_reply, event_data); + else + avail_reply_room = 0; + sz = min_t(u16, event_reply->event_data_length * 4, avail_reply_room); fwevt = mpi3mr_alloc_fwevt(sz); if (!fwevt) { dprint_event_th(mrioc, @@ -3329,8 +3444,7 @@ static void mpi3mr_setup_eedp(struct mpi3mr_ioc *mrioc, * @desc: Sense type * @buf: Sense buffer to populate * @key: Sense key - * @asc: Additional sense code - * @ascq: Additional sense code qualifier + * @code: Additional sense code and its qualifier * * Maps the given sense information into either descriptor or * fixed format sense data. @@ -3338,20 +3452,20 @@ static void mpi3mr_setup_eedp(struct mpi3mr_ioc *mrioc, * Return: Nothing */ static inline void mpi3mr_build_sense_buffer(int desc, u8 *buf, u8 key, - u8 asc, u8 ascq) + u16 code) { if (desc) { buf[0] = 0x72; /* descriptor, current */ buf[1] = key; - buf[2] = asc; - buf[3] = ascq; + buf[2] = scsi_sense_code_asc(code); + buf[3] = scsi_sense_code_ascq(code); buf[7] = 0; } else { buf[0] = 0x70; /* fixed, current */ buf[2] = key; buf[7] = 0xa; - buf[12] = asc; - buf[13] = ascq; + buf[12] = scsi_sense_code_asc(code); + buf[13] = scsi_sense_code_ascq(code); } } @@ -3368,25 +3482,25 @@ static inline void mpi3mr_build_sense_buffer(int desc, u8 *buf, u8 key, static void mpi3mr_map_eedp_error(struct scsi_cmnd *scmd, u16 ioc_status) { - u8 ascq = 0; + u16 sense_code; switch (ioc_status) { case MPI3_IOCSTATUS_EEDP_GUARD_ERROR: - ascq = 0x01; + sense_code = LOGICAL_BLOCK_GUARD_CHECK_FAILED; break; case MPI3_IOCSTATUS_EEDP_APP_TAG_ERROR: - ascq = 0x02; + sense_code = LOGICAL_BLOCK_APPLICATION_TAG_CHECK_FAILED; break; case MPI3_IOCSTATUS_EEDP_REF_TAG_ERROR: - ascq = 0x03; + sense_code = LOGICAL_BLOCK_REFERENCE_TAG_CHECK_FAILED; break; default: - ascq = 0x00; + sense_code = ID_CRC_OR_ECC_ERROR; break; } mpi3mr_build_sense_buffer(0, scmd->sense_buffer, ILLEGAL_REQUEST, - 0x10, ascq); + sense_code); scmd->result = (DID_ABORT << 16) | SAM_STAT_CHECK_CONDITION; } @@ -3447,8 +3561,12 @@ void mpi3mr_process_op_reply_desc(struct mpi3mr_ioc *mrioc, scsi_reply = mpi3mr_get_reply_virt_addr(mrioc, *reply_dma); if (!scsi_reply) { - panic("%s: scsi_reply is NULL, this shouldn't happen\n", - mrioc->name); + ioc_err(mrioc, "scsi_reply is NULL, invalid reply_frame_address\n"); + /* + * Do not let the caller repost an address that + * failed virt-addr lookup back to the hardware. + */ + *reply_dma = 0; goto out; } host_tag = le16_to_cpu(scsi_reply->host_tag); @@ -3471,7 +3589,8 @@ void mpi3mr_process_op_reply_desc(struct mpi3mr_ioc *mrioc, if (sense_buf) { scsi_normalize_sense(sense_buf, sense_count, &sshdr); mpi3mr_scsisense_trigger(mrioc, sshdr.sense_key, - sshdr.asc, sshdr.ascq); + scsi_sense_asc(&sshdr), + scsi_sense_ascq(&sshdr)); } mpi3mr_reply_trigger(mrioc, ioc_status, ioc_loginfo); break; @@ -3658,7 +3777,8 @@ void mpi3mr_process_op_reply_desc(struct mpi3mr_ioc *mrioc, ioc_info(mrioc, "%s :sense_count 0x%x, sense_key 0x%x ASC 0x%x, ASCQ 0x%x\n", __func__, sense_count, sshdr.sense_key, - sshdr.asc, sshdr.ascq); + scsi_sense_asc(&sshdr), + scsi_sense_ascq(&sshdr)); } } out_success: @@ -3943,7 +4063,7 @@ inline void mpi3mr_poll_pend_io_completions(struct mpi3mr_ioc *mrioc) for (i = mrioc->op_reply_q_offset; i < num_of_reply_queues; i++) mpi3mr_process_op_reply_q(mrioc, - mrioc->intr_info[i].op_reply_q); + READ_ONCE(mrioc->intr_info[i].op_reply_q)); } /** @@ -5065,8 +5185,8 @@ static bool mpi3mr_check_return_unmap(struct mpi3mr_ioc *mrioc, __func__, param_len); scsi_print_command(scmd); scmd->result = SAM_STAT_CHECK_CONDITION; - scsi_build_sense_buffer(0, scmd->sense_buffer, ILLEGAL_REQUEST, - 0x1A, 0); + scsi_set_sense_buffer(0, scmd->sense_buffer, ILLEGAL_REQUEST, + PARAMETER_LIST_LENGTH_ERROR); scsi_done(scmd); return true; } @@ -5076,8 +5196,8 @@ static bool mpi3mr_check_return_unmap(struct mpi3mr_ioc *mrioc, __func__, param_len, scsi_bufflen(scmd)); scsi_print_command(scmd); scmd->result = SAM_STAT_CHECK_CONDITION; - scsi_build_sense_buffer(0, scmd->sense_buffer, ILLEGAL_REQUEST, - 0x1A, 0); + scsi_set_sense_buffer(0, scmd->sense_buffer, ILLEGAL_REQUEST, + PARAMETER_LIST_LENGTH_ERROR); scsi_done(scmd); return true; } @@ -5085,8 +5205,8 @@ static bool mpi3mr_check_return_unmap(struct mpi3mr_ioc *mrioc, if (!buf) { scsi_print_command(scmd); scmd->result = SAM_STAT_CHECK_CONDITION; - scsi_build_sense_buffer(0, scmd->sense_buffer, ILLEGAL_REQUEST, - 0x55, 0x03); + scsi_set_sense_buffer(0, scmd->sense_buffer, ILLEGAL_REQUEST, + INSUFFICIENT_RESOURCES); scsi_done(scmd); return true; } @@ -5099,8 +5219,8 @@ static bool mpi3mr_check_return_unmap(struct mpi3mr_ioc *mrioc, __func__, desc_len); scsi_print_command(scmd); scmd->result = SAM_STAT_CHECK_CONDITION; - scsi_build_sense_buffer(0, scmd->sense_buffer, ILLEGAL_REQUEST, - 0x26, 0); + scsi_set_sense_buffer(0, scmd->sense_buffer, ILLEGAL_REQUEST, + INVALID_FIELD_IN_PARAMETER_LIST); scsi_done(scmd); kfree(buf); return true; @@ -5200,7 +5320,8 @@ static enum scsi_qc_status mpi3mr_qcmd(struct Scsi_Host *shost, if (scsi_get_host_state(scmd->device->host) == SHOST_RECOVERY && scmd->cmnd[0] == TEST_UNIT_READY && (stgt_priv_data->dev_removed || (dev_handle == MPI3MR_INVALID_DEV_HANDLE))) { - scsi_build_sense(scmd, 0, UNIT_ATTENTION, 0x29, 0x07); + scsi_set_sense(scmd, 0, UNIT_ATTENTION, + I_T_NEXUS_LOSS_OCCURRED); scsi_done(scmd); goto out; } @@ -5690,6 +5811,8 @@ static void mpi3mr_remove(struct pci_dev *pdev) return; mrioc = shost_priv(shost); + mrioc->is_unload = true; + while (mrioc->reset_in_progress || mrioc->is_driver_loading) ssleep(1); @@ -5822,6 +5945,9 @@ mpi3mr_suspend(struct device *dev) ssleep(1); mrioc->stop_drv_processing = 1; mpi3mr_cleanup_fwevt_list(mrioc); + /* Flush any pending discarded event before unmapping PCI resources below. */ + if (mrioc->fwevt_worker_thread) + flush_workqueue(mrioc->fwevt_worker_thread); scsi_block_requests(shost); mpi3mr_stop_watchdog(mrioc); mpi3mr_cleanup_ioc(mrioc); diff --git a/drivers/scsi/mpi3mr/mpi3mr_transport.c b/drivers/scsi/mpi3mr/mpi3mr_transport.c index 232af978d737..f1e34329f5a2 100644 --- a/drivers/scsi/mpi3mr/mpi3mr_transport.c +++ b/drivers/scsi/mpi3mr/mpi3mr_transport.c @@ -1090,6 +1090,13 @@ void mpi3mr_update_links(struct mpi3mr_ioc *mrioc, return; } + if (phy_number >= mr_sas_node->num_phys) { + spin_unlock_irqrestore(&mrioc->sas_node_lock, flags); + ioc_err(mrioc, "%s: phy_number(%d) >= num_phys(%d)\n", + __func__, phy_number, mr_sas_node->num_phys); + return; + } + mr_sas_phy = &mr_sas_node->phy[phy_number]; mr_sas_phy->attached_handle = handle; spin_unlock_irqrestore(&mrioc->sas_node_lock, flags); @@ -1216,13 +1223,14 @@ void mpi3mr_sas_host_add(struct mpi3mr_ioc *mrioc) } num_phys = sas_io_unit_pg0->num_phys; kfree(sas_io_unit_pg0); + sas_io_unit_pg0 = NULL; mrioc->sas_hba.host_node = 1; INIT_LIST_HEAD(&mrioc->sas_hba.sas_port_list); mrioc->sas_hba.parent_dev = &mrioc->shost->shost_gendev; mrioc->sas_hba.phy = kzalloc_objs(struct mpi3mr_sas_phy, num_phys); if (!mrioc->sas_hba.phy) - return; + goto out; mrioc->sas_hba.num_phys = num_phys; @@ -1230,12 +1238,12 @@ void mpi3mr_sas_host_add(struct mpi3mr_ioc *mrioc) (num_phys * sizeof(struct mpi3_sas_io_unit0_phy_data)); sas_io_unit_pg0 = kzalloc(sz, GFP_KERNEL); if (!sas_io_unit_pg0) - return; + goto out_free_phy; if (mpi3mr_cfg_get_sas_io_unit_pg0(mrioc, sas_io_unit_pg0, sz)) { ioc_err(mrioc, "failure at %s:%d/%s()!\n", __FILE__, __LINE__, __func__); - goto out; + goto out_free_phy; } mrioc->sas_hba.handle = 0; @@ -1249,12 +1257,12 @@ void mpi3mr_sas_host_add(struct mpi3mr_ioc *mrioc) MPI3_SAS_PHY_PGAD_FORM_PHY_NUMBER, i)) { ioc_err(mrioc, "failure at %s:%d/%s()!\n", __FILE__, __LINE__, __func__); - goto out; + goto out_free_phy; } if (ioc_status != MPI3_IOCSTATUS_SUCCESS) { ioc_err(mrioc, "failure at %s:%d/%s()!\n", __FILE__, __LINE__, __func__); - goto out; + goto out_free_phy; } if (!mrioc->sas_hba.handle) @@ -1264,26 +1272,27 @@ void mpi3mr_sas_host_add(struct mpi3mr_ioc *mrioc) if (!(mpi3mr_get_hba_port_by_id(mrioc, port_id))) if (!mpi3mr_alloc_hba_port(mrioc, port_id)) - goto out; + goto out_free_phy; mrioc->sas_hba.phy[i].handle = mrioc->sas_hba.handle; mrioc->sas_hba.phy[i].phy_id = i; mrioc->sas_hba.phy[i].hba_port = mpi3mr_get_hba_port_by_id(mrioc, port_id); - mpi3mr_add_host_phy(mrioc, &mrioc->sas_hba.phy[i], - phy_pg0, mrioc->sas_hba.parent_dev); + if (mpi3mr_add_host_phy(mrioc, &mrioc->sas_hba.phy[i], + phy_pg0, mrioc->sas_hba.parent_dev)) + goto out_free_phy; } if ((mpi3mr_cfg_get_dev_pg0(mrioc, &ioc_status, &dev_pg0, sizeof(dev_pg0), MPI3_DEVICE_PGAD_FORM_HANDLE, mrioc->sas_hba.handle))) { ioc_err(mrioc, "%s: device page0 read failed\n", __func__); - goto out; + goto out_free_phy; } if (ioc_status != MPI3_IOCSTATUS_SUCCESS) { ioc_err(mrioc, "device page read failed for handle(0x%04x), with ioc_status(0x%04x) failure at %s:%d/%s()!\n", mrioc->sas_hba.handle, ioc_status, __FILE__, __LINE__, __func__); - goto out; + goto out_free_phy; } mrioc->sas_hba.enclosure_handle = le16_to_cpu(dev_pg0.enclosure_handle); @@ -1306,6 +1315,17 @@ void mpi3mr_sas_host_add(struct mpi3mr_ioc *mrioc) le64_to_cpu(encl_pg0.enclosure_logical_id); } + goto out; + +out_free_phy: + for (i = 0; i < mrioc->sas_hba.num_phys; i++) { + if (mrioc->sas_hba.phy[i].phy) + sas_phy_delete(mrioc->sas_hba.phy[i].phy); + } + kfree(mrioc->sas_hba.phy); + mrioc->sas_hba.phy = NULL; + mrioc->sas_hba.num_phys = 0; + out: kfree(sas_io_unit_pg0); } @@ -1330,6 +1350,7 @@ static struct mpi3mr_sas_port *mpi3mr_sas_port_add(struct mpi3mr_ioc *mrioc, struct mpi3mr_sas_phy *mr_sas_phy, *next; struct mpi3mr_sas_port *mr_sas_port; unsigned long flags; + bool discard = false; struct mpi3mr_sas_node *mr_sas_node; struct sas_rphy *rphy; struct mpi3mr_tgt_dev *tgtdev = NULL; @@ -1429,7 +1450,7 @@ static struct mpi3mr_sas_port *mpi3mr_sas_port_add(struct mpi3mr_ioc *mrioc, port = sas_port_alloc_num(mr_sas_node->parent_dev); if (!port) { - ioc_err(mrioc, "failure at %s:%d/%s()!\n", + ioc_err(mrioc, "failure at %s:%d/%s() (sas_port_alloc)!\n", __FILE__, __LINE__, __func__); goto out_fail; } @@ -1456,19 +1477,51 @@ static struct mpi3mr_sas_port *mpi3mr_sas_port_add(struct mpi3mr_ioc *mrioc, mr_sas_port->port = port; if (mr_sas_port->remote_identify.device_type == SAS_END_DEVICE) { rphy = sas_end_device_alloc(port); + if (!rphy) { + ioc_err(mrioc, "failure at %s:%d/%s() (sas_end_device_alloc)!\n", + __FILE__, __LINE__, __func__); + sas_port_delete(port); + goto out_fail; + } tgtdev->dev_spec.sas_sata_inf.rphy = rphy; } else { rphy = sas_expander_alloc(port, mr_sas_port->remote_identify.device_type); + if (!rphy) { + ioc_err(mrioc, "failure at %s:%d/%s() (sas_expander_alloc)!\n", + __FILE__, __LINE__, __func__); + sas_port_delete(port); + goto out_fail; + } } rphy->identify = mr_sas_port->remote_identify; + spin_lock_irqsave(&mrioc->fwevt_lock, flags); + if (mrioc->stop_drv_processing || mrioc->reset_in_progress) { + spin_unlock_irqrestore(&mrioc->fwevt_lock, flags); + sas_rphy_free(rphy); + sas_port_delete(port); + goto out_fail; + } if (mrioc->current_event) mrioc->current_event->pending_at_sml = 1; + spin_unlock_irqrestore(&mrioc->fwevt_lock, flags); if ((sas_rphy_add(rphy))) { ioc_err(mrioc, "failure at %s:%d/%s()!\n", __FILE__, __LINE__, __func__); + spin_lock_irqsave(&mrioc->fwevt_lock, flags); + if (mrioc->current_event) { + mrioc->current_event->pending_at_sml = 0; + discard = mrioc->current_event->discard; + } + spin_unlock_irqrestore(&mrioc->fwevt_lock, flags); + if (discard) + mpi3mr_print_device_event_notice(mrioc, true); + sas_rphy_unlink(rphy); + sas_rphy_free(rphy); + sas_port_delete(port); + goto out_fail; } if (mr_sas_port->remote_identify.device_type == SAS_END_DEVICE) { tgtdev->dev_spec.sas_sata_inf.pend_sas_rphy_add = 0; @@ -1486,11 +1539,14 @@ static struct mpi3mr_sas_port *mpi3mr_sas_port_add(struct mpi3mr_ioc *mrioc, list_add_tail(&mr_sas_port->port_list, &mr_sas_node->sas_port_list); spin_unlock_irqrestore(&mrioc->sas_node_lock, flags); + spin_lock_irqsave(&mrioc->fwevt_lock, flags); if (mrioc->current_event) { mrioc->current_event->pending_at_sml = 0; - if (mrioc->current_event->discard) - mpi3mr_print_device_event_notice(mrioc, true); + discard = mrioc->current_event->discard; } + spin_unlock_irqrestore(&mrioc->fwevt_lock, flags); + if (discard) + mpi3mr_print_device_event_notice(mrioc, true); /* fill in report manufacture */ if (mr_sas_port->remote_identify.device_type == @@ -1504,11 +1560,17 @@ static struct mpi3mr_sas_port *mpi3mr_sas_port_add(struct mpi3mr_ioc *mrioc, return mr_sas_port; out_fail: + if (tgtdev) { + tgtdev->dev_spec.sas_sata_inf.pend_sas_rphy_add = 0; + tgtdev->dev_spec.sas_sata_inf.rphy = NULL; + mpi3mr_tgtdev_put(tgtdev); + } + list_for_each_entry_safe(mr_sas_phy, next, &mr_sas_port->phy_list, - port_siblings) + port_siblings) { + mr_sas_phy->phy_belongs_to_port = 0; list_del(&mr_sas_phy->port_siblings); - if (tgtdev) - mpi3mr_tgtdev_put(tgtdev); + } kfree(mr_sas_port); return NULL; } @@ -1530,6 +1592,7 @@ static void mpi3mr_sas_port_remove(struct mpi3mr_ioc *mrioc, u64 sas_address, { int i; unsigned long flags; + bool discard = false; struct mpi3mr_sas_port *mr_sas_port, *next; struct mpi3mr_sas_node *mr_sas_node; u8 found = 0; @@ -1586,8 +1649,10 @@ static void mpi3mr_sas_port_remove(struct mpi3mr_ioc *mrioc, u64 sas_address, spin_unlock_irqrestore(&mrioc->sas_node_lock, flags); + spin_lock_irqsave(&mrioc->fwevt_lock, flags); if (mrioc->current_event) mrioc->current_event->pending_at_sml = 1; + spin_unlock_irqrestore(&mrioc->fwevt_lock, flags); list_for_each_entry_safe(mr_sas_phy, next_phy, &mr_sas_port->phy_list, port_siblings) { @@ -1609,11 +1674,14 @@ static void mpi3mr_sas_port_remove(struct mpi3mr_ioc *mrioc, u64 sas_address, ioc_info(mrioc, "%s: removed sas_address(0x%016llx)\n", __func__, (unsigned long long)sas_address); + spin_lock_irqsave(&mrioc->fwevt_lock, flags); if (mrioc->current_event) { mrioc->current_event->pending_at_sml = 0; - if (mrioc->current_event->discard) - mpi3mr_print_device_event_notice(mrioc, false); + discard = mrioc->current_event->discard; } + spin_unlock_irqrestore(&mrioc->fwevt_lock, flags); + if (discard) + mpi3mr_print_device_event_notice(mrioc, false); kfree(mr_sas_port); } diff --git a/drivers/scsi/mpt3sas/Makefile b/drivers/scsi/mpt3sas/Makefile index 18e2d87eb4a2..c698a106f3e3 100644 --- a/drivers/scsi/mpt3sas/Makefile +++ b/drivers/scsi/mpt3sas/Makefile @@ -1,5 +1,8 @@ # SPDX-License-Identifier: GPL-2.0 # mpt3sas makefile + +CONTEXT_ANALYSIS := y + obj-$(CONFIG_SCSI_MPT3SAS) += mpt3sas.o mpt3sas-y += mpt3sas_base.o \ mpt3sas_config.o \ diff --git a/drivers/scsi/mpt3sas/mpt3sas_scsih.c b/drivers/scsi/mpt3sas/mpt3sas_scsih.c index 0e12009a87f6..085d4672db85 100644 --- a/drivers/scsi/mpt3sas/mpt3sas_scsih.c +++ b/drivers/scsi/mpt3sas/mpt3sas_scsih.c @@ -5401,23 +5401,23 @@ _scsih_setup_eedp(struct MPT3SAS_ADAPTER *ioc, struct scsi_cmnd *scmd, static void _scsih_eedp_error_handling(struct scsi_cmnd *scmd, u16 ioc_status) { - u8 ascq; + u16 sense_code; switch (ioc_status) { case MPI2_IOCSTATUS_EEDP_GUARD_ERROR: - ascq = 0x01; + sense_code = LOGICAL_BLOCK_GUARD_CHECK_FAILED; break; case MPI2_IOCSTATUS_EEDP_APP_TAG_ERROR: - ascq = 0x02; + sense_code = LOGICAL_BLOCK_APPLICATION_TAG_CHECK_FAILED; break; case MPI2_IOCSTATUS_EEDP_REF_TAG_ERROR: - ascq = 0x03; + sense_code = LOGICAL_BLOCK_REFERENCE_TAG_CHECK_FAILED; break; default: - ascq = 0x00; + sense_code = ID_CRC_OR_ECC_ERROR; break; } - scsi_build_sense(scmd, 0, ILLEGAL_REQUEST, 0x10, ascq); + scsi_set_sense(scmd, 0, ILLEGAL_REQUEST, sense_code); set_host_byte(scmd, DID_ABORT); } @@ -5474,7 +5474,8 @@ static enum scsi_qc_status scsih_qcmd(struct Scsi_Host *shost, if (handle == MPT3SAS_INVALID_DEVICE_HANDLE || sas_device_priv_data->block) { if (scsi_get_host_state(scmd->device->host) == SHOST_RECOVERY && scmd->cmnd[0] == TEST_UNIT_READY) { - scsi_build_sense(scmd, 0, UNIT_ATTENTION, 0x29, 0x07); + scsi_set_sense(scmd, 0, UNIT_ATTENTION, + I_T_NEXUS_LOSS_OCCURRED); scsi_done(scmd); return 0; } @@ -5986,7 +5987,7 @@ _scsih_smart_predicted_fault(struct MPT3SAS_ADAPTER *ioc, u16 handle) event_data = (Mpi2EventDataSasDeviceStatusChange_t *) event_reply->EventData; event_data->ReasonCode = MPI2_EVENT_SAS_DEV_STAT_RC_SMART_DATA; - event_data->ASC = 0x5D; + event_data->ASC = ASC_FAILURE_PREDICTION_THRESHOLD_EXCEEDED; event_data->DevHandle = cpu_to_le16(handle); event_data->SASAddress = cpu_to_le64(sas_target_priv_data->sas_address); mpt3sas_ctl_add_to_event_log(ioc, event_reply); @@ -6109,8 +6110,7 @@ _scsih_io_done(struct MPT3SAS_ADAPTER *ioc, u16 smid, u8 msix_index, u32 reply) le32_to_cpu(mpi_reply->SenseCount)); memcpy(scmd->sense_buffer, sense_data, sz); _scsih_normalize_sense(scmd->sense_buffer, &data); - /* failure prediction threshold exceeded */ - if (data.asc == 0x5D) + if (data.asc == ASC_FAILURE_PREDICTION_THRESHOLD_EXCEEDED) _scsih_smart_predicted_fault(ioc, le16_to_cpu(mpi_reply->DevHandle)); mpt3sas_trigger_scsi(ioc, data.skey, data.asc, data.ascq); @@ -6199,8 +6199,8 @@ _scsih_io_done(struct MPT3SAS_ADAPTER *ioc, u16 smid, u8 msix_index, u32 reply) else if (!xfer_cnt && scmd->cmnd[0] == REPORT_LUNS) { mpi_reply->SCSIState = MPI2_SCSI_STATE_AUTOSENSE_VALID; mpi_reply->SCSIStatus = SAM_STAT_CHECK_CONDITION; - scsi_build_sense(scmd, 0, ILLEGAL_REQUEST, - 0x20, 0); + scsi_set_sense(scmd, 0, ILLEGAL_REQUEST, + INVALID_COMMAND_OP_CODE); } break; @@ -7691,38 +7691,41 @@ _scsih_determine_disposition(struct MPT3SAS_ADAPTER *ioc, if (check_sense) { _scsih_normalize_sense(transfer_packet->sense, &sense_info); - if (sense_info.skey == UNIT_ATTENTION) + if (sense_info.skey == UNIT_ATTENTION) { rc = DEVICE_RETRY_UA; - else if (sense_info.skey == NOT_READY) { - /* medium isn't present */ - if (sense_info.asc == 0x3a) + } else if (sense_info.skey == NOT_READY) { + if (sense_info.asc == ASC_MEDIUM_NOT_PRESENT) { rc = DEVICE_READY; - /* LOGICAL UNIT NOT READY */ - else if (sense_info.asc == 0x04) { - if (sense_info.ascq == 0x03 || - sense_info.ascq == 0x0b || - sense_info.ascq == 0x0c) { + } else if (sense_info.asc == ASC_LU_NOT_READY) { + u16 scode = scsi_sense_code(sense_info.asc, + sense_info.ascq); + + if (scode == + LU_NOT_READY_MANUAL_INTERVENTION_REQUIRED || + scode == + LU_NOT_ACCESSIBLE_TARGET_PORT_IN_STANDBY_STATE || + scode == + LU_NOT_ACCESSIBLE_TARGET_PORT_IN_UNAVAILABLE_STATE) rc = DEVICE_ERROR; - } else + else rc = DEVICE_START_UNIT; - } - /* LOGICAL UNIT HAS NOT SELF-CONFIGURED YET */ - else if (sense_info.asc == 0x3e && !sense_info.ascq) + } else if (sense_info.asc == + ASC_LU_HAS_NOT_SELF_CONFIGURED_YET && + !sense_info.ascq) { rc = DEVICE_START_UNIT; + } } else if (sense_info.skey == ILLEGAL_REQUEST && - transfer_packet->cdb[0] == REPORT_LUNS) { + transfer_packet->cdb[0] == REPORT_LUNS) { rc = DEVICE_READY; } else if (sense_info.skey == MEDIUM_ERROR) { - - /* medium is corrupt, lets add the device so - * users can collect some info as needed + /* + * medium is corrupt, lets add the device so users can + * collect some info as needed */ - - if (sense_info.asc == 0x31) + if (sense_info.asc == ASC_MEDIUM_FORMAT_CORRUPTED) rc = DEVICE_READY; } else if (sense_info.skey == HARDWARE_ERROR) { - /* Defect List Error, still add the device */ - if (sense_info.asc == 0x19) + if (sense_info.asc == ASC_DEFECT_LIST_ERROR) rc = DEVICE_READY; } } diff --git a/drivers/scsi/mvsas/Makefile b/drivers/scsi/mvsas/Makefile index 75849258e898..7f45cca38127 100644 --- a/drivers/scsi/mvsas/Makefile +++ b/drivers/scsi/mvsas/Makefile @@ -7,6 +7,8 @@ # Copyright 2009-2011 Marvell. # +CONTEXT_ANALYSIS := y + ccflags-$(CONFIG_SCSI_MVSAS_DEBUG) := -DMV_DEBUG obj-$(CONFIG_SCSI_MVSAS) += mvsas.o diff --git a/drivers/scsi/mvsas/mv_sas.c b/drivers/scsi/mvsas/mv_sas.c index 359226e80eae..d604aaac14a2 100644 --- a/drivers/scsi/mvsas/mv_sas.c +++ b/drivers/scsi/mvsas/mv_sas.c @@ -1055,6 +1055,7 @@ void mvs_update_phyinfo(struct mvs_info *mvi, int i, int get_st) } static void mvs_port_notify_formed(struct asd_sas_phy *sas_phy, int lock) + __context_unsafe(/*conditional locking*/) { struct sas_ha_struct *sas_ha = sas_phy->ha; struct mvs_info *mvi = NULL; int i = 0, hi; @@ -1153,6 +1154,7 @@ static void mvs_free_dev(struct mvs_device *mvi_dev) } static int mvs_dev_found_notify(struct domain_device *dev, int lock) + __context_unsafe(/*conditional locking*/) { unsigned long flags = 0; int res = 0; @@ -1517,6 +1519,7 @@ static int mvs_slot_err(struct mvs_info *mvi, struct sas_task *task, } int mvs_slot_complete(struct mvs_info *mvi, u32 rx_desc, u32 flags) + __must_hold(&mvi->lock) { u32 slot_idx = rx_desc & RXQ_SLOT_MASK; struct mvs_slot_info *slot = &mvi->slot_info[slot_idx]; @@ -1644,6 +1647,7 @@ int mvs_slot_complete(struct mvs_info *mvi, u32 rx_desc, u32 flags) void mvs_do_release_task(struct mvs_info *mvi, int phy_no, struct domain_device *dev) + __must_hold(&mvi->lock) { u32 slot_idx; struct mvs_phy *phy; @@ -1677,6 +1681,7 @@ void mvs_do_release_task(struct mvs_info *mvi, void mvs_release_task(struct mvs_info *mvi, struct domain_device *dev) + __must_hold(&mvi->lock) { int i, phyno[WIDE_PORT_MAX_PHY], num; num = mvs_find_dev_phyno(dev, phyno); @@ -1769,6 +1774,7 @@ static void mvs_sig_time_out(struct timer_list *t) } void mvs_int_port(struct mvs_info *mvi, int phy_no, u32 events) + __must_hold(&mvi->lock) { u32 tmp; struct mvs_phy *phy = &mvi->phy[phy_no]; @@ -1862,6 +1868,7 @@ void mvs_int_port(struct mvs_info *mvi, int phy_no, u32 events) } int mvs_int_rx(struct mvs_info *mvi, bool self_clear) + __must_hold(&mvi->lock) { u32 rx_prod_idx, rx_desc; bool attn = false; diff --git a/drivers/scsi/mvumi.c b/drivers/scsi/mvumi.c index e70d336b4ab3..91c2db697c69 100644 --- a/drivers/scsi/mvumi.c +++ b/drivers/scsi/mvumi.c @@ -722,9 +722,9 @@ static int mvumi_issue_blocked_cmd(struct mvumi_hba *mhba, return -1; } atomic_inc(&cmd->sync_cmd); - spin_lock_irqsave(mhba->shost->host_lock, flags); + spin_lock_irqsave(&mhba->shost->host_lock, flags); mhba->instancet->fire_cmd(mhba, cmd); - spin_unlock_irqrestore(mhba->shost->host_lock, flags); + spin_unlock_irqrestore(&mhba->shost->host_lock, flags); wait_event_timeout(mhba->int_cmd_wait_q, (cmd->cmd_status != REQ_STATUS_PENDING), @@ -732,7 +732,7 @@ static int mvumi_issue_blocked_cmd(struct mvumi_hba *mhba, /* command timeout */ if (atomic_read(&cmd->sync_cmd)) { - spin_lock_irqsave(mhba->shost->host_lock, flags); + spin_lock_irqsave(&mhba->shost->host_lock, flags); atomic_dec(&cmd->sync_cmd); if (mhba->tag_cmd[cmd->frame->tag]) { mhba->tag_cmd[cmd->frame->tag] = NULL; @@ -747,7 +747,7 @@ static int mvumi_issue_blocked_cmd(struct mvumi_hba *mhba, } else atomic_dec(&mhba->fw_outstanding); - spin_unlock_irqrestore(mhba->shost->host_lock, flags); + spin_unlock_irqrestore(&mhba->shost->host_lock, flags); } return 0; } @@ -1791,9 +1791,9 @@ static irqreturn_t mvumi_isr_handler(int irq, void *devp) struct mvumi_hba *mhba = (struct mvumi_hba *) devp; unsigned long flags; - spin_lock_irqsave(mhba->shost->host_lock, flags); + spin_lock_irqsave(&mhba->shost->host_lock, flags); if (unlikely(mhba->instancet->clear_intr(mhba) || !mhba->global_isr)) { - spin_unlock_irqrestore(mhba->shost->host_lock, flags); + spin_unlock_irqrestore(&mhba->shost->host_lock, flags); return IRQ_NONE; } @@ -1814,7 +1814,7 @@ static irqreturn_t mvumi_isr_handler(int irq, void *devp) mhba->isr_status = 0; if (mhba->fw_state == FW_STATE_STARTED) mvumi_handle_clob(mhba); - spin_unlock_irqrestore(mhba->shost->host_lock, flags); + spin_unlock_irqrestore(&mhba->shost->host_lock, flags); return IRQ_HANDLED; } @@ -2067,7 +2067,7 @@ static unsigned char mvumi_build_frame(struct mvumi_hba *mhba, return 0; error: - scsi_build_sense(scmd, 0, ILLEGAL_REQUEST, 0x24, 0); + scsi_set_sense(scmd, 0, ILLEGAL_REQUEST, INVALID_FIELD_IN_CDB); return -1; } @@ -2083,13 +2083,13 @@ static enum scsi_qc_status mvumi_queue_command(struct Scsi_Host *shost, struct mvumi_hba *mhba; unsigned long irq_flags; - spin_lock_irqsave(shost->host_lock, irq_flags); + spin_lock_irqsave(&shost->host_lock, irq_flags); mhba = (struct mvumi_hba *) shost->hostdata; scmd->result = 0; cmd = mvumi_get_cmd(mhba); if (unlikely(!cmd)) { - spin_unlock_irqrestore(shost->host_lock, irq_flags); + spin_unlock_irqrestore(&shost->host_lock, irq_flags); return SCSI_MLQUEUE_HOST_BUSY; } @@ -2099,13 +2099,13 @@ static enum scsi_qc_status mvumi_queue_command(struct Scsi_Host *shost, cmd->scmd = scmd; mvumi_priv(scmd)->cmd_priv = cmd; mhba->instancet->fire_cmd(mhba, cmd); - spin_unlock_irqrestore(shost->host_lock, irq_flags); + spin_unlock_irqrestore(&shost->host_lock, irq_flags); return 0; out_return_cmd: mvumi_return_cmd(mhba, cmd); scsi_done(scmd); - spin_unlock_irqrestore(shost->host_lock, irq_flags); + spin_unlock_irqrestore(&shost->host_lock, irq_flags); return 0; } @@ -2116,7 +2116,7 @@ static enum scsi_timeout_action mvumi_timed_out(struct scsi_cmnd *scmd) struct mvumi_hba *mhba = shost_priv(host); unsigned long flags; - spin_lock_irqsave(mhba->shost->host_lock, flags); + spin_lock_irqsave(&mhba->shost->host_lock, flags); if (mhba->tag_cmd[cmd->frame->tag]) { mhba->tag_cmd[cmd->frame->tag] = NULL; @@ -2135,7 +2135,7 @@ static enum scsi_timeout_action mvumi_timed_out(struct scsi_cmnd *scmd) scmd->sc_data_direction); } mvumi_return_cmd(mhba, cmd); - spin_unlock_irqrestore(mhba->shost->host_lock, flags); + spin_unlock_irqrestore(&mhba->shost->host_lock, flags); return SCSI_EH_NOT_HANDLED; } diff --git a/drivers/scsi/myrb.c b/drivers/scsi/myrb.c index 3678b66310ed..95df6e5345f7 100644 --- a/drivers/scsi/myrb.c +++ b/drivers/scsi/myrb.c @@ -314,17 +314,19 @@ static void myrb_get_event(struct myrb_hba *cb, unsigned int event) scsi_normalize_sense(ev_buf->sense, 32, &sshdr); if (sshdr.sense_key == VENDOR_SPECIFIC && - sshdr.asc == 0x80 && - sshdr.ascq < ARRAY_SIZE(myrb_event_msg)) + scsi_sense_asc(&sshdr) == 0x80 && + scsi_sense_ascq(&sshdr) < ARRAY_SIZE(myrb_event_msg)) shost_printk(KERN_CRIT, cb->host, "Physical drive %d:%d: %s\n", ev_buf->channel, ev_buf->target, - myrb_event_msg[sshdr.ascq]); + myrb_event_msg[scsi_sense_ascq(&sshdr)]); else shost_printk(KERN_CRIT, cb->host, "Physical drive %d:%d: Sense: %X/%02X/%02X\n", ev_buf->channel, ev_buf->target, - sshdr.sense_key, sshdr.asc, sshdr.ascq); + sshdr.sense_key, + scsi_sense_asc(&sshdr), + scsi_sense_ascq(&sshdr)); } dma_free_coherent(&cb->pdev->dev, sizeof(struct myrb_log_entry), @@ -1398,7 +1400,7 @@ myrb_mode_sense(struct myrb_hba *cb, struct scsi_cmnd *scmd, static void myrb_request_sense(struct myrb_hba *cb, struct scsi_cmnd *scmd) { - scsi_build_sense(scmd, 0, NO_SENSE, 0, 0); + scsi_set_sense(scmd, 0, NO_SENSE, NO_ADDITIONAL_SENSE_INFORMATION); scsi_sg_copy_from_buffer(scmd, scmd->sense_buffer, SCSI_SENSE_BUFFERSIZE); } @@ -1446,8 +1448,8 @@ static enum scsi_qc_status myrb_ldev_queuecommand(struct Scsi_Host *shost, return 0; case INQUIRY: if (scmd->cmnd[1] & 1) { - /* Illegal request, invalid field in CDB */ - scsi_build_sense(scmd, 0, ILLEGAL_REQUEST, 0x24, 0); + scsi_set_sense(scmd, 0, ILLEGAL_REQUEST, + INVALID_FIELD_IN_CDB); } else { myrb_inquiry(cb, scmd); scmd->result = (DID_OK << 16); @@ -1461,8 +1463,8 @@ static enum scsi_qc_status myrb_ldev_queuecommand(struct Scsi_Host *shost, case MODE_SENSE: if ((scmd->cmnd[2] & 0x3F) != 0x3F && (scmd->cmnd[2] & 0x3F) != 0x08) { - /* Illegal request, invalid field in CDB */ - scsi_build_sense(scmd, 0, ILLEGAL_REQUEST, 0x24, 0); + scsi_set_sense(scmd, 0, ILLEGAL_REQUEST, + INVALID_FIELD_IN_CDB); } else { myrb_mode_sense(cb, scmd, ldev_info); scmd->result = (DID_OK << 16); @@ -1472,15 +1474,15 @@ static enum scsi_qc_status myrb_ldev_queuecommand(struct Scsi_Host *shost, case READ_CAPACITY: if ((scmd->cmnd[1] & 1) || (scmd->cmnd[8] & 1)) { - /* Illegal request, invalid field in CDB */ - scsi_build_sense(scmd, 0, ILLEGAL_REQUEST, 0x24, 0); + scsi_set_sense(scmd, 0, ILLEGAL_REQUEST, + INVALID_FIELD_IN_CDB); scsi_done(scmd); return 0; } lba = get_unaligned_be32(&scmd->cmnd[2]); if (lba) { - /* Illegal request, invalid field in CDB */ - scsi_build_sense(scmd, 0, ILLEGAL_REQUEST, 0x24, 0); + scsi_set_sense(scmd, 0, ILLEGAL_REQUEST, + INVALID_FIELD_IN_CDB); scsi_done(scmd); return 0; } @@ -1493,8 +1495,8 @@ static enum scsi_qc_status myrb_ldev_queuecommand(struct Scsi_Host *shost, return 0; case SEND_DIAGNOSTIC: if (scmd->cmnd[1] != 0x04) { - /* Illegal request, invalid field in CDB */ - scsi_build_sense(scmd, 0, ILLEGAL_REQUEST, 0x24, 0); + scsi_set_sense(scmd, 0, ILLEGAL_REQUEST, + INVALID_FIELD_IN_CDB); } else { /* Assume good status */ scmd->result = (DID_OK << 16); @@ -1503,8 +1505,8 @@ static enum scsi_qc_status myrb_ldev_queuecommand(struct Scsi_Host *shost, return 0; case READ_6: if (ldev_info->state == MYRB_DEVICE_WO) { - /* Data protect, attempt to read invalid data */ - scsi_build_sense(scmd, 0, DATA_PROTECT, 0x21, 0x06); + scsi_set_sense(scmd, 0, DATA_PROTECT, + ATTEMPT_TO_READ_INVALID_DATA); scsi_done(scmd); return 0; } @@ -1517,8 +1519,8 @@ static enum scsi_qc_status myrb_ldev_queuecommand(struct Scsi_Host *shost, break; case READ_10: if (ldev_info->state == MYRB_DEVICE_WO) { - /* Data protect, attempt to read invalid data */ - scsi_build_sense(scmd, 0, DATA_PROTECT, 0x21, 0x06); + scsi_set_sense(scmd, 0, DATA_PROTECT, + ATTEMPT_TO_READ_INVALID_DATA); scsi_done(scmd); return 0; } @@ -1531,8 +1533,8 @@ static enum scsi_qc_status myrb_ldev_queuecommand(struct Scsi_Host *shost, break; case READ_12: if (ldev_info->state == MYRB_DEVICE_WO) { - /* Data protect, attempt to read invalid data */ - scsi_build_sense(scmd, 0, DATA_PROTECT, 0x21, 0x06); + scsi_set_sense(scmd, 0, DATA_PROTECT, + ATTEMPT_TO_READ_INVALID_DATA); scsi_done(scmd); return 0; } @@ -1544,8 +1546,8 @@ static enum scsi_qc_status myrb_ldev_queuecommand(struct Scsi_Host *shost, block_cnt = get_unaligned_be32(&scmd->cmnd[6]); break; default: - /* Illegal request, invalid opcode */ - scsi_build_sense(scmd, 0, ILLEGAL_REQUEST, 0x20, 0); + scsi_set_sense(scmd, 0, ILLEGAL_REQUEST, + INVALID_COMMAND_OP_CODE); scsi_done(scmd); return 0; } @@ -2328,20 +2330,19 @@ static void myrb_handle_scsi(struct myrb_hba *cb, struct myrb_cmdblk *cmd_blk, dev_dbg(&scmd->device->sdev_gendev, "Bad Data Encountered\n"); if (scmd->sc_data_direction == DMA_FROM_DEVICE) - /* Unrecovered read error */ - scsi_build_sense(scmd, 0, MEDIUM_ERROR, 0x11, 0); + scsi_set_sense(scmd, 0, MEDIUM_ERROR, + UNRECOVERED_READ_ERROR); else - /* Write error */ - scsi_build_sense(scmd, 0, MEDIUM_ERROR, 0x0C, 0); + scsi_set_sense(scmd, 0, MEDIUM_ERROR, SSC_WRITE_ERROR); break; case MYRB_STATUS_IRRECOVERABLE_DATA_ERROR: scmd_printk(KERN_ERR, scmd, "Irrecoverable Data Error\n"); if (scmd->sc_data_direction == DMA_FROM_DEVICE) - /* Unrecovered read error, auto-reallocation failed */ - scsi_build_sense(scmd, 0, MEDIUM_ERROR, 0x11, 0x04); + scsi_set_sense(scmd, 0, MEDIUM_ERROR, + UNRECOVERED_READ_ERROR_AUTO_REALLOCATE_FAILED); else - /* Write error, auto-reallocation failed */ - scsi_build_sense(scmd, 0, MEDIUM_ERROR, 0x0C, 0x02); + scsi_set_sense(scmd, 0, MEDIUM_ERROR, + WRITE_ERROR_AUTO_REALLOCATION_FAILED); break; case MYRB_STATUS_LDRV_NONEXISTENT_OR_OFFLINE: dev_dbg(&scmd->device->sdev_gendev, @@ -2351,8 +2352,8 @@ static void myrb_handle_scsi(struct myrb_hba *cb, struct myrb_cmdblk *cmd_blk, case MYRB_STATUS_ACCESS_BEYOND_END_OF_LDRV: dev_dbg(&scmd->device->sdev_gendev, "Attempt to Access Beyond End of Logical Drive"); - /* Logical block address out of range */ - scsi_build_sense(scmd, 0, NOT_READY, 0x21, 0); + scsi_set_sense(scmd, 0, NOT_READY, + LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE); break; case MYRB_STATUS_DEVICE_NONRESPONSIVE: dev_dbg(&scmd->device->sdev_gendev, "Device nonresponsive\n"); diff --git a/drivers/scsi/myrs.c b/drivers/scsi/myrs.c index afd68225221a..1192b01fab8e 100644 --- a/drivers/scsi/myrs.c +++ b/drivers/scsi/myrs.c @@ -816,7 +816,7 @@ static void myrs_log_event(struct myrs_hba *cs, struct myrs_event *ev) struct Scsi_Host *shost = cs->host; struct scsi_device *sdev; struct scsi_sense_hdr sshdr = {0}; - unsigned char sense_info[4]; + unsigned char asc, sense_info[4]; unsigned char cmd_specific[4]; if (ev->ev_code == 0x1C) { @@ -829,9 +829,11 @@ static void myrs_log_event(struct myrs_hba *cs, struct myrs_event *ev) memcpy(cmd_specific, &ev->sense_data[7], 4); } } + asc = scsi_sense_asc(&sshdr); if (sshdr.sense_key == VENDOR_SPECIFIC && - (sshdr.asc == 0x80 || sshdr.asc == 0x81)) - ev->ev_code = ((sshdr.asc - 0x80) << 8 | sshdr.ascq); + (asc == 0x80 || asc == 0x81)) + ev->ev_code = scsi_sense_code(asc - 0x80, + scsi_sense_ascq(&sshdr)); while (true) { ev_code = myrs_ev_list[ev_idx].ev_code; if (ev_code == ev->ev_code || ev_code == 0) @@ -891,8 +893,9 @@ static void myrs_log_event(struct myrs_hba *cs, struct myrs_event *ev) case 'S': if (sshdr.sense_key == NO_SENSE || (sshdr.sense_key == NOT_READY && - sshdr.asc == 0x04 && (sshdr.ascq == 0x01 || - sshdr.ascq == 0x02))) + (sshdr.sense_code == LU_IS_IN_PROCESS_OF_BECOMING_READY || + sshdr.sense_code == + LU_NOT_READY_INITIALIZING_COMMAND_REQUIRED))) break; shost_printk(KERN_INFO, shost, "event %d: Physical Device %d:%d %s\n", @@ -900,7 +903,8 @@ static void myrs_log_event(struct myrs_hba *cs, struct myrs_event *ev) shost_printk(KERN_INFO, shost, "Physical Device %d:%d Sense Key = %X, ASC = %02X, ASCQ = %02X\n", ev->channel, ev->target, - sshdr.sense_key, sshdr.asc, sshdr.ascq); + sshdr.sense_key, scsi_sense_asc(&sshdr), + scsi_sense_ascq(&sshdr)); shost_printk(KERN_INFO, shost, "Physical Device %d:%d Sense Information = %02X%02X%02X%02X %02X%02X%02X%02X\n", ev->channel, ev->target, @@ -1603,7 +1607,8 @@ static enum scsi_qc_status myrs_queuecommand(struct Scsi_Host *shost, switch (scmd->cmnd[0]) { case REPORT_LUNS: - scsi_build_sense(scmd, 0, ILLEGAL_REQUEST, 0x20, 0x0); + scsi_set_sense(scmd, 0, ILLEGAL_REQUEST, + INVALID_COMMAND_OP_CODE); scsi_done(scmd); return 0; case MODE_SENSE: @@ -1612,8 +1617,8 @@ static enum scsi_qc_status myrs_queuecommand(struct Scsi_Host *shost, if ((scmd->cmnd[2] & 0x3F) != 0x3F && (scmd->cmnd[2] & 0x3F) != 0x08) { - /* Illegal request, invalid field in CDB */ - scsi_build_sense(scmd, 0, ILLEGAL_REQUEST, 0x24, 0); + scsi_set_sense(scmd, 0, ILLEGAL_REQUEST, + INVALID_FIELD_IN_CDB); } else { myrs_mode_sense(cs, scmd, ldev_info); scmd->result = (DID_OK << 16); diff --git a/drivers/scsi/nsp32.c b/drivers/scsi/nsp32.c index 9c9281222a0a..98550c73d8a0 100644 --- a/drivers/scsi/nsp32.c +++ b/drivers/scsi/nsp32.c @@ -1166,7 +1166,7 @@ static irqreturn_t do_nsp32_isr(int irq, void *dev_id) int handled = 0; struct Scsi_Host *host = data->Host; - spin_lock_irqsave(host->host_lock, flags); + spin_lock_irqsave(&host->host_lock, flags); /* * IRQ check, then enable IRQ mask @@ -1433,7 +1433,7 @@ static irqreturn_t do_nsp32_isr(int irq, void *dev_id) nsp32_write2(base, IRQ_CONTROL, 0); out2: - spin_unlock_irqrestore(host->host_lock, flags); + spin_unlock_irqrestore(&host->host_lock, flags); nsp32_dbg(NSP32_DEBUG_INTR, "exit"); @@ -2886,14 +2886,14 @@ static int nsp32_eh_host_reset(struct scsi_cmnd *SCpnt) nsp32_msg(KERN_INFO, "Host Reset"); nsp32_dbg(NSP32_DEBUG_BUSRESET, "SCpnt=0x%x", SCpnt); - spin_lock_irq(SCpnt->device->host->host_lock); + spin_lock_irq(&SCpnt->device->host->host_lock); nsp32hw_init(data); nsp32_write2(base, IRQ_CONTROL, IRQ_CONTROL_ALL_IRQ_MASK); nsp32_do_bus_reset(data); nsp32_write2(base, IRQ_CONTROL, 0); - spin_unlock_irq(SCpnt->device->host->host_lock); + spin_unlock_irq(&SCpnt->device->host->host_lock); return SUCCESS; /* Host reset is succeeded at any time. */ } diff --git a/drivers/scsi/pcmcia/Makefile b/drivers/scsi/pcmcia/Makefile index 02f5b44a2685..06ea2bfcd42a 100644 --- a/drivers/scsi/pcmcia/Makefile +++ b/drivers/scsi/pcmcia/Makefile @@ -1,5 +1,7 @@ # SPDX-License-Identifier: GPL-2.0 +CONTEXT_ANALYSIS := y + ccflags-y := -I $(srctree)/drivers/scsi # 16-bit client drivers diff --git a/drivers/scsi/pcmcia/sym53c500_cs.c b/drivers/scsi/pcmcia/sym53c500_cs.c index 1530c1ad5d36..aeae5c16e406 100644 --- a/drivers/scsi/pcmcia/sym53c500_cs.c +++ b/drivers/scsi/pcmcia/sym53c500_cs.c @@ -360,7 +360,7 @@ SYM53C500_intr(int irq, void *dev_id) struct sym53c500_cmd_priv *scp = scsi_cmd_priv(curSC); int fast_pio = data->fast_pio; - spin_lock_irqsave(dev->host_lock, flags); + spin_lock_irqsave(&dev->host_lock, flags); VDEB(printk("SYM53C500_intr called\n")); @@ -494,7 +494,7 @@ SYM53C500_intr(int irq, void *dev_id) break; } out: - spin_unlock_irqrestore(dev->host_lock, flags); + spin_unlock_irqrestore(&dev->host_lock, flags); return IRQ_HANDLED; idle_out: @@ -588,9 +588,9 @@ SYM53C500_host_reset(struct scsi_cmnd *SCpnt) int port_base = SCpnt->device->host->io_port; DEB(printk("SYM53C500_host_reset called\n")); - spin_lock_irq(SCpnt->device->host->host_lock); + spin_lock_irq(&SCpnt->device->host->host_lock); SYM53C500_int_host_reset(port_base); - spin_unlock_irq(SCpnt->device->host->host_lock); + spin_unlock_irq(&SCpnt->device->host->host_lock); return SUCCESS; } diff --git a/drivers/scsi/pm8001/Makefile b/drivers/scsi/pm8001/Makefile index bbb51b7312f1..b236359810fe 100644 --- a/drivers/scsi/pm8001/Makefile +++ b/drivers/scsi/pm8001/Makefile @@ -4,6 +4,7 @@ # # Copyright (C) 2008-2009 USI Co., Ltd. +CONTEXT_ANALYSIS := y obj-$(CONFIG_SCSI_PM8001) += pm80xx.o diff --git a/drivers/scsi/pm8001/pm8001_defs.h b/drivers/scsi/pm8001/pm8001_defs.h index 4e19d61dffbb..a9605ca317f3 100644 --- a/drivers/scsi/pm8001/pm8001_defs.h +++ b/drivers/scsi/pm8001/pm8001_defs.h @@ -41,6 +41,104 @@ #ifndef _PM8001_DEFS_H_ #define _PM8001_DEFS_H_ +#include + +#ifdef __LITTLE_ENDIAN_BITFIELD +struct sas_identify_frame_local { + /* Byte 0 */ + u8 frame_type:4; + u8 dev_type:3; + u8 _un0:1; + + /* Byte 1 */ + u8 _un1; + + /* Byte 2 */ + union { + struct { + u8 _un20:1; + u8 smp_iport:1; + u8 stp_iport:1; + u8 ssp_iport:1; + u8 _un247:4; + }; + u8 initiator_bits; + }; + + /* Byte 3 */ + union { + struct { + u8 _un30:1; + u8 smp_tport:1; + u8 stp_tport:1; + u8 ssp_tport:1; + u8 _un347:4; + }; + u8 target_bits; + }; + + /* Byte 4 - 11 */ + u8 _un4_11[8]; + + /* Byte 12 - 19 */ + u8 sas_addr[SAS_ADDR_SIZE]; + + /* Byte 20 */ + u8 phy_id; + + u8 _un21_27[7]; + +} __packed; + +#elif defined(__BIG_ENDIAN_BITFIELD) +struct sas_identify_frame_local { + /* Byte 0 */ + u8 _un0:1; + u8 dev_type:3; + u8 frame_type:4; + + /* Byte 1 */ + u8 _un1; + + /* Byte 2 */ + union { + struct { + u8 _un247:4; + u8 ssp_iport:1; + u8 stp_iport:1; + u8 smp_iport:1; + u8 _un20:1; + }; + u8 initiator_bits; + }; + + /* Byte 3 */ + union { + struct { + u8 _un347:4; + u8 ssp_tport:1; + u8 stp_tport:1; + u8 smp_tport:1; + u8 _un30:1; + }; + u8 target_bits; + }; + + /* Byte 4 - 11 */ + u8 _un4_11[8]; + + /* Byte 12 - 19 */ + u8 sas_addr[SAS_ADDR_SIZE]; + + /* Byte 20 */ + u8 phy_id; + + u8 _un21_27[7]; +} __packed; +#else +#error "Bitfield order not defined!" +#endif + enum chip_flavors { chip_8001, chip_8008, diff --git a/drivers/scsi/pm8001/pm8001_hwi.c b/drivers/scsi/pm8001/pm8001_hwi.c index fff8d877abb9..55a01e533fd1 100644 --- a/drivers/scsi/pm8001/pm8001_hwi.c +++ b/drivers/scsi/pm8001/pm8001_hwi.c @@ -3208,7 +3208,7 @@ hw_event_sata_phy_up(struct pm8001_hba_info *pm8001_ha, void *piomb) phy->sas_phy.oob_mode = SATA_OOB_MODE; sas_notify_phy_event(&phy->sas_phy, PHYE_OOB_DONE, GFP_ATOMIC); spin_lock_irqsave(&phy->sas_phy.frame_rcvd_lock, flags); - memcpy(phy->frame_rcvd, ((u8 *)&pPayload->sata_fis - 4), + memcpy(phy->frame_rcvd, &pPayload->sata_fis, sizeof(struct dev_to_host_fis)); phy->frame_rcvd_size = sizeof(struct dev_to_host_fis); phy->identify.target_port_protocols = SAS_PROTOCOL_SATA; diff --git a/drivers/scsi/pm8001/pm8001_hwi.h b/drivers/scsi/pm8001/pm8001_hwi.h index f1ce8df082b0..a21b1b37a8ea 100644 --- a/drivers/scsi/pm8001/pm8001_hwi.h +++ b/drivers/scsi/pm8001/pm8001_hwi.h @@ -42,6 +42,7 @@ #include #include +#include "pm8001_defs.h" /* for Request Opcode of IOMB */ @@ -229,8 +230,9 @@ struct hw_event_resp { __le32 lr_evt_status_phyid_portid; __le32 evt_param; __le32 npip_portstate; - struct sas_identify_frame sas_identify; + struct sas_identify_frame_local sas_identify; struct dev_to_host_fis sata_fis; + u32 _r_a; } __attribute__((packed, aligned(4))); diff --git a/drivers/scsi/pm8001/pm8001_init.c b/drivers/scsi/pm8001/pm8001_init.c index 54b35893261a..5af81c73a8f8 100644 --- a/drivers/scsi/pm8001/pm8001_init.c +++ b/drivers/scsi/pm8001/pm8001_init.c @@ -58,15 +58,15 @@ MODULE_PARM_DESC(link_rate, "Enable link rate.\n" bool pm8001_use_msix = true; module_param_named(use_msix, pm8001_use_msix, bool, 0444); -MODULE_PARM_DESC(zoned, "Use MSIX interrupts. Default: true"); +MODULE_PARM_DESC(use_msix, "Use MSIX interrupts. Default: true"); static bool pm8001_use_tasklet = true; module_param_named(use_tasklet, pm8001_use_tasklet, bool, 0444); -MODULE_PARM_DESC(zoned, "Use MSIX interrupts. Default: true"); +MODULE_PARM_DESC(use_tasklet, "Use tasklets for interrupt handling. Default: true"); static bool pm8001_read_wwn = true; module_param_named(read_wwn, pm8001_read_wwn, bool, 0444); -MODULE_PARM_DESC(zoned, "Get WWN from the controller. Default: true"); +MODULE_PARM_DESC(read_wwn, "Get WWN from the controller. Default: true"); uint pcs_event_log_severity = 0x03; module_param(pcs_event_log_severity, int, 0644); diff --git a/drivers/scsi/pm8001/pm80xx_hwi.c b/drivers/scsi/pm8001/pm80xx_hwi.c index 2c0fa7ab33d2..d2572dd66071 100644 --- a/drivers/scsi/pm8001/pm80xx_hwi.c +++ b/drivers/scsi/pm8001/pm80xx_hwi.c @@ -2294,6 +2294,7 @@ static void mpi_ssp_event(struct pm8001_hba_info *pm8001_ha, void *piomb) static void mpi_sata_completion(struct pm8001_hba_info *pm8001_ha, struct outbound_queue_table *circularQ, void *piomb) + __must_hold(&circularQ->oq_lock) { struct sas_task *t; struct pm8001_ccb_info *ccb; @@ -3296,7 +3297,7 @@ hw_event_sata_phy_up(struct pm8001_hba_info *pm8001_ha, void *piomb) phy->sas_phy.oob_mode = SATA_OOB_MODE; sas_notify_phy_event(&phy->sas_phy, PHYE_OOB_DONE, GFP_ATOMIC); spin_lock_irqsave(&phy->sas_phy.frame_rcvd_lock, flags); - memcpy(phy->frame_rcvd, ((u8 *)&pPayload->sata_fis - 4), + memcpy(phy->frame_rcvd, &pPayload->sata_fis, sizeof(struct dev_to_host_fis)); phy->frame_rcvd_size = sizeof(struct dev_to_host_fis); phy->identify.target_port_protocols = SAS_PROTOCOL_SATA; @@ -3856,6 +3857,7 @@ static int ssp_coalesced_comp_resp(struct pm8001_hba_info *pm8001_ha, */ static void process_one_iomb(struct pm8001_hba_info *pm8001_ha, struct outbound_queue_table *circularQ, void *piomb) + __must_hold(&circularQ->oq_lock) { __le32 pHeader = *(__le32 *)piomb; u32 opc = (u32)((le32_to_cpu(pHeader)) & 0xFFF); diff --git a/drivers/scsi/pm8001/pm80xx_hwi.h b/drivers/scsi/pm8001/pm80xx_hwi.h index d8a63b7fed6a..d6796ba40df9 100644 --- a/drivers/scsi/pm8001/pm80xx_hwi.h +++ b/drivers/scsi/pm8001/pm80xx_hwi.h @@ -43,6 +43,7 @@ #include #include +#include "pm8001_defs.h" /* for Request Opcode of IOMB */ #define OPC_INB_ECHO 1 /* 0x000 */ @@ -236,102 +237,6 @@ /* Port recovery timeout, 10000 ms for PM8006 controller */ #define CHIP_8006_PORT_RECOVERY_TIMEOUT 0x640000 -#ifdef __LITTLE_ENDIAN_BITFIELD -struct sas_identify_frame_local { - /* Byte 0 */ - u8 frame_type:4; - u8 dev_type:3; - u8 _un0:1; - - /* Byte 1 */ - u8 _un1; - - /* Byte 2 */ - union { - struct { - u8 _un20:1; - u8 smp_iport:1; - u8 stp_iport:1; - u8 ssp_iport:1; - u8 _un247:4; - }; - u8 initiator_bits; - }; - - /* Byte 3 */ - union { - struct { - u8 _un30:1; - u8 smp_tport:1; - u8 stp_tport:1; - u8 ssp_tport:1; - u8 _un347:4; - }; - u8 target_bits; - }; - - /* Byte 4 - 11 */ - u8 _un4_11[8]; - - /* Byte 12 - 19 */ - u8 sas_addr[SAS_ADDR_SIZE]; - - /* Byte 20 */ - u8 phy_id; - - u8 _un21_27[7]; - -} __packed; - -#elif defined(__BIG_ENDIAN_BITFIELD) -struct sas_identify_frame_local { - /* Byte 0 */ - u8 _un0:1; - u8 dev_type:3; - u8 frame_type:4; - - /* Byte 1 */ - u8 _un1; - - /* Byte 2 */ - union { - struct { - u8 _un247:4; - u8 ssp_iport:1; - u8 stp_iport:1; - u8 smp_iport:1; - u8 _un20:1; - }; - u8 initiator_bits; - }; - - /* Byte 3 */ - union { - struct { - u8 _un347:4; - u8 ssp_tport:1; - u8 stp_tport:1; - u8 smp_tport:1; - u8 _un30:1; - }; - u8 target_bits; - }; - - /* Byte 4 - 11 */ - u8 _un4_11[8]; - - /* Byte 12 - 19 */ - u8 sas_addr[SAS_ADDR_SIZE]; - - /* Byte 20 */ - u8 phy_id; - - u8 _un21_27[7]; -} __packed; -#else -#error "Bitfield order not defined!" -#endif - struct mpi_msg_hdr { __le32 header; /* Bits [11:0] - Message operation code */ /* Bits [15:12] - Message Category */ @@ -427,8 +332,9 @@ struct hw_event_resp { __le32 lr_status_evt_portid; __le32 evt_param; __le32 phyid_npip_portstate; - struct sas_identify_frame sas_identify; + struct sas_identify_frame_local sas_identify; struct dev_to_host_fis sata_fis; + u32 _r_a; } __attribute__((packed, aligned(4))); /* diff --git a/drivers/scsi/pmcraid.c b/drivers/scsi/pmcraid.c index 942a99393204..b68f6460207c 100644 --- a/drivers/scsi/pmcraid.c +++ b/drivers/scsi/pmcraid.c @@ -497,10 +497,10 @@ static void pmcraid_clr_trans_op( if (pinstance->reset_cmd != NULL) { timer_delete(&pinstance->reset_cmd->timer); spin_lock_irqsave( - pinstance->host->host_lock, lock_flags); + &pinstance->host->host_lock, lock_flags); pinstance->reset_cmd->cmd_done(pinstance->reset_cmd); spin_unlock_irqrestore( - pinstance->host->host_lock, lock_flags); + &pinstance->host->host_lock, lock_flags); } } @@ -562,9 +562,9 @@ static void pmcraid_bist_done(struct timer_list *t) } else { cmd->time_left = 0; pmcraid_info("BIST is complete, proceeding with reset\n"); - spin_lock_irqsave(pinstance->host->host_lock, lock_flags); + spin_lock_irqsave(&pinstance->host->host_lock, lock_flags); pmcraid_ioa_reset(cmd); - spin_unlock_irqrestore(pinstance->host->host_lock, lock_flags); + spin_unlock_irqrestore(&pinstance->host->host_lock, lock_flags); } } @@ -613,9 +613,9 @@ static void pmcraid_reset_alert_done(struct timer_list *t) if (((status & INTRS_CRITICAL_OP_IN_PROGRESS) == 0) || cmd->time_left <= 0) { pmcraid_info("critical op is reset proceeding with reset\n"); - spin_lock_irqsave(pinstance->host->host_lock, lock_flags); + spin_lock_irqsave(&pinstance->host->host_lock, lock_flags); pmcraid_ioa_reset(cmd); - spin_unlock_irqrestore(pinstance->host->host_lock, lock_flags); + spin_unlock_irqrestore(&pinstance->host->host_lock, lock_flags); } else { pmcraid_info("critical op is not yet reset waiting again\n"); /* restart timer if some more time is available to wait */ @@ -699,7 +699,7 @@ static void pmcraid_timeout_handler(struct timer_list *t) * reset is in progress. Otherwise fail this command and get a free * command block to restart the reset sequence. */ - spin_lock_irqsave(pinstance->host->host_lock, lock_flags); + spin_lock_irqsave(&pinstance->host->host_lock, lock_flags); if (!pinstance->ioa_reset_in_progress) { pinstance->ioa_reset_attempts = 0; cmd = pmcraid_get_free_cmd(pinstance); @@ -708,7 +708,7 @@ static void pmcraid_timeout_handler(struct timer_list *t) * Some other command's timeout handler can do the reset job */ if (cmd == NULL) { - spin_unlock_irqrestore(pinstance->host->host_lock, + spin_unlock_irqrestore(&pinstance->host->host_lock, lock_flags); pmcraid_err("no free cmnd block for timeout handler\n"); return; @@ -745,7 +745,7 @@ static void pmcraid_timeout_handler(struct timer_list *t) pinstance->ioa_state = IOA_STATE_IN_RESET_ALERT; scsi_block_requests(pinstance->host); pmcraid_reset_alert(cmd); - spin_unlock_irqrestore(pinstance->host->host_lock, lock_flags); + spin_unlock_irqrestore(&pinstance->host->host_lock, lock_flags); } /** @@ -921,9 +921,9 @@ static void pmcraid_ioa_shutdown_done(struct pmcraid_cmd *cmd) struct pmcraid_instance *pinstance = cmd->drv_inst; unsigned long lock_flags; - spin_lock_irqsave(pinstance->host->host_lock, lock_flags); + spin_lock_irqsave(&pinstance->host->host_lock, lock_flags); pmcraid_ioa_reset(cmd); - spin_unlock_irqrestore(pinstance->host->host_lock, lock_flags); + spin_unlock_irqrestore(&pinstance->host->host_lock, lock_flags); } /** @@ -982,10 +982,10 @@ static void pmcraid_get_fwversion_done(struct pmcraid_cmd *cmd) */ if (ioasc) { pmcraid_err("IOA Inquiry failed with %x\n", ioasc); - spin_lock_irqsave(pinstance->host->host_lock, lock_flags); + spin_lock_irqsave(&pinstance->host->host_lock, lock_flags); pinstance->ioa_state = IOA_STATE_IN_RESET_ALERT; pmcraid_reset_alert(cmd); - spin_unlock_irqrestore(pinstance->host->host_lock, lock_flags); + spin_unlock_irqrestore(&pinstance->host->host_lock, lock_flags); } else { pmcraid_querycfg(cmd); } @@ -1596,11 +1596,11 @@ static void pmcraid_handle_config_change(struct pmcraid_instance *pinstance) spin_unlock_irqrestore(&pinstance->resource_lock, lock_flags); pmcraid_err("too many resources attached\n"); - spin_lock_irqsave(pinstance->host->host_lock, + spin_lock_irqsave(&pinstance->host->host_lock, host_lock_flags); pmcraid_send_hcam(pinstance, PMCRAID_HCAM_CODE_CONFIG_CHANGE); - spin_unlock_irqrestore(pinstance->host->host_lock, + spin_unlock_irqrestore(&pinstance->host->host_lock, host_lock_flags); return; } @@ -1760,9 +1760,9 @@ static void pmcraid_process_ccn(struct pmcraid_cmd *cmd) } else if (ioasc) { dev_info(&pinstance->pdev->dev, "Host RCB (CCN) failed with IOASC: 0x%08X\n", ioasc); - spin_lock_irqsave(pinstance->host->host_lock, lock_flags); + spin_lock_irqsave(&pinstance->host->host_lock, lock_flags); pmcraid_send_hcam(pinstance, PMCRAID_HCAM_CODE_CONFIG_CHANGE); - spin_unlock_irqrestore(pinstance->host->host_lock, lock_flags); + spin_unlock_irqrestore(&pinstance->host->host_lock, lock_flags); } else { pmcraid_handle_config_change(pinstance); } @@ -1800,10 +1800,10 @@ static void pmcraid_process_ldn(struct pmcraid_cmd *cmd) } else if (!ioasc) { pmcraid_handle_error_log(pinstance); if (fd_ioasc == PMCRAID_IOASC_NR_IOA_RESET_REQUIRED) { - spin_lock_irqsave(pinstance->host->host_lock, + spin_lock_irqsave(&pinstance->host->host_lock, lock_flags); pmcraid_initiate_reset(pinstance); - spin_unlock_irqrestore(pinstance->host->host_lock, + spin_unlock_irqrestore(&pinstance->host->host_lock, lock_flags); return; } @@ -2322,17 +2322,17 @@ static int pmcraid_reset_reload( unsigned long lock_flags; int reset = 1; - spin_lock_irqsave(pinstance->host->host_lock, lock_flags); + spin_lock_irqsave(&pinstance->host->host_lock, lock_flags); if (pinstance->ioa_reset_in_progress) { pmcraid_info("reset_reload: reset is already in progress\n"); - spin_unlock_irqrestore(pinstance->host->host_lock, lock_flags); + spin_unlock_irqrestore(&pinstance->host->host_lock, lock_flags); wait_event(pinstance->reset_wait_q, !pinstance->ioa_reset_in_progress); - spin_lock_irqsave(pinstance->host->host_lock, lock_flags); + spin_lock_irqsave(&pinstance->host->host_lock, lock_flags); if (pinstance->ioa_state == IOA_STATE_DEAD) { pmcraid_info("reset_reload: IOA is dead\n"); @@ -2361,7 +2361,7 @@ static int pmcraid_reset_reload( pinstance->force_ioa_reset = reset; pmcraid_info("reset_reload: initiating reset\n"); pmcraid_ioa_reset(reset_cmd); - spin_unlock_irqrestore(pinstance->host->host_lock, lock_flags); + spin_unlock_irqrestore(&pinstance->host->host_lock, lock_flags); pmcraid_info("reset_reload: waiting for reset to complete\n"); wait_event(pinstance->reset_wait_q, !pinstance->ioa_reset_in_progress); @@ -2371,7 +2371,7 @@ static int pmcraid_reset_reload( return pinstance->ioa_state != target_state; out_unlock: - spin_unlock_irqrestore(pinstance->host->host_lock, lock_flags); + spin_unlock_irqrestore(&pinstance->host->host_lock, lock_flags); return reset; } @@ -2719,10 +2719,10 @@ static int pmcraid_reset_device( * This will force the mid-layer to call _eh_bus/host reset, which * will then go to sleep and wait for the reset to complete */ - spin_lock_irqsave(pinstance->host->host_lock, lock_flags); + spin_lock_irqsave(&pinstance->host->host_lock, lock_flags); if (pinstance->ioa_reset_in_progress || pinstance->ioa_state == IOA_STATE_DEAD) { - spin_unlock_irqrestore(pinstance->host->host_lock, lock_flags); + spin_unlock_irqrestore(&pinstance->host->host_lock, lock_flags); return FAILED; } @@ -2736,7 +2736,7 @@ static int pmcraid_reset_device( cmd = pmcraid_get_free_cmd(pinstance); if (cmd == NULL) { - spin_unlock_irqrestore(pinstance->host->host_lock, lock_flags); + spin_unlock_irqrestore(&pinstance->host->host_lock, lock_flags); pmcraid_err("%s: no cmd blocks are available\n", __func__); return FAILED; } @@ -2765,7 +2765,7 @@ static int pmcraid_reset_device( timeout, pmcraid_timeout_handler); - spin_unlock_irqrestore(pinstance->host->host_lock, lock_flags); + spin_unlock_irqrestore(&pinstance->host->host_lock, lock_flags); /* RESET_DEVICE command completes after all pending IOARCBs are * completed. Once this command is completed, pmcraind_internal_done @@ -2960,11 +2960,11 @@ static int pmcraid_eh_abort_handler(struct scsi_cmnd *scsi_cmd) * pmcraid_eh_host_reset which will then go to sleep and wait for the * reset to complete */ - spin_lock_irqsave(pinstance->host->host_lock, host_lock_flags); + spin_lock_irqsave(&pinstance->host->host_lock, host_lock_flags); if (pinstance->ioa_reset_in_progress || pinstance->ioa_state == IOA_STATE_DEAD) { - spin_unlock_irqrestore(pinstance->host->host_lock, + spin_unlock_irqrestore(&pinstance->host->host_lock, host_lock_flags); return rc; } @@ -2992,7 +2992,7 @@ static int pmcraid_eh_abort_handler(struct scsi_cmnd *scsi_cmd) if (cmd_found) cancel_cmd = pmcraid_abort_cmd(cmd); - spin_unlock_irqrestore(pinstance->host->host_lock, + spin_unlock_irqrestore(&pinstance->host->host_lock, host_lock_flags); if (cancel_cmd) { @@ -3720,11 +3720,11 @@ static irqreturn_t pmcraid_isr_msix(int irq, void *dev_id) pmcraid_err("ISR: error interrupts: %x \ initiating reset\n", intrs_val); - spin_lock_irqsave(pinstance->host->host_lock, + spin_lock_irqsave(&pinstance->host->host_lock, lock_flags); pmcraid_initiate_reset(pinstance); spin_unlock_irqrestore( - pinstance->host->host_lock, + &pinstance->host->host_lock, lock_flags); } /* If interrupt was as part of the ioa initialization, @@ -3798,9 +3798,9 @@ static irqreturn_t pmcraid_isr(int irq, void *dev_id) intrs); intrs = ioread32( pinstance->int_regs.ioa_host_interrupt_clr_reg); - spin_lock_irqsave(pinstance->host->host_lock, lock_flags); + spin_lock_irqsave(&pinstance->host->host_lock, lock_flags); pmcraid_initiate_reset(pinstance); - spin_unlock_irqrestore(pinstance->host->host_lock, lock_flags); + spin_unlock_irqrestore(&pinstance->host->host_lock, lock_flags); } else { /* If interrupt was as part of the ioa initialization, * clear. Delete the timer and wakeup the @@ -3859,11 +3859,11 @@ static void pmcraid_worker_function(struct work_struct *workp) /* host_lock must be held before calling * scsi_device_get */ - spin_lock_irqsave(pinstance->host->host_lock, + spin_lock_irqsave(&pinstance->host->host_lock, host_lock_flags); if (!scsi_device_get(sdev)) { spin_unlock_irqrestore( - pinstance->host->host_lock, + &pinstance->host->host_lock, host_lock_flags); pmcraid_info("deleting %x from midlayer\n", res->cfg_entry.resource_address); @@ -3879,7 +3879,7 @@ static void pmcraid_worker_function(struct work_struct *workp) res->change_detected = 0; } else { spin_unlock_irqrestore( - pinstance->host->host_lock, + &pinstance->host->host_lock, host_lock_flags); } } @@ -3986,10 +3986,10 @@ static void pmcraid_tasklet_function(unsigned long instance) atomic_dec(&pinstance->outstanding_cmds); if (cmd->cmd_done == pmcraid_ioa_reset) { - spin_lock_irqsave(pinstance->host->host_lock, + spin_lock_irqsave(&pinstance->host->host_lock, host_lock_flags); cmd->cmd_done(cmd); - spin_unlock_irqrestore(pinstance->host->host_lock, + spin_unlock_irqrestore(&pinstance->host->host_lock, host_lock_flags); } else if (cmd->cmd_done != NULL) { cmd->cmd_done(cmd); @@ -4880,9 +4880,9 @@ static void pmcraid_complete_ioa_reset(struct pmcraid_cmd *cmd) struct pmcraid_instance *pinstance = cmd->drv_inst; unsigned long flags; - spin_lock_irqsave(pinstance->host->host_lock, flags); + spin_lock_irqsave(&pinstance->host->host_lock, flags); pmcraid_ioa_reset(cmd); - spin_unlock_irqrestore(pinstance->host->host_lock, flags); + spin_unlock_irqrestore(&pinstance->host->host_lock, flags); scsi_unblock_requests(pinstance->host); schedule_work(&pinstance->worker_q); } diff --git a/drivers/scsi/ps3rom.c b/drivers/scsi/ps3rom.c index a9c727d22931..c63c581b493c 100644 --- a/drivers/scsi/ps3rom.c +++ b/drivers/scsi/ps3rom.c @@ -233,7 +233,8 @@ static enum scsi_qc_status ps3rom_queuecommand_lck(struct scsi_cmnd *cmd) } if (res) { - scsi_build_sense(cmd, 0, ILLEGAL_REQUEST, 0, 0); + scsi_set_sense(cmd, 0, ILLEGAL_REQUEST, + NO_ADDITIONAL_SENSE_INFORMATION); cmd->result = res; priv->curr_cmd = NULL; scsi_done(cmd); @@ -316,7 +317,7 @@ static irqreturn_t ps3rom_interrupt(int irq, void *data) goto done; } - scsi_build_sense(cmd, 0, sense_key, asc, ascq); + scsi_set_sense(cmd, 0, sense_key, scsi_sense_code(asc, ascq)); done: priv->curr_cmd = NULL; diff --git a/drivers/scsi/qedf/Makefile b/drivers/scsi/qedf/Makefile index c46287826fb8..465982ba5dae 100644 --- a/drivers/scsi/qedf/Makefile +++ b/drivers/scsi/qedf/Makefile @@ -1,4 +1,7 @@ # SPDX-License-Identifier: GPL-2.0-only + +CONTEXT_ANALYSIS := y + obj-$(CONFIG_QEDF) := qedf.o qedf-y = qedf_dbg.o qedf_main.o qedf_io.o qedf_fip.o \ qedf_attr.o qedf_els.o drv_scsi_fw_funcs.o drv_fcoe_fw_funcs.o diff --git a/drivers/scsi/qedi/Makefile b/drivers/scsi/qedi/Makefile index d84eedfd031b..f081d047b6eb 100644 --- a/drivers/scsi/qedi/Makefile +++ b/drivers/scsi/qedi/Makefile @@ -1,4 +1,7 @@ # SPDX-License-Identifier: GPL-2.0-only + +CONTEXT_ANALYSIS := y + obj-$(CONFIG_QEDI) := qedi.o qedi-y := qedi_main.o qedi_iscsi.o qedi_fw.o qedi_sysfs.o \ qedi_dbg.o qedi_fw_api.o diff --git a/drivers/scsi/qedi/qedi_fw.c b/drivers/scsi/qedi/qedi_fw.c index 854efa4f61d8..c8af10c32653 100644 --- a/drivers/scsi/qedi/qedi_fw.c +++ b/drivers/scsi/qedi/qedi_fw.c @@ -73,7 +73,7 @@ static void qedi_process_logout_resp(struct qedi_ctx *qedi, spin_unlock(&qedi_conn->list_lock); cmd->state = RESPONSE_RECEIVED; - __iscsi_complete_pdu(conn, (struct iscsi_hdr *)resp_hdr, NULL, 0); + __iscsi_complete_pdu(session, conn, (struct iscsi_hdr *)resp_hdr, NULL, 0); spin_unlock(&session->back_lock); } @@ -138,7 +138,7 @@ static void qedi_process_text_resp(struct qedi_ctx *qedi, cmd->state = RESPONSE_RECEIVED; - __iscsi_complete_pdu(conn, (struct iscsi_hdr *)resp_hdr_ptr, + __iscsi_complete_pdu(session, conn, (struct iscsi_hdr *)resp_hdr_ptr, qedi_conn->gen_pdu.resp_buf, (qedi_conn->gen_pdu.resp_wr_ptr - qedi_conn->gen_pdu.resp_buf)); @@ -163,7 +163,8 @@ static void qedi_tmf_resp_work(struct work_struct *work) goto exit_tmf_resp; spin_lock(&session->back_lock); - __iscsi_complete_pdu(conn, (struct iscsi_hdr *)resp_hdr_ptr, NULL, 0); + __iscsi_complete_pdu(session, conn, (struct iscsi_hdr *)resp_hdr_ptr, NULL, + 0); spin_unlock(&session->back_lock); exit_tmf_resp: @@ -247,7 +248,8 @@ static void qedi_process_tmf_resp(struct qedi_ctx *qedi, } spin_unlock(&qedi_conn->tmf_work_lock); - __iscsi_complete_pdu(conn, (struct iscsi_hdr *)resp_hdr_ptr, NULL, 0); + __iscsi_complete_pdu(session, conn, (struct iscsi_hdr *)resp_hdr_ptr, NULL, + 0); kfree(resp_hdr_ptr); unblock_sess: @@ -304,7 +306,7 @@ static void qedi_process_login_resp(struct qedi_ctx *qedi, memset(task_ctx, '\0', sizeof(*task_ctx)); - __iscsi_complete_pdu(conn, (struct iscsi_hdr *)resp_hdr_ptr, + __iscsi_complete_pdu(session, conn, (struct iscsi_hdr *)resp_hdr_ptr, qedi_conn->gen_pdu.resp_buf, (qedi_conn->gen_pdu.resp_wr_ptr - qedi_conn->gen_pdu.resp_buf)); @@ -470,7 +472,8 @@ static int qedi_process_nopin_mesg(struct qedi_ctx *qedi, } done: - __iscsi_complete_pdu(conn, (struct iscsi_hdr *)hdr, bdq_data, pdu_len); + __iscsi_complete_pdu(session, conn, (struct iscsi_hdr *)hdr, bdq_data, + pdu_len); spin_unlock_bh(&session->back_lock); return tgt_async_nop; @@ -524,7 +527,7 @@ static void qedi_process_async_mesg(struct qedi_ctx *qedi, resp_hdr->param2 = cpu_to_be16(cqe_async_msg->param2_rsrv); resp_hdr->param3 = cpu_to_be16(cqe_async_msg->param3_rsrv); - __iscsi_complete_pdu(conn, (struct iscsi_hdr *)resp_hdr, bdq_data, + __iscsi_complete_pdu(session, conn, (struct iscsi_hdr *)resp_hdr, bdq_data, pdu_len); spin_unlock_bh(&session->back_lock); @@ -567,7 +570,7 @@ static void qedi_process_reject_mesg(struct qedi_ctx *qedi, hdr->statsn = cpu_to_be32(cqe_reject->stat_sn); hdr->ffffffff = cpu_to_be32(0xffffffff); - __iscsi_complete_pdu(conn, (struct iscsi_hdr *)hdr, + __iscsi_complete_pdu(session, conn, (struct iscsi_hdr *)hdr, conn->data, pld_len); spin_unlock_bh(&session->back_lock); } @@ -664,7 +667,7 @@ static void qedi_scsi_completion(struct qedi_ctx *qedi, if (qedi_io_tracing) qedi_trace_io(qedi, task, cmd->task_id, QEDI_IO_TRACE_RSP); - __iscsi_complete_pdu(conn, (struct iscsi_hdr *)hdr, + __iscsi_complete_pdu(session, conn, (struct iscsi_hdr *)hdr, conn->data, datalen); error: spin_unlock_bh(&session->back_lock); @@ -722,7 +725,7 @@ static void qedi_process_nopin_local_cmpl(struct qedi_ctx *qedi, cmd->state = RESPONSE_RECEIVED; spin_lock_bh(&session->back_lock); - __iscsi_put_task(task); + __iscsi_put_task(session, task); spin_unlock_bh(&session->back_lock); } @@ -1134,6 +1137,7 @@ int qedi_send_iscsi_logout(struct qedi_conn *qedi_conn, int qedi_cleanup_all_io(struct qedi_ctx *qedi, struct qedi_conn *qedi_conn, struct iscsi_task *task, bool in_recovery) + __context_unsafe(/*conditional locking*/) { int rval; struct iscsi_task *ctask; @@ -1316,6 +1320,7 @@ static void qedi_abort_work(struct work_struct *work) struct qedi_conn *qedi_conn = qedi_cmd->conn; struct qedi_ctx *qedi = qedi_conn->qedi; struct iscsi_conn *conn = qedi_conn->cls_conn->dd_data; + struct iscsi_session *session = conn->session; struct qedi_work_map *list_work = NULL; struct iscsi_task *mtask; struct qedi_cmd *cmd; @@ -1326,16 +1331,16 @@ static void qedi_abort_work(struct work_struct *work) mtask = qedi_cmd->task; tmf_hdr = (struct iscsi_tm *)mtask->hdr; - spin_lock_bh(&conn->session->back_lock); - ctask = iscsi_itt_to_ctask(conn, tmf_hdr->rtt); + spin_lock_bh(&session->back_lock); + ctask = iscsi_itt_to_ctask(session, conn, tmf_hdr->rtt); if (!ctask) { - spin_unlock_bh(&conn->session->back_lock); + spin_unlock_bh(&session->back_lock); QEDI_ERR(&qedi->dbg_ctx, "Invalid RTT. Letting abort timeout.\n"); goto clear_cleanup; } if (iscsi_task_is_completed(ctask)) { - spin_unlock_bh(&conn->session->back_lock); + spin_unlock_bh(&session->back_lock); QEDI_INFO(&qedi->dbg_ctx, QEDI_LOG_INFO, "Task already completed\n"); /* @@ -1344,7 +1349,7 @@ static void qedi_abort_work(struct work_struct *work) */ goto send_tmf; } - spin_unlock_bh(&conn->session->back_lock); + spin_unlock_bh(&session->back_lock); cmd = (struct qedi_cmd *)ctask->dd_data; QEDI_INFO(&qedi->dbg_ctx, QEDI_LOG_INFO, diff --git a/drivers/scsi/qedi/qedi_main.c b/drivers/scsi/qedi/qedi_main.c index 227ff7bd1bdc..f394fcbb97e7 100644 --- a/drivers/scsi/qedi/qedi_main.c +++ b/drivers/scsi/qedi/qedi_main.c @@ -2652,8 +2652,6 @@ static int __qedi_probe(struct pci_dev *pdev, int mode) snprintf(host_buf, sizeof(host_buf), "host_%d", qedi->shost->host_no); qedi_ops->common->set_name(qedi->cdev, host_buf); - qedi_ops->register_ops(qedi->cdev, &qedi_cb_ops, qedi); - memset(¶ms, 0, sizeof(params)); params.mtu = DEF_PATH_MTU + IPV6_HDR_LEN + TCP_HDR_LEN; qedi->ll2_mtu = DEF_PATH_MTU; @@ -2670,6 +2668,7 @@ static int __qedi_probe(struct pci_dev *pdev, int mode) spin_lock_init(&qedi->task_idx_lock); mutex_init(&qedi->stats_lock); } + qedi_ops->register_ops(qedi->cdev, &qedi_cb_ops, qedi); qedi_ops->ll2->register_cb_ops(qedi->cdev, &qedi_ll2_cb_ops, qedi); qedi_ops->ll2->start(qedi->cdev, ¶ms); diff --git a/drivers/scsi/qla1280.c b/drivers/scsi/qla1280.c index cdd6fe002c32..f71e668d011c 100644 --- a/drivers/scsi/qla1280.c +++ b/drivers/scsi/qla1280.c @@ -735,15 +735,16 @@ static void qla1280_mailbox_timeout(struct timer_list *t) } static int -_qla1280_wait_for_single_command(struct scsi_qla_host *ha, struct srb *sp, +_qla1280_wait_for_single_command(struct Scsi_Host *host, struct srb *sp, struct completion *wait) + __must_hold(&host->host_lock) { int status = FAILED; struct scsi_cmnd *cmd = sp->cmd; - spin_unlock_irq(ha->host->host_lock); + spin_unlock_irq(&host->host_lock); wait_for_completion_timeout(wait, 4*HZ); - spin_lock_irq(ha->host->host_lock); + spin_lock_irq(&host->host_lock); sp->wait = NULL; if(CMD_HANDLE(cmd) == COMPLETED_HANDLE) { status = SUCCESS; @@ -753,16 +754,19 @@ _qla1280_wait_for_single_command(struct scsi_qla_host *ha, struct srb *sp, } static int -qla1280_wait_for_single_command(struct scsi_qla_host *ha, struct srb *sp) +qla1280_wait_for_single_command(struct Scsi_Host *host, struct srb *sp) + __must_hold(&host->host_lock) { DECLARE_COMPLETION_ONSTACK(wait); sp->wait = &wait; - return _qla1280_wait_for_single_command(ha, sp, &wait); + return _qla1280_wait_for_single_command(host, sp, &wait); } static int -qla1280_wait_for_pending_commands(struct scsi_qla_host *ha, int bus, int target) +qla1280_wait_for_pending_commands(struct scsi_qla_host *ha, struct Scsi_Host *host, + int bus, int target) + __must_hold(&host->host_lock) { int cnt; int status; @@ -785,7 +789,7 @@ qla1280_wait_for_pending_commands(struct scsi_qla_host *ha, int bus, int target) if (target >= 0 && SCSI_TCN_32(cmd) != target) continue; - status = qla1280_wait_for_single_command(ha, sp); + status = qla1280_wait_for_single_command(host, sp); if (status == FAILED) break; } @@ -808,7 +812,9 @@ qla1280_wait_for_pending_commands(struct scsi_qla_host *ha, int bus, int target) * **************************************************************************/ static int -qla1280_error_action(struct scsi_cmnd *cmd, enum action action) +qla1280_error_action(struct Scsi_Host *host, struct scsi_cmnd *cmd, + enum action action) + __must_hold(&host->host_lock) { struct scsi_qla_host *ha; int bus, target, lun; @@ -914,7 +920,7 @@ qla1280_error_action(struct scsi_cmnd *cmd, enum action action) */ if (found >= 0) - result = _qla1280_wait_for_single_command(ha, sp, &wait); + result = _qla1280_wait_for_single_command(host, sp, &wait); if (action == ABORT_COMMAND && result != SUCCESS) { printk(KERN_WARNING @@ -934,7 +940,7 @@ qla1280_error_action(struct scsi_cmnd *cmd, enum action action) * to wait for them. */ if (result == SUCCESS && wait_for_bus >= 0) { - result = qla1280_wait_for_pending_commands(ha, + result = qla1280_wait_for_pending_commands(ha, host, wait_for_bus, wait_for_target); } @@ -951,11 +957,12 @@ qla1280_error_action(struct scsi_cmnd *cmd, enum action action) static int qla1280_eh_abort(struct scsi_cmnd * cmd) { + struct Scsi_Host *host = cmd->device->host; int rc; - spin_lock_irq(cmd->device->host->host_lock); - rc = qla1280_error_action(cmd, ABORT_COMMAND); - spin_unlock_irq(cmd->device->host->host_lock); + spin_lock_irq(&host->host_lock); + rc = qla1280_error_action(host, cmd, ABORT_COMMAND); + spin_unlock_irq(&host->host_lock); return rc; } @@ -967,11 +974,12 @@ qla1280_eh_abort(struct scsi_cmnd * cmd) static int qla1280_eh_device_reset(struct scsi_cmnd *cmd) { + struct Scsi_Host *host = cmd->device->host; int rc; - spin_lock_irq(cmd->device->host->host_lock); - rc = qla1280_error_action(cmd, DEVICE_RESET); - spin_unlock_irq(cmd->device->host->host_lock); + spin_lock_irq(&host->host_lock); + rc = qla1280_error_action(host, cmd, DEVICE_RESET); + spin_unlock_irq(&host->host_lock); return rc; } @@ -983,11 +991,12 @@ qla1280_eh_device_reset(struct scsi_cmnd *cmd) static int qla1280_eh_bus_reset(struct scsi_cmnd *cmd) { + struct Scsi_Host *host = cmd->device->host; int rc; - spin_lock_irq(cmd->device->host->host_lock); - rc = qla1280_error_action(cmd, BUS_RESET); - spin_unlock_irq(cmd->device->host->host_lock); + spin_lock_irq(&host->host_lock); + rc = qla1280_error_action(host, cmd, BUS_RESET); + spin_unlock_irq(&host->host_lock); return rc; } @@ -1003,7 +1012,7 @@ qla1280_eh_adapter_reset(struct scsi_cmnd *cmd) struct Scsi_Host *shost = cmd->device->host; struct scsi_qla_host *ha = (struct scsi_qla_host *)shost->hostdata; - spin_lock_irq(shost->host_lock); + spin_lock_irq(&shost->host_lock); if (qla1280_verbose) { printk(KERN_INFO "scsi(%ld): Issued ADAPTER RESET\n", @@ -1019,7 +1028,7 @@ qla1280_eh_adapter_reset(struct scsi_cmnd *cmd) ha->flags.reset_active = 0; - spin_unlock_irq(shost->host_lock); + spin_unlock_irq(&shost->host_lock); return rc; } @@ -1080,7 +1089,7 @@ qla1280_intr_handler(int irq, void *dev_id) ENTER_INTR ("qla1280_intr_handler"); ha = (struct scsi_qla_host *)dev_id; - spin_lock(ha->host->host_lock); + spin_lock(&ha->host->host_lock); ha->isr_count++; reg = ha->iobase; @@ -1096,7 +1105,7 @@ qla1280_intr_handler(int irq, void *dev_id) if (!list_empty(&ha->done_q)) qla1280_done(ha); - spin_unlock(ha->host->host_lock); + spin_unlock(&ha->host->host_lock); qla1280_enable_intrs(ha); @@ -1214,11 +1223,11 @@ qla1280_sdev_configure(struct scsi_device *device, struct queue_limits *lim) nv->bus[bus].target[target].ppr_1x160.flags.enable_ppr = 0; } - spin_lock_irqsave(ha->host->host_lock, flags); + spin_lock_irqsave(&ha->host->host_lock, flags); if (nv->bus[bus].target[target].parameter.enable_sync) status = qla1280_set_target_parameters(ha, bus, target); qla1280_get_target_parameters(ha, device); - spin_unlock_irqrestore(ha->host->host_lock, flags); + spin_unlock_irqrestore(&ha->host->host_lock, flags); return status; } @@ -1435,7 +1444,7 @@ qla1280_initialize_adapter(struct scsi_qla_host *ha) * needs to be able to drop the lock unconditionally to wait * for completion. */ - spin_lock_irqsave(ha->host->host_lock, flags); + spin_lock_irqsave(&ha->host->host_lock, flags); status = qla1280_load_firmware(ha); if (status) { @@ -1467,7 +1476,7 @@ qla1280_initialize_adapter(struct scsi_qla_host *ha) ha->flags.online = 1; out: - spin_unlock_irqrestore(ha->host->host_lock, flags); + spin_unlock_irqrestore(&ha->host->host_lock, flags); if (status) dprintk(2, "qla1280_initialize_adapter: **** FAILED ****\n"); @@ -1490,13 +1499,14 @@ qla1280_initialize_adapter(struct scsi_qla_host *ha) */ static const struct firmware * qla1280_request_firmware(struct scsi_qla_host *ha) + __must_hold(&ha->host->host_lock) { const struct firmware *fw; int err; int index; char *fwname; - spin_unlock_irq(ha->host->host_lock); + spin_unlock_irq(&ha->host->host_lock); mutex_lock(&qla1280_firmware_mutex); index = ql1280_board_tbl[ha->devnum].fw_index; @@ -1529,7 +1539,7 @@ qla1280_request_firmware(struct scsi_qla_host *ha) ha->fwver3 = fw->data[2]; unlock: mutex_unlock(&qla1280_firmware_mutex); - spin_lock_irq(ha->host->host_lock); + spin_lock_irq(&ha->host->host_lock); return fw; } @@ -1655,6 +1665,7 @@ qla1280_chip_diag(struct scsi_qla_host *ha) static int qla1280_load_firmware_pio(struct scsi_qla_host *ha) + __must_hold(&ha->host->host_lock) { /* enter with host_lock acquired */ @@ -1705,6 +1716,7 @@ qla1280_load_firmware_pio(struct scsi_qla_host *ha) #define DUMP_IT_BACK 0 /* for debug of RISC loading */ static int qla1280_load_firmware_dma(struct scsi_qla_host *ha) + __must_hold(&ha->host->host_lock) { /* enter with host_lock acquired */ const struct firmware *fw; @@ -1844,6 +1856,7 @@ qla1280_start_firmware(struct scsi_qla_host *ha) static int qla1280_load_firmware(struct scsi_qla_host *ha) + __must_hold(&ha->host->host_lock) { /* enter with host_lock taken */ int err; @@ -2413,6 +2426,7 @@ qla1280_nv_write(struct scsi_qla_host *ha, uint16_t data) */ static int qla1280_mailbox_command(struct scsi_qla_host *ha, uint8_t mr, uint16_t *mb) + __must_hold(&ha->host->host_lock) { struct device_reg __iomem *reg = ha->iobase; int status = 0; @@ -2451,14 +2465,14 @@ qla1280_mailbox_command(struct scsi_qla_host *ha, uint8_t mr, uint16_t *mb) timer_setup(&ha->mailbox_timer, qla1280_mailbox_timeout, 0); mod_timer(&ha->mailbox_timer, jiffies + 20 * HZ); - spin_unlock_irq(ha->host->host_lock); + spin_unlock_irq(&ha->host->host_lock); WRT_REG_WORD(®->host_cmd, HC_SET_HOST_INT); qla1280_debounce_register(®->istatus); wait_for_completion(&wait); timer_delete_sync(&ha->mailbox_timer); - spin_lock_irq(ha->host->host_lock); + spin_lock_irq(&ha->host->host_lock); ha->mailbox_wait = NULL; @@ -2538,6 +2552,7 @@ qla1280_poll(struct scsi_qla_host *ha) */ static int qla1280_bus_reset(struct scsi_qla_host *ha, int bus) + __must_hold(&ha->host->host_lock) { uint16_t mb[MAILBOX_REGISTER_COUNT]; uint16_t reset_delay; @@ -2560,9 +2575,9 @@ qla1280_bus_reset(struct scsi_qla_host *ha, int bus) ha->bus_settings[bus].scsi_bus_dead = 1; ha->bus_settings[bus].failed_reset_count++; } else { - spin_unlock_irq(ha->host->host_lock); + spin_unlock_irq(&ha->host->host_lock); ssleep(reset_delay); - spin_lock_irq(ha->host->host_lock); + spin_lock_irq(&ha->host->host_lock); ha->bus_settings[bus].scsi_bus_dead = 0; ha->bus_settings[bus].failed_reset_count = 0; @@ -2598,6 +2613,7 @@ qla1280_bus_reset(struct scsi_qla_host *ha, int bus) */ static int qla1280_device_reset(struct scsi_qla_host *ha, int bus, int target) + __must_hold(&ha->host->host_lock) { uint16_t mb[MAILBOX_REGISTER_COUNT]; int status; @@ -2632,6 +2648,7 @@ qla1280_device_reset(struct scsi_qla_host *ha, int bus, int target) */ static int qla1280_abort_command(struct scsi_qla_host *ha, struct srb * sp, int handle) + __must_hold(&ha->host->host_lock) { uint16_t mb[MAILBOX_REGISTER_COUNT]; unsigned int bus, target, lun; @@ -3749,6 +3766,7 @@ qla1280_error_entry(struct scsi_qla_host *ha, struct response *pkt, */ static int qla1280_abort_isp(struct scsi_qla_host *ha) + __must_hold(&ha->host->host_lock) { struct device_reg __iomem *reg = ha->iobase; struct srb *sp; @@ -3881,6 +3899,7 @@ qla1280_check_for_dead_scsi_bus(struct scsi_qla_host *ha, unsigned int bus) static void qla1280_get_target_parameters(struct scsi_qla_host *ha, struct scsi_device *device) + __must_hold(&ha->host->host_lock) { uint16_t mb[MAILBOX_REGISTER_COUNT]; int bus, target, lun; diff --git a/drivers/scsi/qla2xxx/Makefile b/drivers/scsi/qla2xxx/Makefile index cbc1303e761e..095657510cc3 100644 --- a/drivers/scsi/qla2xxx/Makefile +++ b/drivers/scsi/qla2xxx/Makefile @@ -1,4 +1,7 @@ # SPDX-License-Identifier: GPL-2.0 + +CONTEXT_ANALYSIS := y + qla2xxx-y := qla_os.o qla_init.o qla_mbx.o qla_iocb.o qla_isr.o qla_gs.o \ qla_dbg.o qla_sup.o qla_attr.o qla_mid.o qla_dfs.o qla_bsg.o \ qla_nx.o qla_mr.o qla_nx2.o qla_target.o qla_tmpl.o qla_nvme.o \ diff --git a/drivers/scsi/qla2xxx/qla_attr.c b/drivers/scsi/qla2xxx/qla_attr.c index a4ca22024ede..781149497ff8 100644 --- a/drivers/scsi/qla2xxx/qla_attr.c +++ b/drivers/scsi/qla2xxx/qla_attr.c @@ -2814,13 +2814,13 @@ qla2x00_dev_loss_tmo_callbk(struct fc_rport *rport) * Transport has effectively 'deleted' the rport, clear * all local references. */ - spin_lock_irqsave(host->host_lock, flags); + spin_lock_irqsave(&host->host_lock, flags); /* Confirm port has not reappeared before clearing pointers. */ if (rport->port_state != FC_PORTSTATE_ONLINE) { fcport->rport = NULL; *((fc_port_t **)rport->dd_data) = NULL; } - spin_unlock_irqrestore(host->host_lock, flags); + spin_unlock_irqrestore(&host->host_lock, flags); if (test_bit(ABORT_ISP_ACTIVE, &fcport->vha->dpc_flags)) return; diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c index bb0cc71de37b..ccb039d97353 100644 --- a/drivers/scsi/qla2xxx/qla_init.c +++ b/drivers/scsi/qla2xxx/qla_init.c @@ -6247,9 +6247,9 @@ qla2x00_reg_remote_port(scsi_qla_host_t *vha, fc_port_t *fcport) return; } - spin_lock_irqsave(fcport->vha->host->host_lock, flags); + spin_lock_irqsave(&fcport->vha->host->host_lock, flags); *((fc_port_t **)rport->dd_data) = fcport; - spin_unlock_irqrestore(fcport->vha->host->host_lock, flags); + spin_unlock_irqrestore(&fcport->vha->host->host_lock, flags); fcport->dev_loss_tmo = rport->dev_loss_tmo; rport->supported_classes = fcport->supported_classes; diff --git a/drivers/scsi/qla2xxx/qla_isr.c b/drivers/scsi/qla2xxx/qla_isr.c index 63b70d4abbf0..89c2af3fee4f 100644 --- a/drivers/scsi/qla2xxx/qla_isr.c +++ b/drivers/scsi/qla2xxx/qla_isr.c @@ -3263,21 +3263,24 @@ qla2x00_handle_dif_error(srb_t *sp, void *pkt) /* check guard */ if (e_guard != a_guard) { - scsi_build_sense(cmd, 1, ILLEGAL_REQUEST, 0x10, 0x1); + scsi_set_sense(cmd, 1, ILLEGAL_REQUEST, + LOGICAL_BLOCK_GUARD_CHECK_FAILED); set_host_byte(cmd, DID_ABORT); return 1; } /* check ref tag */ if (e_ref_tag != a_ref_tag) { - scsi_build_sense(cmd, 1, ILLEGAL_REQUEST, 0x10, 0x3); + scsi_set_sense(cmd, 1, ILLEGAL_REQUEST, + LOGICAL_BLOCK_REFERENCE_TAG_CHECK_FAILED); set_host_byte(cmd, DID_ABORT); return 1; } /* check appl tag */ if (e_app_tag != a_app_tag) { - scsi_build_sense(cmd, 1, ILLEGAL_REQUEST, 0x10, 0x2); + scsi_set_sense(cmd, 1, ILLEGAL_REQUEST, + LOGICAL_BLOCK_APPLICATION_TAG_CHECK_FAILED); set_host_byte(cmd, DID_ABORT); return 1; } diff --git a/drivers/scsi/qla2xxx/qla_nx.c b/drivers/scsi/qla2xxx/qla_nx.c index 2366cca51bce..1a9a0f148bb3 100644 --- a/drivers/scsi/qla2xxx/qla_nx.c +++ b/drivers/scsi/qla2xxx/qla_nx.c @@ -431,6 +431,7 @@ static int qla82xx_crb_win_lock(struct qla_hw_data *ha) int qla82xx_wr_32(struct qla_hw_data *ha, ulong off_in, u32 data) + __context_unsafe(/*conditional locking*/) { void __iomem *off; unsigned long flags = 0; @@ -461,6 +462,7 @@ qla82xx_wr_32(struct qla_hw_data *ha, ulong off_in, u32 data) int qla82xx_rd_32(struct qla_hw_data *ha, ulong off_in) + __context_unsafe(/*conditional locking*/) { void __iomem *off; unsigned long flags = 0; diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c index c0efdbff5da7..3c412c7fb6fe 100644 --- a/drivers/scsi/qla2xxx/qla_os.c +++ b/drivers/scsi/qla2xxx/qla_os.c @@ -352,7 +352,7 @@ MODULE_PARM_DESC(ql2xnvme_queues, int ql2xfc2target = 1; module_param(ql2xfc2target, int, 0444); -MODULE_PARM_DESC(qla2xfc2target, +MODULE_PARM_DESC(ql2xfc2target, "Enables FC2 Target support. " "0 - FC2 Target support is disabled. " "1 - FC2 Target support is enabled (default)."); diff --git a/drivers/scsi/qla2xxx/qla_target.c b/drivers/scsi/qla2xxx/qla_target.c index 53a505df8da0..5a7caff61b16 100644 --- a/drivers/scsi/qla2xxx/qla_target.c +++ b/drivers/scsi/qla2xxx/qla_target.c @@ -383,11 +383,13 @@ static bool qlt_24xx_atio_pkt_all_vps(struct scsi_qla_host *vha, vha->vp_idx, entry->vp_index); break; } - if (!ha_locked) + if (!ha_locked) { spin_lock_irqsave(&host->hw->hardware_lock, flags); - qlt_24xx_handle_abts(host, (struct abts_recv_from_24xx *)atio); - if (!ha_locked) + qlt_24xx_handle_abts(host, (struct abts_recv_from_24xx *)atio); spin_unlock_irqrestore(&host->hw->hardware_lock, flags); + } else { + qlt_24xx_handle_abts(host, (struct abts_recv_from_24xx *)atio); + } break; } @@ -2243,18 +2245,20 @@ void qlt_free_ul_mcmd(struct qla_hw_data *ha, struct qla_tgt_mgmt_cmd *mcmd) * ha->hardware_lock supposed to be held on entry. Might drop it, then * reacquire */ -void qlt_send_resp_ctio(struct qla_qpair *qpair, struct qla_tgt_cmd *cmd, - uint8_t scsi_status, uint8_t sense_key, uint8_t asc, uint8_t ascq) +static void qlt_send_resp_ctio(struct qla_qpair *qpair, struct qla_tgt_cmd *cmd, + uint8_t scsi_status, uint8_t sense_key, uint16_t sense_code) { struct atio_from_isp *atio = &cmd->atio; struct ctio7_to_24xx *ctio; uint16_t temp; struct scsi_qla_host *vha = cmd->vha; + uint8_t asc = scsi_sense_code_asc(sense_code); + uint8_t ascq = scsi_sense_code_ascq(sense_code); ql_dbg(ql_dbg_tgt_dif, vha, 0x3066, "Sending response CTIO7 (vha=%p, atio=%p, scsi_status=%02x, " "sense_key=%02x, asc=%02x, ascq=%02x", - vha, atio, scsi_status, sense_key, asc, ascq); + vha, atio, scsi_status, sense_key, asc, ascq); ctio = (struct ctio7_to_24xx *)qla2x00_alloc_iocbs(vha, NULL); if (!ctio) { @@ -2677,44 +2681,47 @@ static void qlt_print_dif_err(struct qla_tgt_prm *prm) { struct qla_tgt_cmd *cmd; struct scsi_qla_host *vha; + u16 scode; /* asc 0x10=dif error */ - if (prm->sense_buffer && (prm->sense_buffer[12] == 0x10)) { - cmd = prm->cmd; - vha = cmd->vha; - /* ASCQ */ - switch (prm->sense_buffer[13]) { - case 1: - ql_dbg(ql_dbg_tgt_dif, vha, 0xe00b, - "BE detected Guard TAG ERR: lba[0x%llx|%lld] len[0x%x] " - "se_cmd=%p tag[%x]", - cmd->lba, cmd->lba, cmd->num_blks, &cmd->se_cmd, - cmd->atio.u.isp24.exchange_addr); - break; - case 2: - ql_dbg(ql_dbg_tgt_dif, vha, 0xe00c, - "BE detected APP TAG ERR: lba[0x%llx|%lld] len[0x%x] " - "se_cmd=%p tag[%x]", - cmd->lba, cmd->lba, cmd->num_blks, &cmd->se_cmd, - cmd->atio.u.isp24.exchange_addr); - break; - case 3: - ql_dbg(ql_dbg_tgt_dif, vha, 0xe00f, - "BE detected REF TAG ERR: lba[0x%llx|%lld] len[0x%x] " - "se_cmd=%p tag[%x]", - cmd->lba, cmd->lba, cmd->num_blks, &cmd->se_cmd, - cmd->atio.u.isp24.exchange_addr); - break; - default: - ql_dbg(ql_dbg_tgt_dif, vha, 0xe010, - "BE detected Dif ERR: lba[%llx|%lld] len[%x] " - "se_cmd=%p tag[%x]", - cmd->lba, cmd->lba, cmd->num_blks, &cmd->se_cmd, - cmd->atio.u.isp24.exchange_addr); - break; - } - ql_dump_buffer(ql_dbg_tgt_dif, vha, 0xe011, cmd->cdb, 16); + if (!prm->sense_buffer || + prm->sense_buffer[12] != ASC_ID_CRC_OR_ECC_ERROR) + return; + + cmd = prm->cmd; + vha = cmd->vha; + scode = scsi_sense_code(prm->sense_buffer[12], prm->sense_buffer[13]); + switch (scode) { + case LOGICAL_BLOCK_GUARD_CHECK_FAILED: + ql_dbg(ql_dbg_tgt_dif, vha, 0xe00b, + "BE detected Guard TAG ERR: lba[0x%llx|%lld] len[0x%x] " + "se_cmd=%p tag[%x]", + cmd->lba, cmd->lba, cmd->num_blks, &cmd->se_cmd, + cmd->atio.u.isp24.exchange_addr); + break; + case LOGICAL_BLOCK_APPLICATION_TAG_CHECK_FAILED: + ql_dbg(ql_dbg_tgt_dif, vha, 0xe00c, + "BE detected APP TAG ERR: lba[0x%llx|%lld] len[0x%x] " + "se_cmd=%p tag[%x]", + cmd->lba, cmd->lba, cmd->num_blks, &cmd->se_cmd, + cmd->atio.u.isp24.exchange_addr); + break; + case LOGICAL_BLOCK_REFERENCE_TAG_CHECK_FAILED: + ql_dbg(ql_dbg_tgt_dif, vha, 0xe00f, + "BE detected REF TAG ERR: lba[0x%llx|%lld] len[0x%x] " + "se_cmd=%p tag[%x]", + cmd->lba, cmd->lba, cmd->num_blks, &cmd->se_cmd, + cmd->atio.u.isp24.exchange_addr); + break; + default: + ql_dbg(ql_dbg_tgt_dif, vha, 0xe010, + "BE detected Dif ERR: lba[%llx|%lld] len[%x] " + "se_cmd=%p tag[%x]", + cmd->lba, cmd->lba, cmd->num_blks, &cmd->se_cmd, + cmd->atio.u.isp24.exchange_addr); + break; } + ql_dump_buffer(ql_dbg_tgt_dif, vha, 0xe011, cmd->cdb, 16); } /* @@ -3467,7 +3474,8 @@ qlt_handle_dif_error(struct qla_qpair *qpair, struct qla_tgt_cmd *cmd, uint8_t *ap = &sts->actual_dif[0]; uint8_t *ep = &sts->expected_dif[0]; uint64_t lba = cmd->se_cmd.t_task_lba; - uint8_t scsi_status, sense_key, asc, ascq; + uint8_t scsi_status, sense_key; + uint16_t sense_code = 0; struct scsi_qla_host *vha = cmd->vha; cmd->trc_flags |= TRC_DIF_ERR; @@ -3483,7 +3491,7 @@ qlt_handle_dif_error(struct qla_qpair *qpair, struct qla_tgt_cmd *cmd, ql_dbg(ql_dbg_tgt_dif, vha, 0xf075, "%s: aborted %d state %d\n", __func__, cmd->aborted, cmd->state); - scsi_status = sense_key = asc = ascq = 0; + scsi_status = sense_key = 0; /* check appl tag */ if (cmd->e_app_tag != cmd->a_app_tag) { @@ -3497,8 +3505,7 @@ qlt_handle_dif_error(struct qla_qpair *qpair, struct qla_tgt_cmd *cmd, cmd->dif_err_code = DIF_ERR_APP; scsi_status = SAM_STAT_CHECK_CONDITION; sense_key = ABORTED_COMMAND; - asc = 0x10; - ascq = 0x2; + sense_code = LOGICAL_BLOCK_APPLICATION_TAG_CHECK_FAILED; } /* check ref tag */ @@ -3513,8 +3520,7 @@ qlt_handle_dif_error(struct qla_qpair *qpair, struct qla_tgt_cmd *cmd, cmd->dif_err_code = DIF_ERR_REF; scsi_status = SAM_STAT_CHECK_CONDITION; sense_key = ABORTED_COMMAND; - asc = 0x10; - ascq = 0x3; + sense_code = LOGICAL_BLOCK_REFERENCE_TAG_CHECK_FAILED; goto out; } @@ -3530,8 +3536,7 @@ qlt_handle_dif_error(struct qla_qpair *qpair, struct qla_tgt_cmd *cmd, cmd->dif_err_code = DIF_ERR_GRD; scsi_status = SAM_STAT_CHECK_CONDITION; sense_key = ABORTED_COMMAND; - asc = 0x10; - ascq = 0x1; + sense_code = LOGICAL_BLOCK_GUARD_CHECK_FAILED; } out: switch (cmd->state) { @@ -3547,8 +3552,8 @@ qlt_handle_dif_error(struct qla_qpair *qpair, struct qla_tgt_cmd *cmd, break; } - qlt_send_resp_ctio(qpair, cmd, scsi_status, sense_key, asc, - ascq); + qlt_send_resp_ctio(qpair, cmd, scsi_status, sense_key, + sense_code); /* assume scsi status gets out on the wire. * Will not wait for completion. */ @@ -3772,6 +3777,7 @@ static int __qlt_send_term_exchange(struct qla_qpair *qpair, */ void qlt_send_term_exchange(struct qla_qpair *qpair, struct qla_tgt_cmd *cmd, struct atio_from_isp *atio, int ha_locked) + __context_unsafe(/*conditional locking*/) { struct scsi_qla_host *vha; unsigned long flags = 0; @@ -6725,11 +6731,13 @@ qlt_chk_qfull_thresh_hold(struct scsi_qla_host *vha, struct qla_qpair *qpair, if (ha->tgt.num_pend_cmds < Q_FULL_THRESH_HOLD(ha)) return 0; - if (!ha_locked) + if (!ha_locked) { spin_lock_irqsave(&ha->hardware_lock, flags); - qlt_send_busy(qpair, atio, qla_sam_status); - if (!ha_locked) + qlt_send_busy(qpair, atio, qla_sam_status); spin_unlock_irqrestore(&ha->hardware_lock, flags); + } else { + qlt_send_busy(qpair, atio, qla_sam_status); + } return 1; } @@ -6738,6 +6746,7 @@ qlt_chk_qfull_thresh_hold(struct scsi_qla_host *vha, struct qla_qpair *qpair, /* called via callback from qla2xxx */ static void qlt_24xx_atio_pkt(struct scsi_qla_host *vha, struct atio_from_isp *atio, uint8_t ha_locked) + __context_unsafe(/*conditional locking*/) { struct qla_hw_data *ha = vha->hw; struct qla_tgt *tgt = vha->vha_tgt.qla_tgt; @@ -6764,12 +6773,13 @@ static void qlt_24xx_atio_pkt(struct scsi_qla_host *vha, "qla_target(%d): ATIO_TYPE7 " "received with UNKNOWN exchange address, " "sending QUEUE_FULL\n", vha->vp_idx); - if (!ha_locked) + if (!ha_locked) { spin_lock_irqsave(&ha->hardware_lock, flags); - qlt_send_busy(ha->base_qpair, atio, qla_sam_status); - if (!ha_locked) - spin_unlock_irqrestore(&ha->hardware_lock, - flags); + qlt_send_busy(ha->base_qpair, atio, qla_sam_status); + spin_unlock_irqrestore(&ha->hardware_lock, flags); + } else { + qlt_send_busy(ha->base_qpair, atio, qla_sam_status); + } break; } diff --git a/drivers/scsi/qla2xxx/qla_target.h b/drivers/scsi/qla2xxx/qla_target.h index 61072fb41b29..71bc1affb1bc 100644 --- a/drivers/scsi/qla2xxx/qla_target.h +++ b/drivers/scsi/qla2xxx/qla_target.h @@ -1178,7 +1178,4 @@ extern irqreturn_t qla83xx_msix_atio_q(int, void *); extern void qlt_logo_completion_handler(fc_port_t *, int); extern void qlt_do_generation_tick(struct scsi_qla_host *, int *); -void qlt_send_resp_ctio(struct qla_qpair *, struct qla_tgt_cmd *, uint8_t, - uint8_t, uint8_t, uint8_t); - #endif /* __QLA_TARGET_H */ diff --git a/drivers/scsi/qla2xxx/qla_tmpl.c b/drivers/scsi/qla2xxx/qla_tmpl.c index fd3984127497..f96b9eb15126 100644 --- a/drivers/scsi/qla2xxx/qla_tmpl.c +++ b/drivers/scsi/qla2xxx/qla_tmpl.c @@ -1034,6 +1034,7 @@ qla27xx_fwdt_template_valid(void *p) void qla27xx_mpi_fwdump(scsi_qla_host_t *vha, int hardware_locked) + __context_unsafe(/*conditional locking*/) { ulong flags = 0; diff --git a/drivers/scsi/qla4xxx/Makefile b/drivers/scsi/qla4xxx/Makefile index 1f8a9096c744..2178d139f3ca 100644 --- a/drivers/scsi/qla4xxx/Makefile +++ b/drivers/scsi/qla4xxx/Makefile @@ -1,4 +1,7 @@ # SPDX-License-Identifier: GPL-2.0-only + +CONTEXT_ANALYSIS := y + qla4xxx-y := ql4_os.o ql4_init.o ql4_mbx.o ql4_iocb.o ql4_isr.o \ ql4_nx.o ql4_nvram.o ql4_dbg.o ql4_attr.o ql4_bsg.o ql4_83xx.o diff --git a/drivers/scsi/qla4xxx/ql4_isr.c b/drivers/scsi/qla4xxx/ql4_isr.c index cf52258ecdde..81989c905c82 100644 --- a/drivers/scsi/qla4xxx/ql4_isr.c +++ b/drivers/scsi/qla4xxx/ql4_isr.c @@ -367,6 +367,7 @@ static void qla4xxx_passthru_status_entry(struct scsi_qla_host *ha, struct ddb_entry *ddb_entry; struct ql4_task_data *task_data; struct iscsi_cls_conn *cls_conn; + struct iscsi_session *session; struct iscsi_conn *conn; itt_t itt; uint32_t fw_ddb_index; @@ -384,9 +385,10 @@ static void qla4xxx_passthru_status_entry(struct scsi_qla_host *ha, cls_conn = ddb_entry->conn; conn = cls_conn->dd_data; - spin_lock(&conn->session->back_lock); - task = iscsi_itt_to_task(conn, itt); - spin_unlock(&conn->session->back_lock); + session = conn->session; + spin_lock(&session->back_lock); + task = iscsi_itt_to_task(session, conn, itt); + spin_unlock(&session->back_lock); if (task == NULL) { ql4_printk(KERN_ERR, ha, "%s: Task is NULL\n", __func__); diff --git a/drivers/scsi/qla4xxx/ql4_nx.c b/drivers/scsi/qla4xxx/ql4_nx.c index f7340cfc990a..6aeb8097a73d 100644 --- a/drivers/scsi/qla4xxx/ql4_nx.c +++ b/drivers/scsi/qla4xxx/ql4_nx.c @@ -406,6 +406,7 @@ void qla4_82xx_crb_win_unlock(struct scsi_qla_host *ha) void qla4_82xx_wr_32(struct scsi_qla_host *ha, ulong off, u32 data) + __context_unsafe(/*conditional locking*/) { unsigned long flags = 0; int rv; @@ -429,6 +430,7 @@ qla4_82xx_wr_32(struct scsi_qla_host *ha, ulong off, u32 data) } uint32_t qla4_82xx_rd_32(struct scsi_qla_host *ha, ulong off) + __context_unsafe(/*conditional locking*/) { unsigned long flags = 0; int rv; diff --git a/drivers/scsi/qlogicfas408.c b/drivers/scsi/qlogicfas408.c index d36293bc2717..af6f6eb51636 100644 --- a/drivers/scsi/qlogicfas408.c +++ b/drivers/scsi/qlogicfas408.c @@ -454,9 +454,9 @@ irqreturn_t qlogicfas408_ihandl(int irq, void *dev_id) unsigned long flags; struct Scsi_Host *host = dev_id; - spin_lock_irqsave(host->host_lock, flags); + spin_lock_irqsave(&host->host_lock, flags); ql_ihandl(dev_id); - spin_unlock_irqrestore(host->host_lock, flags); + spin_unlock_irqrestore(&host->host_lock, flags); return IRQ_HANDLED; } @@ -536,9 +536,9 @@ int qlogicfas408_host_reset(struct scsi_cmnd *cmd) priv->qabort = 2; - spin_lock_irqsave(cmd->device->host->host_lock, flags); + spin_lock_irqsave(&cmd->device->host->host_lock, flags); ql_zap(priv); - spin_unlock_irqrestore(cmd->device->host->host_lock, flags); + spin_unlock_irqrestore(&cmd->device->host->host_lock, flags); return SUCCESS; } diff --git a/drivers/scsi/qlogicpti.c b/drivers/scsi/qlogicpti.c index ea0a2b5a0a42..098916061835 100644 --- a/drivers/scsi/qlogicpti.c +++ b/drivers/scsi/qlogicpti.c @@ -333,7 +333,7 @@ static int qlogicpti_reset_hardware(struct Scsi_Host *host) risc_code_addr = 0x1000; /* all load addresses are at 0x1000 */ - spin_lock_irqsave(host->host_lock, flags); + spin_lock_irqsave(&host->host_lock, flags); sbus_writew(HCCTRL_PAUSE, qpti->qregs + HCCTRL); @@ -382,7 +382,7 @@ static int qlogicpti_reset_hardware(struct Scsi_Host *host) if (qlogicpti_mbox_command(qpti, param, 1)) { printk(KERN_EMERG "qlogicpti%d: Cannot execute ISP firmware.\n", qpti->qpti_id); - spin_unlock_irqrestore(host->host_lock, flags); + spin_unlock_irqrestore(&host->host_lock, flags); return 1; } @@ -393,7 +393,7 @@ static int qlogicpti_reset_hardware(struct Scsi_Host *host) (param[0] != MBOX_COMMAND_COMPLETE)) { printk(KERN_EMERG "qlogicpti%d: Cannot set initiator SCSI ID.\n", qpti->qpti_id); - spin_unlock_irqrestore(host->host_lock, flags); + spin_unlock_irqrestore(&host->host_lock, flags); return 1; } @@ -408,7 +408,7 @@ static int qlogicpti_reset_hardware(struct Scsi_Host *host) if (qlogicpti_mbox_command(qpti, param, 1)) { printk(KERN_EMERG "qlogicpti%d: Cannot init response queue.\n", qpti->qpti_id); - spin_unlock_irqrestore(host->host_lock, flags); + spin_unlock_irqrestore(&host->host_lock, flags); return 1; } @@ -420,7 +420,7 @@ static int qlogicpti_reset_hardware(struct Scsi_Host *host) if (qlogicpti_mbox_command(qpti, param, 1)) { printk(KERN_EMERG "qlogicpti%d: Cannot init request queue.\n", qpti->qpti_id); - spin_unlock_irqrestore(host->host_lock, flags); + spin_unlock_irqrestore(&host->host_lock, flags); return 1; } @@ -466,7 +466,7 @@ static int qlogicpti_reset_hardware(struct Scsi_Host *host) qlogicpti_mbox_command(qpti, param, 0); qpti->send_marker = 1; - spin_unlock_irqrestore(host->host_lock, flags); + spin_unlock_irqrestore(&host->host_lock, flags); return 0; } @@ -501,7 +501,7 @@ static int qlogicpti_load_firmware(struct qlogicpti *qpti) risc_code_addr = 0x1000; /* all f/w modules load at 0x1000 */ risc_code_length = fw->size / 2; - spin_lock_irqsave(host->host_lock, flags); + spin_lock_irqsave(&host->host_lock, flags); /* Verify the checksum twice, one before loading it, and once * afterwards via the mailbox commands. @@ -642,7 +642,7 @@ static int qlogicpti_load_firmware(struct qlogicpti *qpti) } out: - spin_unlock_irqrestore(host->host_lock, flags); + spin_unlock_irqrestore(&host->host_lock, flags); outfirm: release_firmware(fw); return err; @@ -1207,7 +1207,7 @@ static irqreturn_t qpti_intr(int irq, void *dev_id) unsigned long flags; struct scsi_cmnd *dq; - spin_lock_irqsave(qpti->qhost->host_lock, flags); + spin_lock_irqsave(&qpti->qhost->host_lock, flags); dq = qlogicpti_intr_handler(qpti); if (dq != NULL) { @@ -1219,7 +1219,7 @@ static irqreturn_t qpti_intr(int irq, void *dev_id) dq = next; } while (dq != NULL); } - spin_unlock_irqrestore(qpti->qhost->host_lock, flags); + spin_unlock_irqrestore(&qpti->qhost->host_lock, flags); return IRQ_HANDLED; } diff --git a/drivers/scsi/scsi.c b/drivers/scsi/scsi.c index 76cdad063f7b..05232ab6366f 100644 --- a/drivers/scsi/scsi.c +++ b/drivers/scsi/scsi.c @@ -606,7 +606,8 @@ int scsi_report_opcode(struct scsi_device *sdev, unsigned char *buffer, return result; if (result && scsi_sense_valid(&sshdr) && sshdr.sense_key == ILLEGAL_REQUEST && - (sshdr.asc == 0x20 || sshdr.asc == 0x24) && sshdr.ascq == 0x00) + (sshdr.sense_code == INVALID_COMMAND_OP_CODE || + sshdr.sense_code == INVALID_FIELD_IN_CDB)) return -EINVAL; if ((buffer[1] & 3) == 3) /* Command supported */ @@ -727,6 +728,7 @@ int scsi_cdl_enable(struct scsi_device *sdev, bool enable) struct scsi_mode_data data; struct scsi_sense_hdr sshdr; char *buf_data; + size_t avail, offset; int len; ret = scsi_mode_sense(sdev, 0x08, 0x0a, 0xf2, buf, sizeof(buf), @@ -735,11 +737,24 @@ int scsi_cdl_enable(struct scsi_device *sdev, bool enable) return -EINVAL; /* Enable or disable CDL using the ATA feature page */ - len = min_t(size_t, sizeof(buf), - data.length - data.header_length - - data.block_descriptor_length); - buf_data = buf + data.header_length + - data.block_descriptor_length; + avail = min_t(size_t, data.length, sizeof(buf)); + if (data.header_length > avail) + return -EINVAL; + + offset = data.header_length; + avail -= data.header_length; + + if (data.block_descriptor_length > avail) + return -EINVAL; + + offset += data.block_descriptor_length; + avail -= data.block_descriptor_length; + + if (avail < 5) + return -EINVAL; + + buf_data = buf + offset; + len = avail; /* * If we want to enable CDL and CDL is already enabled on the @@ -828,7 +843,7 @@ struct scsi_device *__scsi_iterate_devices(struct Scsi_Host *shost, struct scsi_device *next = NULL; unsigned long flags; - spin_lock_irqsave(shost->host_lock, flags); + spin_lock_irqsave(&shost->host_lock, flags); while (list->next != &shost->__devices) { next = list_entry(list->next, struct scsi_device, siblings); /* @@ -840,7 +855,7 @@ struct scsi_device *__scsi_iterate_devices(struct Scsi_Host *shost, next = NULL; list = list->next; } - spin_unlock_irqrestore(shost->host_lock, flags); + spin_unlock_irqrestore(&shost->host_lock, flags); if (prev) scsi_device_put(prev); @@ -947,11 +962,11 @@ struct scsi_device *scsi_device_lookup_by_target(struct scsi_target *starget, struct Scsi_Host *shost = dev_to_shost(starget->dev.parent); unsigned long flags; - spin_lock_irqsave(shost->host_lock, flags); + spin_lock_irqsave(&shost->host_lock, flags); sdev = __scsi_device_lookup_by_target(starget, lun); if (sdev && scsi_device_get(sdev)) sdev = NULL; - spin_unlock_irqrestore(shost->host_lock, flags); + spin_unlock_irqrestore(&shost->host_lock, flags); return sdev; } @@ -1007,11 +1022,11 @@ struct scsi_device *scsi_device_lookup(struct Scsi_Host *shost, struct scsi_device *sdev; unsigned long flags; - spin_lock_irqsave(shost->host_lock, flags); + spin_lock_irqsave(&shost->host_lock, flags); sdev = __scsi_device_lookup(shost, channel, id, lun); if (sdev && scsi_device_get(sdev)) sdev = NULL; - spin_unlock_irqrestore(shost->host_lock, flags); + spin_unlock_irqrestore(&shost->host_lock, flags); return sdev; } diff --git a/drivers/scsi/scsi_common.c b/drivers/scsi/scsi_common.c index e1a2a62b6910..94b160336247 100644 --- a/drivers/scsi/scsi_common.c +++ b/drivers/scsi/scsi_common.c @@ -191,6 +191,8 @@ EXPORT_SYMBOL(int_to_scsilun); bool scsi_normalize_sense(const u8 *sense_buffer, int sb_len, struct scsi_sense_hdr *sshdr) { + u8 asc = 0, ascq = 0; + memset(sshdr, 0, sizeof(struct scsi_sense_hdr)); if (!sense_buffer || !sb_len) @@ -208,9 +210,9 @@ bool scsi_normalize_sense(const u8 *sense_buffer, int sb_len, if (sb_len > 1) sshdr->sense_key = (sense_buffer[1] & 0xf); if (sb_len > 2) - sshdr->asc = sense_buffer[2]; + asc = sense_buffer[2]; if (sb_len > 3) - sshdr->ascq = sense_buffer[3]; + ascq = sense_buffer[3]; if (sb_len > 7) sshdr->additional_length = sense_buffer[7]; } else { @@ -222,12 +224,14 @@ bool scsi_normalize_sense(const u8 *sense_buffer, int sb_len, if (sb_len > 7) { sb_len = min(sb_len, sense_buffer[7] + 8); if (sb_len > 12) - sshdr->asc = sense_buffer[12]; + asc = sense_buffer[12]; if (sb_len > 13) - sshdr->ascq = sense_buffer[13]; + ascq = sense_buffer[13]; } } + sshdr->sense_code = scsi_sense_code(asc, ascq); + return true; } EXPORT_SYMBOL(scsi_normalize_sense); @@ -272,17 +276,19 @@ const u8 * scsi_sense_desc_find(const u8 * sense_buffer, int sb_len, EXPORT_SYMBOL(scsi_sense_desc_find); /** - * scsi_build_sense_buffer - build sense data in a buffer + * scsi_set_sense_buffer - build sense data in a buffer * @desc: Sense format (non-zero == descriptor format, * 0 == fixed format) * @buf: Where to build sense data * @key: Sense key - * @asc: Additional sense code - * @ascq: Additional sense code qualifier + * @code: Additional sense code and sense code qualifier * **/ -void scsi_build_sense_buffer(int desc, u8 *buf, u8 key, u8 asc, u8 ascq) +void scsi_set_sense_buffer(int desc, u8 *buf, u8 key, u16 code) { + u8 asc = scsi_sense_code_asc(code); + u8 ascq = scsi_sense_code_ascq(code); + if (desc) { buf[0] = 0x72; /* descriptor, current */ buf[1] = key; @@ -297,7 +303,7 @@ void scsi_build_sense_buffer(int desc, u8 *buf, u8 key, u8 asc, u8 ascq) buf[13] = ascq; } } -EXPORT_SYMBOL(scsi_build_sense_buffer); +EXPORT_SYMBOL(scsi_set_sense_buffer); /** * scsi_set_sense_information - set the information field in a diff --git a/drivers/scsi/scsi_debug.c b/drivers/scsi/scsi_debug.c index 3346562275f8..a922c8318a2f 100644 --- a/drivers/scsi/scsi_debug.c +++ b/drivers/scsi/scsi_debug.c @@ -44,6 +44,7 @@ #include #include #include +#include #include @@ -67,9 +68,6 @@ static const char *sdebug_version_date = "20210520"; #define MY_NAME "scsi_debug" -/* Additional Sense Code Qualifier (ASCQ) */ -#define ACK_NAK_TO 0x3 - /* Default values for driver parameters */ #define DEF_NUM_HOST 1 #define DEF_NUM_TGTS 1 @@ -79,7 +77,7 @@ static const char *sdebug_version_date = "20210520"; */ #define DEF_ATO 1 #define DEF_CDB_LEN 10 -#define DEF_JDELAY 1 /* if > 0 unit is a jiffy */ +#define DEF_JDELAY 0 /* if > 0 unit is a jiffy */ #define DEF_DEV_SIZE_PRE_INIT 0 #define DEF_DEV_SIZE_MB 8 #define DEF_ZBC_DEV_SIZE_MB 128 @@ -106,6 +104,7 @@ static const char *sdebug_version_date = "20210520"; #define DEF_PTYPE TYPE_DISK #define DEF_RANDOM false #define DEF_REMOVABLE false +#define DEF_CLUSTERING true #define DEF_SCSI_LEVEL 7 /* INQUIRY, byte2 [6->SPC-4; 7->SPC-5] */ #define DEF_SECTOR_SIZE 512 #define DEF_UNMAP_ALIGNMENT 0 @@ -217,8 +216,7 @@ struct tape_block { * /sys/class/scsi_device//device/queue_depth * but cannot exceed SDEBUG_CANQUEUE . */ -#define SDEBUG_CANQUEUE_WORDS 3 /* a WORD is bits in a long */ -#define SDEBUG_CANQUEUE (SDEBUG_CANQUEUE_WORDS * BITS_PER_LONG) +#define SDEBUG_CANQUEUE (4096) #define DEF_CMD_PER_LUN SDEBUG_CANQUEUE /* UA - Unit Attention; SA - Service Action; SSU - Start Stop Unit */ @@ -850,7 +848,7 @@ static int sdebug_num_hosts; static int sdebug_add_host = DEF_NUM_HOST; /* in sysfs this is relative */ static int sdebug_ato = DEF_ATO; static int sdebug_cdb_len = DEF_CDB_LEN; -static int sdebug_jdelay = DEF_JDELAY; /* if > 0 then unit is jiffies */ +static int sdebug_jdelay = DEF_JDELAY; static int sdebug_dev_size_mb = DEF_DEV_SIZE_PRE_INIT; static int sdebug_dif = DEF_DIF; static int sdebug_dix = DEF_DIX; @@ -899,7 +897,7 @@ static int sdebug_uuid_ctl = DEF_UUID_CTL; static bool sdebug_random = DEF_RANDOM; static bool sdebug_per_host_store = DEF_PER_HOST_STORE; static bool sdebug_removable = DEF_REMOVABLE; -static bool sdebug_clustering; +static bool sdebug_clustering = DEF_CLUSTERING; static bool sdebug_host_lock = DEF_HOST_LOCK; static bool sdebug_strict = DEF_STRICT; static bool sdebug_no_rwlock; @@ -1168,6 +1166,95 @@ static const struct file_operations sdebug_error_fops = { .release = single_release, }; +enum corrupt_options { + Opt_lba = (1u << 0), + Opt_num = (1u << 1), + Opt_bit_errors = (1u << 2), + Opt_reftag_adjust = (1u << 3), + + Opt_invalid, +}; + +static const match_table_t corrupt_tokens = { + { Opt_lba, "lba=%u" }, + { Opt_num, "num=%u" }, + { Opt_bit_errors, "bit_errors=%u" }, + { Opt_reftag_adjust, "reftag_adjust=%d" }, + { Opt_invalid, NULL, }, +}; + +static int corrupt_lbas(struct sdebug_dev_info *devip, u64 lba, u32 num, + u32 nr_bit_errors, s32 reftag_adjust); +static ssize_t sdebug_corrupt_write(struct file *file, const char __user *ubuf, + size_t count, loff_t *ppos) +{ + struct scsi_device *sdev = file->f_inode->i_private; + struct sdebug_dev_info *devip = sdev->hostdata; + substring_t args[MAX_OPT_ARGS]; + char *buf, *options, *p; + int error = 0; + u64 lba = 0; + u32 num = 1; + u32 nr_bit_errors = 0; + s32 reftag_adjust = 0; + + buf = memdup_user_nul(ubuf, count); + if (IS_ERR(buf)) + return PTR_ERR(buf); + + options = buf; + while ((p = strsep(&options, ",\n")) != NULL) { + if (!*p) + continue; + switch (match_token(p, corrupt_tokens, args)) { + case Opt_lba: + error = match_u64(args, &lba); + break; + case Opt_num: + error = match_uint(args, &num); + break; + case Opt_bit_errors: + error = match_uint(args, &nr_bit_errors); + break; + case Opt_reftag_adjust: + error = match_int(args, &reftag_adjust); + break; + default: + pr_warn("unknown parameter or missing value '%s'\n", p); + error = -EINVAL; + } + if (error) + goto out_free_buf; + } + + if (num == 0) { + pr_warn("invalid number of logical blocks: %u\n", num); + error = -EINVAL; + goto out_free_buf; + } + + if (reftag_adjust && + (!sdebug_dix || + (sdebug_dif != T10_PI_TYPE1_PROTECTION && + sdebug_dif != T10_PI_TYPE2_PROTECTION))) { + pr_warn("reftag adjust requires type 1 or type 2 PI with DIX\n"); + error = -EINVAL; + goto out_free_buf; + } + + error = corrupt_lbas(devip, lba, num, nr_bit_errors, reftag_adjust); + +out_free_buf: + kfree(buf); + if (error) + return error; + return count; +} + +static const struct file_operations sdebug_corrupt_fops = { + .write = sdebug_corrupt_write, +}; + static int sdebug_target_reset_fail_show(struct seq_file *m, void *p) { struct scsi_target *starget = (struct scsi_target *)m->private; @@ -1320,9 +1407,13 @@ static void mk_sense_invalid_fld(struct scsi_cmnd *scp, sdev_printk(KERN_ERR, scp->device, "sense_buffer is NULL\n"); return; } - asc = c_d ? INVALID_FIELD_IN_CDB : INVALID_FIELD_IN_PARAM_LIST; + if (c_d) + asc = ASC_INVALID_FIELD_IN_CDB; + else + asc = ASC_INVALID_FIELD_IN_PARAMETER_LIST; memset(sbuff, 0, SCSI_SENSE_BUFFERSIZE); - scsi_build_sense(scp, sdebug_dsense, ILLEGAL_REQUEST, asc, 0); + scsi_set_sense(scp, sdebug_dsense, ILLEGAL_REQUEST, + scsi_sense_code(asc, 0)); memset(sks, 0, sizeof(sks)); sks[0] = 0x80; if (c_d) @@ -1346,7 +1437,7 @@ static void mk_sense_invalid_fld(struct scsi_cmnd *scp, my_name, asc, c_d ? 'C' : 'D', in_byte, in_bit); } -static void mk_sense_buffer(struct scsi_cmnd *scp, int key, int asc, int asq) +static void mk_sense_buffer(struct scsi_cmnd *scp, u8 key, u16 code) { if (!scp->sense_buffer) { sdev_printk(KERN_ERR, scp->device, "sense_buffer is NULL\n"); @@ -1354,16 +1445,16 @@ static void mk_sense_buffer(struct scsi_cmnd *scp, int key, int asc, int asq) } memset(scp->sense_buffer, 0, SCSI_SENSE_BUFFERSIZE); - scsi_build_sense(scp, sdebug_dsense, key, asc, asq); + scsi_set_sense(scp, sdebug_dsense, key, code); if (sdebug_verbose) sdev_printk(KERN_INFO, scp->device, - "%s: [sense_key,asc,ascq]: [0x%x,0x%x,0x%x]\n", - my_name, key, asc, asq); + "%s: [sense_key,sense_code]: [0x%02x,0x%04x]\n", + my_name, key, code); } /* Sense data that has information fields for tapes */ -static void mk_sense_info_tape(struct scsi_cmnd *scp, int key, int asc, int asq, +static void mk_sense_info_tape(struct scsi_cmnd *scp, u8 key, u16 code, unsigned int information, unsigned char tape_flags) { if (!scp->sense_buffer) { @@ -1372,7 +1463,7 @@ static void mk_sense_info_tape(struct scsi_cmnd *scp, int key, int asc, int asq, } memset(scp->sense_buffer, 0, SCSI_SENSE_BUFFERSIZE); - scsi_build_sense(scp, /* sdebug_dsense */ 0, key, asc, asq); + scsi_set_sense(scp, /* sdebug_dsense */ 0, key, code); /* only fixed format so far */ scp->sense_buffer[0] |= 0x80; /* valid */ @@ -1381,13 +1472,13 @@ static void mk_sense_info_tape(struct scsi_cmnd *scp, int key, int asc, int asq, if (sdebug_verbose) sdev_printk(KERN_INFO, scp->device, - "%s: [sense_key,asc,ascq]: [0x%x,0x%x,0x%x]\n", - my_name, key, asc, asq); + "%s: [sense_key,sense_code]: [0x%02x,0x%04x]\n", + my_name, key, code); } static void mk_sense_invalid_opcode(struct scsi_cmnd *scp) { - mk_sense_buffer(scp, ILLEGAL_REQUEST, INVALID_OPCODE, 0); + mk_sense_buffer(scp, ILLEGAL_REQUEST, INVALID_COMMAND_OP_CODE); } static int scsi_debug_ioctl(struct scsi_device *dev, unsigned int cmd, @@ -1484,46 +1575,43 @@ static int make_ua(struct scsi_cmnd *scp, struct sdebug_dev_info *devip) switch (k) { case SDEBUG_UA_POR: - mk_sense_buffer(scp, UNIT_ATTENTION, UA_RESET_ASC, - POWER_ON_RESET_ASCQ); + mk_sense_buffer(scp, UNIT_ATTENTION, + POWER_ON_RESET_OR_BUS_DEVICE_RESET_OCCURRED); if (sdebug_verbose) cp = "power on reset"; break; case SDEBUG_UA_POOCCUR: - mk_sense_buffer(scp, UNIT_ATTENTION, UA_RESET_ASC, - POWER_ON_OCCURRED_ASCQ); + mk_sense_buffer(scp, UNIT_ATTENTION, POWER_ON_OCCURRED); if (sdebug_verbose) cp = "power on occurred"; break; case SDEBUG_UA_BUS_RESET: - mk_sense_buffer(scp, UNIT_ATTENTION, UA_RESET_ASC, - BUS_RESET_ASCQ); + mk_sense_buffer(scp, UNIT_ATTENTION, + SCSI_BUS_RESET_OCCURRED); if (sdebug_verbose) cp = "bus reset"; break; case SDEBUG_UA_MODE_CHANGED: - mk_sense_buffer(scp, UNIT_ATTENTION, UA_CHANGED_ASC, - MODE_CHANGED_ASCQ); + mk_sense_buffer(scp, UNIT_ATTENTION, + MODE_PARAMETERS_CHANGED); if (sdebug_verbose) cp = "mode parameters changed"; break; case SDEBUG_UA_CAPACITY_CHANGED: - mk_sense_buffer(scp, UNIT_ATTENTION, UA_CHANGED_ASC, - CAPACITY_CHANGED_ASCQ); + mk_sense_buffer(scp, UNIT_ATTENTION, + CAPACITY_DATA_HAS_CHANGED); if (sdebug_verbose) cp = "capacity data changed"; break; case SDEBUG_UA_MICROCODE_CHANGED: mk_sense_buffer(scp, UNIT_ATTENTION, - TARGET_CHANGED_ASC, - MICROCODE_CHANGED_ASCQ); + MICROCODE_HAS_BEEN_CHANGED); if (sdebug_verbose) cp = "microcode has been changed"; break; case SDEBUG_UA_MICROCODE_CHANGED_WO_RESET: mk_sense_buffer(scp, UNIT_ATTENTION, - TARGET_CHANGED_ASC, - MICROCODE_CHANGED_WO_RESET_ASCQ); + MICROCODE_HAS_BEEN_CHANGED_WITHOUT_RESET); if (sdebug_verbose) cp = "microcode has been changed without reset"; break; @@ -1539,14 +1627,13 @@ static int make_ua(struct scsi_cmnd *scp, struct sdebug_dev_info *devip) if (sdebug_scsi_level >= 6) /* SPC-4 and above */ clear_luns_changed_on_target(devip); mk_sense_buffer(scp, UNIT_ATTENTION, - TARGET_CHANGED_ASC, - LUNS_CHANGED_ASCQ); + REPORTED_LUNS_DATA_HAS_CHANGED); if (sdebug_verbose) cp = "reported luns data has changed"; break; case SDEBUG_UA_NOT_READY_TO_READY: - mk_sense_buffer(scp, UNIT_ATTENTION, UA_READY_ASC, - 0); + mk_sense_buffer(scp, UNIT_ATTENTION, + NOT_READY_TO_READY_CHANGE_MEDIUM_MAY_HAVE_CHANGED); if (sdebug_verbose) cp = "not ready to ready transition/media change"; break; @@ -2184,14 +2271,14 @@ static int resp_requests(struct scsi_cmnd *scp, if (dsense) { arr[0] = 0x72; arr[1] = NOT_READY; - arr[2] = LOGICAL_UNIT_NOT_READY; + arr[2] = ASC_LU_NOT_READY; arr[3] = (stopped_state == 2) ? 0x1 : 0x2; len = 8; } else { arr[0] = 0x70; arr[2] = NOT_READY; /* NO_SENSE in sense_key */ arr[7] = 0xa; /* 18 byte sense buffer */ - arr[12] = LOGICAL_UNIT_NOT_READY; + arr[12] = ASC_LU_NOT_READY; arr[13] = (stopped_state == 2) ? 0x1 : 0x2; } } else if ((iec_m_pg[2] & 0x4) && (6 == (iec_m_pg[3] & 0xf))) { @@ -2199,14 +2286,14 @@ static int resp_requests(struct scsi_cmnd *scp, if (dsense) { arr[0] = 0x72; arr[1] = 0x0; /* NO_SENSE in sense_key */ - arr[2] = THRESHOLD_EXCEEDED; + arr[2] = ASC_FAILURE_PREDICTION_THRESHOLD_EXCEEDED; arr[3] = 0xff; /* Failure prediction(false) */ len = 8; } else { arr[0] = 0x70; arr[2] = 0x0; /* NO_SENSE in sense_key */ arr[7] = 0xa; /* 18 byte sense buffer */ - arr[12] = THRESHOLD_EXCEEDED; + arr[12] = ASC_FAILURE_PREDICTION_THRESHOLD_EXCEEDED; arr[13] = 0xff; /* Failure prediction(false) */ } } else { /* nothing to report */ @@ -2457,8 +2544,7 @@ static int resp_rsup_opcodes(struct scsi_cmnd *scp, a_len = alloc_len; arr = kzalloc((a_len < 256) ? 320 : a_len + 64, GFP_ATOMIC); if (NULL == arr) { - mk_sense_buffer(scp, ILLEGAL_REQUEST, INSUFF_RES_ASC, - INSUFF_RES_ASCQ); + mk_sense_buffer(scp, ILLEGAL_REQUEST, INSUFFICIENT_RESOURCES); return check_condition_result; } switch (reporting_opts) { @@ -2924,8 +3010,9 @@ static int resp_mode_sense(struct scsi_cmnd *scp, else bd_len = 0; alloc_len = msense_6 ? cmd[4] : get_unaligned_be16(cmd + 7); - if (0x3 == pcontrol) { /* Saving values not supported */ - mk_sense_buffer(scp, ILLEGAL_REQUEST, SAVING_PARAMS_UNSUP, 0); + if (0x3 == pcontrol) { + mk_sense_buffer(scp, ILLEGAL_REQUEST, + SAVING_PARAMETERS_NOT_SUPPORTED); return check_condition_result; } target_dev_id = ((devip->sdbg_host->shost->host_no + 1) * 2000) + @@ -3174,7 +3261,7 @@ static int resp_mode_select(struct scsi_cmnd *scp, (arr[off + 1] + 2); if ((pg_len + off) > param_len) { mk_sense_buffer(scp, ILLEGAL_REQUEST, - PARAMETER_LIST_LENGTH_ERR, 0); + PARAMETER_LIST_LENGTH_ERROR); return check_condition_result; } switch (mpage) { @@ -3256,7 +3343,7 @@ static int resp_ie_l_pg(unsigned char *arr) memcpy(arr, ie_l_pg, sizeof(ie_l_pg)); if (iec_m_pg[2] & 0x4) { /* TEST bit set */ - arr[4] = THRESHOLD_EXCEEDED; + arr[4] = ASC_FAILURE_PREDICTION_THRESHOLD_EXCEEDED; arr[5] = 0xff; } return sizeof(ie_l_pg); @@ -3413,7 +3500,8 @@ static int resp_locate(struct scsi_cmnd *scp, break; if (i < pos) { devip->tape_location[partition] = i; - mk_sense_buffer(scp, BLANK_CHECK, 0x05, 0); + mk_sense_buffer(scp, BLANK_CHECK, + LU_DOES_NOT_RESPOND_TO_SELECTION); return check_condition_result; } devip->tape_location[partition] = pos; @@ -3438,8 +3526,9 @@ static int resp_write_filemarks(struct scsi_cmnd *scp, for (i = 0, pos = devip->tape_location[partition]; i < count; i++, pos++) { if (pos >= devip->tape_eop[partition] - 1) { /* don't overwrite EOD */ devip->tape_location[partition] = devip->tape_eop[partition] - 1; - mk_sense_info_tape(scp, VOLUME_OVERFLOW, NO_ADDITIONAL_SENSE, - EOP_EOM_DETECTED_ASCQ, count, SENSE_FLAG_EOM); + mk_sense_info_tape(scp, VOLUME_OVERFLOW, + END_OF_PARTITION_MEDIUM_DETECTED, + count, SENSE_FLAG_EOM); return check_condition_result; } (devip->tape_blocks[partition] + pos)->fl_size = data; @@ -3540,31 +3629,28 @@ static int resp_space(struct scsi_cmnd *scp, is_fm: devip->tape_location[partition] = pos; - mk_sense_info_tape(scp, NO_SENSE, NO_ADDITIONAL_SENSE, - FILEMARK_DETECTED_ASCQ, count - i, - SENSE_FLAG_FILEMARK); + mk_sense_info_tape(scp, NO_SENSE, FILEMARK_DETECTED, + count - i, SENSE_FLAG_FILEMARK); return check_condition_result; is_eod: devip->tape_location[partition] = pos; - mk_sense_info_tape(scp, BLANK_CHECK, NO_ADDITIONAL_SENSE, - EOD_DETECTED_ASCQ, count - i, - 0); + mk_sense_info_tape(scp, BLANK_CHECK, END_OF_DATA_DETECTED, + count - i, 0); return check_condition_result; is_bop: devip->tape_location[partition] = 0; - mk_sense_info_tape(scp, NO_SENSE, NO_ADDITIONAL_SENSE, - BEGINNING_OF_P_M_DETECTED_ASCQ, count - i, - SENSE_FLAG_EOM); + mk_sense_info_tape(scp, NO_SENSE, + BEGINNING_OF_PARTITION_MEDIUM_DETECTED, + count - i, SENSE_FLAG_EOM); devip->tape_location[partition] = 0; return check_condition_result; is_eop: devip->tape_location[partition] = devip->tape_eop[partition] - 1; - mk_sense_info_tape(scp, MEDIUM_ERROR, NO_ADDITIONAL_SENSE, - EOP_EOM_DETECTED_ASCQ, (unsigned int)i, - SENSE_FLAG_EOM); + mk_sense_info_tape(scp, MEDIUM_ERROR, END_OF_PARTITION_MEDIUM_DETECTED, + (unsigned int)i, SENSE_FLAG_EOM); return check_condition_result; } @@ -3852,8 +3938,7 @@ static int check_zbc_access_params(struct scsi_cmnd *scp, /* For host-managed, reads cannot cross zone types boundaries */ if (zsp->z_type != zsp_end->z_type) { mk_sense_buffer(scp, ILLEGAL_REQUEST, - LBA_OUT_OF_RANGE, - READ_INVDATA_ASCQ); + ATTEMPT_TO_READ_INVALID_DATA); return check_condition_result; } return 0; @@ -3861,8 +3946,8 @@ static int check_zbc_access_params(struct scsi_cmnd *scp, /* Writing into a gap zone is not allowed */ if (zbc_zone_is_gap(zsp)) { - mk_sense_buffer(scp, ILLEGAL_REQUEST, LBA_OUT_OF_RANGE, - ATTEMPT_ACCESS_GAP); + mk_sense_buffer(scp, ILLEGAL_REQUEST, + ATTEMPT_TO_ACCESS_GAP_ZONE); return check_condition_result; } @@ -3870,8 +3955,7 @@ static int check_zbc_access_params(struct scsi_cmnd *scp, if (zbc_zone_is_conv(zsp)) { if (!zbc_zone_is_conv(zsp_end)) { mk_sense_buffer(scp, ILLEGAL_REQUEST, - LBA_OUT_OF_RANGE, - WRITE_BOUNDARY_ASCQ); + WRITE_BOUNDARY_VIOLATION); return check_condition_result; } return 0; @@ -3881,21 +3965,29 @@ static int check_zbc_access_params(struct scsi_cmnd *scp, /* Writes cannot cross sequential zone boundaries */ if (zsp_end != zsp) { mk_sense_buffer(scp, ILLEGAL_REQUEST, - LBA_OUT_OF_RANGE, - WRITE_BOUNDARY_ASCQ); + WRITE_BOUNDARY_VIOLATION); return check_condition_result; } /* Cannot write full zones */ if (zsp->z_cond == ZC5_FULL) { mk_sense_buffer(scp, ILLEGAL_REQUEST, - INVALID_FIELD_IN_CDB, 0); + INVALID_FIELD_IN_CDB); return check_condition_result; } /* Writes must be aligned to the zone WP */ if (lba != zsp->z_wp) { mk_sense_buffer(scp, ILLEGAL_REQUEST, - LBA_OUT_OF_RANGE, - UNALIGNED_WRITE_ASCQ); + UNALIGNED_WRITE_COMMAND); + return check_condition_result; + } + /* + * Writes must end on a physical block boundary, that is, the + * transfer length must be a multiple of the physical block + * size. + */ + if (!IS_ALIGNED(lba + num, 1U << sdebug_physblk_exp)) { + mk_sense_buffer(scp, ILLEGAL_REQUEST, + UNALIGNED_WRITE_COMMAND); return check_condition_result; } } @@ -3905,8 +3997,7 @@ static int check_zbc_access_params(struct scsi_cmnd *scp, if (devip->max_open && devip->nr_exp_open >= devip->max_open) { mk_sense_buffer(scp, DATA_PROTECT, - INSUFF_RES_ASC, - INSUFF_ZONE_ASCQ); + INSUFFICIENT_ZONE_RESOURCES); return check_condition_result; } zbc_open_zone(devip, zsp, false); @@ -3923,17 +4014,18 @@ static inline int check_device_access_params struct sdebug_dev_info *devip = (struct sdebug_dev_info *)sdp->hostdata; if (lba + num > sdebug_capacity) { - mk_sense_buffer(scp, ILLEGAL_REQUEST, LBA_OUT_OF_RANGE, 0); + mk_sense_buffer(scp, ILLEGAL_REQUEST, + LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE); return check_condition_result; } /* transfer length excessive (tie in to block limits VPD page) */ if (num > sdebug_store_sectors) { /* needs work to find which cdb byte 'num' comes from */ - mk_sense_buffer(scp, ILLEGAL_REQUEST, INVALID_FIELD_IN_CDB, 0); + mk_sense_buffer(scp, ILLEGAL_REQUEST, INVALID_FIELD_IN_CDB); return check_condition_result; } if (write && unlikely(sdebug_wp)) { - mk_sense_buffer(scp, DATA_PROTECT, WRITE_PROTECTED, 0x2); + mk_sense_buffer(scp, DATA_PROTECT, LU_SOFTWARE_WRITE_PROTECTED); return check_condition_result; } if (sdebug_dev_is_zoned(devip)) @@ -3960,24 +4052,27 @@ static inline struct sdeb_store_info *devip2sip(struct sdebug_dev_info *devip, static inline void sdeb_read_lock(rwlock_t *lock) + __acquires_shared(lock) { if (sdebug_no_rwlock) - __acquire(lock); + __acquire_shared(lock); else read_lock(lock); } static inline void sdeb_read_unlock(rwlock_t *lock) + __releases_shared(lock) { if (sdebug_no_rwlock) - __release(lock); + __release_shared(lock); else read_unlock(lock); } static inline void sdeb_write_lock(rwlock_t *lock) + __acquires(lock) { if (sdebug_no_rwlock) __acquire(lock); @@ -3987,6 +4082,7 @@ sdeb_write_lock(rwlock_t *lock) static inline void sdeb_write_unlock(rwlock_t *lock) + __releases(lock) { if (sdebug_no_rwlock) __release(lock); @@ -3996,6 +4092,7 @@ sdeb_write_unlock(rwlock_t *lock) static inline void sdeb_data_read_lock(struct sdeb_store_info *sip) + __acquires_shared(&sip->macc_data_lck) { BUG_ON(!sip); @@ -4004,6 +4101,7 @@ sdeb_data_read_lock(struct sdeb_store_info *sip) static inline void sdeb_data_read_unlock(struct sdeb_store_info *sip) + __releases_shared(&sip->macc_data_lck) { BUG_ON(!sip); @@ -4012,6 +4110,7 @@ sdeb_data_read_unlock(struct sdeb_store_info *sip) static inline void sdeb_data_write_lock(struct sdeb_store_info *sip) + __acquires(&sip->macc_data_lck) { BUG_ON(!sip); @@ -4020,6 +4119,7 @@ sdeb_data_write_lock(struct sdeb_store_info *sip) static inline void sdeb_data_write_unlock(struct sdeb_store_info *sip) + __releases(&sip->macc_data_lck) { BUG_ON(!sip); @@ -4028,6 +4128,7 @@ sdeb_data_write_unlock(struct sdeb_store_info *sip) static inline void sdeb_data_sector_read_lock(struct sdeb_store_info *sip) + __acquires_shared(&sip->macc_sector_lck) { BUG_ON(!sip); @@ -4036,6 +4137,7 @@ sdeb_data_sector_read_lock(struct sdeb_store_info *sip) static inline void sdeb_data_sector_read_unlock(struct sdeb_store_info *sip) + __releases_shared(&sip->macc_sector_lck) { BUG_ON(!sip); @@ -4044,6 +4146,7 @@ sdeb_data_sector_read_unlock(struct sdeb_store_info *sip) static inline void sdeb_data_sector_write_lock(struct sdeb_store_info *sip) + __acquires(&sip->macc_sector_lck) { BUG_ON(!sip); @@ -4052,6 +4155,7 @@ sdeb_data_sector_write_lock(struct sdeb_store_info *sip) static inline void sdeb_data_sector_write_unlock(struct sdeb_store_info *sip) + __releases(&sip->macc_sector_lck) { BUG_ON(!sip); @@ -4073,50 +4177,67 @@ sdeb_data_sector_write_unlock(struct sdeb_store_info *sip) static inline void sdeb_data_lock(struct sdeb_store_info *sip, bool atomic) + __acquires(&sip->macc_data_lck) { - if (atomic) + if (atomic) { sdeb_data_write_lock(sip); - else + } else { sdeb_data_read_lock(sip); + __release_shared(&sip->macc_data_lck); + __acquire(&sip->macc_data_lck); + } } static inline void sdeb_data_unlock(struct sdeb_store_info *sip, bool atomic) + __releases(&sip->macc_data_lck) { - if (atomic) + if (atomic) { sdeb_data_write_unlock(sip); - else + } else { + __release(&sip->macc_data_lck); + __acquire_shared(&sip->macc_data_lck); sdeb_data_read_unlock(sip); + } } /* Allow many reads but only 1x write per sector */ static inline void sdeb_data_sector_lock(struct sdeb_store_info *sip, bool do_write) + __acquires(&sip->macc_sector_lck) { - if (do_write) + if (do_write) { sdeb_data_sector_write_lock(sip); - else + } else { sdeb_data_sector_read_lock(sip); + __release_shared(&sip->macc_sector_lck); + __acquire(&sip->macc_sector_lck); + } } static inline void sdeb_data_sector_unlock(struct sdeb_store_info *sip, bool do_write) + __releases(&sip->macc_sector_lck) { - if (do_write) + if (do_write) { sdeb_data_sector_write_unlock(sip); - else + } else { + __release(&sip->macc_sector_lck); + __acquire_shared(&sip->macc_sector_lck); sdeb_data_sector_read_unlock(sip); + } } static inline void sdeb_meta_read_lock(struct sdeb_store_info *sip) -{ - if (sdebug_no_rwlock) { - if (sip) - __acquire(&sip->macc_meta_lck); - else - __acquire(&sdeb_fake_rw_lck); - } else { + __acquires_shared(&sip->macc_meta_lck) + __context_unsafe(/* + * Can't be annotated with + * __{acquire,release}(,_shared}() without triggering + * undefined behavior. + */) +{ + if (!sdebug_no_rwlock) { if (sip) read_lock(&sip->macc_meta_lck); else @@ -4126,13 +4247,14 @@ sdeb_meta_read_lock(struct sdeb_store_info *sip) static inline void sdeb_meta_read_unlock(struct sdeb_store_info *sip) -{ - if (sdebug_no_rwlock) { - if (sip) - __release(&sip->macc_meta_lck); - else - __release(&sdeb_fake_rw_lck); - } else { + __releases_shared(&sip->macc_meta_lck) + __context_unsafe(/* + * Can't be annotated with + * __{acquire,release}(,_shared}() without triggering + * undefined behavior. + */) +{ + if (!sdebug_no_rwlock) { if (sip) read_unlock(&sip->macc_meta_lck); else @@ -4142,13 +4264,14 @@ sdeb_meta_read_unlock(struct sdeb_store_info *sip) static inline void sdeb_meta_write_lock(struct sdeb_store_info *sip) -{ - if (sdebug_no_rwlock) { - if (sip) - __acquire(&sip->macc_meta_lck); - else - __acquire(&sdeb_fake_rw_lck); - } else { + __acquires(&sip->macc_meta_lck) + __context_unsafe(/* + * Can't be annotated with + * __{acquire,release}(,_shared}() without triggering + * undefined behavior. + */) +{ + if (!sdebug_no_rwlock) { if (sip) write_lock(&sip->macc_meta_lck); else @@ -4158,13 +4281,14 @@ sdeb_meta_write_lock(struct sdeb_store_info *sip) static inline void sdeb_meta_write_unlock(struct sdeb_store_info *sip) -{ - if (sdebug_no_rwlock) { - if (sip) - __release(&sip->macc_meta_lck); - else - __release(&sdeb_fake_rw_lck); - } else { + __releases(&sip->macc_meta_lck) + __context_unsafe(/* + * Can't be annotated with + * __{acquire,release}(,_shared}() without triggering + * undefined behavior. + */) +{ + if (!sdebug_no_rwlock) { if (sip) write_unlock(&sip->macc_meta_lck); else @@ -4181,6 +4305,8 @@ static int do_device_access(struct sdeb_store_info *sip, struct scsi_cmnd *scp, u64 block; enum dma_data_direction dir; struct scsi_data_buffer *sdb = &scp->sdb; + struct scsi_device *sdp = scp->device; + struct sdebug_dev_info *devip = (struct sdebug_dev_info *)sdp->hostdata; u8 *fsp; int i, total = 0; @@ -4208,6 +4334,25 @@ static int do_device_access(struct sdeb_store_info *sip, struct scsi_cmnd *scp, fsp = sip->storep; + /* + * A write to a sequential write required zone has to end on a physical + * block boundary, so if the data-out buffer does not hold all of the + * data that the command asks for, write up to the last whole physical + * block that it does hold. What is left over is reported as part of + * the residual. + */ + if (do_write && sdebug_dev_is_zoned(devip)) { + struct sdeb_zone_state *zsp = zbc_zone(devip, lba); + + if (zsp->z_type == ZBC_ZTYPE_SWR) { + u32 avail = (sdb->length - sg_skip) + >> ilog2(sdebug_sector_size); + + if (avail < num) + num = round_down(avail, 1U << sdebug_physblk_exp); + } + } + block = do_div(lba, sdebug_store_sectors); /* Only allow 1x atomic write or multiple non-atomic writes at any given time */ @@ -4442,17 +4587,17 @@ static int resp_read_tape(struct scsi_cmnd *scp, struct sdebug_dev_info *devip) i++, pos++, blp++) { devip->tape_location[partition] = pos + 1; if (IS_TAPE_BLOCK_FM(blp->fl_size)) { - mk_sense_info_tape(scp, NO_SENSE, NO_ADDITIONAL_SENSE, - FILEMARK_DETECTED_ASCQ, fixed ? num - i : size, - SENSE_FLAG_FILEMARK); + mk_sense_info_tape(scp, NO_SENSE, FILEMARK_DETECTED, + fixed ? num - i : size, + SENSE_FLAG_FILEMARK); scsi_set_resid(scp, (num - i) * size); return check_condition_result; } /* Assume no REW */ if (IS_TAPE_BLOCK_EOD(blp->fl_size)) { - mk_sense_info_tape(scp, BLANK_CHECK, NO_ADDITIONAL_SENSE, - EOD_DETECTED_ASCQ, fixed ? num - i : size, - 0); + mk_sense_info_tape(scp, BLANK_CHECK, + END_OF_DATA_DETECTED, + fixed ? num - i : size, 0); devip->tape_location[partition] = pos; scsi_set_resid(scp, (num - i) * size); return check_condition_result; @@ -4464,9 +4609,9 @@ static int resp_read_tape(struct scsi_cmnd *scp, struct sdebug_dev_info *devip) if (fixed) { if (blp->fl_size != devip->tape_blksize) { scsi_set_resid(scp, (num - i) * size); - mk_sense_info_tape(scp, NO_SENSE, NO_ADDITIONAL_SENSE, - 0, num - i, - SENSE_FLAG_ILI); + mk_sense_info_tape(scp, NO_SENSE, + NO_ADDITIONAL_SENSE_INFORMATION, + num - i, SENSE_FLAG_ILI); return check_condition_result; } } else { @@ -4474,18 +4619,19 @@ static int resp_read_tape(struct scsi_cmnd *scp, struct sdebug_dev_info *devip) if (blp->fl_size < size) scsi_set_resid(scp, size - blp->fl_size); if (!sili) { - mk_sense_info_tape(scp, NO_SENSE, NO_ADDITIONAL_SENSE, - 0, size - blp->fl_size, - SENSE_FLAG_ILI); + mk_sense_info_tape(scp, NO_SENSE, + NO_ADDITIONAL_SENSE_INFORMATION, + size - blp->fl_size, + SENSE_FLAG_ILI); return check_condition_result; } } } } if (pos >= devip->tape_eop[partition]) { - mk_sense_info_tape(scp, NO_SENSE, NO_ADDITIONAL_SENSE, - EOP_EOM_DETECTED_ASCQ, fixed ? num - i : size, - SENSE_FLAG_EOM); + mk_sense_info_tape(scp, NO_SENSE, + END_OF_PARTITION_MEDIUM_DETECTED, + fixed ? num - i : size, SENSE_FLAG_EOM); devip->tape_location[partition] = pos - 1; return check_condition_result; } @@ -4494,6 +4640,70 @@ static int resp_read_tape(struct scsi_cmnd *scp, struct sdebug_dev_info *devip) return 0; } +/* + * Returns 0 upon success or -1 with *scsi_status set to a SCSI status code upon + * failure. + */ +static int __resp_read_dt0_dix(struct scsi_cmnd *scp, u64 lba, u32 num, + u32 ei_lba, int *scsi_status) +{ + const u8 *const cmd = scp->cmnd; + + switch (prot_verify_read(scp, lba, num, ei_lba)) { + case 1: /* Guard tag error */ + if (cmd[1] >> 5 != 3) { /* RDPROTECT != 3 */ + mk_sense_buffer(scp, ABORTED_COMMAND, + LOGICAL_BLOCK_GUARD_CHECK_FAILED); + *scsi_status = check_condition_result; + return -1; + } + if (scp->prot_flags & SCSI_PROT_GUARD_CHECK) { + mk_sense_buffer(scp, ILLEGAL_REQUEST, + LOGICAL_BLOCK_GUARD_CHECK_FAILED); + *scsi_status = illegal_condition_result; + return -1; + } + break; + case 3: /* Reference tag error */ + if (cmd[1] >> 5 != 3) { /* RDPROTECT != 3 */ + mk_sense_buffer(scp, ABORTED_COMMAND, + LOGICAL_BLOCK_REFERENCE_TAG_CHECK_FAILED); + *scsi_status = check_condition_result; + return -1; + } + if (scp->prot_flags & SCSI_PROT_REF_CHECK) { + mk_sense_buffer(scp, ILLEGAL_REQUEST, + LOGICAL_BLOCK_REFERENCE_TAG_CHECK_FAILED); + *scsi_status = illegal_condition_result; + return -1; + } + break; + } + return 0; +} + +/* + * Returns the number of bytes transferred, or -1 with *scsi_status set to a + * SCSI status code on failure. + */ +static int __resp_read_dt0(struct scsi_cmnd *scp, struct sdeb_store_info *sip, + u64 lba, u32 num, u32 ei_lba, int *scsi_status) +{ + int ret; + + /* DIX + T10 DIF */ + if (unlikely(sdebug_dix && scsi_prot_sg_count(scp))) { + ret = __resp_read_dt0_dix(scp, lba, num, ei_lba, scsi_status); + if (ret < 0) + return ret; + } + + ret = do_device_access(sip, scp, 0, lba, num, 0, false, false); + if (ret < 0) + *scsi_status = DID_ERROR << 16; + return ret; +} + static int resp_read_dt0(struct scsi_cmnd *scp, struct sdebug_dev_info *devip) { bool check_prot; @@ -4503,7 +4713,7 @@ static int resp_read_dt0(struct scsi_cmnd *scp, struct sdebug_dev_info *devip) u64 lba; struct sdeb_store_info *sip = devip2sip(devip, true); u8 *cmd = scp->cmnd; - bool meta_data_locked = false; + int scsi_status; switch (cmd[0]) { case READ_16: @@ -4572,8 +4782,7 @@ static int resp_read_dt0(struct scsi_cmnd *scp, struct sdebug_dev_info *devip) if (unlikely((SDEBUG_OPT_MEDIUM_ERR & sdebug_opts) && (lba <= (sdebug_medium_error_start + sdebug_medium_error_count - 1)) && ((lba + num) > sdebug_medium_error_start))) { - /* claim unrecoverable read error */ - mk_sense_buffer(scp, MEDIUM_ERROR, UNRECOVERED_READ_ERR, 0); + mk_sense_buffer(scp, MEDIUM_ERROR, UNRECOVERED_READ_ERROR); /* set info field and valid bit for fixed descriptor */ if (0x70 == (scp->sense_buffer[0] & 0x7f)) { scp->sense_buffer[0] |= 0x80; /* Valid bit */ @@ -4586,60 +4795,34 @@ static int resp_read_dt0(struct scsi_cmnd *scp, struct sdebug_dev_info *devip) } if (sdebug_dev_is_zoned(devip) || - (sdebug_dix && scsi_prot_sg_count(scp))) { + (sdebug_dix && scsi_prot_sg_count(scp))) { sdeb_meta_read_lock(sip); - meta_data_locked = true; - } - - /* DIX + T10 DIF */ - if (unlikely(sdebug_dix && scsi_prot_sg_count(scp))) { - switch (prot_verify_read(scp, lba, num, ei_lba)) { - case 1: /* Guard tag error */ - if (cmd[1] >> 5 != 3) { /* RDPROTECT != 3 */ - sdeb_meta_read_unlock(sip); - mk_sense_buffer(scp, ABORTED_COMMAND, 0x10, 1); - return check_condition_result; - } else if (scp->prot_flags & SCSI_PROT_GUARD_CHECK) { - sdeb_meta_read_unlock(sip); - mk_sense_buffer(scp, ILLEGAL_REQUEST, 0x10, 1); - return illegal_condition_result; - } - break; - case 3: /* Reference tag error */ - if (cmd[1] >> 5 != 3) { /* RDPROTECT != 3 */ - sdeb_meta_read_unlock(sip); - mk_sense_buffer(scp, ABORTED_COMMAND, 0x10, 3); - return check_condition_result; - } else if (scp->prot_flags & SCSI_PROT_REF_CHECK) { - sdeb_meta_read_unlock(sip); - mk_sense_buffer(scp, ILLEGAL_REQUEST, 0x10, 3); - return illegal_condition_result; - } - break; - } + ret = __resp_read_dt0(scp, sip, lba, num, ei_lba, &scsi_status); + sdeb_meta_read_unlock(sip); + } else { + ret = __resp_read_dt0(scp, sip, lba, num, ei_lba, &scsi_status); } - ret = do_device_access(sip, scp, 0, lba, num, 0, false, false); - if (meta_data_locked) - sdeb_meta_read_unlock(sip); - if (unlikely(ret == -1)) - return DID_ERROR << 16; + if (unlikely(ret < 0)) + return scsi_status; scsi_set_resid(scp, scsi_bufflen(scp) - ret); if (unlikely((sdebug_opts & SDEBUG_OPT_RECOV_DIF_DIX) && atomic_read(&sdeb_inject_pending))) { if (sdebug_opts & SDEBUG_OPT_RECOVERED_ERR) { - mk_sense_buffer(scp, RECOVERED_ERROR, THRESHOLD_EXCEEDED, 0); + mk_sense_buffer(scp, RECOVERED_ERROR, + FAILURE_PREDICTION_THRESHOLD_EXCEEDED); atomic_set(&sdeb_inject_pending, 0); return check_condition_result; } else if (sdebug_opts & SDEBUG_OPT_DIF_ERR) { - /* Logical block guard check failed */ - mk_sense_buffer(scp, ABORTED_COMMAND, 0x10, 1); + mk_sense_buffer(scp, ABORTED_COMMAND, + LOGICAL_BLOCK_GUARD_CHECK_FAILED); atomic_set(&sdeb_inject_pending, 0); return illegal_condition_result; } else if (SDEBUG_OPT_DIX_ERR & sdebug_opts) { - mk_sense_buffer(scp, ILLEGAL_REQUEST, 0x10, 1); + mk_sense_buffer(scp, ILLEGAL_REQUEST, + LOGICAL_BLOCK_GUARD_CHECK_FAILED); atomic_set(&sdeb_inject_pending, 0); return illegal_condition_result; } @@ -4757,6 +4940,11 @@ static unsigned int map_state(struct sdeb_store_info *sip, sector_t lba, return mapped; } +/* + * Callers may map the whole range of a write without checking how much of + * it was written. SBC-6 4.7.4.6.2 allows a deallocated LBA to become mapped + * at any time, and only requires an LBA that was written to be mapped. + */ static void map_region(struct sdeb_store_info *sip, sector_t lba, unsigned int len) { @@ -4846,22 +5034,177 @@ static int resp_write_tape(struct scsi_cmnd *scp, struct sdebug_dev_info *devip) blp->fl_size = TAPE_BLOCK_EOD_FLAG; if (pos >= devip->tape_eop[partition] - 1) { mk_sense_info_tape(scp, VOLUME_OVERFLOW, - NO_ADDITIONAL_SENSE, EOP_EOM_DETECTED_ASCQ, - fixed ? num - i : transfer, - SENSE_FLAG_EOM); + END_OF_PARTITION_MEDIUM_DETECTED, + fixed ? num - i : transfer, SENSE_FLAG_EOM); return check_condition_result; } if (ew) { /* early warning */ mk_sense_info_tape(scp, NO_SENSE, - NO_ADDITIONAL_SENSE, EOP_EOM_DETECTED_ASCQ, - fixed ? num - i : transfer, - SENSE_FLAG_EOM); + END_OF_PARTITION_MEDIUM_DETECTED, + fixed ? num - i : transfer, SENSE_FLAG_EOM); return check_condition_result; } return 0; } +static int __corrupt_lbas(struct sdeb_store_info *sip, u64 lba, u32 num, + u32 nr_bit_errors, s32 reftag_adjust, bool lbp) +{ + u32 block, num_mapped, b, i; + + if (!sip) { + pr_err("can't corrupt with fake_rw\n"); + return -EINVAL; + } + + if (num > sdebug_capacity || lba > sdebug_capacity - num) { + pr_err("logical blocks out of bounds: %llu:%u", lba, num); + return -EINVAL; + } + + if (lbp && (!map_state(sip, lba, &num_mapped) || num > num_mapped)) { + pr_err("can't modify unmapped logical blocks: %llu:%u", + lba, num); + return -EINVAL; + } + + /* + * For each possible bit error, flip the same bit in each corrupted + * block to simulate repeated patterns like errors in cables. + */ + sdeb_data_lock(sip, false); + for (b = 0; b < nr_bit_errors; b++) { + unsigned int bit; + + bit = get_random_u32_below(sdebug_sector_size * BITS_PER_BYTE); + pr_info("flipping bit %u in LBAs %llu:%llu\n", + bit, lba, lba + num - 1); + + div_u64_rem(lba, sdebug_store_sectors, &block); + for (i = 0; i < num; i++) { + u8 *p = sip->storep + (block * sdebug_sector_size); + + sdeb_data_sector_lock(sip, true); + p[bit / BITS_PER_BYTE] ^= (1 << (bit % BITS_PER_BYTE)); + sdeb_data_sector_unlock(sip, true); + if (++block >= sdebug_store_sectors) + block = 0; + } + } + + if (reftag_adjust) { + pr_info("adjusting reftag by %d sectors for LBAs %llu:%llu\n", + reftag_adjust, lba, lba + num - 1); + for (i = 0; i < num; i++) { + struct t10_pi_tuple *sdt = dif_store(sip, lba + i); + + be32_add_cpu(&sdt->ref_tag, reftag_adjust); + } + } + sdeb_data_unlock(sip, false); + + return 0; +} + +static int corrupt_lbas(struct sdebug_dev_info *devip, u64 lba, u32 num, + u32 nr_bit_errors, s32 reftag_adjust) +{ + struct sdeb_store_info *sip = devip2sip(devip, false); + const bool lbp = scsi_debug_lbp(); + int error = 0; + + if (sdebug_dev_is_zoned(devip) || sdebug_dix || lbp) { + sdeb_meta_write_lock(sip); + error = __corrupt_lbas(sip, lba, num, nr_bit_errors, + reftag_adjust, lbp); + sdeb_meta_write_unlock(sip); + } else { + error = __corrupt_lbas(sip, lba, num, nr_bit_errors, + reftag_adjust, lbp); + } + return error; +} + +/* + * Returns 0 upon success or -1 with *scsi_status set to a SCSI status code upon + * failure. + */ +static int __resp_write_dt0_dix(struct scsi_cmnd *scp, + u64 lba, u32 num, + u32 ei_lba, int *scsi_status) +{ + switch (prot_verify_write(scp, lba, num, ei_lba)) { + case 1: /* Guard tag error */ + if (scp->prot_flags & SCSI_PROT_GUARD_CHECK) { + mk_sense_buffer(scp, ILLEGAL_REQUEST, + LOGICAL_BLOCK_GUARD_CHECK_FAILED); + *scsi_status = illegal_condition_result; + return -1; + } + if (scp->cmnd[1] >> 5 != 3) { /* WRPROTECT != 3 */ + mk_sense_buffer(scp, ABORTED_COMMAND, + LOGICAL_BLOCK_GUARD_CHECK_FAILED); + *scsi_status = check_condition_result; + return -1; + } + break; + case 3: /* Reference tag error */ + if (scp->prot_flags & SCSI_PROT_REF_CHECK) { + mk_sense_buffer(scp, ILLEGAL_REQUEST, + LOGICAL_BLOCK_REFERENCE_TAG_CHECK_FAILED); + *scsi_status = illegal_condition_result; + return -1; + } + if (scp->cmnd[1] >> 5 != 3) { /* WRPROTECT != 3 */ + mk_sense_buffer(scp, ABORTED_COMMAND, + LOGICAL_BLOCK_REFERENCE_TAG_CHECK_FAILED); + *scsi_status = check_condition_result; + return -1; + } + break; + } + + return 0; +} + +/* + * Returns the number of bytes transferred, or -1 with *scsi_status set to a + * SCSI status code on failure. + */ +static int __resp_write_dt0(struct scsi_cmnd *scp, + struct sdebug_dev_info *devip, + struct sdeb_store_info *sip, u64 lba, u32 num, + u32 ei_lba, u8 group, bool lbp, int *scsi_status) +{ + int ret; + + *scsi_status = check_device_access_params(scp, lba, num, true); + if (*scsi_status) + return -1; + + /* DIX + T10 DIF */ + if (unlikely(sdebug_dix && scsi_prot_sg_count(scp))) { + ret = __resp_write_dt0_dix(scp, lba, num, ei_lba, + scsi_status); + if (ret < 0) + return ret; + } + + ret = do_device_access(sip, scp, 0, lba, num, group, true, false); + if (ret < 0) + *scsi_status = DID_ERROR << 16; + + if (unlikely(lbp)) + map_region(sip, lba, num); + + /* If ZBC zone then bump its write pointer */ + if (sdebug_dev_is_zoned(devip) && ret > 0) + zbc_inc_wp(devip, lba, ret >> ilog2(sdebug_sector_size)); + + return ret; +} + static int resp_write_dt0(struct scsi_cmnd *scp, struct sdebug_dev_info *devip) { bool check_prot; @@ -4872,13 +5215,13 @@ static int resp_write_dt0(struct scsi_cmnd *scp, struct sdebug_dev_info *devip) u64 lba; struct sdeb_store_info *sip = devip2sip(devip, true); u8 *cmd = scp->cmnd; - bool meta_data_locked = false; + int scsi_status = DID_ERROR << 16; + bool lbp = scsi_debug_lbp(); if (unlikely(sdebug_opts & SDEBUG_OPT_UNALIGNED_WRITE && atomic_read(&sdeb_inject_pending))) { atomic_set(&sdeb_inject_pending, 0); - mk_sense_buffer(scp, ILLEGAL_REQUEST, LBA_OUT_OF_RANGE, - UNALIGNED_WRITE_ASCQ); + mk_sense_buffer(scp, ILLEGAL_REQUEST, UNALIGNED_WRITE_COMMAND); return check_condition_result; } @@ -4940,78 +5283,42 @@ static int resp_write_dt0(struct scsi_cmnd *scp, struct sdebug_dev_info *devip) } if (sdebug_dev_is_zoned(devip) || - (sdebug_dix && scsi_prot_sg_count(scp)) || - scsi_debug_lbp()) { + (sdebug_dix && scsi_prot_sg_count(scp)) || lbp) { sdeb_meta_write_lock(sip); - meta_data_locked = true; - } - - ret = check_device_access_params(scp, lba, num, true); - if (ret) { - if (meta_data_locked) - sdeb_meta_write_unlock(sip); - return ret; - } - - /* DIX + T10 DIF */ - if (unlikely(sdebug_dix && scsi_prot_sg_count(scp))) { - switch (prot_verify_write(scp, lba, num, ei_lba)) { - case 1: /* Guard tag error */ - if (scp->prot_flags & SCSI_PROT_GUARD_CHECK) { - sdeb_meta_write_unlock(sip); - mk_sense_buffer(scp, ILLEGAL_REQUEST, 0x10, 1); - return illegal_condition_result; - } else if (scp->cmnd[1] >> 5 != 3) { /* WRPROTECT != 3 */ - sdeb_meta_write_unlock(sip); - mk_sense_buffer(scp, ABORTED_COMMAND, 0x10, 1); - return check_condition_result; - } - break; - case 3: /* Reference tag error */ - if (scp->prot_flags & SCSI_PROT_REF_CHECK) { - sdeb_meta_write_unlock(sip); - mk_sense_buffer(scp, ILLEGAL_REQUEST, 0x10, 3); - return illegal_condition_result; - } else if (scp->cmnd[1] >> 5 != 3) { /* WRPROTECT != 3 */ - sdeb_meta_write_unlock(sip); - mk_sense_buffer(scp, ABORTED_COMMAND, 0x10, 3); - return check_condition_result; - } - break; - } - } - - ret = do_device_access(sip, scp, 0, lba, num, group, true, false); - if (unlikely(scsi_debug_lbp())) - map_region(sip, lba, num); - - /* If ZBC zone then bump its write pointer */ - if (sdebug_dev_is_zoned(devip)) - zbc_inc_wp(devip, lba, num); - if (meta_data_locked) + ret = __resp_write_dt0(scp, devip, sip, lba, num, ei_lba, group, + lbp, &scsi_status); sdeb_meta_write_unlock(sip); + } else { + ret = __resp_write_dt0(scp, devip, sip, lba, num, ei_lba, group, + lbp, &scsi_status); + } if (unlikely(-1 == ret)) - return DID_ERROR << 16; + return scsi_status; else if (unlikely(sdebug_verbose && (ret < (num * sdebug_sector_size)))) sdev_printk(KERN_INFO, scp->device, "%s: write: cdb indicated=%u, IO sent=%d bytes\n", my_name, num * sdebug_sector_size, ret); + if (ret < scsi_bufflen(scp)) + scsi_set_resid(scp, scsi_bufflen(scp) - ret); + if (unlikely((sdebug_opts & SDEBUG_OPT_RECOV_DIF_DIX) && atomic_read(&sdeb_inject_pending))) { if (sdebug_opts & SDEBUG_OPT_RECOVERED_ERR) { - mk_sense_buffer(scp, RECOVERED_ERROR, THRESHOLD_EXCEEDED, 0); + mk_sense_buffer(scp, RECOVERED_ERROR, + FAILURE_PREDICTION_THRESHOLD_EXCEEDED); atomic_set(&sdeb_inject_pending, 0); return check_condition_result; } else if (sdebug_opts & SDEBUG_OPT_DIF_ERR) { - /* Logical block guard check failed */ - mk_sense_buffer(scp, ABORTED_COMMAND, 0x10, 1); + mk_sense_buffer(scp, ABORTED_COMMAND, + LOGICAL_BLOCK_GUARD_CHECK_FAILED); atomic_set(&sdeb_inject_pending, 0); return illegal_condition_result; } else if (sdebug_opts & SDEBUG_OPT_DIX_ERR) { - mk_sense_buffer(scp, ILLEGAL_REQUEST, 0x10, 1); + mk_sense_buffer(scp, ILLEGAL_REQUEST, + LOGICAL_BLOCK_GUARD_CHECK_FAILED); atomic_set(&sdeb_inject_pending, 0); return illegal_condition_result; } @@ -5032,7 +5339,8 @@ static int resp_write_scat(struct scsi_cmnd *scp, struct sdeb_store_info *sip = devip2sip(devip, true); u8 wrprotect; u16 lbdof, num_lrd, k; - u32 num, num_by, bt_len, lbdof_blen, sg_off, cum_lb; + u32 num, bt_len, lbdof_blen, cum_lb; + u64 num_by, sg_off; u32 lb_size = sdebug_sector_size; u32 ei_lba; u64 lba; @@ -5068,13 +5376,15 @@ static int resp_write_scat(struct scsi_cmnd *scp, "Unprotected WR to DIF device\n"); } } - if ((num_lrd == 0) || (bt_len == 0)) + if (num_lrd == 0 || bt_len == 0) { + scsi_set_resid(scp, scsi_bufflen(scp)); return 0; /* T10 says these do-nothings are not errors */ + } if (lbdof == 0) { if (sdebug_verbose) sdev_printk(KERN_INFO, scp->device, "%s: LB Data Offset field bad\n", my_name); - mk_sense_buffer(scp, ILLEGAL_REQUEST, INVALID_FIELD_IN_CDB, 0); + mk_sense_buffer(scp, ILLEGAL_REQUEST, INVALID_FIELD_IN_CDB); return illegal_condition_result; } lbdof_blen = lbdof * lb_size; @@ -5082,7 +5392,7 @@ static int resp_write_scat(struct scsi_cmnd *scp, if (sdebug_verbose) sdev_printk(KERN_INFO, scp->device, "%s: LBA range descriptors don't fit\n", my_name); - mk_sense_buffer(scp, ILLEGAL_REQUEST, INVALID_FIELD_IN_CDB, 0); + mk_sense_buffer(scp, ILLEGAL_REQUEST, INVALID_FIELD_IN_CDB); return illegal_condition_result; } lrdp = kzalloc(lbdof_blen, GFP_ATOMIC | __GFP_NOWARN); @@ -5108,14 +5418,14 @@ static int resp_write_scat(struct scsi_cmnd *scp, num = get_unaligned_be32(up + 8); if (sdebug_verbose) sdev_printk(KERN_INFO, scp->device, - "%s: k=%d LBA=0x%llx num=%u sg_off=%u\n", + "%s: k=%d LBA=0x%llx num=%u sg_off=%llu\n", my_name, k, lba, num, sg_off); if (num == 0) continue; ret = check_device_access_params(scp, lba, num, true); if (ret) goto err_out_unlock; - num_by = num * lb_size; + num_by = (u64)num * lb_size; ei_lba = is_16 ? 0 : get_unaligned_be32(up + 12); if ((cum_lb + num) > bt_len) { @@ -5123,8 +5433,7 @@ static int resp_write_scat(struct scsi_cmnd *scp, sdev_printk(KERN_INFO, scp->device, "%s: sum of blocks > data provided\n", my_name); - mk_sense_buffer(scp, ILLEGAL_REQUEST, WRITE_ERROR_ASC, - 0); + mk_sense_buffer(scp, ILLEGAL_REQUEST, SSC_WRITE_ERROR); ret = illegal_condition_result; goto err_out_unlock; } @@ -5135,8 +5444,9 @@ static int resp_write_scat(struct scsi_cmnd *scp, ei_lba); if (prot_ret) { - mk_sense_buffer(scp, ILLEGAL_REQUEST, 0x10, - prot_ret); + mk_sense_buffer(scp, ILLEGAL_REQUEST, + scsi_sense_code(ASC_ID_CRC_OR_ECC_ERROR, + prot_ret)); ret = illegal_condition_result; goto err_out_unlock; } @@ -5146,10 +5456,13 @@ static int resp_write_scat(struct scsi_cmnd *scp, * Write ranges atomically to keep as close to pre-atomic * writes behaviour as possible. */ - ret = do_device_access(sip, scp, sg_off, lba, num, group, true, true); - /* If ZBC zone then bump its write pointer */ - if (sdebug_dev_is_zoned(devip)) - zbc_inc_wp(devip, lba, num); + ret = do_device_access(sip, scp, + min_t(u64, sg_off, scsi_bufflen(scp)), + lba, num, group, true, true); + /* If ZBC zone then bump its write pointer over the data written */ + if (sdebug_dev_is_zoned(devip) && ret > 0) + zbc_inc_wp(devip, lba, + ret >> ilog2(sdebug_sector_size)); if (unlikely(scsi_debug_lbp())) map_region(sip, lba, num); if (unlikely(-1 == ret)) { @@ -5157,24 +5470,28 @@ static int resp_write_scat(struct scsi_cmnd *scp, goto err_out_unlock; } else if (unlikely(sdebug_verbose && (ret < num_by))) sdev_printk(KERN_INFO, scp->device, - "%s: write: cdb indicated=%u, IO sent=%d bytes\n", + "%s: write: cdb indicated=%llu, IO sent=%d bytes\n", my_name, num_by, ret); if (unlikely((sdebug_opts & SDEBUG_OPT_RECOV_DIF_DIX) && atomic_read(&sdeb_inject_pending))) { + /* This range has been written */ + sg_off += num_by; if (sdebug_opts & SDEBUG_OPT_RECOVERED_ERR) { - mk_sense_buffer(scp, RECOVERED_ERROR, THRESHOLD_EXCEEDED, 0); + mk_sense_buffer(scp, RECOVERED_ERROR, + FAILURE_PREDICTION_THRESHOLD_EXCEEDED); atomic_set(&sdeb_inject_pending, 0); ret = check_condition_result; goto err_out_unlock; } else if (sdebug_opts & SDEBUG_OPT_DIF_ERR) { - /* Logical block guard check failed */ - mk_sense_buffer(scp, ABORTED_COMMAND, 0x10, 1); + mk_sense_buffer(scp, ABORTED_COMMAND, + LOGICAL_BLOCK_GUARD_CHECK_FAILED); atomic_set(&sdeb_inject_pending, 0); ret = illegal_condition_result; goto err_out_unlock; } else if (sdebug_opts & SDEBUG_OPT_DIX_ERR) { - mk_sense_buffer(scp, ILLEGAL_REQUEST, 0x10, 1); + mk_sense_buffer(scp, ILLEGAL_REQUEST, + LOGICAL_BLOCK_GUARD_CHECK_FAILED); atomic_set(&sdeb_inject_pending, 0); ret = illegal_condition_result; goto err_out_unlock; @@ -5185,14 +5502,21 @@ static int resp_write_scat(struct scsi_cmnd *scp, } ret = 0; err_out_unlock: + /* + * sg_off counts what the command asked for, which can exceed the + * buffer: lbdof is not validated against it, and a range is counted + * in full even if do_device_access() copied less. + */ + if (scsi_bufflen(scp) > sg_off) + scsi_set_resid(scp, scsi_bufflen(scp) - sg_off); sdeb_meta_write_unlock(sip); err_out: kfree(lrdp); return ret; } -static int resp_write_same(struct scsi_cmnd *scp, u64 lba, u32 num, - u32 ei_lba, bool unmap, bool ndob) +static int __resp_write_same(struct scsi_cmnd *scp, u64 lba, u32 num, + u32 ei_lba, bool unmap, bool ndob, bool lbp) { struct scsi_device *sdp = scp->device; struct sdebug_dev_info *devip = (struct sdebug_dev_info *)sdp->hostdata; @@ -5204,20 +5528,14 @@ static int resp_write_same(struct scsi_cmnd *scp, u64 lba, u32 num, scp->device->hostdata, true); u8 *fs1p; u8 *fsp; - bool meta_data_locked = false; - - if (sdebug_dev_is_zoned(devip) || scsi_debug_lbp()) { - sdeb_meta_write_lock(sip); - meta_data_locked = true; - } ret = check_device_access_params(scp, lba, num, true); if (ret) - goto out; + return ret; - if (unmap && scsi_debug_lbp()) { + if (unmap && lbp) { unmap_region(sip, lba, num); - goto out; + return ret; } lbaa = lba; block = do_div(lbaa, sdebug_store_sectors); @@ -5233,7 +5551,7 @@ static int resp_write_same(struct scsi_cmnd *scp, u64 lba, u32 num, if (-1 == ret) { ret = DID_ERROR << 16; - goto out; + goto unlock; } else if (sdebug_verbose && !ndob && (ret < lb_size)) sdev_printk(KERN_INFO, scp->device, "%s: %s: lb size=%u, IO sent=%d bytes\n", @@ -5245,16 +5563,36 @@ static int resp_write_same(struct scsi_cmnd *scp, u64 lba, u32 num, block = do_div(lbaa, sdebug_store_sectors); memmove(fsp + (block * lb_size), fs1p, lb_size); } - if (scsi_debug_lbp()) + if (lbp) map_region(sip, lba, num); /* If ZBC zone then bump its write pointer */ if (sdebug_dev_is_zoned(devip)) zbc_inc_wp(devip, lba, num); - sdeb_data_write_unlock(sip); ret = 0; -out: - if (meta_data_locked) +unlock: + sdeb_data_write_unlock(sip); + return ret; +} + +static int resp_write_same(struct scsi_cmnd *scp, u64 lba, u32 num, u32 ei_lba, + bool unmap, bool ndob) +{ + struct scsi_device *sdp = scp->device; + struct sdebug_dev_info *devip = sdp->hostdata; + struct sdeb_store_info *sip = devip2sip(devip, true); + const bool lbp = scsi_debug_lbp(); + int ret; + + if (sdebug_dev_is_zoned(devip) || lbp) { + sdeb_meta_write_lock(sip); + ret = __resp_write_same(scp, lba, num, ei_lba, unmap, ndob, + lbp); sdeb_meta_write_unlock(sip); + } else { + ret = __resp_write_same(scp, lba, num, ei_lba, unmap, ndob, + lbp); + } + return ret; } @@ -5393,8 +5731,7 @@ static int resp_comp_write(struct scsi_cmnd *scp, dnum = 2 * num; arr = kcalloc(lb_size, dnum, GFP_ATOMIC); if (NULL == arr) { - mk_sense_buffer(scp, ILLEGAL_REQUEST, INSUFF_RES_ASC, - INSUFF_RES_ASCQ); + mk_sense_buffer(scp, ILLEGAL_REQUEST, INSUFFICIENT_RESOURCES); return check_condition_result; } @@ -5407,20 +5744,21 @@ static int resp_comp_write(struct scsi_cmnd *scp, "indicated=%u, IO sent=%d bytes\n", my_name, dnum * lb_size, ret); - sdeb_data_write_lock(sip); sdeb_meta_write_lock(sip); + sdeb_data_write_lock(sip); if (!comp_write_worker(sip, lba, num, arr, false)) { - mk_sense_buffer(scp, MISCOMPARE, MISCOMPARE_VERIFY_ASC, 0); + mk_sense_buffer(scp, MISCOMPARE, + MISCOMPARE_DURING_VERIFY_OPERATION); retval = check_condition_result; goto cleanup_unlock; } - /* Cover sip->map_storep (which map_region()) sets with data lock */ + /* Cover sip->map_storep (which map_region() sets) with the meta lock */ if (scsi_debug_lbp()) map_region(sip, lba, num); cleanup_unlock: - sdeb_meta_write_unlock(sip); sdeb_data_write_unlock(sip); + sdeb_meta_write_unlock(sip); cleanup_free: kfree(arr); return retval; @@ -5453,8 +5791,7 @@ static int resp_unmap(struct scsi_cmnd *scp, struct sdebug_dev_info *devip) buf = kzalloc(scsi_bufflen(scp), GFP_ATOMIC); if (!buf) { - mk_sense_buffer(scp, ILLEGAL_REQUEST, INSUFF_RES_ASC, - INSUFF_RES_ASCQ); + mk_sense_buffer(scp, ILLEGAL_REQUEST, INSUFFICIENT_RESOURCES); return check_condition_result; } @@ -5592,7 +5929,8 @@ static int resp_sync_cache(struct scsi_cmnd *scp, num_blocks = get_unaligned_be32(cmd + 10); } if (lba + num_blocks > sdebug_capacity) { - mk_sense_buffer(scp, ILLEGAL_REQUEST, LBA_OUT_OF_RANGE, 0); + mk_sense_buffer(scp, ILLEGAL_REQUEST, + LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE); return check_condition_result; } if (!write_since_sync || (cmd[1] & 0x2)) @@ -5630,7 +5968,8 @@ static int resp_pre_fetch(struct scsi_cmnd *scp, nblks = get_unaligned_be32(cmd + 10); } if (lba + nblks > sdebug_capacity) { - mk_sense_buffer(scp, ILLEGAL_REQUEST, LBA_OUT_OF_RANGE, 0); + mk_sense_buffer(scp, ILLEGAL_REQUEST, + LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE); return check_condition_result; } if (!fsp) @@ -5801,8 +6140,7 @@ static int resp_verify(struct scsi_cmnd *scp, struct sdebug_dev_info *devip) arr = kcalloc(lb_size, vnum, GFP_ATOMIC | __GFP_NOWARN); if (!arr) { - mk_sense_buffer(scp, ILLEGAL_REQUEST, INSUFF_RES_ASC, - INSUFF_RES_ASCQ); + mk_sense_buffer(scp, ILLEGAL_REQUEST, INSUFFICIENT_RESOURCES); return check_condition_result; } /* Not changing store, so only need read access */ @@ -5823,7 +6161,8 @@ static int resp_verify(struct scsi_cmnd *scp, struct sdebug_dev_info *devip) } ret = 0; if (!comp_write_worker(sip, lba, vnum, arr, true)) { - mk_sense_buffer(scp, MISCOMPARE, MISCOMPARE_VERIFY_ASC, 0); + mk_sense_buffer(scp, MISCOMPARE, + MISCOMPARE_DURING_VERIFY_OPERATION); ret = check_condition_result; goto cleanup; } @@ -5862,7 +6201,8 @@ static int resp_report_zones(struct scsi_cmnd *scp, partial = cmd[14] & 0x80; if (zs_lba >= sdebug_capacity) { - mk_sense_buffer(scp, ILLEGAL_REQUEST, LBA_OUT_OF_RANGE, 0); + mk_sense_buffer(scp, ILLEGAL_REQUEST, + LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE); return check_condition_result; } @@ -5873,8 +6213,8 @@ static int resp_report_zones(struct scsi_cmnd *scp, arr = kzalloc(arr_len, GFP_ATOMIC | __GFP_NOWARN); if (!arr) { - mk_sense_buffer(scp, ILLEGAL_REQUEST, INSUFF_RES_ASC, - INSUFF_RES_ASCQ); + mk_sense_buffer(scp, ILLEGAL_REQUEST, + INSUFFICIENT_RESOURCES); return check_condition_result; } @@ -5939,8 +6279,7 @@ static int resp_report_zones(struct scsi_cmnd *scp, continue; break; default: - mk_sense_buffer(scp, ILLEGAL_REQUEST, - INVALID_FIELD_IN_CDB, 0); + mk_sense_buffer(scp, ILLEGAL_REQUEST, INVALID_FIELD_IN_CDB); ret = check_condition_result; goto fini; } @@ -5988,6 +6327,7 @@ static int resp_atomic_write(struct scsi_cmnd *scp, u8 *cmd = scp->cmnd; u16 boundary, len; u64 lba, lba_tmp; + bool lbp = scsi_debug_lbp(); int ret; if (!scsi_debug_atomic_write()) { @@ -6005,13 +6345,13 @@ static int resp_atomic_write(struct scsi_cmnd *scp, if (sdebug_atomic_wr_align && do_div(lba_tmp, sdebug_atomic_wr_align)) { /* Does not meet alignment requirement */ - mk_sense_buffer(scp, ILLEGAL_REQUEST, INVALID_FIELD_IN_CDB, 0); + mk_sense_buffer(scp, ILLEGAL_REQUEST, INVALID_FIELD_IN_CDB); return check_condition_result; } if (sdebug_atomic_wr_gran && len % sdebug_atomic_wr_gran) { /* Does not meet alignment requirement */ - mk_sense_buffer(scp, ILLEGAL_REQUEST, INVALID_FIELD_IN_CDB, 0); + mk_sense_buffer(scp, ILLEGAL_REQUEST, INVALID_FIELD_IN_CDB); return check_condition_result; } @@ -6032,11 +6372,34 @@ static int resp_atomic_write(struct scsi_cmnd *scp, } } - ret = do_device_access(sip, scp, 0, lba, len, 0, true, true); - if (unlikely(ret == -1)) + ret = check_device_access_params(scp, lba, len, true); + if (ret) + return ret; + + /* + * Short atomic writes are not allowed: SBC-6 4.28.2 requires an + * atomic write that cannot complete to leave its LBAs unaltered, and + * do_device_access() would already have written part of it. + */ + if (scsi_bufflen(scp) < len * sdebug_sector_size) + return DID_ERROR << 16; + + if (lbp) { + sdeb_meta_write_lock(sip); + ret = do_device_access(sip, scp, 0, lba, len, 0, true, true); + map_region(sip, lba, len); + sdeb_meta_write_unlock(sip); + } else { + ret = do_device_access(sip, scp, 0, lba, len, 0, true, true); + } + + if (unlikely(ret < 0)) return DID_ERROR << 16; if (unlikely(ret != len * sdebug_sector_size)) return DID_ERROR << 16; + + if (ret < scsi_bufflen(scp)) + scsi_set_resid(scp, scsi_bufflen(scp) - ret); return 0; } @@ -6072,8 +6435,8 @@ static int resp_open_zone(struct scsi_cmnd *scp, struct sdebug_dev_info *devip) /* Check if all closed zones can be open */ if (devip->max_open && devip->nr_exp_open + devip->nr_closed > devip->max_open) { - mk_sense_buffer(scp, DATA_PROTECT, INSUFF_RES_ASC, - INSUFF_ZONE_ASCQ); + mk_sense_buffer(scp, DATA_PROTECT, + INSUFFICIENT_ZONE_RESOURCES); res = check_condition_result; goto fini; } @@ -6085,19 +6448,20 @@ static int resp_open_zone(struct scsi_cmnd *scp, struct sdebug_dev_info *devip) /* Open the specified zone */ z_id = get_unaligned_be64(cmd + 2); if (z_id >= sdebug_capacity) { - mk_sense_buffer(scp, ILLEGAL_REQUEST, LBA_OUT_OF_RANGE, 0); + mk_sense_buffer(scp, ILLEGAL_REQUEST, + LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE); res = check_condition_result; goto fini; } zsp = zbc_zone(devip, z_id); if (z_id != zsp->z_start) { - mk_sense_buffer(scp, ILLEGAL_REQUEST, INVALID_FIELD_IN_CDB, 0); + mk_sense_buffer(scp, ILLEGAL_REQUEST, INVALID_FIELD_IN_CDB); res = check_condition_result; goto fini; } if (zbc_zone_is_conv(zsp)) { - mk_sense_buffer(scp, ILLEGAL_REQUEST, INVALID_FIELD_IN_CDB, 0); + mk_sense_buffer(scp, ILLEGAL_REQUEST, INVALID_FIELD_IN_CDB); res = check_condition_result; goto fini; } @@ -6107,8 +6471,7 @@ static int resp_open_zone(struct scsi_cmnd *scp, struct sdebug_dev_info *devip) goto fini; if (devip->max_open && devip->nr_exp_open >= devip->max_open) { - mk_sense_buffer(scp, DATA_PROTECT, INSUFF_RES_ASC, - INSUFF_ZONE_ASCQ); + mk_sense_buffer(scp, DATA_PROTECT, INSUFFICIENT_ZONE_RESOURCES); res = check_condition_result; goto fini; } @@ -6152,19 +6515,20 @@ static int resp_close_zone(struct scsi_cmnd *scp, /* Close specified zone */ z_id = get_unaligned_be64(cmd + 2); if (z_id >= sdebug_capacity) { - mk_sense_buffer(scp, ILLEGAL_REQUEST, LBA_OUT_OF_RANGE, 0); + mk_sense_buffer(scp, ILLEGAL_REQUEST, + LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE); res = check_condition_result; goto fini; } zsp = zbc_zone(devip, z_id); if (z_id != zsp->z_start) { - mk_sense_buffer(scp, ILLEGAL_REQUEST, INVALID_FIELD_IN_CDB, 0); + mk_sense_buffer(scp, ILLEGAL_REQUEST, INVALID_FIELD_IN_CDB); res = check_condition_result; goto fini; } if (zbc_zone_is_conv(zsp)) { - mk_sense_buffer(scp, ILLEGAL_REQUEST, INVALID_FIELD_IN_CDB, 0); + mk_sense_buffer(scp, ILLEGAL_REQUEST, INVALID_FIELD_IN_CDB); res = check_condition_result; goto fini; } @@ -6224,19 +6588,20 @@ static int resp_finish_zone(struct scsi_cmnd *scp, /* Finish the specified zone */ z_id = get_unaligned_be64(cmd + 2); if (z_id >= sdebug_capacity) { - mk_sense_buffer(scp, ILLEGAL_REQUEST, LBA_OUT_OF_RANGE, 0); + mk_sense_buffer(scp, ILLEGAL_REQUEST, + LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE); res = check_condition_result; goto fini; } zsp = zbc_zone(devip, z_id); if (z_id != zsp->z_start) { - mk_sense_buffer(scp, ILLEGAL_REQUEST, INVALID_FIELD_IN_CDB, 0); + mk_sense_buffer(scp, ILLEGAL_REQUEST, INVALID_FIELD_IN_CDB); res = check_condition_result; goto fini; } if (zbc_zone_is_conv(zsp)) { - mk_sense_buffer(scp, ILLEGAL_REQUEST, INVALID_FIELD_IN_CDB, 0); + mk_sense_buffer(scp, ILLEGAL_REQUEST, INVALID_FIELD_IN_CDB); res = check_condition_result; goto fini; } @@ -6303,19 +6668,20 @@ static int resp_rwp_zone(struct scsi_cmnd *scp, struct sdebug_dev_info *devip) z_id = get_unaligned_be64(cmd + 2); if (z_id >= sdebug_capacity) { - mk_sense_buffer(scp, ILLEGAL_REQUEST, LBA_OUT_OF_RANGE, 0); + mk_sense_buffer(scp, ILLEGAL_REQUEST, + LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE); res = check_condition_result; goto fini; } zsp = zbc_zone(devip, z_id); if (z_id != zsp->z_start) { - mk_sense_buffer(scp, ILLEGAL_REQUEST, INVALID_FIELD_IN_CDB, 0); + mk_sense_buffer(scp, ILLEGAL_REQUEST, INVALID_FIELD_IN_CDB); res = check_condition_result; goto fini; } if (zbc_zone_is_conv(zsp)) { - mk_sense_buffer(scp, ILLEGAL_REQUEST, INVALID_FIELD_IN_CDB, 0); + mk_sense_buffer(scp, ILLEGAL_REQUEST, INVALID_FIELD_IN_CDB); res = check_condition_result; goto fini; } @@ -6628,6 +6994,8 @@ static int scsi_debug_sdev_configure(struct scsi_device *sdp, if (IS_ERR_OR_NULL(dentry)) pr_info("failed to create error file for device %s\n", dev_name(&sdp->sdev_gendev)); + debugfs_create_file("corrupt", 0600, devip->debugfs_entry, sdp, + &sdebug_corrupt_fops); return 0; } @@ -7186,7 +7554,7 @@ static int schedule_resp(struct scsi_cmnd *cmnd, struct sdebug_dev_info *devip, cmnd->result = scsi_result; if (cmnd->result == 0 && unlikely(sdebug_opts & SDEBUG_OPT_TRANSPORT_ERR)) { if (atomic_read(&sdeb_inject_pending)) { - mk_sense_buffer(cmnd, ABORTED_COMMAND, TRANSPORT_PROBLEM, ACK_NAK_TO); + mk_sense_buffer(cmnd, ABORTED_COMMAND, ACK_NAK_TIMEOUT); atomic_set(&sdeb_inject_pending, 0); cmnd->result = check_condition_result; } @@ -7373,8 +7741,8 @@ MODULE_VERSION(SDEBUG_VERSION); MODULE_PARM_DESC(add_host, "add n hosts, in sysfs if negative remove host(s) (def=1)"); MODULE_PARM_DESC(ato, "application tag ownership: 0=disk 1=host (def=1)"); MODULE_PARM_DESC(cdb_len, "suggest CDB lengths to drivers (def=10)"); -MODULE_PARM_DESC(clustering, "when set enables larger transfers (def=0)"); -MODULE_PARM_DESC(delay, "response delay (def=1 jiffy); 0:imm, -1,-2:tiny"); +MODULE_PARM_DESC(clustering, "when set enables larger transfers (def=1)"); +MODULE_PARM_DESC(delay, "response delay (def=0 jiffy); 0:imm, -1,-2:tiny"); MODULE_PARM_DESC(dev_size_mb, "size in MiB of ram shared by devs(def=8)"); MODULE_PARM_DESC(dif, "data integrity field type: 0-3 (def=0)"); MODULE_PARM_DESC(dix, "data integrity extensions mask (def=0)"); @@ -8481,8 +8849,8 @@ static int __init scsi_debug_init(void) return -EINVAL; } - if (sdebug_physblk_exp > 15) { - pr_err("invalid physblk_exp %u\n", sdebug_physblk_exp); + if (sdebug_physblk_exp < 0 || sdebug_physblk_exp > 15) { + pr_err("invalid physblk_exp %d\n", sdebug_physblk_exp); return -EINVAL; } @@ -8559,6 +8927,16 @@ static int __init scsi_debug_init(void) sdebug_dev_size_mb = DEF_ZBC_DEV_SIZE_MB; } + if (sdeb_zbc_in_use && sdebug_lowest_aligned) { + pr_err("lowest_aligned is not supported by a zoned device\n"); + return -EINVAL; + } + + if (sdeb_zbc_in_use && sdebug_atomic_wr) { + pr_err("atomic_wr is not supported by a zoned device\n"); + return -EINVAL; + } + if (sdebug_dev_size_mb == DEF_DEV_SIZE_PRE_INIT) sdebug_dev_size_mb = DEF_DEV_SIZE_MB; if (sdebug_dev_size_mb < 1) @@ -8979,7 +9357,8 @@ static int resp_not_ready(struct scsi_cmnd *scp, struct sdebug_dev_info *devip) return 0; } } - mk_sense_buffer(scp, NOT_READY, LOGICAL_UNIT_NOT_READY, 0x1); + mk_sense_buffer(scp, NOT_READY, + LU_IS_IN_PROCESS_OF_BECOMING_READY); if (sdebug_verbose) sdev_printk(KERN_INFO, sdp, "%s: Not ready: in process of becoming ready\n", my_name); @@ -8997,7 +9376,8 @@ static int resp_not_ready(struct scsi_cmnd *scp, struct sdebug_dev_info *devip) return check_condition_result; } } - mk_sense_buffer(scp, NOT_READY, LOGICAL_UNIT_NOT_READY, 0x2); + mk_sense_buffer(scp, NOT_READY, + LU_NOT_READY_INITIALIZING_COMMAND_REQUIRED); if (sdebug_verbose) sdev_printk(KERN_INFO, sdp, "%s: Not ready: initializing command required\n", my_name); @@ -9194,7 +9574,8 @@ static int sdebug_fail_cmd(struct scsi_cmnd *cmnd, int *retval, out_handle: if (err->cnt < 0) err->cnt++; - mk_sense_buffer(cmnd, err->sense_key, err->asc, err->asq); + mk_sense_buffer(cmnd, err->sense_key, + scsi_sense_code(err->asc, err->asq)); result = err->status_byte | err->host_byte << 16 | err->driver_byte << 24; *info = *err; *retval = schedule_resp(cmnd, devip, result, NULL, 0, 0); diff --git a/drivers/scsi/scsi_debugfs.c b/drivers/scsi/scsi_debugfs.c index eb52e39f37c9..54d8824250b1 100644 --- a/drivers/scsi/scsi_debugfs.c +++ b/drivers/scsi/scsi_debugfs.c @@ -38,7 +38,7 @@ static const char *scsi_cmd_list_info(struct scsi_cmnd *cmd) struct Scsi_Host *shost = cmd->device->host; struct scsi_cmnd *cmd2; - guard(spinlock_irq)(shost->host_lock); + guard(spinlock_irq)(&shost->host_lock); list_for_each_entry(cmd2, &shost->eh_abort_list, eh_entry) if (cmd == cmd2) diff --git a/drivers/scsi/scsi_devinfo.c b/drivers/scsi/scsi_devinfo.c index 15ffbe93ac72..cfc259fd0141 100644 --- a/drivers/scsi/scsi_devinfo.c +++ b/drivers/scsi/scsi_devinfo.c @@ -161,7 +161,7 @@ static struct { {"DGC", "DISK", NULL, BLIST_SPARSELUN}, /* EMC CLARiiON, no storage on LUN 0 */ {"EMC", "Invista", "*", BLIST_SPARSELUN | BLIST_LARGELUN}, {"EMC", "SYMMETRIX", NULL, BLIST_SPARSELUN | BLIST_LARGELUN | - BLIST_REPORTLUN2 | BLIST_RETRY_ITF}, + BLIST_REPORTLUN2 | BLIST_RETRY_ITF | BLIST_SKIP_IO_HINTS}, {"EMULEX", "MD21/S2 ESDI", NULL, BLIST_SINGLELUN}, {"easyRAID", "16P", NULL, BLIST_NOREPORTLUN}, {"easyRAID", "X6P", NULL, BLIST_NOREPORTLUN}, @@ -691,7 +691,8 @@ static ssize_t proc_scsi_devinfo_write(struct file *file, if (!buf || length>PAGE_SIZE) return -EINVAL; - if (!(buffer = (char *) __get_free_page(GFP_KERNEL))) + buffer = kmalloc(PAGE_SIZE, GFP_KERNEL); + if (!buffer) return -ENOMEM; if (copy_from_user(buffer, buf, length)) { err =-EFAULT; @@ -708,7 +709,7 @@ static ssize_t proc_scsi_devinfo_write(struct file *file, scsi_dev_info_list_add_str(buffer); out: - free_page((unsigned long)buffer); + kfree(buffer); return err; } diff --git a/drivers/scsi/scsi_error.c b/drivers/scsi/scsi_error.c index b729407348f7..75442d60c30e 100644 --- a/drivers/scsi/scsi_error.c +++ b/drivers/scsi/scsi_error.c @@ -63,7 +63,7 @@ static enum scsi_disposition scsi_try_to_abort_cmd(const struct scsi_host_templa void scsi_eh_wakeup(struct Scsi_Host *shost, unsigned int busy) { - lockdep_assert_held(shost->host_lock); + lockdep_assert_held(&shost->host_lock); if (busy == shost->host_failed) { trace_scsi_eh_wakeup(shost); @@ -88,9 +88,9 @@ void scsi_rcu_eh_wakeup(struct work_struct *work) busy = scsi_host_busy(shost); - spin_lock_irqsave(shost->host_lock, flags); + spin_lock_irqsave(&shost->host_lock, flags); scsi_eh_wakeup(shost, busy); - spin_unlock_irqrestore(shost->host_lock, flags); + spin_unlock_irqrestore(&shost->host_lock, flags); } /** @@ -103,7 +103,7 @@ void scsi_schedule_eh(struct Scsi_Host *shost) { unsigned long flags; - spin_lock_irqsave(shost->host_lock, flags); + spin_lock_irqsave(&shost->host_lock, flags); if (scsi_host_set_state(shost, SHOST_RECOVERY) == 0 || scsi_host_set_state(shost, SHOST_CANCEL_RECOVERY) == 0) { @@ -111,7 +111,7 @@ void scsi_schedule_eh(struct Scsi_Host *shost) queue_work(shost->tmf_work_q, &shost->eh_work); } - spin_unlock_irqrestore(shost->host_lock, flags); + spin_unlock_irqrestore(&shost->host_lock, flags); } EXPORT_SYMBOL_GPL(scsi_schedule_eh); @@ -201,7 +201,7 @@ scmd_eh_abort_handler(struct work_struct *work) goto out; } - spin_lock_irqsave(shost->host_lock, flags); + spin_lock_irqsave(&shost->host_lock, flags); list_del_init(&scmd->eh_entry); /* @@ -213,7 +213,7 @@ scmd_eh_abort_handler(struct work_struct *work) if (shost->eh_deadline != -1) shost->last_reset = 0; - spin_unlock_irqrestore(shost->host_lock, flags); + spin_unlock_irqrestore(&shost->host_lock, flags); if (!scsi_noretry_cmd(scmd) && scsi_cmd_retry_allowed(scmd) && @@ -231,9 +231,9 @@ scmd_eh_abort_handler(struct work_struct *work) return; out: - spin_lock_irqsave(shost->host_lock, flags); + spin_lock_irqsave(&shost->host_lock, flags); list_del_init(&scmd->eh_entry); - spin_unlock_irqrestore(shost->host_lock, flags); + spin_unlock_irqrestore(&shost->host_lock, flags); scsi_eh_scmd_add(scmd); } @@ -267,12 +267,11 @@ scsi_abort_command(struct scsi_cmnd *scmd) return FAILED; } - spin_lock_irqsave(shost->host_lock, flags); + spin_lock_irqsave(&shost->host_lock, flags); if (shost->eh_deadline != -1 && !shost->last_reset) shost->last_reset = jiffies; - BUG_ON(!list_empty(&scmd->eh_entry)); list_add_tail(&scmd->eh_entry, &shost->eh_abort_list); - spin_unlock_irqrestore(shost->host_lock, flags); + spin_unlock_irqrestore(&shost->host_lock, flags); scmd->eh_eflags |= SCSI_EH_ABORT_SCHEDULED; SCSI_LOG_ERROR_RECOVERY(3, @@ -305,9 +304,9 @@ static void scsi_eh_inc_host_failed(struct rcu_head *head) unsigned int busy; unsigned long flags; - spin_lock_irqsave(shost->host_lock, flags); + spin_lock_irqsave(&shost->host_lock, flags); shost->host_failed++; - spin_unlock_irqrestore(shost->host_lock, flags); + spin_unlock_irqrestore(&shost->host_lock, flags); /* * The counting of busy requests needs to occur after adding to * host_failed or after the lock acquire for adding to host_failed @@ -315,9 +314,9 @@ static void scsi_eh_inc_host_failed(struct rcu_head *head) */ busy = scsi_host_busy(shost); - spin_lock_irqsave(shost->host_lock, flags); + spin_lock_irqsave(&shost->host_lock, flags); scsi_eh_wakeup(shost, busy); - spin_unlock_irqrestore(shost->host_lock, flags); + spin_unlock_irqrestore(&shost->host_lock, flags); } /** @@ -333,7 +332,7 @@ void scsi_eh_scmd_add(struct scsi_cmnd *scmd) WARN_ON_ONCE(!shost->ehandler); WARN_ON_ONCE(!test_bit(SCMD_STATE_INFLIGHT, &scmd->state)); - spin_lock_irqsave(shost->host_lock, flags); + spin_lock_irqsave(&shost->host_lock, flags); if (scsi_host_set_state(shost, SHOST_RECOVERY)) { ret = scsi_host_set_state(shost, SHOST_CANCEL_RECOVERY); WARN_ON_ONCE(ret); @@ -343,7 +342,7 @@ void scsi_eh_scmd_add(struct scsi_cmnd *scmd) scsi_eh_reset(scmd); list_add_tail(&scmd->eh_entry, &shost->eh_cmd_q); - spin_unlock_irqrestore(shost->host_lock, flags); + spin_unlock_irqrestore(&shost->host_lock, flags); /* * Ensure that all tasks observe the host state change before the * host_failed change. @@ -490,24 +489,27 @@ static void scsi_report_sense(struct scsi_device *sdev, enum scsi_device_event evt_type = SDEV_EVT_MAXBITS; /* i.e. none */ if (sshdr->sense_key == UNIT_ATTENTION) { - if (sshdr->asc == 0x3f && sshdr->ascq == 0x03) { + if (sshdr->sense_code == INQUIRY_DATA_HAS_CHANGED) { evt_type = SDEV_EVT_INQUIRY_CHANGE_REPORTED; sdev_printk(KERN_WARNING, sdev, "Inquiry data has changed"); - } else if (sshdr->asc == 0x3f && sshdr->ascq == 0x0e) { + } else if (sshdr->sense_code == REPORTED_LUNS_DATA_HAS_CHANGED) { evt_type = SDEV_EVT_LUN_CHANGE_REPORTED; scsi_report_lun_change(sdev); sdev_printk(KERN_WARNING, sdev, "LUN assignments on this target have " "changed. The Linux SCSI layer does not " "automatically remap LUN assignments.\n"); - } else if (sshdr->asc == 0x3f) + } else if (scsi_sense_asc(sshdr) == + ASC_TARGET_OPERATING_CONDITIONS_HAVE_CHANGED) { sdev_printk(KERN_WARNING, sdev, "Operating parameters on this target have " "changed. The Linux SCSI layer does not " "automatically adjust these parameters.\n"); + } - if (sshdr->asc == 0x38 && sshdr->ascq == 0x07) { + if (sshdr->sense_code == + THIN_PROVISIONING_SOFT_THRESHOLD_REACHED) { evt_type = SDEV_EVT_SOFT_THRESHOLD_REACHED_REPORTED; sdev_printk(KERN_WARNING, sdev, "Warning! Received an indication that the " @@ -515,7 +517,8 @@ static void scsi_report_sense(struct scsi_device *sdev, "threshold.\n"); } - if (sshdr->asc == 0x29) { + if (scsi_sense_asc(sshdr) == + ASC_POWER_ON_RESET_OR_BUS_DEVICE_RESET_OCCURRED) { evt_type = SDEV_EVT_POWER_ON_RESET_OCCURRED; /* * Do not print message if it is an expected side-effect @@ -526,21 +529,22 @@ static void scsi_report_sense(struct scsi_device *sdev, "Power-on or device reset occurred\n"); } - if (sshdr->asc == 0x2a && sshdr->ascq == 0x01) { + if (sshdr->sense_code == MODE_PARAMETERS_CHANGED) { evt_type = SDEV_EVT_MODE_PARAMETER_CHANGE_REPORTED; sdev_printk(KERN_WARNING, sdev, "Mode parameters changed"); - } else if (sshdr->asc == 0x2a && sshdr->ascq == 0x06) { + } else if (sshdr->sense_code == ASYMMETRIC_ACCESS_STATE_CHANGED) { evt_type = SDEV_EVT_ALUA_STATE_CHANGE_REPORTED; sdev_printk(KERN_WARNING, sdev, "Asymmetric access state changed"); - } else if (sshdr->asc == 0x2a && sshdr->ascq == 0x09) { + } else if (sshdr->sense_code == CAPACITY_DATA_HAS_CHANGED) { evt_type = SDEV_EVT_CAPACITY_CHANGE_REPORTED; sdev_printk(KERN_WARNING, sdev, "Capacity data has changed"); - } else if (sshdr->asc == 0x2a) + } else if (scsi_sense_asc(sshdr) == ASC_PARAMETERS_CHANGED) { sdev_printk(KERN_WARNING, sdev, "Parameters changed"); + } } if (evt_type != SDEV_EVT_MAXBITS) { @@ -582,9 +586,11 @@ enum scsi_disposition scsi_check_sense(struct scsi_cmnd *scmd) * that all ULDs interested in these can see that those have * happened, even if someone else gets the sense data. */ - if (sshdr.asc == 0x28) + if (scsi_sense_asc(&sshdr) == + ASC_NOT_READY_TO_READY_CHANGE_MEDIUM_MAY_HAVE_CHANGED) atomic_inc(&sdev->ua_new_media_ctr); - else if (sshdr.asc == 0x29) + else if (scsi_sense_asc(&sshdr) == + ASC_POWER_ON_RESET_OR_BUS_DEVICE_RESET_OCCURRED) atomic_inc(&sdev->ua_por_ctr); } @@ -636,7 +642,8 @@ enum scsi_disposition scsi_check_sense(struct scsi_cmnd *scmd) return /* soft_error */ SUCCESS; case ABORTED_COMMAND: - if (sshdr.asc == 0x10) /* DIF */ + if (scsi_sense_asc(&sshdr) == ASC_ID_CRC_OR_ECC_ERROR) + /* DIF */ return SUCCESS; /* @@ -647,18 +654,20 @@ enum scsi_disposition scsi_check_sense(struct scsi_cmnd *scmd) * COMMAND TIMEOUT DURING PROCESSING DUE TO ERROR RECOVERY * additional sense code qualifiers. */ - if (sshdr.asc == 0x2e && - sshdr.ascq >= 0x01 && sshdr.ascq <= 0x03) { + if (sshdr.sense_code >= COMMAND_TIMEOUT_BEFORE_PROCESSING && + sshdr.sense_code <= + COMMAND_TIMEOUT_DURING_PROCESSING_DUE_TO_ERROR_RECOVERY) { set_scsi_ml_byte(scmd, SCSIML_STAT_DL_TIMEOUT); req->cmd_flags |= REQ_FAILFAST_DEV; req->rq_flags |= RQF_QUIET; return SUCCESS; } - if (sshdr.asc == 0x44 && sdev->sdev_bflags & BLIST_RETRY_ITF) + if ((sdev->sdev_bflags & BLIST_RETRY_ITF) && + scsi_sense_asc(&sshdr) == ASC_INTERNAL_TARGET_FAILURE) return ADD_TO_MLQUEUE; - if (sshdr.asc == 0xc1 && sshdr.ascq == 0x01 && - sdev->sdev_bflags & BLIST_RETRY_ASC_C1) + if ((sdev->sdev_bflags & BLIST_RETRY_ASC_C1) && + sshdr.sense_code == scsi_sense_code(0xc1, 0x01)) return ADD_TO_MLQUEUE; return NEEDS_RETRY; @@ -672,12 +681,13 @@ enum scsi_disposition scsi_check_sense(struct scsi_cmnd *scmd) */ if (scmd->device->expecting_cc_ua) { /* - * Because some device does not queue unit - * attentions correctly, we carefully check - * additional sense code and qualifier so as - * not to squash media change unit attention. + * Because some devices do not queue unit attentions + * correctly, we carefully check additional sense code + * and qualifier so as not to squash media change unit + * attention. */ - if (sshdr.asc != 0x28 || sshdr.ascq != 0x00) { + if (sshdr.sense_code != + NOT_READY_TO_READY_CHANGE_MEDIUM_MAY_HAVE_CHANGED) { scmd->device->expecting_cc_ua = 0; return NEEDS_RETRY; } @@ -688,21 +698,23 @@ enum scsi_disposition scsi_check_sense(struct scsi_cmnd *scmd) * REPORTED LUNS DATA HAS CHANGED. */ if (scmd->device->sdev_target->expecting_lun_change && - sshdr.asc == 0x3f && sshdr.ascq == 0x0e) + sshdr.sense_code == REPORTED_LUNS_DATA_HAS_CHANGED) return NEEDS_RETRY; /* * if the device is in the process of becoming ready, we * should retry. */ - if ((sshdr.asc == 0x04) && - (sshdr.ascq == 0x01 || sshdr.ascq == 0x0a)) + if (sshdr.sense_code == LU_IS_IN_PROCESS_OF_BECOMING_READY || + sshdr.sense_code == + LU_NOT_ACCESSIBLE_ASYMMETRIC_ACCESS_STATE_TRANSITION) return NEEDS_RETRY; /* * if the device is not started, we need to wake * the error handler to start the motor */ if (scmd->device->allow_restart && - (sshdr.asc == 0x04) && (sshdr.ascq == 0x02)) + sshdr.sense_code == + LU_NOT_READY_INITIALIZING_COMMAND_REQUIRED) return FAILED; /* * Pass the UA upwards for a determination in the completion @@ -712,7 +724,7 @@ enum scsi_disposition scsi_check_sense(struct scsi_cmnd *scmd) /* these are not supported */ case DATA_PROTECT: - if (sshdr.asc == 0x27 && sshdr.ascq == 0x07) { + if (sshdr.sense_code == SPACE_ALLOCATION_FAILED_WRITE_PROTECT) { /* Thin provisioning hard threshold reached */ set_scsi_ml_byte(scmd, SCSIML_STAT_NOSPC); return SUCCESS; @@ -726,11 +738,14 @@ enum scsi_disposition scsi_check_sense(struct scsi_cmnd *scmd) return SUCCESS; case MEDIUM_ERROR: - if (sshdr.asc == 0x11 || /* UNRECOVERED READ ERR */ - sshdr.asc == 0x13 || /* AMNF DATA FIELD */ - sshdr.asc == 0x14) { /* RECORD NOT FOUND */ + switch (scsi_sense_asc(&sshdr)) { + case ASC_UNRECOVERED_READ_ERROR: + case ASC_ADDRESS_MARK_NOT_FOUND_FOR_DATA_FIELD: + case ASC_RECORDED_ENTITY_NOT_FOUND: set_scsi_ml_byte(scmd, SCSIML_STAT_MED_ERROR); return SUCCESS; + default: + break; } return NEEDS_RETRY; @@ -742,13 +757,17 @@ enum scsi_disposition scsi_check_sense(struct scsi_cmnd *scmd) fallthrough; case ILLEGAL_REQUEST: - if (sshdr.asc == 0x20 || /* Invalid command operation code */ - sshdr.asc == 0x21 || /* Logical block address out of range */ - sshdr.asc == 0x22 || /* Invalid function */ - sshdr.asc == 0x24 || /* Invalid field in cdb */ - sshdr.asc == 0x26 || /* Parameter value invalid */ - sshdr.asc == 0x27) { /* Write protected */ + switch (scsi_sense_asc(&sshdr)) { + case ASC_INVALID_COMMAND_OP_CODE: + case ASC_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE: + case ASC_ILLEGAL_FUNCTION: + case ASC_INVALID_FIELD_IN_CDB: + case ASC_INVALID_FIELD_IN_PARAMETER_LIST: + case ASC_WRITE_PROTECTED: set_scsi_ml_byte(scmd, SCSIML_STAT_TGT_FAILURE); + break; + default: + break; } return SUCCESS; @@ -760,7 +779,7 @@ enum scsi_disposition scsi_check_sense(struct scsi_cmnd *scmd) * that the command was in fact aborted because it exceeded its * duration limit. Never retry these commands. */ - if (sshdr.asc == 0x55 && sshdr.ascq == 0x0a) { + if (sshdr.sense_code == DATA_CURRENTLY_UNAVAILABLE) { set_scsi_ml_byte(scmd, SCSIML_STAT_DL_TIMEOUT); req->cmd_flags |= REQ_FAILFAST_DEV; req->rq_flags |= RQF_QUIET; @@ -940,9 +959,9 @@ static enum scsi_disposition scsi_try_host_reset(struct scsi_cmnd *scmd) if (rtn == SUCCESS) { if (!hostt->skip_settle_delay) ssleep(HOST_RESET_SETTLE_TIME); - spin_lock_irqsave(host->host_lock, flags); + spin_lock_irqsave(&host->host_lock, flags); scsi_report_bus_reset(host, scmd_channel(scmd)); - spin_unlock_irqrestore(host->host_lock, flags); + spin_unlock_irqrestore(&host->host_lock, flags); } return rtn; @@ -970,9 +989,9 @@ static enum scsi_disposition scsi_try_bus_reset(struct scsi_cmnd *scmd) if (rtn == SUCCESS) { if (!hostt->skip_settle_delay) ssleep(BUS_RESET_SETTLE_TIME); - spin_lock_irqsave(host->host_lock, flags); + spin_lock_irqsave(&host->host_lock, flags); scsi_report_bus_reset(host, scmd_channel(scmd)); - spin_unlock_irqrestore(host->host_lock, flags); + spin_unlock_irqrestore(&host->host_lock, flags); } return rtn; @@ -1006,10 +1025,10 @@ static enum scsi_disposition scsi_try_target_reset(struct scsi_cmnd *scmd) rtn = hostt->eh_target_reset_handler(scmd); if (rtn == SUCCESS) { - spin_lock_irqsave(host->host_lock, flags); + spin_lock_irqsave(&host->host_lock, flags); __starget_for_each_device(scsi_target(scmd->device), NULL, __scsi_report_device_reset); - spin_unlock_irqrestore(host->host_lock, flags); + spin_unlock_irqrestore(&host->host_lock, flags); } return rtn; @@ -2215,11 +2234,11 @@ static void scsi_restart_operations(struct Scsi_Host *shost) SCSI_LOG_ERROR_RECOVERY(3, shost_printk(KERN_INFO, shost, "waking up host to restart\n")); - spin_lock_irqsave(shost->host_lock, flags); + spin_lock_irqsave(&shost->host_lock, flags); if (scsi_host_set_state(shost, SHOST_RUNNING)) if (scsi_host_set_state(shost, SHOST_CANCEL)) BUG_ON(scsi_host_set_state(shost, SHOST_DEL)); - spin_unlock_irqrestore(shost->host_lock, flags); + spin_unlock_irqrestore(&shost->host_lock, flags); wake_up(&shost->host_wait); @@ -2239,11 +2258,11 @@ static void scsi_restart_operations(struct Scsi_Host *shost) * recovery or scsi_device_unbusy() will wake us again when these * pending commands complete. */ - spin_lock_irqsave(shost->host_lock, flags); + spin_lock_irqsave(&shost->host_lock, flags); if (shost->host_eh_scheduled) if (scsi_host_set_state(shost, SHOST_RECOVERY)) WARN_ON(scsi_host_set_state(shost, SHOST_CANCEL_RECOVERY)); - spin_unlock_irqrestore(shost->host_lock, flags); + spin_unlock_irqrestore(&shost->host_lock, flags); } /** @@ -2335,19 +2354,19 @@ static void scsi_unjam_host(struct Scsi_Host *shost) LIST_HEAD(eh_work_q); LIST_HEAD(eh_done_q); - spin_lock_irqsave(shost->host_lock, flags); + spin_lock_irqsave(&shost->host_lock, flags); list_splice_init(&shost->eh_cmd_q, &eh_work_q); - spin_unlock_irqrestore(shost->host_lock, flags); + spin_unlock_irqrestore(&shost->host_lock, flags); SCSI_LOG_ERROR_RECOVERY(1, scsi_eh_prt_fail_stats(shost, &eh_work_q)); if (!scsi_eh_get_sense(&eh_work_q, &eh_done_q)) scsi_eh_ready_devs(shost, &eh_work_q, &eh_done_q); - spin_lock_irqsave(shost->host_lock, flags); + spin_lock_irqsave(&shost->host_lock, flags); if (shost->eh_deadline != -1) shost->last_reset = 0; - spin_unlock_irqrestore(shost->host_lock, flags); + spin_unlock_irqrestore(&shost->host_lock, flags); scsi_eh_flush_done_q(&eh_done_q); } @@ -2551,9 +2570,9 @@ scsi_ioctl_reset(struct scsi_device *dev, int __user *arg) scmd->sc_data_direction = DMA_BIDIRECTIONAL; - spin_lock_irqsave(shost->host_lock, flags); + spin_lock_irqsave(&shost->host_lock, flags); shost->tmf_in_progress = 1; - spin_unlock_irqrestore(shost->host_lock, flags); + spin_unlock_irqrestore(&shost->host_lock, flags); switch (val & ~SG_SCSI_RESET_NO_ESCALATE) { case SG_SCSI_RESET_NOTHING: @@ -2586,9 +2605,9 @@ scsi_ioctl_reset(struct scsi_device *dev, int __user *arg) error = (rtn == SUCCESS) ? 0 : -EIO; - spin_lock_irqsave(shost->host_lock, flags); + spin_lock_irqsave(&shost->host_lock, flags); shost->tmf_in_progress = 0; - spin_unlock_irqrestore(shost->host_lock, flags); + spin_unlock_irqrestore(&shost->host_lock, flags); /* * be sure to wake up anyone who was sleeping or had their queue diff --git a/drivers/scsi/scsi_ioctl.c b/drivers/scsi/scsi_ioctl.c index c14f81403a09..122403ec3ab8 100644 --- a/drivers/scsi/scsi_ioctl.c +++ b/drivers/scsi/scsi_ioctl.c @@ -96,7 +96,8 @@ static int ioctl_internal_command(struct scsi_device *sdev, char *cmd, "ioctl_internal_command: " "ILLEGAL REQUEST " "asc=0x%x ascq=0x%x\n", - sshdr.asc, sshdr.ascq); + scsi_sense_asc(&sshdr), + scsi_sense_ascq(&sshdr)); break; case NOT_READY: /* This happens if there is no disc in drive */ if (sdev->removable) diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c index af27fd3df8d4..f695a6605815 100644 --- a/drivers/scsi/scsi_lib.c +++ b/drivers/scsi/scsi_lib.c @@ -243,23 +243,23 @@ static int scsi_check_passthrough(struct scsi_cmnd *scmd, continue; if (status_byte(failure->result) != SAM_STAT_CHECK_CONDITION || - failure->sense == SCMD_FAILURE_SENSE_ANY) + failure->sense_key == SCMD_FAILURE_SENSE_KEY_ANY) goto maybe_retry; if (!scsi_command_normalize_sense(scmd, &sshdr)) return 0; - if (failure->sense != sshdr.sense_key) + if (failure->sense_key != sshdr.sense_key) continue; - if (failure->asc == SCMD_FAILURE_ASC_ANY) + if (scsi_failure_asc(failure) == SCMD_FAILURE_ASC_ANY) goto maybe_retry; - if (failure->asc != sshdr.asc) + if (scsi_failure_asc(failure) != scsi_sense_asc(&sshdr)) continue; - if (failure->ascq == SCMD_FAILURE_ASCQ_ANY || - failure->ascq == sshdr.ascq) + if (scsi_failure_ascq(failure) == SCMD_FAILURE_ASCQ_ANY || + scsi_failure_ascq(failure) == scsi_sense_ascq(&sshdr)) goto maybe_retry; } @@ -388,10 +388,10 @@ static void scsi_dec_host_busy(struct Scsi_Host *shost, struct scsi_cmnd *cmd) unsigned int busy = scsi_host_busy(shost); - spin_lock_irqsave(shost->host_lock, flags); + spin_lock_irqsave(&shost->host_lock, flags); if (shost->host_failed || shost->host_eh_scheduled) scsi_eh_wakeup(shost, busy); - spin_unlock_irqrestore(shost->host_lock, flags); + spin_unlock_irqrestore(&shost->host_lock, flags); } rcu_read_unlock(); } @@ -436,9 +436,9 @@ static void scsi_single_lun_run(struct scsi_device *current_sdev) struct scsi_target *starget = scsi_target(current_sdev); unsigned long flags; - spin_lock_irqsave(shost->host_lock, flags); + spin_lock_irqsave(&shost->host_lock, flags); starget->starget_sdev_user = NULL; - spin_unlock_irqrestore(shost->host_lock, flags); + spin_unlock_irqrestore(&shost->host_lock, flags); /* * Call blk_run_queue for all LUNs on the target, starting with @@ -449,11 +449,11 @@ static void scsi_single_lun_run(struct scsi_device *current_sdev) blk_mq_run_hw_queues(current_sdev->request_queue, shost->queuecommand_may_block); - spin_lock_irqsave(shost->host_lock, flags); + spin_lock_irqsave(&shost->host_lock, flags); if (!starget->starget_sdev_user) __starget_for_each_device(starget, current_sdev, scsi_kick_sdev_queue); - spin_unlock_irqrestore(shost->host_lock, flags); + spin_unlock_irqrestore(&shost->host_lock, flags); } static inline bool scsi_device_is_busy(struct scsi_device *sdev) @@ -491,7 +491,7 @@ static void scsi_starved_list_run(struct Scsi_Host *shost) struct scsi_device *sdev; unsigned long flags; - spin_lock_irqsave(shost->host_lock, flags); + spin_lock_irqsave(&shost->host_lock, flags); list_splice_init(&shost->starved_list, &starved_list); while (!list_empty(&starved_list)) { @@ -532,16 +532,16 @@ static void scsi_starved_list_run(struct Scsi_Host *shost) slq = sdev->request_queue; if (!blk_get_queue(slq)) continue; - spin_unlock_irqrestore(shost->host_lock, flags); + spin_unlock_irqrestore(&shost->host_lock, flags); blk_mq_run_hw_queues(slq, false); blk_put_queue(slq); - spin_lock_irqsave(shost->host_lock, flags); + spin_lock_irqsave(&shost->host_lock, flags); } /* put any unprocessed entries back */ list_splice(&starved_list, &shost->starved_list); - spin_unlock_irqrestore(shost->host_lock, flags); + spin_unlock_irqrestore(&shost->host_lock, flags); } /** @@ -578,7 +578,7 @@ void scsi_run_host_queues(struct Scsi_Host *shost) struct scsi_device *sdev, *prev = NULL; unsigned long flags; - spin_lock_irqsave(shost->host_lock, flags); + spin_lock_irqsave(&shost->host_lock, flags); __shost_for_each_device(sdev, shost) { /* * Only skip devices so deep into removal they will never need @@ -589,7 +589,7 @@ void scsi_run_host_queues(struct Scsi_Host *shost) if (sdev->sdev_state == SDEV_DEL || !get_device(&sdev->sdev_gendev)) continue; - spin_unlock_irqrestore(shost->host_lock, flags); + spin_unlock_irqrestore(&shost->host_lock, flags); if (prev) put_device(&prev->sdev_gendev); @@ -597,9 +597,9 @@ void scsi_run_host_queues(struct Scsi_Host *shost) prev = sdev; - spin_lock_irqsave(shost->host_lock, flags); + spin_lock_irqsave(&shost->host_lock, flags); } - spin_unlock_irqrestore(shost->host_lock, flags); + spin_unlock_irqrestore(&shost->host_lock, flags); if (prev) put_device(&prev->sdev_gendev); } @@ -839,6 +839,8 @@ static void scsi_io_completion_action(struct scsi_cmnd *cmd, int result) */ action = ACTION_RETRY; } else if (sense_valid && sense_current) { + u8 asc = scsi_sense_asc(&sshdr); + switch (sshdr.sense_key) { case UNIT_ATTENTION: if (cmd->device->removable) { @@ -865,64 +867,72 @@ static void scsi_io_completion_action(struct scsi_cmnd *cmd, int result) * where READ CAPACITY failed, we may have * read past the end of the disk. */ - if ((cmd->device->use_10_for_rw && - sshdr.asc == 0x20 && sshdr.ascq == 0x00) && + if (cmd->device->use_10_for_rw && + sshdr.sense_code == INVALID_COMMAND_OP_CODE && (cmd->cmnd[0] == READ_10 || cmd->cmnd[0] == WRITE_10)) { /* This will issue a new 6-byte command. */ cmd->device->use_10_for_rw = 0; action = ACTION_REPREP; - } else if (sshdr.asc == 0x10) /* DIX */ { + break; + } + if (asc == ASC_ID_CRC_OR_ECC_ERROR) { + /* DIX */ action = ACTION_FAIL; blk_stat = BLK_STS_PROTECTION; - /* INVALID COMMAND OPCODE or INVALID FIELD IN CDB */ - } else if (sshdr.asc == 0x20 || sshdr.asc == 0x24) { + break; + } + if (asc == ASC_INVALID_COMMAND_OP_CODE || + asc == ASC_INVALID_FIELD_IN_CDB) { action = ACTION_FAIL; blk_stat = BLK_STS_TARGET; - } else - action = ACTION_FAIL; + break; + } + action = ACTION_FAIL; break; case ABORTED_COMMAND: action = ACTION_FAIL; - if (sshdr.asc == 0x10) /* DIF */ + if (asc == ASC_ID_CRC_OR_ECC_ERROR) /* DIF */ blk_stat = BLK_STS_PROTECTION; break; case NOT_READY: /* If the device is in the process of becoming * ready, or has a temporary blockage, retry. */ - if (sshdr.asc == 0x04) { - switch (sshdr.ascq) { - case 0x01: /* becoming ready */ - case 0x04: /* format in progress */ - case 0x05: /* rebuild in progress */ - case 0x06: /* recalculation in progress */ - case 0x07: /* operation in progress */ - case 0x08: /* Long write in progress */ - case 0x09: /* self test in progress */ - case 0x11: /* notify (enable spinup) required */ - case 0x14: /* space allocation in progress */ - case 0x1a: /* start stop unit in progress */ - case 0x1b: /* sanitize in progress */ - case 0x1d: /* configuration in progress */ - action = ACTION_DELAYED_RETRY; - break; - case 0x0a: /* ALUA state transition */ - action = ACTION_DELAYED_REPREP; - break; - /* - * Depopulation might take many hours, - * thus it is not worthwhile to retry. - */ - case 0x24: /* depopulation in progress */ - case 0x25: /* depopulation restore in progress */ - fallthrough; - default: - action = ACTION_FAIL; - break; - } - } else + if (asc != ASC_LU_NOT_READY) { action = ACTION_FAIL; + break; + } + + switch (sshdr.sense_code) { + case LU_IS_IN_PROCESS_OF_BECOMING_READY: + case LU_NOT_READY_FORMAT_IN_PROGRESS: + case LU_NOT_READY_REBUILD_IN_PROGRESS: + case LU_NOT_READY_RECALCULATION_IN_PROGRESS: + case LU_NOT_READY_OP_IN_PROGRESS: + case LU_NOT_READY_LONG_WRITE_IN_PROGRESS: + case LU_NOT_READY_SELFTEST_IN_PROGRESS: + case LU_NOT_READY_NOTIFY_REQUIRED: + case LU_NOT_READY_SPACE_ALLOCATION_IN_PROGRESS: + case LU_NOT_READY_START_STOP_UNIT_COMMAND_IN_PROGRESS: + case LU_NOT_READY_SANITIZE_IN_PROGRESS: + case LU_NOT_READY_CONFIG_IN_PROGRESS: + action = ACTION_DELAYED_RETRY; + break; + case LU_NOT_ACCESSIBLE_ASYMMETRIC_ACCESS_STATE_TRANSITION: + action = ACTION_DELAYED_REPREP; + break; + /* + * Depopulation might take many hours, thus it is not + * worthwhile to retry. + */ + case DEPOPULATION_IN_PROGRESS: + case DEPOPULATION_RESTORATION_IN_PROGRESS: + fallthrough; + default: + action = ACTION_FAIL; + break; + } break; case VOLUME_OVERFLOW: /* See SSC3rXX or current. */ @@ -930,11 +940,14 @@ static void scsi_io_completion_action(struct scsi_cmnd *cmd, int result) break; case DATA_PROTECT: action = ACTION_FAIL; - if ((sshdr.asc == 0x0C && sshdr.ascq == 0x12) || - (sshdr.asc == 0x55 && - (sshdr.ascq == 0x0E || sshdr.ascq == 0x0F))) { - /* Insufficient zone resources */ + switch (sshdr.sense_code) { + case WRITE_ERROR_INSUFFICIENT_ZONE_RESOURCES: + case INSUFFICIENT_ZONE_RESOURCES: + case INSUFFICIENT_ZONE_RESOURCES_TO_COMPLETE_WRITE: blk_stat = BLK_STS_ZONE_OPEN_RESOURCE; + break; + default: + break; } break; case COMPLETED: @@ -1041,7 +1054,7 @@ static int scsi_io_completion_nz_result(struct scsi_cmnd *cmd, int result, * skip print since caller wants ATA registers. Only occurs * on SCSI ATA PASS_THROUGH commands when CK_COND=1 */ - if ((sshdr.asc == 0x0) && (sshdr.ascq == 0x1d)) + if (sshdr.sense_code == ATA_PASS_THROUGH_INFORMATION_AVAILABLE) do_print = false; else if (req->rq_flags & RQF_QUIET) do_print = false; @@ -1309,7 +1322,6 @@ void scsi_init_command(struct scsi_device *dev, struct scsi_cmnd *cmd) } cmd->device = dev; - INIT_LIST_HEAD(&cmd->eh_entry); INIT_DELAYED_WORK(&cmd->abort_work, scmd_eh_abort_handler); } @@ -1433,14 +1445,14 @@ static inline int scsi_target_queue_ready(struct Scsi_Host *shost, unsigned int busy; if (starget->single_lun) { - spin_lock_irq(shost->host_lock); + spin_lock_irq(&shost->host_lock); if (starget->starget_sdev_user && starget->starget_sdev_user != sdev) { - spin_unlock_irq(shost->host_lock); + spin_unlock_irq(&shost->host_lock); return 0; } starget->starget_sdev_user = sdev; - spin_unlock_irq(shost->host_lock); + spin_unlock_irq(&shost->host_lock); } if (starget->can_queue <= 0) @@ -1467,9 +1479,9 @@ static inline int scsi_target_queue_ready(struct Scsi_Host *shost, return 1; starved: - spin_lock_irq(shost->host_lock); + spin_lock_irq(&shost->host_lock); list_move_tail(&sdev->starved_entry, &shost->starved_list); - spin_unlock_irq(shost->host_lock); + spin_unlock_irq(&shost->host_lock); out_dec: if (starget->can_queue > 0) atomic_dec(&starget->target_busy); @@ -1506,10 +1518,10 @@ static inline int scsi_host_queue_ready(struct request_queue *q, /* We're OK to process the command, so we can't be starved */ if (!list_empty(&sdev->starved_entry)) { - spin_lock_irq(shost->host_lock); + spin_lock_irq(&shost->host_lock); if (!list_empty(&sdev->starved_entry)) list_del_init(&sdev->starved_entry); - spin_unlock_irq(shost->host_lock); + spin_unlock_irq(&shost->host_lock); } __set_bit(SCMD_STATE_INFLIGHT, &cmd->state); @@ -1517,10 +1529,10 @@ static inline int scsi_host_queue_ready(struct request_queue *q, return 1; starved: - spin_lock_irq(shost->host_lock); + spin_lock_irq(&shost->host_lock); if (list_empty(&sdev->starved_entry)) list_add_tail(&sdev->starved_entry, &shost->starved_list); - spin_unlock_irq(shost->host_lock); + spin_unlock_irq(&shost->host_lock); out_dec: scsi_dec_host_busy(shost, cmd); return 0; @@ -1577,8 +1589,6 @@ static void scsi_complete(struct request *rq) return; } - INIT_LIST_HEAD(&cmd->eh_entry); - atomic_inc(&cmd->device->iodone_cnt); if (cmd->result) atomic_inc(&cmd->device->ioerr_cnt); @@ -2372,9 +2382,8 @@ scsi_mode_sense(struct scsi_device *sdev, int dbd, int modepage, int subpage, struct scsi_sense_hdr my_sshdr; struct scsi_failure failure_defs[] = { { - .sense = UNIT_ATTENTION, - .asc = SCMD_FAILURE_ASC_ANY, - .ascq = SCMD_FAILURE_ASCQ_ANY, + .sense_key = UNIT_ATTENTION, + .sense_code = SCMD_FAILURE_SENSE_CODE_ANY, .allowed = retries, .result = SAM_STAT_CHECK_CONDITION, }, @@ -2432,8 +2441,8 @@ scsi_mode_sense(struct scsi_device *sdev, int dbd, int modepage, int subpage, if (!scsi_status_is_good(result)) { if (scsi_sense_valid(sshdr)) { - if ((sshdr->sense_key == ILLEGAL_REQUEST) && - (sshdr->asc == 0x20) && (sshdr->ascq == 0)) { + if (sshdr->sense_key == ILLEGAL_REQUEST && + sshdr->sense_code == INVALID_COMMAND_OP_CODE) { /* * Invalid command operation code: retry using * MODE SENSE(6) if this was a MODE SENSE(10) @@ -3573,21 +3582,20 @@ int scsi_vpd_tpg_id(struct scsi_device *sdev, int *rel_id) EXPORT_SYMBOL(scsi_vpd_tpg_id); /** - * scsi_build_sense - build sense data for a command + * scsi_set_sense - build sense data for a command * @scmd: scsi command for which the sense should be formatted * @desc: Sense format (non-zero == descriptor format, * 0 == fixed format) * @key: Sense key - * @asc: Additional sense code - * @ascq: Additional sense code qualifier + * @code: Additional sense code and sense code qualifier * **/ -void scsi_build_sense(struct scsi_cmnd *scmd, int desc, u8 key, u8 asc, u8 ascq) +void scsi_set_sense(struct scsi_cmnd *scmd, int desc, u8 key, u16 code) { - scsi_build_sense_buffer(desc, scmd->sense_buffer, key, asc, ascq); + scsi_set_sense_buffer(desc, scmd->sense_buffer, key, code); scmd->result = SAM_STAT_CHECK_CONDITION; } -EXPORT_SYMBOL_GPL(scsi_build_sense); +EXPORT_SYMBOL_GPL(scsi_set_sense); #ifdef CONFIG_SCSI_LIB_KUNIT_TEST #include "scsi_lib_test.c" diff --git a/drivers/scsi/scsi_lib_test.c b/drivers/scsi/scsi_lib_test.c index ae8af0e0047a..dfd8eefe57e1 100644 --- a/drivers/scsi/scsi_lib_test.c +++ b/drivers/scsi/scsi_lib_test.c @@ -17,42 +17,43 @@ static void scsi_lib_test_multiple_sense(struct kunit *test) { struct scsi_failure multiple_sense_failure_defs[] = { { - .sense = DATA_PROTECT, - .asc = 0x1, - .ascq = 0x1, + .sense_key = DATA_PROTECT, + .sense_code = + scsi_sense_code(ASC_NO_INDEX_SECTOR_SIGNAL, + 0x1), .result = SAM_STAT_CHECK_CONDITION, }, { - .sense = UNIT_ATTENTION, - .asc = 0x11, - .ascq = 0x0, + .sense_key = UNIT_ATTENTION, + .sense_code = UNRECOVERED_READ_ERROR, .allowed = SCSI_LIB_TEST_MAX_ALLOWED, .result = SAM_STAT_CHECK_CONDITION, }, { - .sense = NOT_READY, - .asc = 0x11, - .ascq = 0x22, + .sense_key = NOT_READY, + .sense_code = + scsi_sense_code(ASC_UNRECOVERED_READ_ERROR, + 0x22), .allowed = SCSI_LIB_TEST_MAX_ALLOWED, .result = SAM_STAT_CHECK_CONDITION, }, { - .sense = ABORTED_COMMAND, - .asc = 0x11, - .ascq = SCMD_FAILURE_ASCQ_ANY, + .sense_key = ABORTED_COMMAND, + .sense_code = + scsi_sense_code(ASC_UNRECOVERED_READ_ERROR, + SCMD_FAILURE_ASCQ_ANY), .allowed = SCSI_LIB_TEST_MAX_ALLOWED, .result = SAM_STAT_CHECK_CONDITION, }, { - .sense = HARDWARE_ERROR, - .asc = SCMD_FAILURE_ASC_ANY, + .sense_key = HARDWARE_ERROR, + .sense_code = scsi_sense_code(SCMD_FAILURE_ASC_ANY, 0), .allowed = SCSI_LIB_TEST_MAX_ALLOWED, .result = SAM_STAT_CHECK_CONDITION, }, { - .sense = ILLEGAL_REQUEST, - .asc = 0x91, - .ascq = 0x36, + .sense_key = ILLEGAL_REQUEST, + .sense_code = scsi_sense_code(0x91, 0x36), .allowed = SCSI_LIB_TEST_MAX_ALLOWED, .result = SAM_STAT_CHECK_CONDITION, }, @@ -72,32 +73,36 @@ static void scsi_lib_test_multiple_sense(struct kunit *test) KUNIT_EXPECT_EQ(test, 0, scsi_check_passthrough(&sc, &failures)); KUNIT_EXPECT_EQ(test, 0, scsi_check_passthrough(&sc, NULL)); /* Command failed but caller did not pass in a failures array */ - scsi_build_sense(&sc, 0, ILLEGAL_REQUEST, 0x91, 0x36); + scsi_set_sense(&sc, 0, ILLEGAL_REQUEST, scsi_sense_code(0x91, 0x36)); KUNIT_EXPECT_EQ(test, 0, scsi_check_passthrough(&sc, NULL)); /* Match end of array */ - scsi_build_sense(&sc, 0, ILLEGAL_REQUEST, 0x91, 0x36); + scsi_set_sense(&sc, 0, ILLEGAL_REQUEST, scsi_sense_code(0x91, 0x36)); KUNIT_EXPECT_EQ(test, -EAGAIN, scsi_check_passthrough(&sc, &failures)); /* Basic match in array */ - scsi_build_sense(&sc, 0, UNIT_ATTENTION, 0x11, 0x0); + scsi_set_sense(&sc, 0, UNIT_ATTENTION, UNRECOVERED_READ_ERROR); KUNIT_EXPECT_EQ(test, -EAGAIN, scsi_check_passthrough(&sc, &failures)); /* No matching sense entry */ - scsi_build_sense(&sc, 0, MISCOMPARE, 0x11, 0x11); + scsi_set_sense(&sc, 0, MISCOMPARE, READ_ERROR_LOSS_OF_STREAMING); KUNIT_EXPECT_EQ(test, 0, scsi_check_passthrough(&sc, &failures)); /* Match using SCMD_FAILURE_ASCQ_ANY */ - scsi_build_sense(&sc, 0, ABORTED_COMMAND, 0x11, 0x22); + scsi_set_sense(&sc, 0, ABORTED_COMMAND, + scsi_sense_code(ASC_UNRECOVERED_READ_ERROR, 0x22)); KUNIT_EXPECT_EQ(test, -EAGAIN, scsi_check_passthrough(&sc, &failures)); /* Fail to match */ - scsi_build_sense(&sc, 0, ABORTED_COMMAND, 0x22, 0x22); + scsi_set_sense(&sc, 0, ABORTED_COMMAND, + scsi_sense_code(ASC_ILLEGAL_FUNCTION, 0x22)); KUNIT_EXPECT_EQ(test, 0, scsi_check_passthrough(&sc, &failures)); /* Match using SCMD_FAILURE_ASC_ANY */ - scsi_build_sense(&sc, 0, HARDWARE_ERROR, 0x11, 0x22); + scsi_set_sense(&sc, 0, HARDWARE_ERROR, + scsi_sense_code(ASC_UNRECOVERED_READ_ERROR, 0x22)); KUNIT_EXPECT_EQ(test, -EAGAIN, scsi_check_passthrough(&sc, &failures)); /* No matching status entry */ sc.result = SAM_STAT_RESERVATION_CONFLICT; KUNIT_EXPECT_EQ(test, 0, scsi_check_passthrough(&sc, &failures)); /* Test hitting allowed limit */ - scsi_build_sense(&sc, 0, NOT_READY, 0x11, 0x22); + scsi_set_sense(&sc, 0, NOT_READY, + scsi_sense_code(ASC_UNRECOVERED_READ_ERROR, 0x22)); for (i = 0; i < SCSI_LIB_TEST_MAX_ALLOWED; i++) KUNIT_EXPECT_EQ(test, -EAGAIN, scsi_check_passthrough(&sc, &failures)); @@ -108,7 +113,8 @@ static void scsi_lib_test_multiple_sense(struct kunit *test) scsi_failures_reset_retries(&failures); /* Test no retries allowed */ - scsi_build_sense(&sc, 0, DATA_PROTECT, 0x1, 0x1); + scsi_set_sense(&sc, 0, DATA_PROTECT, + scsi_sense_code(ASC_NO_INDEX_SECTOR_SIGNAL, 0x1)); KUNIT_EXPECT_EQ(test, 0, scsi_check_passthrough(&sc, &failures)); } @@ -116,8 +122,9 @@ static void scsi_lib_test_any_sense(struct kunit *test) { struct scsi_failure any_sense_failure_defs[] = { { - .result = SCMD_FAILURE_SENSE_ANY, + .sense_key = SCMD_FAILURE_SENSE_KEY_ANY, .allowed = SCSI_LIB_TEST_MAX_ALLOWED, + .result = SAM_STAT_CHECK_CONDITION, }, {} }; @@ -129,9 +136,10 @@ static void scsi_lib_test_any_sense(struct kunit *test) .sense_buffer = sense, }; - /* Match using SCMD_FAILURE_SENSE_ANY */ + /* Match using SCMD_FAILURE_SENSE_KEY_ANY */ failures.failure_definitions = any_sense_failure_defs; - scsi_build_sense(&sc, 0, MEDIUM_ERROR, 0x11, 0x22); + scsi_set_sense(&sc, 0, MEDIUM_ERROR, + scsi_sense_code(ASC_UNRECOVERED_READ_ERROR, 0x22)); KUNIT_EXPECT_EQ(test, -EAGAIN, scsi_check_passthrough(&sc, &failures)); } @@ -215,14 +223,13 @@ static void scsi_lib_test_total_allowed(struct kunit *test) { struct scsi_failure total_allowed_defs[] = { { - .sense = UNIT_ATTENTION, - .asc = SCMD_FAILURE_ASC_ANY, - .ascq = SCMD_FAILURE_ASCQ_ANY, + .sense_key = UNIT_ATTENTION, + .sense_code = SCMD_FAILURE_SENSE_CODE_ANY, .result = SAM_STAT_CHECK_CONDITION, }, /* Fail all CCs except the UA above */ { - .sense = SCMD_FAILURE_SENSE_ANY, + .sense_key = SCMD_FAILURE_SENSE_KEY_ANY, .result = SAM_STAT_CHECK_CONDITION, }, /* Retry any other errors not listed above */ @@ -245,7 +252,8 @@ static void scsi_lib_test_total_allowed(struct kunit *test) scsi_failures_reset_retries(&failures); failures.total_allowed = SCSI_LIB_TEST_TOTAL_MAX_ALLOWED; - scsi_build_sense(&sc, 0, UNIT_ATTENTION, 0x28, 0x0); + scsi_set_sense(&sc, 0, UNIT_ATTENTION, + NOT_READY_TO_READY_CHANGE_MEDIUM_MAY_HAVE_CHANGED); for (i = 0; i < SCSI_LIB_TEST_TOTAL_MAX_ALLOWED; i++) /* Retry since we under the total_allowed limit */ KUNIT_EXPECT_EQ(test, -EAGAIN, scsi_check_passthrough(&sc, @@ -259,13 +267,15 @@ static void scsi_lib_test_mixed_total(struct kunit *test) { struct scsi_failure mixed_total_defs[] = { { - .sense = UNIT_ATTENTION, - .asc = 0x28, + .sense_key = UNIT_ATTENTION, + .sense_code = + NOT_READY_TO_READY_CHANGE_MEDIUM_MAY_HAVE_CHANGED, .result = SAM_STAT_CHECK_CONDITION, }, { - .sense = UNIT_ATTENTION, - .asc = 0x29, + .sense_key = UNIT_ATTENTION, + .sense_code = + POWER_ON_RESET_OR_BUS_DEVICE_RESET_OCCURRED, .result = SAM_STAT_CHECK_CONDITION, }, { @@ -291,7 +301,8 @@ static void scsi_lib_test_mixed_total(struct kunit *test) scsi_failures_reset_retries(&failures); failures.total_allowed = SCSI_LIB_TEST_TOTAL_MAX_ALLOWED; - scsi_build_sense(&sc, 0, UNIT_ATTENTION, 0x28, 0x0); + scsi_set_sense(&sc, 0, UNIT_ATTENTION, + NOT_READY_TO_READY_CHANGE_MEDIUM_MAY_HAVE_CHANGED); for (i = 0; i < SCSI_LIB_TEST_TOTAL_MAX_ALLOWED; i++) /* Retry since we under the total_allowed limit */ KUNIT_EXPECT_EQ(test, -EAGAIN, scsi_check_passthrough(&sc, @@ -300,7 +311,8 @@ static void scsi_lib_test_mixed_total(struct kunit *test) KUNIT_EXPECT_EQ(test, 0, scsi_check_passthrough(&sc, &failures)); scsi_failures_reset_retries(&failures); - scsi_build_sense(&sc, 0, UNIT_ATTENTION, 0x28, 0x0); + scsi_set_sense(&sc, 0, UNIT_ATTENTION, + NOT_READY_TO_READY_CHANGE_MEDIUM_MAY_HAVE_CHANGED); for (i = 0; i < SCSI_LIB_TEST_TOTAL_MAX_ALLOWED; i++) /* Retry since we under the total_allowed limit */ KUNIT_EXPECT_EQ(test, -EAGAIN, scsi_check_passthrough(&sc, @@ -308,7 +320,8 @@ static void scsi_lib_test_mixed_total(struct kunit *test) sc.result = DID_TIME_OUT << 16; /* Retry because this failure has a per failure limit */ KUNIT_EXPECT_EQ(test, -EAGAIN, scsi_check_passthrough(&sc, &failures)); - scsi_build_sense(&sc, 0, UNIT_ATTENTION, 0x29, 0x0); + scsi_set_sense(&sc, 0, UNIT_ATTENTION, + POWER_ON_RESET_OR_BUS_DEVICE_RESET_OCCURRED); /* total_allowed is now hit so no more retries */ KUNIT_EXPECT_EQ(test, 0, scsi_check_passthrough(&sc, &failures)); } diff --git a/drivers/scsi/scsi_logging.c b/drivers/scsi/scsi_logging.c index 3cd0d3074085..0a9a2f7c1966 100644 --- a/drivers/scsi/scsi_logging.c +++ b/drivers/scsi/scsi_logging.c @@ -238,29 +238,32 @@ EXPORT_SYMBOL(scsi_print_command); static size_t scsi_format_extd_sense(char *buffer, size_t buf_len, - unsigned char asc, unsigned char ascq) + const struct scsi_sense_hdr *sshdr) { size_t off = 0; const char *extd_sense_fmt = NULL; - const char *extd_sense_str = scsi_extd_sense_format(asc, ascq, - &extd_sense_fmt); + const char *extd_sense_str = + scsi_extd_sense_format(sshdr, &extd_sense_fmt); if (extd_sense_str) { off = scnprintf(buffer, buf_len, "Add. Sense: %s", extd_sense_str); if (extd_sense_fmt) off += scnprintf(buffer + off, buf_len - off, - "(%s%x)", extd_sense_fmt, ascq); + "(%s%x)", extd_sense_fmt, + scsi_sense_ascq(sshdr)); } else { - if (asc >= 0x80) + if (scsi_sense_asc(sshdr) >= 0x80) off = scnprintf(buffer, buf_len, "<>"); off += scnprintf(buffer + off, buf_len - off, - "ASC=0x%x ", asc); - if (ascq >= 0x80) + "ASC=0x%x ", + scsi_sense_asc(sshdr)); + if (scsi_sense_ascq(sshdr) >= 0x80) off += scnprintf(buffer + off, buf_len - off, "<>"); off += scnprintf(buffer + off, buf_len - off, - "ASCQ=0x%x ", ascq); + "ASCQ=0x%x ", + scsi_sense_ascq(sshdr)); } return off; } @@ -333,8 +336,7 @@ scsi_log_print_sense_hdr(const struct scsi_device *sdev, const char *name, if (!logbuf) return; off = sdev_format_header(logbuf, logbuf_len, name, tag); - off += scsi_format_extd_sense(logbuf + off, logbuf_len - off, - sshdr->asc, sshdr->ascq); + off += scsi_format_extd_sense(logbuf + off, logbuf_len - off, sshdr); dev_printk(KERN_INFO, &sdev->sdev_gendev, "%s", logbuf); scsi_log_release_buffer(logbuf); } diff --git a/drivers/scsi/scsi_proc.c b/drivers/scsi/scsi_proc.c index 1799dcae775c..fdc355d783da 100644 --- a/drivers/scsi/scsi_proc.c +++ b/drivers/scsi/scsi_proc.c @@ -28,6 +28,7 @@ #include #include #include +#include #include #include @@ -74,7 +75,7 @@ static ssize_t proc_scsi_host_write(struct file *file, const char __user *buf, if (!shost->hostt->write_info) return -EINVAL; - page = (char *)__get_free_page(GFP_KERNEL); + page = kmalloc(PAGE_SIZE, GFP_KERNEL); if (page) { ret = -EFAULT; if (copy_from_user(page, buf, count)) @@ -82,7 +83,7 @@ static ssize_t proc_scsi_host_write(struct file *file, const char __user *buf, ret = shost->hostt->write_info(shost, page, count); } out: - free_page((unsigned long)page); + kfree(page); return ret; } @@ -412,7 +413,7 @@ static ssize_t proc_scsi_write(struct file *file, const char __user *buf, if (!buf || length > PAGE_SIZE) return -EINVAL; - buffer = (char *)__get_free_page(GFP_KERNEL); + buffer = kmalloc(PAGE_SIZE, GFP_KERNEL); if (!buffer) return -ENOMEM; @@ -467,7 +468,7 @@ static ssize_t proc_scsi_write(struct file *file, const char __user *buf, err = length; out: - free_page((unsigned long)buffer); + kfree(buffer); return err; } diff --git a/drivers/scsi/scsi_scan.c b/drivers/scsi/scsi_scan.c index 0f0f243c2561..8aae12fd38f3 100644 --- a/drivers/scsi/scsi_scan.c +++ b/drivers/scsi/scsi_scan.c @@ -397,11 +397,11 @@ static void scsi_target_destroy(struct scsi_target *starget) BUG_ON(starget->state == STARGET_DEL); starget->state = STARGET_DEL; transport_destroy_device(dev); - spin_lock_irqsave(shost->host_lock, flags); + spin_lock_irqsave(&shost->host_lock, flags); if (shost->hostt->target_destroy) shost->hostt->target_destroy(starget); list_del_init(&starget->siblings); - spin_unlock_irqrestore(shost->host_lock, flags); + spin_unlock_irqrestore(&shost->host_lock, flags); put_device(dev); } @@ -524,14 +524,14 @@ static struct scsi_target *scsi_alloc_target(struct device *parent, starget->scsi_level = SCSI_2; starget->max_target_blocked = SCSI_DEFAULT_TARGET_BLOCKED; retry: - spin_lock_irqsave(shost->host_lock, flags); + spin_lock_irqsave(&shost->host_lock, flags); found_target = __scsi_find_target(parent, channel, id); if (found_target) goto found; list_add_tail(&starget->siblings, &shost->__targets); - spin_unlock_irqrestore(shost->host_lock, flags); + spin_unlock_irqrestore(&shost->host_lock, flags); /* allocate and add */ transport_setup_device(dev); if (shost->hostt->target_alloc) { @@ -558,7 +558,7 @@ static struct scsi_target *scsi_alloc_target(struct device *parent, */ ref_got = kref_get_unless_zero(&found_target->reap_ref); - spin_unlock_irqrestore(shost->host_lock, flags); + spin_unlock_irqrestore(&shost->host_lock, flags); if (ref_got) { put_device(dev); return found_target; @@ -652,19 +652,18 @@ static int scsi_probe_lun(struct scsi_device *sdev, unsigned char *inq_result, int pass, count, result, resid; struct scsi_failure failure_defs[] = { /* - * not-ready to ready transition [asc/ascq=0x28/0x0] or - * power-on, reset [asc/ascq=0x29/0x0], continue. INQUIRY - * should not yield UNIT_ATTENTION but many buggy devices do - * so anyway. + * not-ready to ready transition or power-on, reset, continue. + * INQUIRY should not yield UNIT_ATTENTION but many buggy + * devices do so anyway. */ { - .sense = UNIT_ATTENTION, - .asc = 0x28, + .sense_key = UNIT_ATTENTION, + .sense_code = NOT_READY_TO_READY_CHANGE_MEDIUM_MAY_HAVE_CHANGED, .result = SAM_STAT_CHECK_CONDITION, }, { - .sense = UNIT_ATTENTION, - .asc = 0x29, + .sense_key = UNIT_ATTENTION, + .sense_code = POWER_ON_RESET_OR_BUS_DEVICE_RESET_OCCURRED, .result = SAM_STAT_CHECK_CONDITION, }, { @@ -1457,14 +1456,13 @@ static int scsi_report_lun_scan(struct Scsi_Host *shost, struct scsi_device *sdev; struct scsi_failure failure_defs[] = { { - .sense = UNIT_ATTENTION, - .asc = SCMD_FAILURE_ASC_ANY, - .ascq = SCMD_FAILURE_ASCQ_ANY, + .sense_key = UNIT_ATTENTION, + .sense_code = SCMD_FAILURE_SENSE_CODE_ANY, .result = SAM_STAT_CHECK_CONDITION, }, /* Fail all CCs except the UA above */ { - .sense = SCMD_FAILURE_SENSE_ANY, + .sense_key = SCMD_FAILURE_SENSE_KEY_ANY, .result = SAM_STAT_CHECK_CONDITION, }, /* Retry any other errors not listed above */ @@ -2106,16 +2104,16 @@ void scsi_forget_host(struct Scsi_Host *shost) unsigned long flags; restart: - spin_lock_irqsave(shost->host_lock, flags); + spin_lock_irqsave(&shost->host_lock, flags); list_for_each_entry(sdev, &shost->__devices, siblings) { if (scsi_device_is_pseudo_dev(sdev) || sdev->sdev_state == SDEV_DEL) continue; - spin_unlock_irqrestore(shost->host_lock, flags); + spin_unlock_irqrestore(&shost->host_lock, flags); __scsi_remove_device(sdev); goto restart; } - spin_unlock_irqrestore(shost->host_lock, flags); + spin_unlock_irqrestore(&shost->host_lock, flags); /* * Remove the pseudo device last since it may be needed during removal diff --git a/drivers/scsi/scsi_sysfs.c b/drivers/scsi/scsi_sysfs.c index 9480432f650b..fe54792ed69e 100644 --- a/drivers/scsi/scsi_sysfs.c +++ b/drivers/scsi/scsi_sysfs.c @@ -214,7 +214,7 @@ store_shost_state(struct device *dev, struct device_attribute *attr, if (!state) return -EINVAL; - scoped_guard(spinlock_irq, shost->host_lock) + scoped_guard(spinlock_irq, &shost->host_lock) if (scsi_host_set_state(shost, state)) return -EINVAL; return count; @@ -352,7 +352,7 @@ store_shost_eh_deadline(struct device *dev, struct device_attribute *attr, return -EINVAL; } - spin_lock_irqsave(shost->host_lock, flags); + spin_lock_irqsave(&shost->host_lock, flags); if (scsi_host_in_recovery(shost)) ret = -EBUSY; else { @@ -363,7 +363,7 @@ store_shost_eh_deadline(struct device *dev, struct device_attribute *attr, ret = count; } - spin_unlock_irqrestore(shost->host_lock, flags); + spin_unlock_irqrestore(&shost->host_lock, flags); return ret; } @@ -459,11 +459,11 @@ static void scsi_device_dev_release(struct device *dev) parent = sdev->sdev_gendev.parent; - spin_lock_irqsave(sdev->host->host_lock, flags); + spin_lock_irqsave(&sdev->host->host_lock, flags); list_del(&sdev->siblings); list_del(&sdev->same_target_siblings); list_del(&sdev->starved_entry); - spin_unlock_irqrestore(sdev->host->host_lock, flags); + spin_unlock_irqrestore(&sdev->host->host_lock, flags); cancel_work_sync(&sdev->event_work); @@ -1547,7 +1547,7 @@ static void __scsi_remove_target(struct scsi_target *starget) unsigned long flags; struct scsi_device *sdev; - spin_lock_irqsave(shost->host_lock, flags); + spin_lock_irqsave(&shost->host_lock, flags); restart: list_for_each_entry(sdev, &shost->__devices, siblings) { /* @@ -1563,13 +1563,13 @@ static void __scsi_remove_target(struct scsi_target *starget) sdev->sdev_state == SDEV_CANCEL || !get_device(&sdev->sdev_gendev)) continue; - spin_unlock_irqrestore(shost->host_lock, flags); + spin_unlock_irqrestore(&shost->host_lock, flags); scsi_remove_device(sdev); put_device(&sdev->sdev_gendev); - spin_lock_irqsave(shost->host_lock, flags); + spin_lock_irqsave(&shost->host_lock, flags); goto restart; } - spin_unlock_irqrestore(shost->host_lock, flags); + spin_unlock_irqrestore(&shost->host_lock, flags); } /** @@ -1587,7 +1587,7 @@ void scsi_remove_target(struct device *dev) unsigned long flags; restart: - spin_lock_irqsave(shost->host_lock, flags); + spin_lock_irqsave(&shost->host_lock, flags); list_for_each_entry(starget, &shost->__targets, siblings) { if (starget->state == STARGET_DEL || starget->state == STARGET_REMOVE || @@ -1599,13 +1599,13 @@ void scsi_remove_target(struct device *dev) starget->state = STARGET_CREATED_REMOVE; else starget->state = STARGET_REMOVE; - spin_unlock_irqrestore(shost->host_lock, flags); + spin_unlock_irqrestore(&shost->host_lock, flags); __scsi_remove_target(starget); scsi_target_reap(starget); goto restart; } } - spin_unlock_irqrestore(shost->host_lock, flags); + spin_unlock_irqrestore(&shost->host_lock, flags); } EXPORT_SYMBOL(scsi_remove_target); @@ -1710,10 +1710,10 @@ void scsi_sysfs_device_initialize(struct scsi_device *sdev) sdev->lun_in_cdb = 1; transport_setup_device(&sdev->sdev_gendev); - spin_lock_irqsave(shost->host_lock, flags); + spin_lock_irqsave(&shost->host_lock, flags); list_add_tail(&sdev->same_target_siblings, &starget->devices); list_add_tail(&sdev->siblings, &shost->__devices); - spin_unlock_irqrestore(shost->host_lock, flags); + spin_unlock_irqrestore(&shost->host_lock, flags); /* * device can now only be removed via __scsi_remove_device() so hold * the target. Target will be held in CREATED state until something diff --git a/drivers/scsi/scsi_transport_fc.c b/drivers/scsi/scsi_transport_fc.c index 173ed6373f04..bec6ca38375b 100644 --- a/drivers/scsi/scsi_transport_fc.c +++ b/drivers/scsi/scsi_transport_fc.c @@ -645,19 +645,19 @@ fc_find_rport_by_wwpn(struct Scsi_Host *shost, u64 wwpn) struct fc_rport *rport; unsigned long flags; - spin_lock_irqsave(shost->host_lock, flags); + spin_lock_irqsave(&shost->host_lock, flags); list_for_each_entry(rport, &fc_host_rports(shost), peers) { if (rport->port_state != FC_PORTSTATE_ONLINE) continue; if (rport->port_name == wwpn) { - spin_unlock_irqrestore(shost->host_lock, flags); + spin_unlock_irqrestore(&shost->host_lock, flags); return rport; } } - spin_unlock_irqrestore(shost->host_lock, flags); + spin_unlock_irqrestore(&shost->host_lock, flags); return NULL; } EXPORT_SYMBOL(fc_find_rport_by_wwpn); @@ -1718,13 +1718,13 @@ store_fc_vport_delete(struct device *dev, struct device_attribute *attr, struct Scsi_Host *shost = vport_to_shost(vport); unsigned long flags; - spin_lock_irqsave(shost->host_lock, flags); + spin_lock_irqsave(&shost->host_lock, flags); if (vport->flags & (FC_VPORT_DEL | FC_VPORT_CREATING)) { - spin_unlock_irqrestore(shost->host_lock, flags); + spin_unlock_irqrestore(&shost->host_lock, flags); return -EBUSY; } vport->flags |= FC_VPORT_DELETING; - spin_unlock_irqrestore(shost->host_lock, flags); + spin_unlock_irqrestore(&shost->host_lock, flags); fc_queue_work(shost, &vport->vport_delete_work); return count; @@ -2052,7 +2052,7 @@ store_fc_private_host_tgtid_bind_type(struct device *dev, /* if changing bind type, purge all unused consistent bindings */ if (val != fc_host_tgtid_bind_type(shost)) { - spin_lock_irqsave(shost->host_lock, flags); + spin_lock_irqsave(&shost->host_lock, flags); while (!list_empty(&fc_host_rport_bindings(shost))) { get_list_head_entry(rport, &fc_host_rport_bindings(shost), peers); @@ -2060,7 +2060,7 @@ store_fc_private_host_tgtid_bind_type(struct device *dev, rport->port_state = FC_PORTSTATE_DELETED; fc_queue_work(shost, &rport->rport_delete_work); } - spin_unlock_irqrestore(shost->host_lock, flags); + spin_unlock_irqrestore(&shost->host_lock, flags); } fc_host_tgtid_bind_type(shost) = val; @@ -2107,10 +2107,10 @@ store_fc_private_host_dev_loss_tmo(struct device *dev, return rc; fc_host_dev_loss_tmo(shost) = val; - spin_lock_irqsave(shost->host_lock, flags); + spin_lock_irqsave(&shost->host_lock, flags); list_for_each_entry(rport, &fc_host->rports, peers) fc_rport_set_dev_loss_tmo(rport, val); - spin_unlock_irqrestore(shost->host_lock, flags); + spin_unlock_irqrestore(&shost->host_lock, flags); return count; } @@ -2417,7 +2417,7 @@ store_fc_host_vport_delete(struct device *dev, struct device_attribute *attr, if (stat) return stat; - spin_lock_irqsave(shost->host_lock, flags); + spin_lock_irqsave(&shost->host_lock, flags); match = 0; /* we only allow support on Channel 0 !!! */ list_for_each_entry(vport, &fc_host->vports, peers) { @@ -2430,7 +2430,7 @@ store_fc_host_vport_delete(struct device *dev, struct device_attribute *attr, break; } } - spin_unlock_irqrestore(shost->host_lock, flags); + spin_unlock_irqrestore(&shost->host_lock, flags); if (!match) return -ENODEV; @@ -2590,7 +2590,7 @@ fc_user_scan_tgt(struct Scsi_Host *shost, uint channel, uint id, u64 lun) struct fc_rport *rport; unsigned long flags; - spin_lock_irqsave(shost->host_lock, flags); + spin_lock_irqsave(&shost->host_lock, flags); list_for_each_entry(rport, &fc_host_rports(shost), peers) { if (rport->scsi_target_id == -1) @@ -2602,14 +2602,14 @@ fc_user_scan_tgt(struct Scsi_Host *shost, uint channel, uint id, u64 lun) if ((channel == rport->channel) && (id == rport->scsi_target_id)) { - spin_unlock_irqrestore(shost->host_lock, flags); + spin_unlock_irqrestore(&shost->host_lock, flags); scsi_scan_target(&rport->dev, channel, id, lun, SCSI_SCAN_MANUAL); return; } } - spin_unlock_irqrestore(shost->host_lock, flags); + spin_unlock_irqrestore(&shost->host_lock, flags); } /* @@ -2922,7 +2922,7 @@ fc_remove_host(struct Scsi_Host *shost) struct fc_host_attrs *fc_host = shost_to_fc_host(shost); unsigned long flags; - spin_lock_irqsave(shost->host_lock, flags); + spin_lock_irqsave(&shost->host_lock, flags); /* Remove any vports */ list_for_each_entry_safe(vport, next_vport, &fc_host->vports, peers) { @@ -2945,7 +2945,7 @@ fc_remove_host(struct Scsi_Host *shost) fc_queue_work(shost, &rport->rport_delete_work); } - spin_unlock_irqrestore(shost->host_lock, flags); + spin_unlock_irqrestore(&shost->host_lock, flags); /* flush all scan work items */ scsi_flush_work(shost); @@ -3021,18 +3021,18 @@ fc_rport_final_delete(struct work_struct *work) * only when rmmod'ing the LLDD and we're asking for * immediate termination of the rports */ - spin_lock_irqsave(shost->host_lock, flags); + spin_lock_irqsave(&shost->host_lock, flags); if (rport->flags & FC_RPORT_DEVLOSS_PENDING) { - spin_unlock_irqrestore(shost->host_lock, flags); + spin_unlock_irqrestore(&shost->host_lock, flags); if (!cancel_delayed_work(&rport->fail_io_work)) fc_flush_devloss(shost, rport); if (!cancel_delayed_work(&rport->dev_loss_work)) fc_flush_devloss(shost, rport); cancel_work_sync(&rport->scan_work); - spin_lock_irqsave(shost->host_lock, flags); + spin_lock_irqsave(&shost->host_lock, flags); rport->flags &= ~FC_RPORT_DEVLOSS_PENDING; } - spin_unlock_irqrestore(shost->host_lock, flags); + spin_unlock_irqrestore(&shost->host_lock, flags); /* Delete SCSI target and sdevs */ if (rport->scsi_target_id != -1) @@ -3045,13 +3045,13 @@ fc_rport_final_delete(struct work_struct *work) * Avoid this call if we already called it when we preserved the * rport for the binding. */ - spin_lock_irqsave(shost->host_lock, flags); + spin_lock_irqsave(&shost->host_lock, flags); if (!(rport->flags & FC_RPORT_DEVLOSS_CALLBK_DONE) && (i->f->dev_loss_tmo_callbk)) { rport->flags |= FC_RPORT_DEVLOSS_CALLBK_DONE; do_callback = 1; } - spin_unlock_irqrestore(shost->host_lock, flags); + spin_unlock_irqrestore(&shost->host_lock, flags); if (do_callback) i->f->dev_loss_tmo_callbk(rport); @@ -3123,7 +3123,7 @@ fc_remote_port_create(struct Scsi_Host *shost, int channel, INIT_WORK(&rport->stgt_delete_work, fc_starget_delete); INIT_WORK(&rport->rport_delete_work, fc_rport_final_delete); - spin_lock_irqsave(shost->host_lock, flags); + spin_lock_irqsave(&shost->host_lock, flags); rport->number = fc_host->next_rport_number++; if ((rport->roles & FC_PORT_ROLE_FCP_TARGET) || @@ -3134,7 +3134,7 @@ fc_remote_port_create(struct Scsi_Host *shost, int channel, list_add_tail(&rport->peers, &fc_host->rports); scsi_host_get(shost); /* for fc_host->rport list */ - spin_unlock_irqrestore(shost->host_lock, flags); + spin_unlock_irqrestore(&shost->host_lock, flags); rport->devloss_work_q = alloc_workqueue("fc_dl_%d_%d", WQ_PERCPU, 0, shost->host_no, rport->number); @@ -3144,10 +3144,10 @@ fc_remote_port_create(struct Scsi_Host *shost, int channel, * Note that we have not yet called device_initialize() / get_device() * Cannot reclaim incremented rport->number because we released host_lock */ - spin_lock_irqsave(shost->host_lock, flags); + spin_lock_irqsave(&shost->host_lock, flags); list_del(&rport->peers); scsi_host_put(shost); /* for fc_host->rport list */ - spin_unlock_irqrestore(shost->host_lock, flags); + spin_unlock_irqrestore(&shost->host_lock, flags); kfree(rport); return NULL; } @@ -3181,10 +3181,10 @@ fc_remote_port_create(struct Scsi_Host *shost, int channel, delete_rport: transport_destroy_device(dev); - spin_lock_irqsave(shost->host_lock, flags); + spin_lock_irqsave(&shost->host_lock, flags); list_del(&rport->peers); scsi_host_put(shost); /* for fc_host->rport list */ - spin_unlock_irqrestore(shost->host_lock, flags); + spin_unlock_irqrestore(&shost->host_lock, flags); put_device(dev->parent); kfree(rport); return NULL; @@ -3246,7 +3246,7 @@ fc_remote_port_add(struct Scsi_Host *shost, int channel, * deleted, but we've held off the real delete while the target * is in a "blocked" state. */ - spin_lock_irqsave(shost->host_lock, flags); + spin_lock_irqsave(&shost->host_lock, flags); list_for_each_entry(rport, &fc_host->rports, peers) { @@ -3281,7 +3281,7 @@ fc_remote_port_add(struct Scsi_Host *shost, int channel, rport->port_state = FC_PORTSTATE_ONLINE; rport->roles = ids->roles; - spin_unlock_irqrestore(shost->host_lock, flags); + spin_unlock_irqrestore(&shost->host_lock, flags); if (fci->f->dd_fcrport_size) memset(rport->dd_data, 0, @@ -3318,24 +3318,24 @@ fc_remote_port_add(struct Scsi_Host *shost, int channel, if (!cancel_delayed_work(&rport->dev_loss_work)) fc_flush_devloss(shost, rport); - spin_lock_irqsave(shost->host_lock, flags); + spin_lock_irqsave(&shost->host_lock, flags); rport->flags &= ~(FC_RPORT_FAST_FAIL_TIMEDOUT | FC_RPORT_DEVLOSS_PENDING | FC_RPORT_DEVLOSS_CALLBK_DONE); - spin_unlock_irqrestore(shost->host_lock, flags); + spin_unlock_irqrestore(&shost->host_lock, flags); /* if target, initiate a scan */ if (rport->scsi_target_id != -1) { scsi_target_unblock(&rport->dev, SDEV_RUNNING); - spin_lock_irqsave(shost->host_lock, + spin_lock_irqsave(&shost->host_lock, flags); rport->flags |= FC_RPORT_SCAN_PENDING; scsi_queue_work(shost, &rport->scan_work); - spin_unlock_irqrestore(shost->host_lock, + spin_unlock_irqrestore(&shost->host_lock, flags); } @@ -3394,14 +3394,14 @@ fc_remote_port_add(struct Scsi_Host *shost, int channel, if (fci->f->dd_fcrport_size) memset(rport->dd_data, 0, fci->f->dd_fcrport_size); - spin_unlock_irqrestore(shost->host_lock, flags); + spin_unlock_irqrestore(&shost->host_lock, flags); fc_remote_port_rolechg(rport, ids->roles); return rport; } } - spin_unlock_irqrestore(shost->host_lock, flags); + spin_unlock_irqrestore(&shost->host_lock, flags); /* No consistent binding found - create new remote port entry */ rport = fc_remote_port_create(shost, channel, ids); @@ -3478,11 +3478,11 @@ fc_remote_port_delete(struct fc_rport *rport) * there's still a scan pending. */ - spin_lock_irqsave(shost->host_lock, flags); + spin_lock_irqsave(&shost->host_lock, flags); if ((rport->port_state != FC_PORTSTATE_ONLINE) && (rport->port_state != FC_PORTSTATE_MARGINAL)) { - spin_unlock_irqrestore(shost->host_lock, flags); + spin_unlock_irqrestore(&shost->host_lock, flags); return; } @@ -3503,7 +3503,7 @@ fc_remote_port_delete(struct fc_rport *rport) rport->flags |= FC_RPORT_DEVLOSS_PENDING; - spin_unlock_irqrestore(shost->host_lock, flags); + spin_unlock_irqrestore(&shost->host_lock, flags); scsi_block_targets(shost, &rport->dev); @@ -3547,7 +3547,7 @@ fc_remote_port_rolechg(struct fc_rport *rport, u32 roles) unsigned long flags; int create = 0; - spin_lock_irqsave(shost->host_lock, flags); + spin_lock_irqsave(&shost->host_lock, flags); if (roles & FC_PORT_ROLE_FCP_TARGET) { if (rport->scsi_target_id == -1) { rport->scsi_target_id = fc_host->next_target_id++; @@ -3558,7 +3558,7 @@ fc_remote_port_rolechg(struct fc_rport *rport, u32 roles) rport->roles = roles; - spin_unlock_irqrestore(shost->host_lock, flags); + spin_unlock_irqrestore(&shost->host_lock, flags); if (create) { /* @@ -3578,21 +3578,21 @@ fc_remote_port_rolechg(struct fc_rport *rport, u32 roles) if (!cancel_delayed_work(&rport->dev_loss_work)) fc_flush_devloss(shost, rport); - spin_lock_irqsave(shost->host_lock, flags); + spin_lock_irqsave(&shost->host_lock, flags); rport->flags &= ~(FC_RPORT_FAST_FAIL_TIMEDOUT | FC_RPORT_DEVLOSS_PENDING | FC_RPORT_DEVLOSS_CALLBK_DONE); - spin_unlock_irqrestore(shost->host_lock, flags); + spin_unlock_irqrestore(&shost->host_lock, flags); /* ensure any stgt delete functions are done */ fc_flush_work(shost); scsi_target_unblock(&rport->dev, SDEV_RUNNING); /* initiate a scan of the target */ - spin_lock_irqsave(shost->host_lock, flags); + spin_lock_irqsave(&shost->host_lock, flags); rport->flags |= FC_RPORT_SCAN_PENDING; scsi_queue_work(shost, &rport->scan_work); - spin_unlock_irqrestore(shost->host_lock, flags); + spin_unlock_irqrestore(&shost->host_lock, flags); } } EXPORT_SYMBOL(fc_remote_port_rolechg); @@ -3615,7 +3615,7 @@ fc_timeout_deleted_rport(struct work_struct *work) unsigned long flags; int do_callback = 0; - spin_lock_irqsave(shost->host_lock, flags); + spin_lock_irqsave(&shost->host_lock, flags); rport->flags &= ~FC_RPORT_DEVLOSS_PENDING; @@ -3631,7 +3631,7 @@ fc_timeout_deleted_rport(struct work_struct *work) dev_printk(KERN_ERR, &rport->dev, "blocked FC remote port time out: no longer" " a FCP target, removing starget\n"); - spin_unlock_irqrestore(shost->host_lock, flags); + spin_unlock_irqrestore(&shost->host_lock, flags); scsi_target_unblock(&rport->dev, SDEV_TRANSPORT_OFFLINE); fc_queue_work(shost, &rport->stgt_delete_work); return; @@ -3639,7 +3639,7 @@ fc_timeout_deleted_rport(struct work_struct *work) /* NOOP state - we're flushing workq's */ if (rport->port_state != FC_PORTSTATE_BLOCKED) { - spin_unlock_irqrestore(shost->host_lock, flags); + spin_unlock_irqrestore(&shost->host_lock, flags); dev_printk(KERN_ERR, &rport->dev, "blocked FC remote port time out: leaving" " rport%s alone\n", @@ -3656,7 +3656,7 @@ fc_timeout_deleted_rport(struct work_struct *work) " rport%s\n", (rport->scsi_target_id != -1) ? " and starget" : ""); fc_queue_work(shost, &rport->rport_delete_work); - spin_unlock_irqrestore(shost->host_lock, flags); + spin_unlock_irqrestore(&shost->host_lock, flags); return; } @@ -3686,10 +3686,10 @@ fc_timeout_deleted_rport(struct work_struct *work) * item to teardown the starget. (FCOE libFC folks prefer this * and to have the rport_port_id still set when it's done). */ - spin_unlock_irqrestore(shost->host_lock, flags); + spin_unlock_irqrestore(&shost->host_lock, flags); fc_terminate_rport_io(rport); - spin_lock_irqsave(shost->host_lock, flags); + spin_lock_irqsave(&shost->host_lock, flags); if (rport->port_state == FC_PORTSTATE_NOTPRESENT) { /* still missing */ @@ -3722,7 +3722,7 @@ fc_timeout_deleted_rport(struct work_struct *work) do_callback = 1; } - spin_unlock_irqrestore(shost->host_lock, flags); + spin_unlock_irqrestore(&shost->host_lock, flags); /* * Notify the driver that the rport is now dead. The LLDD will @@ -3777,9 +3777,9 @@ fc_scsi_scan_rport(struct work_struct *work) SCSI_SCAN_RESCAN); } - spin_lock_irqsave(shost->host_lock, flags); + spin_lock_irqsave(&shost->host_lock, flags); rport->flags &= ~FC_RPORT_SCAN_PENDING; - spin_unlock_irqrestore(shost->host_lock, flags); + spin_unlock_irqrestore(&shost->host_lock, flags); } /** @@ -3801,14 +3801,14 @@ int fc_block_rport(struct fc_rport *rport) struct Scsi_Host *shost = rport_to_shost(rport); unsigned long flags; - spin_lock_irqsave(shost->host_lock, flags); + spin_lock_irqsave(&shost->host_lock, flags); while (rport->port_state == FC_PORTSTATE_BLOCKED && !(rport->flags & FC_RPORT_FAST_FAIL_TIMEDOUT)) { - spin_unlock_irqrestore(shost->host_lock, flags); + spin_unlock_irqrestore(&shost->host_lock, flags); msleep(1000); - spin_lock_irqsave(shost->host_lock, flags); + spin_lock_irqsave(&shost->host_lock, flags); } - spin_unlock_irqrestore(shost->host_lock, flags); + spin_unlock_irqrestore(&shost->host_lock, flags); if (rport->flags & FC_RPORT_FAST_FAIL_TIMEDOUT) return FAST_IO_FAIL; @@ -3916,10 +3916,10 @@ fc_vport_setup(struct Scsi_Host *shost, int channel, struct device *pdev, vport->flags = FC_VPORT_CREATING; INIT_WORK(&vport->vport_delete_work, fc_vport_sched_delete); - spin_lock_irqsave(shost->host_lock, flags); + spin_lock_irqsave(&shost->host_lock, flags); if (fc_host->npiv_vports_inuse >= fc_host->max_npiv_vports) { - spin_unlock_irqrestore(shost->host_lock, flags); + spin_unlock_irqrestore(&shost->host_lock, flags); kfree(vport); return -ENOSPC; } @@ -3928,7 +3928,7 @@ fc_vport_setup(struct Scsi_Host *shost, int channel, struct device *pdev, list_add_tail(&vport->peers, &fc_host->vports); scsi_host_get(shost); /* for fc_host->vport list */ - spin_unlock_irqrestore(shost->host_lock, flags); + spin_unlock_irqrestore(&shost->host_lock, flags); dev = &vport->dev; device_initialize(dev); /* takes self reference */ @@ -3965,9 +3965,9 @@ fc_vport_setup(struct Scsi_Host *shost, int channel, struct device *pdev, "%s, err=%d\n", __func__, dev_name(dev), error); } - spin_lock_irqsave(shost->host_lock, flags); + spin_lock_irqsave(&shost->host_lock, flags); vport->flags &= ~FC_VPORT_CREATING; - spin_unlock_irqrestore(shost->host_lock, flags); + spin_unlock_irqrestore(&shost->host_lock, flags); dev_printk(KERN_NOTICE, pdev, "%s created via shost%d channel %d\n", dev_name(dev), @@ -3982,11 +3982,11 @@ fc_vport_setup(struct Scsi_Host *shost, int channel, struct device *pdev, device_del(dev); delete_vport: transport_destroy_device(dev); - spin_lock_irqsave(shost->host_lock, flags); + spin_lock_irqsave(&shost->host_lock, flags); list_del(&vport->peers); scsi_host_put(shost); /* for fc_host->vport list */ fc_host->npiv_vports_inuse--; - spin_unlock_irqrestore(shost->host_lock, flags); + spin_unlock_irqrestore(&shost->host_lock, flags); put_device(dev->parent); kfree(vport); @@ -4041,7 +4041,7 @@ fc_vport_terminate(struct fc_vport *vport) else stat = -ENOENT; - spin_lock_irqsave(shost->host_lock, flags); + spin_lock_irqsave(&shost->host_lock, flags); vport->flags &= ~FC_VPORT_DELETING; if (!stat) { vport->flags |= FC_VPORT_DELETED; @@ -4049,7 +4049,7 @@ fc_vport_terminate(struct fc_vport *vport) fc_host->npiv_vports_inuse--; scsi_host_put(shost); /* for fc_host->vport list */ } - spin_unlock_irqrestore(shost->host_lock, flags); + spin_unlock_irqrestore(&shost->host_lock, flags); if (stat) return stat; @@ -4345,7 +4345,8 @@ fc_bsg_hostadd(struct Scsi_Host *shost, struct fc_host_attrs *fc_host) scsi_init_limits(shost, &lim); lim.max_segments = min_not_zero(lim.max_segments, i->f->max_bsg_segments); q = bsg_setup_queue(dev, bsg_name, &lim, fc_bsg_dispatch, - fc_bsg_job_timeout, i->f->dd_bsg_size); + fc_bsg_job_timeout, i->f->dd_bsg_size, + SCSI_SENSE_BUFFERSIZE); if (IS_ERR(q)) { dev_err(dev, "fc_host%d: bsg interface failed to initialize - setup queue\n", @@ -4378,7 +4379,8 @@ fc_bsg_rportadd(struct Scsi_Host *shost, struct fc_rport *rport) scsi_init_limits(shost, &lim); lim.max_segments = min_not_zero(lim.max_segments, i->f->max_bsg_segments); q = bsg_setup_queue(dev, dev_name(dev), &lim, fc_bsg_dispatch_prep, - fc_bsg_job_timeout, i->f->dd_bsg_size); + fc_bsg_job_timeout, i->f->dd_bsg_size, + SCSI_SENSE_BUFFERSIZE); if (IS_ERR(q)) { dev_err(dev, "failed to setup bsg queue\n"); return PTR_ERR(q); diff --git a/drivers/scsi/scsi_transport_iscsi.c b/drivers/scsi/scsi_transport_iscsi.c index 8aa76f813bcd..b094af7c997e 100644 --- a/drivers/scsi/scsi_transport_iscsi.c +++ b/drivers/scsi/scsi_transport_iscsi.c @@ -1545,7 +1545,7 @@ iscsi_bsg_host_add(struct Scsi_Host *shost, struct iscsi_cls_host *ihost) snprintf(bsg_name, sizeof(bsg_name), "iscsi_host%d", shost->host_no); scsi_init_limits(shost, &lim); q = bsg_setup_queue(dev, bsg_name, &lim, iscsi_bsg_host_dispatch, NULL, - 0); + 0, SCSI_SENSE_BUFFERSIZE); if (IS_ERR(q)) { shost_printk(KERN_ERR, shost, "bsg interface failed to " "initialize - no request queue\n"); @@ -2243,6 +2243,7 @@ static void iscsi_ep_disconnect(struct iscsi_cls_conn *conn, bool is_active) static void iscsi_if_disconnect_bound_ep(struct iscsi_cls_conn *conn, struct iscsi_endpoint *ep, bool is_active) + __must_hold(&conn->ep_mutex) { /* Check if this was a conn error and the kernel took ownership */ spin_lock_irq(&conn->lock); diff --git a/drivers/scsi/scsi_transport_sas.c b/drivers/scsi/scsi_transport_sas.c index d689b9ed08a6..a825966f60e5 100644 --- a/drivers/scsi/scsi_transport_sas.c +++ b/drivers/scsi/scsi_transport_sas.c @@ -199,7 +199,8 @@ static int sas_bsg_initialize(struct Scsi_Host *shost, struct sas_rphy *rphy) if (rphy) { q = bsg_setup_queue(&rphy->dev, dev_name(&rphy->dev), NULL, - sas_smp_dispatch, NULL, 0); + sas_smp_dispatch, NULL, 0, + SCSI_SENSE_BUFFERSIZE); if (IS_ERR(q)) return PTR_ERR(q); rphy->q = q; @@ -208,7 +209,8 @@ static int sas_bsg_initialize(struct Scsi_Host *shost, struct sas_rphy *rphy) snprintf(name, sizeof(name), "sas_host%d", shost->host_no); q = bsg_setup_queue(&shost->shost_gendev, name, NULL, - sas_smp_dispatch, NULL, 0); + sas_smp_dispatch, NULL, 0, + SCSI_SENSE_BUFFERSIZE); if (IS_ERR(q)) return PTR_ERR(q); to_sas_host_attrs(shost)->q = q; diff --git a/drivers/scsi/scsi_transport_spi.c b/drivers/scsi/scsi_transport_spi.c index 3e3da8c2ff26..bd049d549244 100644 --- a/drivers/scsi/scsi_transport_spi.c +++ b/drivers/scsi/scsi_transport_spi.c @@ -112,9 +112,8 @@ static int spi_execute(struct scsi_device *sdev, const void *cmd, REQ_FAILFAST_DRIVER; struct scsi_failure failure_defs[] = { { - .sense = UNIT_ATTENTION, - .asc = SCMD_FAILURE_ASC_ANY, - .ascq = SCMD_FAILURE_ASCQ_ANY, + .sense_key = UNIT_ATTENTION, + .sense_code = SCMD_FAILURE_SENSE_CODE_ANY, .allowed = DV_RETRIES, .result = SAM_STAT_CHECK_CONDITION, }, @@ -680,10 +679,9 @@ spi_dv_device_echo_buffer(struct scsi_device *sdev, u8 *buffer, if (result || !scsi_device_online(sdev)) { scsi_device_set_state(sdev, SDEV_QUIESCE); - if (result > 0 && scsi_sense_valid(&sshdr) - && sshdr.sense_key == ILLEGAL_REQUEST - /* INVALID FIELD IN CDB */ - && sshdr.asc == 0x24 && sshdr.ascq == 0x00) + if (result > 0 && scsi_sense_valid(&sshdr) && + sshdr.sense_key == ILLEGAL_REQUEST && + sshdr.sense_code == INVALID_FIELD_IN_CDB) /* This would mean that the drive lied * to us about supporting an echo * buffer (unfortunately some Western diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c index a1b21ea14e54..b0d2542fd317 100644 --- a/drivers/scsi/sd.c +++ b/drivers/scsi/sd.c @@ -1786,8 +1786,7 @@ static int media_not_present(struct scsi_disk *sdkp, switch (sshdr->sense_key) { case UNIT_ATTENTION: case NOT_READY: - /* medium not present */ - if (sshdr->asc == 0x3A) { + if (scsi_sense_asc(sshdr) == ASC_MEDIUM_NOT_PRESENT) { set_media_not_present(sdkp); return 1; } @@ -1911,12 +1910,14 @@ static int sd_sync_cache(struct scsi_disk *sdkp) if (scsi_status_is_check_condition(res) && scsi_sense_valid(&sshdr)) { + u8 asc = scsi_sense_asc(&sshdr); + sd_print_sense_hdr(sdkp, &sshdr); /* we need to evaluate the error return */ - if (sshdr.asc == 0x3a || /* medium not present */ - sshdr.asc == 0x20 || /* invalid command */ - (sshdr.asc == 0x74 && sshdr.ascq == 0x71)) /* drive is password locked */ + if (asc == ASC_MEDIUM_NOT_PRESENT || + asc == ASC_INVALID_COMMAND_OP_CODE || + sshdr.sense_code == LU_ACCESS_NOT_AUTHORIZED) /* this is no error here */ return 0; @@ -1926,8 +1927,8 @@ static int sd_sync_cache(struct scsi_disk *sdkp) * this is called during shutdown or suspend so just * return success so those operations can proceed. */ - if ((sshdr.asc == 0x04 && sshdr.ascq == 0x04) || - sshdr.sense_key == ILLEGAL_REQUEST) + if (sshdr.sense_key == ILLEGAL_REQUEST || + sshdr.sense_code == LU_NOT_READY_FORMAT_IN_PROGRESS) return 0; } @@ -2015,7 +2016,9 @@ static int sd_scsi_to_pr_err(struct scsi_sense_hdr *sshdr, int result) return PR_STS_IOERR; if (sshdr->sense_key == ILLEGAL_REQUEST && - (sshdr->asc == 0x26 || sshdr->asc == 0x24)) + (scsi_sense_asc(sshdr) == + ASC_INVALID_FIELD_IN_PARAMETER_LIST || + scsi_sense_asc(sshdr) == ASC_INVALID_FIELD_IN_CDB)) return -EINVAL; fallthrough; @@ -2033,9 +2036,8 @@ static int sd_pr_in_command(struct block_device *bdev, u8 sa, u8 cmd[10] = { PERSISTENT_RESERVE_IN, sa }; struct scsi_failure failure_defs[] = { { - .sense = UNIT_ATTENTION, - .asc = SCMD_FAILURE_ASC_ANY, - .ascq = SCMD_FAILURE_ASCQ_ANY, + .sense_key = UNIT_ATTENTION, + .sense_code = SCMD_FAILURE_SENSE_CODE_ANY, .allowed = 5, .result = SAM_STAT_CHECK_CONDITION, }, @@ -2145,9 +2147,8 @@ static int sd_pr_out_command(struct block_device *bdev, u8 sa, u64 key, struct scsi_sense_hdr sshdr; struct scsi_failure failure_defs[] = { { - .sense = UNIT_ATTENTION, - .asc = SCMD_FAILURE_ASC_ANY, - .ascq = SCMD_FAILURE_ASCQ_ANY, + .sense_key = UNIT_ATTENTION, + .sense_code = SCMD_FAILURE_SENSE_CODE_ANY, .allowed = 5, .result = SAM_STAT_CHECK_CONDITION, }, @@ -2440,16 +2441,17 @@ static int sd_done(struct scsi_cmnd *SCpnt) memset(SCpnt->sense_buffer, 0, SCSI_SENSE_BUFFERSIZE); break; case ABORTED_COMMAND: - if (sshdr.asc == 0x10) /* DIF: Target detected corruption */ + if (scsi_sense_asc(&sshdr) == ASC_ID_CRC_OR_ECC_ERROR) /* DIF */ good_bytes = sd_completed_bytes(SCpnt); break; case ILLEGAL_REQUEST: - switch (sshdr.asc) { - case 0x10: /* DIX: Host detected corruption */ + switch (scsi_sense_asc(&sshdr)) { + case ASC_ID_CRC_OR_ECC_ERROR: + /* DIX */ good_bytes = sd_completed_bytes(SCpnt); break; - case 0x20: /* INVALID COMMAND OPCODE */ - case 0x24: /* INVALID FIELD IN CDB */ + case ASC_INVALID_COMMAND_OP_CODE: + case ASC_INVALID_FIELD_IN_CDB: switch (SCpnt->cmnd[0]) { case UNMAP: sd_disable_discard(sdkp); @@ -2494,15 +2496,15 @@ sd_spinup_disk(struct scsi_disk *sdkp) struct scsi_failure failure_defs[] = { /* Do not retry Medium Not Present */ { - .sense = UNIT_ATTENTION, - .asc = 0x3A, - .ascq = SCMD_FAILURE_ASCQ_ANY, + .sense_key = UNIT_ATTENTION, + .sense_code = + MEDIUM_NOT_PRESENT | SCMD_FAILURE_ASCQ_ANY, .result = SAM_STAT_CHECK_CONDITION, }, { - .sense = NOT_READY, - .asc = 0x3A, - .ascq = SCMD_FAILURE_ASCQ_ANY, + .sense_key = NOT_READY, + .sense_code = + MEDIUM_NOT_PRESENT | SCMD_FAILURE_ASCQ_ANY, .result = SAM_STAT_CHECK_CONDITION, }, /* Retry when scsi_status_is_good would return false 3 times */ @@ -2566,18 +2568,18 @@ sd_spinup_disk(struct scsi_disk *sdkp) break; if (sense_valid && sshdr.sense_key == NOT_READY) { - if (sshdr.asc == 4 && sshdr.ascq == 3) - break; /* manual intervention required */ - if (sshdr.asc == 4 && sshdr.ascq == 0xb) - break; /* standby */ - if (sshdr.asc == 4 && sshdr.ascq == 0xc) - break; /* unavailable */ - if (sshdr.asc == 4 && sshdr.ascq == 0x1b) - break; /* sanitize in progress */ - if (sshdr.asc == 4 && sshdr.ascq == 0x24) - break; /* depopulation in progress */ - if (sshdr.asc == 4 && sshdr.ascq == 0x25) - break; /* depopulation restoration in progress */ + switch (sshdr.sense_code) { + case LU_NOT_READY_MANUAL_INTERVENTION_REQUIRED: + case LU_NOT_ACCESSIBLE_TARGET_PORT_IN_STANDBY_STATE: + case LU_NOT_ACCESSIBLE_TARGET_PORT_IN_UNAVAILABLE_STATE: + case LU_NOT_READY_SANITIZE_IN_PROGRESS: + case DEPOPULATION_IN_PROGRESS: + case DEPOPULATION_RESTORATION_IN_PROGRESS: + goto out; + default: + break; + } + /* * Issue command to spin up drive when not ready */ @@ -2608,8 +2610,9 @@ sd_spinup_disk(struct scsi_disk *sdkp) * occur here. It's characteristic of these devices. */ } else if (sense_valid && - sshdr.sense_key == UNIT_ATTENTION && - sshdr.asc == 0x28) { + sshdr.sense_key == UNIT_ATTENTION && + scsi_sense_asc(&sshdr) == + ASC_NOT_READY_TO_READY_CHANGE_MEDIUM_MAY_HAVE_CHANGED) { if (!spintime) { spintime_expire = jiffies + 5 * HZ; spintime = 1; @@ -2628,6 +2631,7 @@ sd_spinup_disk(struct scsi_disk *sdkp) } while (spintime && time_before_eq(jiffies, spintime_expire)); +out: if (spintime) { if (scsi_status_is_good(the_result)) printk(KERN_CONT "ready\n"); @@ -2753,15 +2757,14 @@ static int read_capacity_16(struct scsi_disk *sdkp, struct scsi_device *sdp, sense_valid = scsi_sense_valid(&sshdr); if (sense_valid && sshdr.sense_key == ILLEGAL_REQUEST && - (sshdr.asc == 0x20 || sshdr.asc == 0x24) && - sshdr.ascq == 0x00) - /* Invalid Command Operation Code or - * Invalid Field in CDB, just retry - * silently with RC10 */ + (sshdr.sense_code == INVALID_COMMAND_OP_CODE || + sshdr.sense_code == INVALID_FIELD_IN_CDB)) + /* Just retry silently with RC10 */ return -EINVAL; if (sense_valid && sshdr.sense_key == UNIT_ATTENTION && - sshdr.asc == 0x29 && sshdr.ascq == 0x00) + sshdr.sense_code == + POWER_ON_RESET_OR_BUS_DEVICE_RESET_OCCURRED) /* Device reset might occur several times, * give it one more chance */ if (--reset_retries > 0) @@ -2817,19 +2820,19 @@ static int read_capacity_10(struct scsi_disk *sdkp, struct scsi_device *sdp, struct scsi_failure failure_defs[] = { /* Do not retry Medium Not Present */ { - .sense = UNIT_ATTENTION, - .asc = 0x3A, + .sense_key = UNIT_ATTENTION, + .sense_code = MEDIUM_NOT_PRESENT, .result = SAM_STAT_CHECK_CONDITION, }, { - .sense = NOT_READY, - .asc = 0x3A, + .sense_key = NOT_READY, + .sense_code = MEDIUM_NOT_PRESENT, .result = SAM_STAT_CHECK_CONDITION, }, /* Device reset might occur several times so retry a lot */ { - .sense = UNIT_ATTENTION, - .asc = 0x29, + .sense_key = UNIT_ATTENTION, + .sense_code = POWER_ON_RESET_OR_BUS_DEVICE_RESET_OCCURRED, .allowed = READ_CAPACITY_RETRIES_ON_RESET, .result = SAM_STAT_CHECK_CONDITION, }, @@ -3258,8 +3261,7 @@ sd_read_cache_type(struct scsi_disk *sdkp, unsigned char *buffer) bad_sense: if (res == -EIO && scsi_sense_valid(&sshdr) && sshdr.sense_key == ILLEGAL_REQUEST && - sshdr.asc == 0x24 && sshdr.ascq == 0x0) - /* Invalid field in CDB */ + sshdr.sense_code == INVALID_FIELD_IN_CDB) sd_first_printk(KERN_NOTICE, sdkp, "Cache data unavailable\n"); else sd_first_printk(KERN_ERR, sdkp, @@ -4159,23 +4161,20 @@ static int sd_start_stop_device(struct scsi_disk *sdkp, int start) struct scsi_failure failure_defs[] = { { /* Power on, reset, or bus device reset occurred */ - .sense = UNIT_ATTENTION, - .asc = 0x29, - .ascq = 0, + .sense_key = UNIT_ATTENTION, + .sense_code = POWER_ON_RESET_OR_BUS_DEVICE_RESET_OCCURRED, .result = SAM_STAT_CHECK_CONDITION, }, { /* Power on occurred */ - .sense = UNIT_ATTENTION, - .asc = 0x29, - .ascq = 1, + .sense_key = UNIT_ATTENTION, + .sense_code = POWER_ON_OCCURRED, .result = SAM_STAT_CHECK_CONDITION, }, { /* SCSI bus reset */ - .sense = UNIT_ATTENTION, - .asc = 0x29, - .ascq = 2, + .sense_key = UNIT_ATTENTION, + .sense_code = SCSI_BUS_RESET_OCCURRED, .result = SAM_STAT_CHECK_CONDITION, }, {} @@ -4207,8 +4206,7 @@ static int sd_start_stop_device(struct scsi_disk *sdkp, int start) sd_print_result(sdkp, "Start/Stop Unit failed", res); if (res > 0 && scsi_sense_valid(&sshdr)) { sd_print_sense_hdr(sdkp, &sshdr); - /* 0x3a is medium not present */ - if (sshdr.asc == 0x3a) + if (scsi_sense_asc(&sshdr) == ASC_MEDIUM_NOT_PRESENT) res = 0; } } diff --git a/drivers/scsi/sd_zbc.c b/drivers/scsi/sd_zbc.c index 56e455fb5add..8cbf171e6fab 100644 --- a/drivers/scsi/sd_zbc.c +++ b/drivers/scsi/sd_zbc.c @@ -369,7 +369,7 @@ unsigned int sd_zbc_complete(struct scsi_cmnd *cmd, unsigned int good_bytes, if (op_is_zone_mgmt(req_op(rq)) && result && sshdr->sense_key == ILLEGAL_REQUEST && - sshdr->asc == 0x24) { + scsi_sense_asc(sshdr) == ASC_INVALID_FIELD_IN_CDB) { /* * INVALID FIELD IN CDB error: a zone management command was * attempted on a conventional zone. Nothing to worry about, @@ -589,7 +589,7 @@ int sd_zbc_revalidate_zones(struct scsi_disk *sdkp) int sd_zbc_read_zones(struct scsi_disk *sdkp, struct queue_limits *lim, u8 buf[SD_BUF_SIZE]) { - unsigned int nr_zones; + u64 nr_zones; u32 zone_blocks = 0; int ret; @@ -621,6 +621,12 @@ int sd_zbc_read_zones(struct scsi_disk *sdkp, struct queue_limits *lim, goto err; nr_zones = round_up(sdkp->capacity, zone_blocks) >> ilog2(zone_blocks); + if (nr_zones > INT_MAX) { + sd_printk(KERN_ERR, sdkp, "Too many zones (%llu)\n", + nr_zones); + ret = -EINVAL; + goto err; + } sdkp->early_zone_info.nr_zones = nr_zones; sdkp->early_zone_info.zone_blocks = zone_blocks; diff --git a/drivers/scsi/sense_codes.h b/drivers/scsi/sense_codes.h index 805d4c13d070..c2eb1a9ec4c0 100644 --- a/drivers/scsi/sense_codes.h +++ b/drivers/scsi/sense_codes.h @@ -4,876 +4,1642 @@ * http://www.t10.org/lists/asc-num.txt [most recent: 20200817] */ -SENSE_CODE(0x0000, "No additional sense information") -SENSE_CODE(0x0001, "Filemark detected") -SENSE_CODE(0x0002, "End-of-partition/medium detected") -SENSE_CODE(0x0003, "Setmark detected") -SENSE_CODE(0x0004, "Beginning-of-partition/medium detected") -SENSE_CODE(0x0005, "End-of-data detected") -SENSE_CODE(0x0006, "I/O process terminated") -SENSE_CODE(0x0007, "Programmable early warning detected") -SENSE_CODE(0x0011, "Audio play operation in progress") -SENSE_CODE(0x0012, "Audio play operation paused") -SENSE_CODE(0x0013, "Audio play operation successfully completed") -SENSE_CODE(0x0014, "Audio play operation stopped due to error") -SENSE_CODE(0x0015, "No current audio status to return") -SENSE_CODE(0x0016, "Operation in progress") -SENSE_CODE(0x0017, "Cleaning requested") -SENSE_CODE(0x0018, "Erase operation in progress") -SENSE_CODE(0x0019, "Locate operation in progress") -SENSE_CODE(0x001A, "Rewind operation in progress") -SENSE_CODE(0x001B, "Set capacity operation in progress") -SENSE_CODE(0x001C, "Verify operation in progress") -SENSE_CODE(0x001D, "ATA pass through information available") -SENSE_CODE(0x001E, "Conflicting SA creation request") -SENSE_CODE(0x001F, "Logical unit transitioning to another power condition") -SENSE_CODE(0x0020, "Extended copy information available") -SENSE_CODE(0x0021, "Atomic command aborted due to ACA") -SENSE_CODE(0x0022, "Deferred microcode is pending") - -SENSE_CODE(0x0100, "No index/sector signal") - -SENSE_CODE(0x0200, "No seek complete") - -SENSE_CODE(0x0300, "Peripheral device write fault") -SENSE_CODE(0x0301, "No write current") -SENSE_CODE(0x0302, "Excessive write errors") - -SENSE_CODE(0x0400, "Logical unit not ready, cause not reportable") -SENSE_CODE(0x0401, "Logical unit is in process of becoming ready") -SENSE_CODE(0x0402, "Logical unit not ready, initializing command required") -SENSE_CODE(0x0403, "Logical unit not ready, manual intervention required") -SENSE_CODE(0x0404, "Logical unit not ready, format in progress") -SENSE_CODE(0x0405, "Logical unit not ready, rebuild in progress") -SENSE_CODE(0x0406, "Logical unit not ready, recalculation in progress") -SENSE_CODE(0x0407, "Logical unit not ready, operation in progress") -SENSE_CODE(0x0408, "Logical unit not ready, long write in progress") -SENSE_CODE(0x0409, "Logical unit not ready, self-test in progress") -SENSE_CODE(0x040A, "Logical unit not accessible, asymmetric access state transition") -SENSE_CODE(0x040B, "Logical unit not accessible, target port in standby state") -SENSE_CODE(0x040C, "Logical unit not accessible, target port in unavailable state") -SENSE_CODE(0x040D, "Logical unit not ready, structure check required") -SENSE_CODE(0x040E, "Logical unit not ready, security session in progress") -SENSE_CODE(0x0410, "Logical unit not ready, auxiliary memory not accessible") -SENSE_CODE(0x0411, "Logical unit not ready, notify (enable spinup) required") -SENSE_CODE(0x0412, "Logical unit not ready, offline") -SENSE_CODE(0x0413, "Logical unit not ready, SA creation in progress") -SENSE_CODE(0x0414, "Logical unit not ready, space allocation in progress") -SENSE_CODE(0x0415, "Logical unit not ready, robotics disabled") -SENSE_CODE(0x0416, "Logical unit not ready, configuration required") -SENSE_CODE(0x0417, "Logical unit not ready, calibration required") -SENSE_CODE(0x0418, "Logical unit not ready, a door is open") -SENSE_CODE(0x0419, "Logical unit not ready, operating in sequential mode") -SENSE_CODE(0x041A, "Logical unit not ready, start stop unit command in progress") -SENSE_CODE(0x041B, "Logical unit not ready, sanitize in progress") -SENSE_CODE(0x041C, "Logical unit not ready, additional power use not yet granted") -SENSE_CODE(0x041D, "Logical unit not ready, configuration in progress") -SENSE_CODE(0x041E, "Logical unit not ready, microcode activation required") -SENSE_CODE(0x041F, "Logical unit not ready, microcode download required") -SENSE_CODE(0x0420, "Logical unit not ready, logical unit reset required") -SENSE_CODE(0x0421, "Logical unit not ready, hard reset required") -SENSE_CODE(0x0422, "Logical unit not ready, power cycle required") -SENSE_CODE(0x0423, "Logical unit not ready, affiliation required") -SENSE_CODE(0x0424, "Depopulation in progress") -SENSE_CODE(0x0425, "Depopulation restoration in progress") - -SENSE_CODE(0x0500, "Logical unit does not respond to selection") - -SENSE_CODE(0x0600, "No reference position found") - -SENSE_CODE(0x0700, "Multiple peripheral devices selected") - -SENSE_CODE(0x0800, "Logical unit communication failure") -SENSE_CODE(0x0801, "Logical unit communication time-out") -SENSE_CODE(0x0802, "Logical unit communication parity error") -SENSE_CODE(0x0803, "Logical unit communication CRC error (Ultra-DMA/32)") -SENSE_CODE(0x0804, "Unreachable copy target") - -SENSE_CODE(0x0900, "Track following error") -SENSE_CODE(0x0901, "Tracking servo failure") -SENSE_CODE(0x0902, "Focus servo failure") -SENSE_CODE(0x0903, "Spindle servo failure") -SENSE_CODE(0x0904, "Head select fault") -SENSE_CODE(0x0905, "Vibration induced tracking error") - -SENSE_CODE(0x0A00, "Error log overflow") - -SENSE_CODE(0x0B00, "Warning") -SENSE_CODE(0x0B01, "Warning - specified temperature exceeded") -SENSE_CODE(0x0B02, "Warning - enclosure degraded") -SENSE_CODE(0x0B03, "Warning - background self-test failed") -SENSE_CODE(0x0B04, "Warning - background pre-scan detected medium error") -SENSE_CODE(0x0B05, "Warning - background medium scan detected medium error") -SENSE_CODE(0x0B06, "Warning - non-volatile cache now volatile") -SENSE_CODE(0x0B07, "Warning - degraded power to non-volatile cache") -SENSE_CODE(0x0B08, "Warning - power loss expected") -SENSE_CODE(0x0B09, "Warning - device statistics notification active") -SENSE_CODE(0x0B0A, "Warning - high critical temperature limit exceeded") -SENSE_CODE(0x0B0B, "Warning - low critical temperature limit exceeded") -SENSE_CODE(0x0B0C, "Warning - high operating temperature limit exceeded") -SENSE_CODE(0x0B0D, "Warning - low operating temperature limit exceeded") -SENSE_CODE(0x0B0E, "Warning - high critical humidity limit exceeded") -SENSE_CODE(0x0B0F, "Warning - low critical humidity limit exceeded") -SENSE_CODE(0x0B10, "Warning - high operating humidity limit exceeded") -SENSE_CODE(0x0B11, "Warning - low operating humidity limit exceeded") -SENSE_CODE(0x0B12, "Warning - microcode security at risk") -SENSE_CODE(0x0B13, "Warning - microcode digital signature validation failure") -SENSE_CODE(0x0B14, "Warning - physical element status change") - -SENSE_CODE(0x0C00, "Write error") -SENSE_CODE(0x0C01, "Write error - recovered with auto reallocation") -SENSE_CODE(0x0C02, "Write error - auto reallocation failed") -SENSE_CODE(0x0C03, "Write error - recommend reassignment") -SENSE_CODE(0x0C04, "Compression check miscompare error") -SENSE_CODE(0x0C05, "Data expansion occurred during compression") -SENSE_CODE(0x0C06, "Block not compressible") -SENSE_CODE(0x0C07, "Write error - recovery needed") -SENSE_CODE(0x0C08, "Write error - recovery failed") -SENSE_CODE(0x0C09, "Write error - loss of streaming") -SENSE_CODE(0x0C0A, "Write error - padding blocks added") -SENSE_CODE(0x0C0B, "Auxiliary memory write error") -SENSE_CODE(0x0C0C, "Write error - unexpected unsolicited data") -SENSE_CODE(0x0C0D, "Write error - not enough unsolicited data") -SENSE_CODE(0x0C0E, "Multiple write errors") -SENSE_CODE(0x0C0F, "Defects in error window") -SENSE_CODE(0x0C10, "Incomplete multiple atomic write operations") -SENSE_CODE(0x0C11, "Write error - recovery scan needed") -SENSE_CODE(0x0C12, "Write error - insufficient zone resources") - -SENSE_CODE(0x0D00, "Error detected by third party temporary initiator") -SENSE_CODE(0x0D01, "Third party device failure") -SENSE_CODE(0x0D02, "Copy target device not reachable") -SENSE_CODE(0x0D03, "Incorrect copy target device type") -SENSE_CODE(0x0D04, "Copy target device data underrun") -SENSE_CODE(0x0D05, "Copy target device data overrun") - -SENSE_CODE(0x0E00, "Invalid information unit") -SENSE_CODE(0x0E01, "Information unit too short") -SENSE_CODE(0x0E02, "Information unit too long") -SENSE_CODE(0x0E03, "Invalid field in command information unit") - -SENSE_CODE(0x1000, "Id CRC or ECC error") -SENSE_CODE(0x1001, "Logical block guard check failed") -SENSE_CODE(0x1002, "Logical block application tag check failed") -SENSE_CODE(0x1003, "Logical block reference tag check failed") -SENSE_CODE(0x1004, "Logical block protection error on recover buffered data") -SENSE_CODE(0x1005, "Logical block protection method error") - -SENSE_CODE(0x1100, "Unrecovered read error") -SENSE_CODE(0x1101, "Read retries exhausted") -SENSE_CODE(0x1102, "Error too long to correct") -SENSE_CODE(0x1103, "Multiple read errors") -SENSE_CODE(0x1104, "Unrecovered read error - auto reallocate failed") -SENSE_CODE(0x1105, "L-EC uncorrectable error") -SENSE_CODE(0x1106, "CIRC unrecovered error") -SENSE_CODE(0x1107, "Data re-synchronization error") -SENSE_CODE(0x1108, "Incomplete block read") -SENSE_CODE(0x1109, "No gap found") -SENSE_CODE(0x110A, "Miscorrected error") -SENSE_CODE(0x110B, "Unrecovered read error - recommend reassignment") -SENSE_CODE(0x110C, "Unrecovered read error - recommend rewrite the data") -SENSE_CODE(0x110D, "De-compression CRC error") -SENSE_CODE(0x110E, "Cannot decompress using declared algorithm") -SENSE_CODE(0x110F, "Error reading UPC/EAN number") -SENSE_CODE(0x1110, "Error reading ISRC number") -SENSE_CODE(0x1111, "Read error - loss of streaming") -SENSE_CODE(0x1112, "Auxiliary memory read error") -SENSE_CODE(0x1113, "Read error - failed retransmission request") -SENSE_CODE(0x1114, "Read error - lba marked bad by application client") -SENSE_CODE(0x1115, "Write after sanitize required") - -SENSE_CODE(0x1200, "Address mark not found for id field") - -SENSE_CODE(0x1300, "Address mark not found for data field") - -SENSE_CODE(0x1400, "Recorded entity not found") -SENSE_CODE(0x1401, "Record not found") -SENSE_CODE(0x1402, "Filemark or setmark not found") -SENSE_CODE(0x1403, "End-of-data not found") -SENSE_CODE(0x1404, "Block sequence error") -SENSE_CODE(0x1405, "Record not found - recommend reassignment") -SENSE_CODE(0x1406, "Record not found - data auto-reallocated") -SENSE_CODE(0x1407, "Locate operation failure") - -SENSE_CODE(0x1500, "Random positioning error") -SENSE_CODE(0x1501, "Mechanical positioning error") -SENSE_CODE(0x1502, "Positioning error detected by read of medium") - -SENSE_CODE(0x1600, "Data synchronization mark error") -SENSE_CODE(0x1601, "Data sync error - data rewritten") -SENSE_CODE(0x1602, "Data sync error - recommend rewrite") -SENSE_CODE(0x1603, "Data sync error - data auto-reallocated") -SENSE_CODE(0x1604, "Data sync error - recommend reassignment") - -SENSE_CODE(0x1700, "Recovered data with no error correction applied") -SENSE_CODE(0x1701, "Recovered data with retries") -SENSE_CODE(0x1702, "Recovered data with positive head offset") -SENSE_CODE(0x1703, "Recovered data with negative head offset") -SENSE_CODE(0x1704, "Recovered data with retries and/or circ applied") -SENSE_CODE(0x1705, "Recovered data using previous sector id") -SENSE_CODE(0x1706, "Recovered data without ECC - data auto-reallocated") -SENSE_CODE(0x1707, "Recovered data without ECC - recommend reassignment") -SENSE_CODE(0x1708, "Recovered data without ECC - recommend rewrite") -SENSE_CODE(0x1709, "Recovered data without ECC - data rewritten") - -SENSE_CODE(0x1800, "Recovered data with error correction applied") -SENSE_CODE(0x1801, "Recovered data with error corr. & retries applied") -SENSE_CODE(0x1802, "Recovered data - data auto-reallocated") -SENSE_CODE(0x1803, "Recovered data with CIRC") -SENSE_CODE(0x1804, "Recovered data with L-EC") -SENSE_CODE(0x1805, "Recovered data - recommend reassignment") -SENSE_CODE(0x1806, "Recovered data - recommend rewrite") -SENSE_CODE(0x1807, "Recovered data with ECC - data rewritten") -SENSE_CODE(0x1808, "Recovered data with linking") - -SENSE_CODE(0x1900, "Defect list error") -SENSE_CODE(0x1901, "Defect list not available") -SENSE_CODE(0x1902, "Defect list error in primary list") -SENSE_CODE(0x1903, "Defect list error in grown list") - -SENSE_CODE(0x1A00, "Parameter list length error") - -SENSE_CODE(0x1B00, "Synchronous data transfer error") - -SENSE_CODE(0x1C00, "Defect list not found") -SENSE_CODE(0x1C01, "Primary defect list not found") -SENSE_CODE(0x1C02, "Grown defect list not found") - -SENSE_CODE(0x1D00, "Miscompare during verify operation") -SENSE_CODE(0x1D01, "Miscompare verify of unmapped LBA") - -SENSE_CODE(0x1E00, "Recovered id with ECC correction") - -SENSE_CODE(0x1F00, "Partial defect list transfer") - -SENSE_CODE(0x2000, "Invalid command operation code") -SENSE_CODE(0x2001, "Access denied - initiator pending-enrolled") -SENSE_CODE(0x2002, "Access denied - no access rights") -SENSE_CODE(0x2003, "Access denied - invalid mgmt id key") -SENSE_CODE(0x2004, "Illegal command while in write capable state") -SENSE_CODE(0x2005, "Obsolete") -SENSE_CODE(0x2006, "Illegal command while in explicit address mode") -SENSE_CODE(0x2007, "Illegal command while in implicit address mode") -SENSE_CODE(0x2008, "Access denied - enrollment conflict") -SENSE_CODE(0x2009, "Access denied - invalid LU identifier") -SENSE_CODE(0x200A, "Access denied - invalid proxy token") -SENSE_CODE(0x200B, "Access denied - ACL LUN conflict") -SENSE_CODE(0x200C, "Illegal command when not in append-only mode") -SENSE_CODE(0x200D, "Not an administrative logical unit") -SENSE_CODE(0x200E, "Not a subsidiary logical unit") -SENSE_CODE(0x200F, "Not a conglomerate logical unit") - -SENSE_CODE(0x2100, "Logical block address out of range") -SENSE_CODE(0x2101, "Invalid element address") -SENSE_CODE(0x2102, "Invalid address for write") -SENSE_CODE(0x2103, "Invalid write crossing layer jump") -SENSE_CODE(0x2104, "Unaligned write command") -SENSE_CODE(0x2105, "Write boundary violation") -SENSE_CODE(0x2106, "Attempt to read invalid data") -SENSE_CODE(0x2107, "Read boundary violation") -SENSE_CODE(0x2108, "Misaligned write command") -SENSE_CODE(0x2109, "Attempt to access gap zone") - -SENSE_CODE(0x2200, "Illegal function (use 20 00, 24 00, or 26 00)") - -SENSE_CODE(0x2300, "Invalid token operation, cause not reportable") -SENSE_CODE(0x2301, "Invalid token operation, unsupported token type") -SENSE_CODE(0x2302, "Invalid token operation, remote token usage not supported") -SENSE_CODE(0x2303, "Invalid token operation, remote rod token creation not supported") -SENSE_CODE(0x2304, "Invalid token operation, token unknown") -SENSE_CODE(0x2305, "Invalid token operation, token corrupt") -SENSE_CODE(0x2306, "Invalid token operation, token revoked") -SENSE_CODE(0x2307, "Invalid token operation, token expired") -SENSE_CODE(0x2308, "Invalid token operation, token cancelled") -SENSE_CODE(0x2309, "Invalid token operation, token deleted") -SENSE_CODE(0x230A, "Invalid token operation, invalid token length") - -SENSE_CODE(0x2400, "Invalid field in cdb") -SENSE_CODE(0x2401, "CDB decryption error") -SENSE_CODE(0x2402, "Obsolete") -SENSE_CODE(0x2403, "Obsolete") -SENSE_CODE(0x2404, "Security audit value frozen") -SENSE_CODE(0x2405, "Security working key frozen") -SENSE_CODE(0x2406, "Nonce not unique") -SENSE_CODE(0x2407, "Nonce timestamp out of range") -SENSE_CODE(0x2408, "Invalid XCDB") -SENSE_CODE(0x2409, "Invalid fast format") - -SENSE_CODE(0x2500, "Logical unit not supported") - -SENSE_CODE(0x2600, "Invalid field in parameter list") -SENSE_CODE(0x2601, "Parameter not supported") -SENSE_CODE(0x2602, "Parameter value invalid") -SENSE_CODE(0x2603, "Threshold parameters not supported") -SENSE_CODE(0x2604, "Invalid release of persistent reservation") -SENSE_CODE(0x2605, "Data decryption error") -SENSE_CODE(0x2606, "Too many target descriptors") -SENSE_CODE(0x2607, "Unsupported target descriptor type code") -SENSE_CODE(0x2608, "Too many segment descriptors") -SENSE_CODE(0x2609, "Unsupported segment descriptor type code") -SENSE_CODE(0x260A, "Unexpected inexact segment") -SENSE_CODE(0x260B, "Inline data length exceeded") -SENSE_CODE(0x260C, "Invalid operation for copy source or destination") -SENSE_CODE(0x260D, "Copy segment granularity violation") -SENSE_CODE(0x260E, "Invalid parameter while port is enabled") -SENSE_CODE(0x260F, "Invalid data-out buffer integrity check value") -SENSE_CODE(0x2610, "Data decryption key fail limit reached") -SENSE_CODE(0x2611, "Incomplete key-associated data set") -SENSE_CODE(0x2612, "Vendor specific key reference not found") -SENSE_CODE(0x2613, "Application tag mode page is invalid") -SENSE_CODE(0x2614, "Tape stream mirroring prevented") -SENSE_CODE(0x2615, "Copy source or copy destination not authorized") -SENSE_CODE(0x2616, "Fast copy not possible") - -SENSE_CODE(0x2700, "Write protected") -SENSE_CODE(0x2701, "Hardware write protected") -SENSE_CODE(0x2702, "Logical unit software write protected") -SENSE_CODE(0x2703, "Associated write protect") -SENSE_CODE(0x2704, "Persistent write protect") -SENSE_CODE(0x2705, "Permanent write protect") -SENSE_CODE(0x2706, "Conditional write protect") -SENSE_CODE(0x2707, "Space allocation failed write protect") -SENSE_CODE(0x2708, "Zone is read only") - -SENSE_CODE(0x2800, "Not ready to ready change, medium may have changed") -SENSE_CODE(0x2801, "Import or export element accessed") -SENSE_CODE(0x2802, "Format-layer may have changed") -SENSE_CODE(0x2803, "Import/export element accessed, medium changed") - -SENSE_CODE(0x2900, "Power on, reset, or bus device reset occurred") -SENSE_CODE(0x2901, "Power on occurred") -SENSE_CODE(0x2902, "Scsi bus reset occurred") -SENSE_CODE(0x2903, "Bus device reset function occurred") -SENSE_CODE(0x2904, "Device internal reset") -SENSE_CODE(0x2905, "Transceiver mode changed to single-ended") -SENSE_CODE(0x2906, "Transceiver mode changed to lvd") -SENSE_CODE(0x2907, "I_T nexus loss occurred") - -SENSE_CODE(0x2A00, "Parameters changed") -SENSE_CODE(0x2A01, "Mode parameters changed") -SENSE_CODE(0x2A02, "Log parameters changed") -SENSE_CODE(0x2A03, "Reservations preempted") -SENSE_CODE(0x2A04, "Reservations released") -SENSE_CODE(0x2A05, "Registrations preempted") -SENSE_CODE(0x2A06, "Asymmetric access state changed") -SENSE_CODE(0x2A07, "Implicit asymmetric access state transition failed") -SENSE_CODE(0x2A08, "Priority changed") -SENSE_CODE(0x2A09, "Capacity data has changed") -SENSE_CODE(0x2A0A, "Error history I_T nexus cleared") -SENSE_CODE(0x2A0B, "Error history snapshot released") -SENSE_CODE(0x2A0C, "Error recovery attributes have changed") -SENSE_CODE(0x2A0D, "Data encryption capabilities changed") -SENSE_CODE(0x2A10, "Timestamp changed") -SENSE_CODE(0x2A11, "Data encryption parameters changed by another i_t nexus") -SENSE_CODE(0x2A12, "Data encryption parameters changed by vendor specific event") -SENSE_CODE(0x2A13, "Data encryption key instance counter has changed") -SENSE_CODE(0x2A14, "SA creation capabilities data has changed") -SENSE_CODE(0x2A15, "Medium removal prevention preempted") -SENSE_CODE(0x2A16, "Zone reset write pointer recommended") - -SENSE_CODE(0x2B00, "Copy cannot execute since host cannot disconnect") - -SENSE_CODE(0x2C00, "Command sequence error") -SENSE_CODE(0x2C01, "Too many windows specified") -SENSE_CODE(0x2C02, "Invalid combination of windows specified") -SENSE_CODE(0x2C03, "Current program area is not empty") -SENSE_CODE(0x2C04, "Current program area is empty") -SENSE_CODE(0x2C05, "Illegal power condition request") -SENSE_CODE(0x2C06, "Persistent prevent conflict") -SENSE_CODE(0x2C07, "Previous busy status") -SENSE_CODE(0x2C08, "Previous task set full status") -SENSE_CODE(0x2C09, "Previous reservation conflict status") -SENSE_CODE(0x2C0A, "Partition or collection contains user objects") -SENSE_CODE(0x2C0B, "Not reserved") -SENSE_CODE(0x2C0C, "Orwrite generation does not match") -SENSE_CODE(0x2C0D, "Reset write pointer not allowed") -SENSE_CODE(0x2C0E, "Zone is offline") -SENSE_CODE(0x2C0F, "Stream not open") -SENSE_CODE(0x2C10, "Unwritten data in zone") -SENSE_CODE(0x2C11, "Descriptor format sense data required") -SENSE_CODE(0x2C12, "Zone is inactive") -SENSE_CODE(0x2C13, "Well known logical unit access required") - -SENSE_CODE(0x2D00, "Overwrite error on update in place") - -SENSE_CODE(0x2E00, "Insufficient time for operation") -SENSE_CODE(0x2E01, "Command timeout before processing") -SENSE_CODE(0x2E02, "Command timeout during processing") -SENSE_CODE(0x2E03, "Command timeout during processing due to error recovery") - -SENSE_CODE(0x2F00, "Commands cleared by another initiator") -SENSE_CODE(0x2F01, "Commands cleared by power loss notification") -SENSE_CODE(0x2F02, "Commands cleared by device server") -SENSE_CODE(0x2F03, "Some commands cleared by queuing layer event") - -SENSE_CODE(0x3000, "Incompatible medium installed") -SENSE_CODE(0x3001, "Cannot read medium - unknown format") -SENSE_CODE(0x3002, "Cannot read medium - incompatible format") -SENSE_CODE(0x3003, "Cleaning cartridge installed") -SENSE_CODE(0x3004, "Cannot write medium - unknown format") -SENSE_CODE(0x3005, "Cannot write medium - incompatible format") -SENSE_CODE(0x3006, "Cannot format medium - incompatible medium") -SENSE_CODE(0x3007, "Cleaning failure") -SENSE_CODE(0x3008, "Cannot write - application code mismatch") -SENSE_CODE(0x3009, "Current session not fixated for append") -SENSE_CODE(0x300A, "Cleaning request rejected") -SENSE_CODE(0x300C, "WORM medium - overwrite attempted") -SENSE_CODE(0x300D, "WORM medium - integrity check") -SENSE_CODE(0x3010, "Medium not formatted") -SENSE_CODE(0x3011, "Incompatible volume type") -SENSE_CODE(0x3012, "Incompatible volume qualifier") -SENSE_CODE(0x3013, "Cleaning volume expired") - -SENSE_CODE(0x3100, "Medium format corrupted") -SENSE_CODE(0x3101, "Format command failed") -SENSE_CODE(0x3102, "Zoned formatting failed due to spare linking") -SENSE_CODE(0x3103, "Sanitize command failed") -SENSE_CODE(0x3104, "Depopulation failed") -SENSE_CODE(0x3105, "Depopulation restoration failed") - -SENSE_CODE(0x3200, "No defect spare location available") -SENSE_CODE(0x3201, "Defect list update failure") - -SENSE_CODE(0x3300, "Tape length error") - -SENSE_CODE(0x3400, "Enclosure failure") - -SENSE_CODE(0x3500, "Enclosure services failure") -SENSE_CODE(0x3501, "Unsupported enclosure function") -SENSE_CODE(0x3502, "Enclosure services unavailable") -SENSE_CODE(0x3503, "Enclosure services transfer failure") -SENSE_CODE(0x3504, "Enclosure services transfer refused") -SENSE_CODE(0x3505, "Enclosure services checksum error") - -SENSE_CODE(0x3600, "Ribbon, ink, or toner failure") - -SENSE_CODE(0x3700, "Rounded parameter") - -SENSE_CODE(0x3800, "Event status notification") -SENSE_CODE(0x3802, "Esn - power management class event") -SENSE_CODE(0x3804, "Esn - media class event") -SENSE_CODE(0x3806, "Esn - device busy class event") -SENSE_CODE(0x3807, "Thin Provisioning soft threshold reached") -SENSE_CODE(0x3808, "Depopulation interrupted") - -SENSE_CODE(0x3900, "Saving parameters not supported") - -SENSE_CODE(0x3A00, "Medium not present") -SENSE_CODE(0x3A01, "Medium not present - tray closed") -SENSE_CODE(0x3A02, "Medium not present - tray open") -SENSE_CODE(0x3A03, "Medium not present - loadable") -SENSE_CODE(0x3A04, "Medium not present - medium auxiliary memory accessible") - -SENSE_CODE(0x3B00, "Sequential positioning error") -SENSE_CODE(0x3B01, "Tape position error at beginning-of-medium") -SENSE_CODE(0x3B02, "Tape position error at end-of-medium") -SENSE_CODE(0x3B03, "Tape or electronic vertical forms unit not ready") -SENSE_CODE(0x3B04, "Slew failure") -SENSE_CODE(0x3B05, "Paper jam") -SENSE_CODE(0x3B06, "Failed to sense top-of-form") -SENSE_CODE(0x3B07, "Failed to sense bottom-of-form") -SENSE_CODE(0x3B08, "Reposition error") -SENSE_CODE(0x3B09, "Read past end of medium") -SENSE_CODE(0x3B0A, "Read past beginning of medium") -SENSE_CODE(0x3B0B, "Position past end of medium") -SENSE_CODE(0x3B0C, "Position past beginning of medium") -SENSE_CODE(0x3B0D, "Medium destination element full") -SENSE_CODE(0x3B0E, "Medium source element empty") -SENSE_CODE(0x3B0F, "End of medium reached") -SENSE_CODE(0x3B11, "Medium magazine not accessible") -SENSE_CODE(0x3B12, "Medium magazine removed") -SENSE_CODE(0x3B13, "Medium magazine inserted") -SENSE_CODE(0x3B14, "Medium magazine locked") -SENSE_CODE(0x3B15, "Medium magazine unlocked") -SENSE_CODE(0x3B16, "Mechanical positioning or changer error") -SENSE_CODE(0x3B17, "Read past end of user object") -SENSE_CODE(0x3B18, "Element disabled") -SENSE_CODE(0x3B19, "Element enabled") -SENSE_CODE(0x3B1A, "Data transfer device removed") -SENSE_CODE(0x3B1B, "Data transfer device inserted") -SENSE_CODE(0x3B1C, "Too many logical objects on partition to support operation") -SENSE_CODE(0x3B20, "Element static information changed") - -SENSE_CODE(0x3D00, "Invalid bits in identify message") - -SENSE_CODE(0x3E00, "Logical unit has not self-configured yet") -SENSE_CODE(0x3E01, "Logical unit failure") -SENSE_CODE(0x3E02, "Timeout on logical unit") -SENSE_CODE(0x3E03, "Logical unit failed self-test") -SENSE_CODE(0x3E04, "Logical unit unable to update self-test log") - -SENSE_CODE(0x3F00, "Target operating conditions have changed") -SENSE_CODE(0x3F01, "Microcode has been changed") -SENSE_CODE(0x3F02, "Changed operating definition") -SENSE_CODE(0x3F03, "Inquiry data has changed") -SENSE_CODE(0x3F04, "Component device attached") -SENSE_CODE(0x3F05, "Device identifier changed") -SENSE_CODE(0x3F06, "Redundancy group created or modified") -SENSE_CODE(0x3F07, "Redundancy group deleted") -SENSE_CODE(0x3F08, "Spare created or modified") -SENSE_CODE(0x3F09, "Spare deleted") -SENSE_CODE(0x3F0A, "Volume set created or modified") -SENSE_CODE(0x3F0B, "Volume set deleted") -SENSE_CODE(0x3F0C, "Volume set deassigned") -SENSE_CODE(0x3F0D, "Volume set reassigned") -SENSE_CODE(0x3F0E, "Reported luns data has changed") -SENSE_CODE(0x3F0F, "Echo buffer overwritten") -SENSE_CODE(0x3F10, "Medium loadable") -SENSE_CODE(0x3F11, "Medium auxiliary memory accessible") -SENSE_CODE(0x3F12, "iSCSI IP address added") -SENSE_CODE(0x3F13, "iSCSI IP address removed") -SENSE_CODE(0x3F14, "iSCSI IP address changed") -SENSE_CODE(0x3F15, "Inspect referrals sense descriptors") -SENSE_CODE(0x3F16, "Microcode has been changed without reset") -SENSE_CODE(0x3F17, "Zone transition to full") -SENSE_CODE(0x3F18, "Bind completed") -SENSE_CODE(0x3F19, "Bind redirected") -SENSE_CODE(0x3F1A, "Subsidiary binding changed") +SENSE_CODE(NO_ADDITIONAL_SENSE_INFORMATION, + "No additional sense information") +SENSE_CODE(FILEMARK_DETECTED, + "Filemark detected") +SENSE_CODE(END_OF_PARTITION_MEDIUM_DETECTED, + "End-of-partition/medium detected") +SENSE_CODE(SETMARK_DETECTED, + "Setmark detected") +SENSE_CODE(BEGINNING_OF_PARTITION_MEDIUM_DETECTED, + "Beginning-of-partition/medium detected") +SENSE_CODE(END_OF_DATA_DETECTED, + "End-of-data detected") +SENSE_CODE(IO_PROCESS_TERMINATED, + "I/O process terminated") +SENSE_CODE(PROGRAMMABLE_EARLY_WARNING_DETECTED, + "Programmable early warning detected") +SENSE_CODE(AUDIO_PLAY_OP_IN_PROGRESS, + "Audio play operation in progress") +SENSE_CODE(AUDIO_PLAY_OP_PAUSED, + "Audio play operation paused") +SENSE_CODE(AUDIO_PLAY_OP_SUCCESSFULLY_COMPLETED, + "Audio play operation successfully completed") +SENSE_CODE(AUDIO_PLAY_OP_STOPPED_DUE_TO_ERROR, + "Audio play operation stopped due to error") +SENSE_CODE(NO_CURRENT_AUDIO_STATUS_TO_RETURN, + "No current audio status to return") +SENSE_CODE(OP_IN_PROGRESS, + "Operation in progress") +SENSE_CODE(CLEANING_REQUESTED, + "Cleaning requested") +SENSE_CODE(ERASE_OP_IN_PROGRESS, + "Erase operation in progress") +SENSE_CODE(LOCATE_OP_IN_PROGRESS, + "Locate operation in progress") +SENSE_CODE(REWIND_OP_IN_PROGRESS, + "Rewind operation in progress") +SENSE_CODE(SET_CAPACITY_OP_IN_PROGRESS, + "Set capacity operation in progress") +SENSE_CODE(VERIFY_OP_IN_PROGRESS, + "Verify operation in progress") +SENSE_CODE(ATA_PASS_THROUGH_INFORMATION_AVAILABLE, + "ATA pass through information available") +SENSE_CODE(CONFLICTING_SA_CREATION_REQUEST, + "Conflicting SA creation request") +SENSE_CODE(LU_TRANSITIONING_TO_ANOTHER_POWER_CONDITION, + "Logical unit transitioning to another power condition") +SENSE_CODE(EXTENDED_COPY_INFORMATION_AVAILABLE, + "Extended copy information available") +SENSE_CODE(ATOMIC_COMMAND_ABORTED_DUE_TO_ACA, + "Atomic command aborted due to ACA") +SENSE_CODE(DEFERRED_MICROCODE_IS_PENDING, + "Deferred microcode is pending") +SENSE_CODE(OVERLAPPING_ATOMIC_COMMAND_IN_PROGRESS, + "Overlapping atomic command in progress") + +SENSE_CODE(NO_INDEX_SECTOR_SIGNAL, + "No index/sector signal") + +SENSE_CODE(NO_SEEK_COMPLETE, + "No seek complete") + +SENSE_CODE(PERIPHERAL_DEVICE_WRITE_FAULT, + "Peripheral device write fault") +SENSE_CODE(NO_WRITE_CURRENT, + "No write current") +SENSE_CODE(EXCESSIVE_WRITE_ERRORS, + "Excessive write errors") + +SENSE_CODE(LU_NOT_READY, + "Logical unit not ready, cause not reportable") +SENSE_CODE(LU_IS_IN_PROCESS_OF_BECOMING_READY, + "Logical unit is in process of becoming ready") +SENSE_CODE(LU_NOT_READY_INITIALIZING_COMMAND_REQUIRED, + "Logical unit not ready, initializing command required") +SENSE_CODE(LU_NOT_READY_MANUAL_INTERVENTION_REQUIRED, + "Logical unit not ready, manual intervention required") +SENSE_CODE(LU_NOT_READY_FORMAT_IN_PROGRESS, + "Logical unit not ready, format in progress") +SENSE_CODE(LU_NOT_READY_REBUILD_IN_PROGRESS, + "Logical unit not ready, rebuild in progress") +SENSE_CODE(LU_NOT_READY_RECALCULATION_IN_PROGRESS, + "Logical unit not ready, recalculation in progress") +SENSE_CODE(LU_NOT_READY_OP_IN_PROGRESS, + "Logical unit not ready, operation in progress") +SENSE_CODE(LU_NOT_READY_LONG_WRITE_IN_PROGRESS, + "Logical unit not ready, long write in progress") +SENSE_CODE(LU_NOT_READY_SELFTEST_IN_PROGRESS, + "Logical unit not ready, self-test in progress") +SENSE_CODE(LU_NOT_ACCESSIBLE_ASYMMETRIC_ACCESS_STATE_TRANSITION, + "Logical unit not accessible, asymmetric access state transition") +SENSE_CODE(LU_NOT_ACCESSIBLE_TARGET_PORT_IN_STANDBY_STATE, + "Logical unit not accessible, target port in standby state") +SENSE_CODE(LU_NOT_ACCESSIBLE_TARGET_PORT_IN_UNAVAILABLE_STATE, + "Logical unit not accessible, target port in unavailable state") +SENSE_CODE(LU_NOT_READY_STRUCTURE_CHECK_REQUIRED, + "Logical unit not ready, structure check required") +SENSE_CODE(LU_NOT_READY_SECURITY_SESSION_IN_PROGRESS, + "Logical unit not ready, security session in progress") +SENSE_CODE(LU_NOT_READY_AUXILIARY_MEMORY_NOT_ACCESSIBLE, + "Logical unit not ready, auxiliary memory not accessible") +SENSE_CODE(LU_NOT_READY_NOTIFY_REQUIRED, + "Logical unit not ready, notify (enable spinup) required") +SENSE_CODE(LU_NOT_READY_OFFLINE, + "Logical unit not ready, offline") +SENSE_CODE(LU_NOT_READY_SA_CREATION_IN_PROGRESS, + "Logical unit not ready, SA creation in progress") +SENSE_CODE(LU_NOT_READY_SPACE_ALLOCATION_IN_PROGRESS, + "Logical unit not ready, space allocation in progress") +SENSE_CODE(LU_NOT_READY_ROBOTICS_DISABLED, + "Logical unit not ready, robotics disabled") +SENSE_CODE(LU_NOT_READY_CONFIG_REQUIRED, + "Logical unit not ready, configuration required") +SENSE_CODE(LU_NOT_READY_CALIBRATION_REQUIRED, + "Logical unit not ready, calibration required") +SENSE_CODE(LU_NOT_READY_A_DOOR_IS_OPEN, + "Logical unit not ready, a door is open") +SENSE_CODE(LU_NOT_READY_OPERATING_IN_SEQUENTIAL_MODE, + "Logical unit not ready, operating in sequential mode") +SENSE_CODE(LU_NOT_READY_START_STOP_UNIT_COMMAND_IN_PROGRESS, + "Logical unit not ready, start stop unit command in progress") +SENSE_CODE(LU_NOT_READY_SANITIZE_IN_PROGRESS, + "Logical unit not ready, sanitize in progress") +SENSE_CODE(LU_NOT_READY_ADDITIONAL_POWER_USE_NOT_YET_GRANTED, + "Logical unit not ready, additional power use not yet granted") +SENSE_CODE(LU_NOT_READY_CONFIG_IN_PROGRESS, + "Logical unit not ready, configuration in progress") +SENSE_CODE(LU_NOT_READY_MICROCODE_ACTIVATION_REQUIRED, + "Logical unit not ready, microcode activation required") +SENSE_CODE(LU_NOT_READY_MICROCODE_DOWNLOAD_REQUIRED, + "Logical unit not ready, microcode download required") +SENSE_CODE(LU_NOT_READY_LU_RESET_REQUIRED, + "Logical unit not ready, logical unit reset required") +SENSE_CODE(LU_NOT_READY_HARD_RESET_REQUIRED, + "Logical unit not ready, hard reset required") +SENSE_CODE(LU_NOT_READY_POWER_CYCLE_REQUIRED, + "Logical unit not ready, power cycle required") +SENSE_CODE(LU_NOT_READY_AFFILIATION_REQUIRED, + "Logical unit not ready, affiliation required") +SENSE_CODE(DEPOPULATION_IN_PROGRESS, + "Depopulation in progress") +SENSE_CODE(DEPOPULATION_RESTORATION_IN_PROGRESS, + "Depopulation restoration in progress") + +SENSE_CODE(LU_DOES_NOT_RESPOND_TO_SELECTION, + "Logical unit does not respond to selection") + +SENSE_CODE(NO_REFERENCE_POSITION_FOUND, + "No reference position found") + +SENSE_CODE(MULTIPLE_PERIPHERAL_DEVICES_SELECTED, + "Multiple peripheral devices selected") + +SENSE_CODE(LU_COMMUNICATION_FAILURE, + "Logical unit communication failure") +SENSE_CODE(LU_COMMUNICATION_TIMEOUT, + "Logical unit communication time-out") +SENSE_CODE(LU_COMMUNICATION_PARITY_ERROR, + "Logical unit communication parity error") +SENSE_CODE(LU_COMMUNICATION_CRC_ERROR, + "Logical unit communication CRC error (Ultra-DMA/32)") +SENSE_CODE(UNREACHABLE_COPY_TARGET, + "Unreachable copy target") + +SENSE_CODE(TRACK_FOLLOWING_ERROR, + "Track following error") +SENSE_CODE(TRACKING_SERVO_FAILURE, + "Tracking servo failure") +SENSE_CODE(FOCUS_SERVO_FAILURE, + "Focus servo failure") +SENSE_CODE(SPINDLE_SERVO_FAILURE, + "Spindle servo failure") +SENSE_CODE(HEAD_SELECT_FAULT, + "Head select fault") +SENSE_CODE(VIBRATION_INDUCED_TRACKING_ERROR, + "Vibration induced tracking error") + +SENSE_CODE(ERROR_LOG_OVERFLOW, + "Error log overflow") + +SENSE_CODE(SSC_WARNING, + "Warning") +SENSE_CODE(WARNING_SPECIFIED_TEMPERATURE_EXCEEDED, + "Warning - specified temperature exceeded") +SENSE_CODE(WARNING_ENCLOSURE_DEGRADED, + "Warning - enclosure degraded") +SENSE_CODE(WARNING_BACKGROUND_SELFTEST_FAILED, + "Warning - background self-test failed") +SENSE_CODE(WARNING_BACKGROUND_PRESCAN_DETECTED_MEDIUM_ERROR, + "Warning - background pre-scan detected medium error") +SENSE_CODE(WARNING_BACKGROUND_MEDIUM_SCAN_DETECTED_MEDIUM_ERROR, + "Warning - background medium scan detected medium error") +SENSE_CODE(WARNING_NONVOLATILE_CACHE_NOW_VOLATILE, + "Warning - non-volatile cache now volatile") +SENSE_CODE(WARNING_DEGRADED_POWER_TO_NONVOLATILE_CACHE, + "Warning - degraded power to non-volatile cache") +SENSE_CODE(WARNING_POWER_LOSS_EXPECTED, + "Warning - power loss expected") +SENSE_CODE(WARNING_DEVICE_STATISTICS_NOTIFICATION_ACTIVE, + "Warning - device statistics notification active") +SENSE_CODE(WARNING_HIGH_CRITICAL_TEMPERATURE_LIMIT_EXCEEDED, + "Warning - high critical temperature limit exceeded") +SENSE_CODE(WARNING_LOW_CRITICAL_TEMPERATURE_LIMIT_EXCEEDED, + "Warning - low critical temperature limit exceeded") +SENSE_CODE(WARNING_HIGH_OPERATING_TEMPERATURE_LIMIT_EXCEEDED, + "Warning - high operating temperature limit exceeded") +SENSE_CODE(WARNING_LOW_OPERATING_TEMPERATURE_LIMIT_EXCEEDED, + "Warning - low operating temperature limit exceeded") +SENSE_CODE(WARNING_HIGH_CRITICAL_HUMIDITY_LIMIT_EXCEEDED, + "Warning - high critical humidity limit exceeded") +SENSE_CODE(WARNING_LOW_CRITICAL_HUMIDITY_LIMIT_EXCEEDED, + "Warning - low critical humidity limit exceeded") +SENSE_CODE(WARNING_HIGH_OPERATING_HUMIDITY_LIMIT_EXCEEDED, + "Warning - high operating humidity limit exceeded") +SENSE_CODE(WARNING_LOW_OPERATING_HUMIDITY_LIMIT_EXCEEDED, + "Warning - low operating humidity limit exceeded") +SENSE_CODE(WARNING_MICROCODE_SECURITY_AT_RISK, + "Warning - microcode security at risk") +SENSE_CODE(WARNING_MICROCODE_DIGITAL_SIGNATURE_VALIDATION_FAILURE, + "Warning - microcode digital signature validation failure") +SENSE_CODE(WARNING_PHYSICAL_ELEMENT_STATUS_CHANGE, + "Warning - physical element status change") + +SENSE_CODE(SSC_WRITE_ERROR, + "Write error") +SENSE_CODE(WRITE_ERROR_RECOVERED_WITH_AUTO_REALLOCATION, + "Write error - recovered with auto reallocation") +SENSE_CODE(WRITE_ERROR_AUTO_REALLOCATION_FAILED, + "Write error - auto reallocation failed") +SENSE_CODE(WRITE_ERROR_RECOMMEND_REASSIGNMENT, + "Write error - recommend reassignment") +SENSE_CODE(COMPRESSION_CHECK_MISCOMPARE_ERROR, + "Compression check miscompare error") +SENSE_CODE(DATA_EXPANSION_OCCURRED_DURING_COMPRESSION, + "Data expansion occurred during compression") +SENSE_CODE(BLOCK_NOT_COMPRESSIBLE, + "Block not compressible") +SENSE_CODE(WRITE_ERROR_RECOVERY_NEEDED, + "Write error - recovery needed") +SENSE_CODE(WRITE_ERROR_RECOVERY_FAILED, + "Write error - recovery failed") +SENSE_CODE(WRITE_ERROR_LOSS_OF_STREAMING, + "Write error - loss of streaming") +SENSE_CODE(WRITE_ERROR_PADDING_BLOCKS_ADDED, + "Write error - padding blocks added") +SENSE_CODE(AUXILIARY_MEMORY_WRITE_ERROR, + "Auxiliary memory write error") +SENSE_CODE(WRITE_ERROR_UNEXPECTED_UNSOLICITED_DATA, + "Write error - unexpected unsolicited data") +SENSE_CODE(WRITE_ERROR_NOT_ENOUGH_UNSOLICITED_DATA, + "Write error - not enough unsolicited data") +SENSE_CODE(MULTIPLE_WRITE_ERRORS, + "Multiple write errors") +SENSE_CODE(DEFECTS_IN_ERROR_WINDOW, + "Defects in error window") +SENSE_CODE(INCOMPLETE_MULTIPLE_ATOMIC_WRITE_OPERATIONS, + "Incomplete multiple atomic write operations") +SENSE_CODE(WRITE_ERROR_RECOVERY_SCAN_NEEDED, + "Write error - recovery scan needed") +SENSE_CODE(WRITE_ERROR_INSUFFICIENT_ZONE_RESOURCES, + "Write error - insufficient zone resources") + +SENSE_CODE(ERROR_DETECTED_BY_THIRD_PARTY_TEMPORARY_INITIATOR, + "Error detected by third party temporary initiator") +SENSE_CODE(THIRD_PARTY_DEVICE_FAILURE, + "Third party device failure") +SENSE_CODE(COPY_TARGET_DEVICE_NOT_REACHABLE, + "Copy target device not reachable") +SENSE_CODE(INCORRECT_COPY_TARGET_DEVICE_TYPE, + "Incorrect copy target device type") +SENSE_CODE(COPY_TARGET_DEVICE_DATA_UNDERRUN, + "Copy target device data underrun") +SENSE_CODE(COPY_TARGET_DEVICE_DATA_OVERRUN, + "Copy target device data overrun") + +SENSE_CODE(INVALID_INFORMATION_UNIT, + "Invalid information unit") +SENSE_CODE(INFORMATION_UNIT_TOO_SHORT, + "Information unit too short") +SENSE_CODE(INFORMATION_UNIT_TOO_LONG, + "Information unit too long") +SENSE_CODE(INVALID_FIELD_IN_COMMAND_INFORMATION_UNIT, + "Invalid field in command information unit") + +SENSE_CODE(ID_CRC_OR_ECC_ERROR, + "Id CRC or ECC error") +SENSE_CODE(LOGICAL_BLOCK_GUARD_CHECK_FAILED, + "Logical block guard check failed") +SENSE_CODE(LOGICAL_BLOCK_APPLICATION_TAG_CHECK_FAILED, + "Logical block application tag check failed") +SENSE_CODE(LOGICAL_BLOCK_REFERENCE_TAG_CHECK_FAILED, + "Logical block reference tag check failed") +SENSE_CODE(LOGICAL_BLOCK_PROTECTION_ERROR_ON_RECOVER_BUFFERED_DATA, + "Logical block protection error on recover buffered data") +SENSE_CODE(LOGICAL_BLOCK_PROTECTION_METHOD_ERROR, + "Logical block protection method error") + +SENSE_CODE(UNRECOVERED_READ_ERROR, + "Unrecovered read error") +SENSE_CODE(READ_RETRIES_EXHAUSTED, + "Read retries exhausted") +SENSE_CODE(ERROR_TOO_LONG_TO_CORRECT, + "Error too long to correct") +SENSE_CODE(MULTIPLE_READ_ERRORS, + "Multiple read errors") +SENSE_CODE(UNRECOVERED_READ_ERROR_AUTO_REALLOCATE_FAILED, + "Unrecovered read error - auto reallocate failed") +SENSE_CODE(LEC_UNCORRECTABLE_ERROR, + "L-EC uncorrectable error") +SENSE_CODE(CIRC_UNRECOVERED_ERROR, + "CIRC unrecovered error") +SENSE_CODE(DATA_RESYNCHRONIZATION_ERROR, + "Data re-synchronization error") +SENSE_CODE(INCOMPLETE_BLOCK_READ, + "Incomplete block read") +SENSE_CODE(NO_GAP_FOUND, + "No gap found") +SENSE_CODE(MISCORRECTED_ERROR, + "Miscorrected error") +SENSE_CODE(UNRECOVERED_READ_ERROR_RECOMMEND_REASSIGNMENT, + "Unrecovered read error - recommend reassignment") +SENSE_CODE(UNRECOVERED_READ_ERROR_RECOMMEND_REWRITE_THE_DATA, + "Unrecovered read error - recommend rewrite the data") +SENSE_CODE(DECOMPRESSION_CRC_ERROR, + "De-compression CRC error") +SENSE_CODE(CANNOT_DECOMPRESS_USING_DECLARED_ALGORITHM, + "Cannot decompress using declared algorithm") +SENSE_CODE(ERROR_READING_UPC_EAN_NUMBER, + "Error reading UPC/EAN number") +SENSE_CODE(ERROR_READING_ISRC_NUMBER, + "Error reading ISRC number") +SENSE_CODE(READ_ERROR_LOSS_OF_STREAMING, + "Read error - loss of streaming") +SENSE_CODE(AUXILIARY_MEMORY_READ_ERROR, + "Auxiliary memory read error") +SENSE_CODE(READ_ERROR_FAILED_RETRANSMISSION_REQUEST, + "Read error - failed retransmission request") +SENSE_CODE(READ_ERROR_LBA_MARKED_BAD_BY_APPLICATION_CLIENT, + "Read error - lba marked bad by application client") +SENSE_CODE(WRITE_AFTER_SANITIZE_REQUIRED, + "Write after sanitize required") + +SENSE_CODE(ADDRESS_MARK_NOT_FOUND_FOR_ID_FIELD, + "Address mark not found for id field") + +SENSE_CODE(ADDRESS_MARK_NOT_FOUND_FOR_DATA_FIELD, + "Address mark not found for data field") + +SENSE_CODE(RECORDED_ENTITY_NOT_FOUND, + "Recorded entity not found") +SENSE_CODE(RECORD_NOT_FOUND, + "Record not found") +SENSE_CODE(FILEMARK_OR_SETMARK_NOT_FOUND, + "Filemark or setmark not found") +SENSE_CODE(END_OF_DATA_NOT_FOUND, + "End-of-data not found") +SENSE_CODE(BLOCK_SEQUENCE_ERROR, + "Block sequence error") +SENSE_CODE(RECORD_NOT_FOUND_RECOMMEND_REASSIGNMENT, + "Record not found - recommend reassignment") +SENSE_CODE(RECORD_NOT_FOUND_DATA_AUTO_REALLOCATED, + "Record not found - data auto-reallocated") +SENSE_CODE(LOCATE_OPERATION_FAILURE, + "Locate operation failure") + +SENSE_CODE(RANDOM_POSITIONING_ERROR, + "Random positioning error") +SENSE_CODE(MECHANICAL_POSITIONING_ERROR, + "Mechanical positioning error") +SENSE_CODE(POSITIONING_ERROR_DETECTED_BY_READ_OF_MEDIUM, + "Positioning error detected by read of medium") + +SENSE_CODE(DATA_SYNCHRONIZATION_MARK_ERROR, + "Data synchronization mark error") +SENSE_CODE(DATA_SYNC_ERROR_DATA_REWRITTEN, + "Data sync error - data rewritten") +SENSE_CODE(DATA_SYNC_ERROR_RECOMMEND_REWRITE, + "Data sync error - recommend rewrite") +SENSE_CODE(DATA_SYNC_ERROR_DATA_AUTO_REALLOCATED, + "Data sync error - data auto-reallocated") +SENSE_CODE(DATA_SYNC_ERROR_RECOMMEND_REASSIGNMENT, + "Data sync error - recommend reassignment") + +SENSE_CODE(RECOVERED_DATA_WITH_NO_ERROR_CORRECTION_APPLIED, + "Recovered data with no error correction applied") +SENSE_CODE(RECOVERED_DATA_WITH_RETRIES, + "Recovered data with retries") +SENSE_CODE(RECOVERED_DATA_WITH_POSITIVE_HEAD_OFFSET, + "Recovered data with positive head offset") +SENSE_CODE(RECOVERED_DATA_WITH_NEGATIVE_HEAD_OFFSET, + "Recovered data with negative head offset") +SENSE_CODE(RECOVERED_DATA_WITH_RETRIES_AND_OR_CIRC_APPLIED, + "Recovered data with retries and/or circ applied") +SENSE_CODE(RECOVERED_DATA_USING_PREVIOUS_SECTOR_ID, + "Recovered data using previous sector id") +SENSE_CODE(RECOVERED_DATA_WITHOUT_ECC_DATA_AUTO_REALLOCATED, + "Recovered data without ECC - data auto-reallocated") +SENSE_CODE(RECOVERED_DATA_WITHOUT_ECC_RECOMMEND_REASSIGNMENT, + "Recovered data without ECC - recommend reassignment") +SENSE_CODE(RECOVERED_DATA_WITHOUT_ECC_RECOMMEND_REWRITE, + "Recovered data without ECC - recommend rewrite") +SENSE_CODE(RECOVERED_DATA_WITHOUT_ECC_DATA_REWRITTEN, + "Recovered data without ECC - data rewritten") + +SENSE_CODE(RECOVERED_DATA_WITH_ERROR_CORRECTION_APPLIED, + "Recovered data with error correction applied") +SENSE_CODE(RECOVERED_DATA_WITH_ERROR_CORRECTION_RETRIES_APPLIED, + "Recovered data with error corr. & retries applied") +SENSE_CODE(RECOVERED_DATA_DATA_AUTO_REALLOCATED, + "Recovered data - data auto-reallocated") +SENSE_CODE(RECOVERED_DATA_WITH_CIRC, + "Recovered data with CIRC") +SENSE_CODE(RECOVERED_DATA_WITH_LEC, + "Recovered data with L-EC") +SENSE_CODE(RECOVERED_DATA_RECOMMEND_REASSIGNMENT, + "Recovered data - recommend reassignment") +SENSE_CODE(RECOVERED_DATA_RECOMMEND_REWRITE, + "Recovered data - recommend rewrite") +SENSE_CODE(RECOVERED_DATA_WITH_ECC_DATA_REWRITTEN, + "Recovered data with ECC - data rewritten") +SENSE_CODE(RECOVERED_DATA_WITH_LINKING, + "Recovered data with linking") + +SENSE_CODE(DEFECT_LIST_ERROR, + "Defect list error") +SENSE_CODE(DEFECT_LIST_NOT_AVAILABLE, + "Defect list not available") +SENSE_CODE(DEFECT_LIST_ERROR_IN_PRIMARY_LIST, + "Defect list error in primary list") +SENSE_CODE(DEFECT_LIST_ERROR_IN_GROWN_LIST, + "Defect list error in grown list") + +SENSE_CODE(PARAMETER_LIST_LENGTH_ERROR, + "Parameter list length error") + +SENSE_CODE(SYNCHRONOUS_DATA_TRANSFER_ERROR, + "Synchronous data transfer error") + +SENSE_CODE(DEFECT_LIST_NOT_FOUND, + "Defect list not found") +SENSE_CODE(PRIMARY_DEFECT_LIST_NOT_FOUND, + "Primary defect list not found") +SENSE_CODE(GROWN_DEFECT_LIST_NOT_FOUND, + "Grown defect list not found") + +SENSE_CODE(MISCOMPARE_DURING_VERIFY_OPERATION, + "Miscompare during verify operation") +SENSE_CODE(MISCOMPARE_VERIFY_OF_UNMAPPED_LBA, + "Miscompare verify of unmapped LBA") + +SENSE_CODE(RECOVERED_ID_WITH_ECC_CORRECTION, + "Recovered id with ECC correction") + +SENSE_CODE(PARTIAL_DEFECT_LIST_TRANSFER, + "Partial defect list transfer") + +SENSE_CODE(INVALID_COMMAND_OP_CODE, + "Invalid command operation code") +SENSE_CODE(ACCESS_DENIED_INITIATOR_PENDING_ENROLLED, + "Access denied - initiator pending-enrolled") +SENSE_CODE(ACCESS_DENIED_NO_ACCESS_RIGHTS, + "Access denied - no access rights") +SENSE_CODE(ACCESS_DENIED_INVALID_MGMT_ID_KEY, + "Access denied - invalid mgmt id key") +SENSE_CODE(ILLEGAL_COMMAND_WHILE_IN_WRITE_CAPABLE_STATE, + "Illegal command while in write capable state") +SENSE_CODE(0x2005, + "Obsolete") +SENSE_CODE(ILLEGAL_COMMAND_WHILE_IN_EXPLICIT_ADDRESS_MODE, + "Illegal command while in explicit address mode") +SENSE_CODE(ILLEGAL_COMMAND_WHILE_IN_IMPLICIT_ADDRESS_MODE, + "Illegal command while in implicit address mode") +SENSE_CODE(ACCESS_DENIED_ENROLLMENT_CONFLICT, + "Access denied - enrollment conflict") +SENSE_CODE(ACCESS_DENIED_INVALID_LU_IDENTIFIER, + "Access denied - invalid LU identifier") +SENSE_CODE(ACCESS_DENIED_INVALID_PROXY_TOKEN, + "Access denied - invalid proxy token") +SENSE_CODE(ACCESS_DENIED_ACL_LUN_CONFLICT, + "Access denied - ACL LUN conflict") +SENSE_CODE(ILLEGAL_COMMAND_WHEN_NOT_IN_APPEND_ONLY_MODE, + "Illegal command when not in append-only mode") +SENSE_CODE(NOT_AN_ADMINISTRATIVE_LOGICAL_UNIT, + "Not an administrative logical unit") +SENSE_CODE(NOT_A_SUBSIDIARY_LOGICAL_UNIT, + "Not a subsidiary logical unit") +SENSE_CODE(NOT_A_CONGLOMERATE_LOGICAL_UNIT, + "Not a conglomerate logical unit") + +SENSE_CODE(LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE, + "Logical block address out of range") +SENSE_CODE(INVALID_ELEMENT_ADDRESS, + "Invalid element address") +SENSE_CODE(INVALID_ADDRESS_FOR_WRITE, + "Invalid address for write") +SENSE_CODE(INVALID_WRITE_CROSSING_LAYER_JUMP, + "Invalid write crossing layer jump") +SENSE_CODE(UNALIGNED_WRITE_COMMAND, + "Unaligned write command") +SENSE_CODE(WRITE_BOUNDARY_VIOLATION, + "Write boundary violation") +SENSE_CODE(ATTEMPT_TO_READ_INVALID_DATA, + "Attempt to read invalid data") +SENSE_CODE(READ_BOUNDARY_VIOLATION, + "Read boundary violation") +SENSE_CODE(MISALIGNED_WRITE_COMMAND, + "Misaligned write command") +SENSE_CODE(ATTEMPT_TO_ACCESS_GAP_ZONE, + "Attempt to access gap zone") + +SENSE_CODE(ILLEGAL_FUNCTION, + "Illegal function (use 20 00, 24 00, or 26 00)") + +SENSE_CODE(INVALID_TOKEN_OP, + "Invalid token operation, cause not reportable") +SENSE_CODE(INVALID_TOKEN_OP_UNSUPPORTED_TOKEN_TYPE, + "Invalid token operation, unsupported token type") +SENSE_CODE(INVALID_TOKEN_OP_REMOTE_TOKEN_USAGE_NOT_SUPPORTED, + "Invalid token operation, remote token usage not supported") +SENSE_CODE(INVALID_TOKEN_OP_REMOTE_ROD_TOKEN_CREATION_NOT_SUPPORTED, + "Invalid token operation, remote rod token creation not supported") +SENSE_CODE(INVALID_TOKEN_OP_TOKEN_UNKNOWN, + "Invalid token operation, token unknown") +SENSE_CODE(INVALID_TOKEN_OP_TOKEN_CORRUPT, + "Invalid token operation, token corrupt") +SENSE_CODE(INVALID_TOKEN_OP_TOKEN_REVOKED, + "Invalid token operation, token revoked") +SENSE_CODE(INVALID_TOKEN_OP_TOKEN_EXPIRED, + "Invalid token operation, token expired") +SENSE_CODE(INVALID_TOKEN_OP_TOKEN_CANCELLED, + "Invalid token operation, token cancelled") +SENSE_CODE(INVALID_TOKEN_OP_TOKEN_DELETED, + "Invalid token operation, token deleted") +SENSE_CODE(INVALID_TOKEN_OP_INVALID_TOKEN_LENGTH, + "Invalid token operation, invalid token length") + +SENSE_CODE(INVALID_FIELD_IN_CDB, + "Invalid field in cdb") +SENSE_CODE(CDB_DECRYPTION_ERROR, + "CDB decryption error") +SENSE_CODE(0x2402, + "Obsolete") +SENSE_CODE(0x2403, + "Obsolete") +SENSE_CODE(SECURITY_AUDIT_VALUE_FROZEN, + "Security audit value frozen") +SENSE_CODE(SECURITY_WORKING_KEY_FROZEN, + "Security working key frozen") +SENSE_CODE(NONCE_NOT_UNIQUE, + "Nonce not unique") +SENSE_CODE(NONCE_TIMESTAMP_OUT_OF_RANGE, + "Nonce timestamp out of range") +SENSE_CODE(INVALID_XCDB, + "Invalid XCDB") +SENSE_CODE(INVALID_FAST_FORMAT, + "Invalid fast format") + +SENSE_CODE(LU_NOT_SUPPORTED, + "Logical unit not supported") + +SENSE_CODE(INVALID_FIELD_IN_PARAMETER_LIST, + "Invalid field in parameter list") +SENSE_CODE(PARAMETER_NOT_SUPPORTED, + "Parameter not supported") +SENSE_CODE(PARAMETER_VALUE_INVALID, + "Parameter value invalid") +SENSE_CODE(THRESHOLD_PARAMETERS_NOT_SUPPORTED, + "Threshold parameters not supported") +SENSE_CODE(INVALID_RELEASE_OF_PERSISTENT_RESERVATION, + "Invalid release of persistent reservation") +SENSE_CODE(DATA_DECRYPTION_ERROR, + "Data decryption error") +SENSE_CODE(TOO_MANY_TARGET_DESCRIPTORS, + "Too many target descriptors") +SENSE_CODE(UNSUPPORTED_TARGET_DESCRIPTOR_TYPE_CODE, + "Unsupported target descriptor type code") +SENSE_CODE(TOO_MANY_SEGMENT_DESCRIPTORS, + "Too many segment descriptors") +SENSE_CODE(UNSUPPORTED_SEGMENT_DESCRIPTOR_TYPE_CODE, + "Unsupported segment descriptor type code") +SENSE_CODE(UNEXPECTED_INEXACT_SEGMENT, + "Unexpected inexact segment") +SENSE_CODE(INLINE_DATA_LENGTH_EXCEEDED, + "Inline data length exceeded") +SENSE_CODE(INVALID_OP_FOR_COPY_SOURCE_OR_DESTINATION, + "Invalid operation for copy source or destination") +SENSE_CODE(COPY_SEGMENT_GRANULARITY_VIOLATION, + "Copy segment granularity violation") +SENSE_CODE(INVALID_PARAMETER_WHILE_PORT_IS_ENABLED, + "Invalid parameter while port is enabled") +SENSE_CODE(INVALID_DATA_OUT_BUFFER_INTEGRITY_CHECK_VALUE, + "Invalid data-out buffer integrity check value") +SENSE_CODE(DATA_DECRYPTION_KEY_FAIL_LIMIT_REACHED, + "Data decryption key fail limit reached") +SENSE_CODE(INCOMPLETE_KEY_ASSOCIATED_DATA_SET, + "Incomplete key-associated data set") +SENSE_CODE(VENDOR_SPECIFIC_KEY_REFERENCE_NOT_FOUND, + "Vendor specific key reference not found") +SENSE_CODE(APPLICATION_TAG_MODE_PAGE_IS_INVALID, + "Application tag mode page is invalid") +SENSE_CODE(TAPE_STREAM_MIRRORING_PREVENTED, + "Tape stream mirroring prevented") +SENSE_CODE(COPY_SOURCE_OR_COPY_DESTINATION_NOT_AUTHORIZED, + "Copy source or copy destination not authorized") +SENSE_CODE(FAST_COPY_NOT_POSSIBLE, + "Fast copy not possible") + +SENSE_CODE(WRITE_PROTECTED, + "Write protected") +SENSE_CODE(HW_WRITE_PROTECTED, + "Hardware write protected") +SENSE_CODE(LU_SOFTWARE_WRITE_PROTECTED, + "Logical unit software write protected") +SENSE_CODE(ASSOCIATED_WRITE_PROTECT, + "Associated write protect") +SENSE_CODE(PERSISTENT_WRITE_PROTECT, + "Persistent write protect") +SENSE_CODE(PERMANENT_WRITE_PROTECT, + "Permanent write protect") +SENSE_CODE(CONDITIONAL_WRITE_PROTECT, + "Conditional write protect") +SENSE_CODE(SPACE_ALLOCATION_FAILED_WRITE_PROTECT, + "Space allocation failed write protect") +SENSE_CODE(ZONE_IS_READ_ONLY, + "Zone is read only") + +SENSE_CODE(NOT_READY_TO_READY_CHANGE_MEDIUM_MAY_HAVE_CHANGED, + "Not ready to ready change, medium may have changed") +SENSE_CODE(IMPORT_OR_EXPORT_ELEMENT_ACCESSED, + "Import or export element accessed") +SENSE_CODE(FORMAT_LAYER_MAY_HAVE_CHANGED, + "Format-layer may have changed") +SENSE_CODE(IMPORT_EXPORT_ELEMENT_ACCESSED_MEDIUM_CHANGED, + "Import/export element accessed, medium changed") + +SENSE_CODE(POWER_ON_RESET_OR_BUS_DEVICE_RESET_OCCURRED, + "Power on, reset, or bus device reset occurred") +SENSE_CODE(POWER_ON_OCCURRED, + "Power on occurred") +SENSE_CODE(SCSI_BUS_RESET_OCCURRED, + "Scsi bus reset occurred") +SENSE_CODE(BUS_DEVICE_RESET_FUNCTION_OCCURRED, + "Bus device reset function occurred") +SENSE_CODE(DEVICE_INTERNAL_RESET, + "Device internal reset") +SENSE_CODE(TRANSCEIVER_MODE_CHANGED_TO_SINGLE_ENDED, + "Transceiver mode changed to single-ended") +SENSE_CODE(TRANSCEIVER_MODE_CHANGED_TO_LVD, + "Transceiver mode changed to lvd") +SENSE_CODE(I_T_NEXUS_LOSS_OCCURRED, + "I_T nexus loss occurred") + +SENSE_CODE(PARAMETERS_CHANGED, + "Parameters changed") +SENSE_CODE(MODE_PARAMETERS_CHANGED, + "Mode parameters changed") +SENSE_CODE(LOG_PARAMETERS_CHANGED, + "Log parameters changed") +SENSE_CODE(RESERVATIONS_PREEMPTED, + "Reservations preempted") +SENSE_CODE(RESERVATIONS_RELEASED, + "Reservations released") +SENSE_CODE(REGISTRATIONS_PREEMPTED, + "Registrations preempted") +SENSE_CODE(ASYMMETRIC_ACCESS_STATE_CHANGED, + "Asymmetric access state changed") +SENSE_CODE(IMPLICIT_ASYMMETRIC_ACCESS_STATE_TRANSITION_FAILED, + "Implicit asymmetric access state transition failed") +SENSE_CODE(PRIORITY_CHANGED, + "Priority changed") +SENSE_CODE(CAPACITY_DATA_HAS_CHANGED, + "Capacity data has changed") +SENSE_CODE(ERROR_HISTORY_I_T_NEXUS_CLEARED, + "Error history I_T nexus cleared") +SENSE_CODE(ERROR_HISTORY_SNAPSHOT_RELEASED, + "Error history snapshot released") +SENSE_CODE(ERROR_RECOVERY_ATTRIBUTES_HAVE_CHANGED, + "Error recovery attributes have changed") +SENSE_CODE(DATA_ENCRYPTION_CAPABILITIES_CHANGED, + "Data encryption capabilities changed") +SENSE_CODE(TIMESTAMP_CHANGED, + "Timestamp changed") +SENSE_CODE(DATA_ENCRYPTION_PARAMS_CHANGED_BY_ANOTHER_I_T_NEXUS, + "Data encryption parameters changed by another i_t nexus") +SENSE_CODE(DATA_ENCRYPTION_PARAMS_CHANGED_BY_VENDOR_SPECIFIC_EVENT, + "Data encryption parameters changed by vendor specific event") +SENSE_CODE(DATA_ENCRYPTION_KEY_INSTANCE_COUNTER_HAS_CHANGED, + "Data encryption key instance counter has changed") +SENSE_CODE(SA_CREATION_CAPABILITIES_DATA_HAS_CHANGED, + "SA creation capabilities data has changed") +SENSE_CODE(MEDIUM_REMOVAL_PREVENTION_PREEMPTED, + "Medium removal prevention preempted") +SENSE_CODE(ZONE_RESET_WRITE_POINTER_RECOMMENDED, + "Zone reset write pointer recommended") + +SENSE_CODE(COPY_CANNOT_EXECUTE_SINCE_HOST_CANNOT_DISCONNECT, + "Copy cannot execute since host cannot disconnect") + +SENSE_CODE(COMMAND_SEQUENCE_ERROR, + "Command sequence error") +SENSE_CODE(TOO_MANY_WINDOWS_SPECIFIED, + "Too many windows specified") +SENSE_CODE(INVALID_COMBINATION_OF_WINDOWS_SPECIFIED, + "Invalid combination of windows specified") +SENSE_CODE(CURRENT_PROGRAM_AREA_IS_NOT_EMPTY, + "Current program area is not empty") +SENSE_CODE(CURRENT_PROGRAM_AREA_IS_EMPTY, + "Current program area is empty") +SENSE_CODE(ILLEGAL_POWER_CONDITION_REQUEST, + "Illegal power condition request") +SENSE_CODE(PERSISTENT_PREVENT_CONFLICT, + "Persistent prevent conflict") +SENSE_CODE(PREVIOUS_BUSY_STATUS, + "Previous busy status") +SENSE_CODE(PREVIOUS_TASK_SET_FULL_STATUS, + "Previous task set full status") +SENSE_CODE(PREVIOUS_RESERVATION_CONFLICT_STATUS, + "Previous reservation conflict status") +SENSE_CODE(PARTITION_OR_COLLECTION_CONTAINS_USER_OBJECTS, + "Partition or collection contains user objects") +SENSE_CODE(NOT_RESERVED, + "Not reserved") +SENSE_CODE(ORWRITE_GENERATION_DOES_NOT_MATCH, + "Orwrite generation does not match") +SENSE_CODE(RESET_WRITE_POINTER_NOT_ALLOWED, + "Reset write pointer not allowed") +SENSE_CODE(ZONE_IS_OFFLINE, + "Zone is offline") +SENSE_CODE(STREAM_NOT_OPEN, + "Stream not open") +SENSE_CODE(UNWRITTEN_DATA_IN_ZONE, + "Unwritten data in zone") +SENSE_CODE(DESCRIPTOR_FORMAT_SENSE_DATA_REQUIRED, + "Descriptor format sense data required") +SENSE_CODE(ZONE_IS_INACTIVE, + "Zone is inactive") +SENSE_CODE(WELL_KNOWN_LU_ACCESS_REQUIRED, + "Well known logical unit access required") + +SENSE_CODE(OVERWRITE_ERROR_ON_UPDATE_IN_PLACE, + "Overwrite error on update in place") + +SENSE_CODE(INSUFFICIENT_TIME_FOR_OPERATION, + "Insufficient time for operation") +SENSE_CODE(COMMAND_TIMEOUT_BEFORE_PROCESSING, + "Command timeout before processing") +SENSE_CODE(COMMAND_TIMEOUT_DURING_PROCESSING, + "Command timeout during processing") +SENSE_CODE(COMMAND_TIMEOUT_DURING_PROCESSING_DUE_TO_ERROR_RECOVERY, + "Command timeout during processing due to error recovery") + +SENSE_CODE(COMMANDS_CLEARED_BY_ANOTHER_INITIATOR, + "Commands cleared by another initiator") +SENSE_CODE(COMMANDS_CLEARED_BY_POWER_LOSS_NOTIFICATION, + "Commands cleared by power loss notification") +SENSE_CODE(COMMANDS_CLEARED_BY_DEVICE_SERVER, + "Commands cleared by device server") +SENSE_CODE(SOME_COMMANDS_CLEARED_BY_QUEUING_LAYER_EVENT, + "Some commands cleared by queuing layer event") + +SENSE_CODE(INCOMPATIBLE_MEDIUM_INSTALLED, + "Incompatible medium installed") +SENSE_CODE(CANNOT_READ_MEDIUM_UNKNOWN_FORMAT, + "Cannot read medium - unknown format") +SENSE_CODE(CANNOT_READ_MEDIUM_INCOMPATIBLE_FORMAT, + "Cannot read medium - incompatible format") +SENSE_CODE(CLEANING_CARTRIDGE_INSTALLED, + "Cleaning cartridge installed") +SENSE_CODE(CANNOT_WRITE_MEDIUM_UNKNOWN_FORMAT, + "Cannot write medium - unknown format") +SENSE_CODE(CANNOT_WRITE_MEDIUM_INCOMPATIBLE_FORMAT, + "Cannot write medium - incompatible format") +SENSE_CODE(CANNOT_FORMAT_MEDIUM_INCOMPATIBLE_MEDIUM, + "Cannot format medium - incompatible medium") +SENSE_CODE(CLEANING_FAILURE, + "Cleaning failure") +SENSE_CODE(CANNOT_WRITE_APPLICATION_CODE_MISMATCH, + "Cannot write - application code mismatch") +SENSE_CODE(CURRENT_SESSION_NOT_FIXATED_FOR_APPEND, + "Current session not fixated for append") +SENSE_CODE(CLEANING_REQUEST_REJECTED, + "Cleaning request rejected") +SENSE_CODE(WORM_MEDIUM_OVERWRITE_ATTEMPTED, + "WORM medium - overwrite attempted") +SENSE_CODE(WORM_MEDIUM_INTEGRITY_CHECK, + "WORM medium - integrity check") +SENSE_CODE(MEDIUM_NOT_FORMATTED, + "Medium not formatted") +SENSE_CODE(INCOMPATIBLE_VOLUME_TYPE, + "Incompatible volume type") +SENSE_CODE(INCOMPATIBLE_VOLUME_QUALIFIER, + "Incompatible volume qualifier") +SENSE_CODE(CLEANING_VOLUME_EXPIRED, + "Cleaning volume expired") + +SENSE_CODE(MEDIUM_FORMAT_CORRUPTED, + "Medium format corrupted") +SENSE_CODE(FORMAT_COMMAND_FAILED, + "Format command failed") +SENSE_CODE(ZONED_FORMATTING_FAILED_DUE_TO_SPARE_LINKING, + "Zoned formatting failed due to spare linking") +SENSE_CODE(SANITIZE_COMMAND_FAILED, + "Sanitize command failed") +SENSE_CODE(DEPOPULATION_FAILED, + "Depopulation failed") +SENSE_CODE(DEPOPULATION_RESTORATION_FAILED, + "Depopulation restoration failed") + +SENSE_CODE(NO_DEFECT_SPARE_LOCATION_AVAILABLE, + "No defect spare location available") +SENSE_CODE(DEFECT_LIST_UPDATE_FAILURE, + "Defect list update failure") + +SENSE_CODE(TAPE_LENGTH_ERROR, + "Tape length error") + +SENSE_CODE(ENCLOSURE_FAILURE, + "Enclosure failure") + +SENSE_CODE(ENCLOSURE_SERVICES_FAILURE, + "Enclosure services failure") +SENSE_CODE(UNSUPPORTED_ENCLOSURE_FUNCTION, + "Unsupported enclosure function") +SENSE_CODE(ENCLOSURE_SERVICES_UNAVAILABLE, + "Enclosure services unavailable") +SENSE_CODE(ENCLOSURE_SERVICES_TRANSFER_FAILURE, + "Enclosure services transfer failure") +SENSE_CODE(ENCLOSURE_SERVICES_TRANSFER_REFUSED, + "Enclosure services transfer refused") +SENSE_CODE(ENCLOSURE_SERVICES_CHECKSUM_ERROR, + "Enclosure services checksum error") + +SENSE_CODE(RIBBON_INK_OR_TONER_FAILURE, + "Ribbon, ink, or toner failure") + +SENSE_CODE(ROUNDED_PARAMETER, + "Rounded parameter") + +SENSE_CODE(EVENT_STATUS_NOTIFICATION, + "Event status notification") +SENSE_CODE(ESN_POWER_MANAGEMENT_CLASS_EVENT, + "Esn - power management class event") +SENSE_CODE(ESN_MEDIA_CLASS_EVENT, + "Esn - media class event") +SENSE_CODE(ESN_DEVICE_BUSY_CLASS_EVENT, + "Esn - device busy class event") +SENSE_CODE(THIN_PROVISIONING_SOFT_THRESHOLD_REACHED, + "Thin Provisioning soft threshold reached") +SENSE_CODE(DEPOPULATION_INTERRUPTED, + "Depopulation interrupted") +SENSE_CODE(DEPOPULATION_RESTORATION_INTERRUPTED, + "Depopulation restoration interrupted") + +SENSE_CODE(SAVING_PARAMETERS_NOT_SUPPORTED, + "Saving parameters not supported") + +SENSE_CODE(MEDIUM_NOT_PRESENT, + "Medium not present") +SENSE_CODE(MEDIUM_NOT_PRESENT_TRAY_CLOSED, + "Medium not present - tray closed") +SENSE_CODE(MEDIUM_NOT_PRESENT_TRAY_OPEN, + "Medium not present - tray open") +SENSE_CODE(MEDIUM_NOT_PRESENT_LOADABLE, + "Medium not present - loadable") +SENSE_CODE(MEDIUM_NOT_PRESENT_MEDIUM_AUXILIARY_MEMORY_ACCESSIBLE, + "Medium not present - medium auxiliary memory accessible") + +SENSE_CODE(SEQUENTIAL_POSITIONING_ERROR, + "Sequential positioning error") +SENSE_CODE(TAPE_POSITION_ERROR_AT_BEGINNING_OF_MEDIUM, + "Tape position error at beginning-of-medium") +SENSE_CODE(TAPE_POSITION_ERROR_AT_END_OF_MEDIUM, + "Tape position error at end-of-medium") +SENSE_CODE(TAPE_OR_ELECTRONIC_VERTICAL_FORMS_UNIT_NOT_READY, + "Tape or electronic vertical forms unit not ready") +SENSE_CODE(SLEW_FAILURE, + "Slew failure") +SENSE_CODE(PAPER_JAM, + "Paper jam") +SENSE_CODE(FAILED_TO_SENSE_TOP_OF_FORM, + "Failed to sense top-of-form") +SENSE_CODE(FAILED_TO_SENSE_BOTTOM_OF_FORM, + "Failed to sense bottom-of-form") +SENSE_CODE(REPOSITION_ERROR, + "Reposition error") +SENSE_CODE(READ_PAST_END_OF_MEDIUM, + "Read past end of medium") +SENSE_CODE(READ_PAST_BEGINNING_OF_MEDIUM, + "Read past beginning of medium") +SENSE_CODE(POSITION_PAST_END_OF_MEDIUM, + "Position past end of medium") +SENSE_CODE(POSITION_PAST_BEGINNING_OF_MEDIUM, + "Position past beginning of medium") +SENSE_CODE(MEDIUM_DESTINATION_ELEMENT_FULL, + "Medium destination element full") +SENSE_CODE(MEDIUM_SOURCE_ELEMENT_EMPTY, + "Medium source element empty") +SENSE_CODE(END_OF_MEDIUM_REACHED, + "End of medium reached") +SENSE_CODE(MEDIUM_MAGAZINE_NOT_ACCESSIBLE, + "Medium magazine not accessible") +SENSE_CODE(MEDIUM_MAGAZINE_REMOVED, + "Medium magazine removed") +SENSE_CODE(MEDIUM_MAGAZINE_INSERTED, + "Medium magazine inserted") +SENSE_CODE(MEDIUM_MAGAZINE_LOCKED, + "Medium magazine locked") +SENSE_CODE(MEDIUM_MAGAZINE_UNLOCKED, + "Medium magazine unlocked") +SENSE_CODE(MECHANICAL_POSITIONING_OR_CHANGER_ERROR, + "Mechanical positioning or changer error") +SENSE_CODE(READ_PAST_END_OF_USER_OBJECT, + "Read past end of user object") +SENSE_CODE(ELEMENT_DISABLED, + "Element disabled") +SENSE_CODE(ELEMENT_ENABLED, + "Element enabled") +SENSE_CODE(DATA_TRANSFER_DEVICE_REMOVED, + "Data transfer device removed") +SENSE_CODE(DATA_TRANSFER_DEVICE_INSERTED, + "Data transfer device inserted") +SENSE_CODE(TOO_MANY_LOGICAL_OBJECTS_ON_PARTITION_TO_SUPPORT_OP, + "Too many logical objects on partition to support operation") +SENSE_CODE(ELEMENT_STATIC_INFORMATION_CHANGED, + "Element static information changed") + +SENSE_CODE(INVALID_BITS_IN_IDENTIFY_MESSAGE, + "Invalid bits in identify message") + +SENSE_CODE(LU_HAS_NOT_SELF_CONFIGURED_YET, + "Logical unit has not self-configured yet") +SENSE_CODE(LU_FAILURE, + "Logical unit failure") +SENSE_CODE(TIMEOUT_ON_LOGICAL_UNIT, + "Timeout on logical unit") +SENSE_CODE(LU_FAILED_SELF_TEST, + "Logical unit failed self-test") +SENSE_CODE(LU_UNABLE_TO_UPDATE_SELFTEST_LOG, + "Logical unit unable to update self-test log") + +SENSE_CODE(TARGET_OPERATING_CONDITIONS_HAVE_CHANGED, + "Target operating conditions have changed") +SENSE_CODE(MICROCODE_HAS_BEEN_CHANGED, + "Microcode has been changed") +SENSE_CODE(CHANGED_OPERATING_DEFINITION, + "Changed operating definition") +SENSE_CODE(INQUIRY_DATA_HAS_CHANGED, + "Inquiry data has changed") +SENSE_CODE(COMPONENT_DEVICE_ATTACHED, + "Component device attached") +SENSE_CODE(DEVICE_IDENTIFIER_CHANGED, + "Device identifier changed") +SENSE_CODE(REDUNDANCY_GROUP_CREATED_OR_MODIFIED, + "Redundancy group created or modified") +SENSE_CODE(REDUNDANCY_GROUP_DELETED, + "Redundancy group deleted") +SENSE_CODE(SPARE_CREATED_OR_MODIFIED, + "Spare created or modified") +SENSE_CODE(SPARE_DELETED, + "Spare deleted") +SENSE_CODE(VOLUME_SET_CREATED_OR_MODIFIED, + "Volume set created or modified") +SENSE_CODE(VOLUME_SET_DELETED, + "Volume set deleted") +SENSE_CODE(VOLUME_SET_DEASSIGNED, + "Volume set deassigned") +SENSE_CODE(VOLUME_SET_REASSIGNED, + "Volume set reassigned") +SENSE_CODE(REPORTED_LUNS_DATA_HAS_CHANGED, + "Reported luns data has changed") +SENSE_CODE(ECHO_BUFFER_OVERWRITTEN, + "Echo buffer overwritten") +SENSE_CODE(MEDIUM_LOADABLE, + "Medium loadable") +SENSE_CODE(MEDIUM_AUXILIARY_MEMORY_ACCESSIBLE, + "Medium auxiliary memory accessible") +SENSE_CODE(iSCSI_IP_ADDRESS_ADDED, + "iSCSI IP address added") +SENSE_CODE(iSCSI_IP_ADDRESS_REMOVED, + "iSCSI IP address removed") +SENSE_CODE(iSCSI_IP_ADDRESS_CHANGED, + "iSCSI IP address changed") +SENSE_CODE(INSPECT_REFERRALS_SENSE_DESCRIPTORS, + "Inspect referrals sense descriptors") +SENSE_CODE(MICROCODE_HAS_BEEN_CHANGED_WITHOUT_RESET, + "Microcode has been changed without reset") +SENSE_CODE(ZONE_TRANSITION_TO_FULL, + "Zone transition to full") +SENSE_CODE(BIND_COMPLETED, + "Bind completed") +SENSE_CODE(BIND_REDIRECTED, + "Bind redirected") +SENSE_CODE(SUBSIDIARY_BINDING_CHANGED, + "Subsidiary binding changed") /* - * SENSE_CODE(0x40NN, "Ram failure") - * SENSE_CODE(0x40NN, "Diagnostic failure on component nn") - * SENSE_CODE(0x41NN, "Data path failure") - * SENSE_CODE(0x42NN, "Power-on or self-test failure") + * SENSE_CODE(0x40NN, "Ram failure") + * SENSE_CODE(0x40NN, "Diagnostic failure on component nn") + * + * SENSE_CODE(0x41NN, "Data path failure") + * + * SENSE_CODE(0x42NN, "Power-on or self-test failure") */ -SENSE_CODE(0x4300, "Message error") - -SENSE_CODE(0x4400, "Internal target failure") -SENSE_CODE(0x4401, "Persistent reservation information lost") -SENSE_CODE(0x4471, "ATA device failed set features") - -SENSE_CODE(0x4500, "Select or reselect failure") - -SENSE_CODE(0x4600, "Unsuccessful soft reset") - -SENSE_CODE(0x4700, "Scsi parity error") -SENSE_CODE(0x4701, "Data phase CRC error detected") -SENSE_CODE(0x4702, "Scsi parity error detected during st data phase") -SENSE_CODE(0x4703, "Information unit iuCRC error detected") -SENSE_CODE(0x4704, "Asynchronous information protection error detected") -SENSE_CODE(0x4705, "Protocol service CRC error") -SENSE_CODE(0x4706, "Phy test function in progress") -SENSE_CODE(0x477f, "Some commands cleared by iSCSI Protocol event") - -SENSE_CODE(0x4800, "Initiator detected error message received") - -SENSE_CODE(0x4900, "Invalid message error") - -SENSE_CODE(0x4A00, "Command phase error") - -SENSE_CODE(0x4B00, "Data phase error") -SENSE_CODE(0x4B01, "Invalid target port transfer tag received") -SENSE_CODE(0x4B02, "Too much write data") -SENSE_CODE(0x4B03, "Ack/nak timeout") -SENSE_CODE(0x4B04, "Nak received") -SENSE_CODE(0x4B05, "Data offset error") -SENSE_CODE(0x4B06, "Initiator response timeout") -SENSE_CODE(0x4B07, "Connection lost") -SENSE_CODE(0x4B08, "Data-in buffer overflow - data buffer size") -SENSE_CODE(0x4B09, "Data-in buffer overflow - data buffer descriptor area") -SENSE_CODE(0x4B0A, "Data-in buffer error") -SENSE_CODE(0x4B0B, "Data-out buffer overflow - data buffer size") -SENSE_CODE(0x4B0C, "Data-out buffer overflow - data buffer descriptor area") -SENSE_CODE(0x4B0D, "Data-out buffer error") -SENSE_CODE(0x4B0E, "PCIe fabric error") -SENSE_CODE(0x4B0F, "PCIe completion timeout") -SENSE_CODE(0x4B10, "PCIe completer abort") -SENSE_CODE(0x4B11, "PCIe poisoned tlp received") -SENSE_CODE(0x4B12, "PCIe eCRC check failed") -SENSE_CODE(0x4B13, "PCIe unsupported request") -SENSE_CODE(0x4B14, "PCIe acs violation") -SENSE_CODE(0x4B15, "PCIe tlp prefix blocked") - -SENSE_CODE(0x4C00, "Logical unit failed self-configuration") + +SENSE_CODE(MESSAGE_ERROR, + "Message error") + +SENSE_CODE(INTERNAL_TARGET_FAILURE, + "Internal target failure") +SENSE_CODE(PERSISTENT_RESERVATION_INFORMATION_LOST, + "Persistent reservation information lost") +SENSE_CODE(ATA_DEVICE_FAILED_SET_FEATURES, + "ATA device failed set features") + +SENSE_CODE(SELECT_OR_RESELECT_FAILURE, + "Select or reselect failure") + +SENSE_CODE(UNSUCCESSFUL_SOFT_RESET, + "Unsuccessful soft reset") + +SENSE_CODE(SCSI_PARITY_ERROR, + "Scsi parity error") +SENSE_CODE(DATA_PHASE_CRC_ERROR_DETECTED, + "Data phase CRC error detected") +SENSE_CODE(SCSI_PARITY_ERROR_DETECTED_DURING_ST_DATA_PHASE, + "Scsi parity error detected during st data phase") +SENSE_CODE(INFORMATION_UNIT_iuCRC_ERROR_DETECTED, + "Information unit iuCRC error detected") +SENSE_CODE(ASYNCHRONOUS_INFORMATION_PROTECTION_ERROR_DETECTED, + "Asynchronous information protection error detected") +SENSE_CODE(PROTOCOL_SERVICE_CRC_ERROR, + "Protocol service CRC error") +SENSE_CODE(PHY_TEST_FUNCTION_IN_PROGRESS, + "Phy test function in progress") +SENSE_CODE(SOME_COMMANDS_CLEARED_BY_ISCSI_PROTOCOL_EVENT, + "Some commands cleared by iSCSI Protocol event") + +SENSE_CODE(INITIATOR_DETECTED_ERROR_MESSAGE_RECEIVED, + "Initiator detected error message received") + +SENSE_CODE(INVALID_MESSAGE_ERROR, + "Invalid message error") + +SENSE_CODE(COMMAND_PHASE_ERROR, + "Command phase error") + +SENSE_CODE(DATA_PHASE_ERROR, + "Data phase error") +SENSE_CODE(INVALID_TARGET_PORT_TRANSFER_TAG_RECEIVED, + "Invalid target port transfer tag received") +SENSE_CODE(TOO_MUCH_WRITE_DATA, + "Too much write data") +SENSE_CODE(ACK_NAK_TIMEOUT, + "Ack/nak timeout") +SENSE_CODE(NAK_RECEIVED, + "Nak received") +SENSE_CODE(DATA_OFFSET_ERROR, + "Data offset error") +SENSE_CODE(INITIATOR_RESPONSE_TIMEOUT, + "Initiator response timeout") +SENSE_CODE(CONNECTION_LOST, + "Connection lost") +SENSE_CODE(DATA_IN_BUFFER_OVERFLOW_BUFFER_SIZE, + "Data-in buffer overflow - data buffer size") +SENSE_CODE(DATA_IN_BUFFER_OVERFLOW_BUFFER_DESCRIPTOR_AREA, + "Data-in buffer overflow - data buffer descriptor area") +SENSE_CODE(DATA_IN_BUFFER_ERROR, + "Data-in buffer error") +SENSE_CODE(DATA_OUT_BUFFER_OVERFLOW_BUFFER_SIZE, + "Data-out buffer overflow - data buffer size") +SENSE_CODE(DATA_OUT_BUFFER_OVERFLOW_BUFFER_DESCRIPTOR_AREA, + "Data-out buffer overflow - data buffer descriptor area") +SENSE_CODE(DATA_OUT_BUFFER_ERROR, + "Data-out buffer error") +SENSE_CODE(PCIE_FABRIC_ERROR, + "PCIe fabric error") +SENSE_CODE(PCIE_COMPLETION_TIMEOUT, + "PCIe completion timeout") +SENSE_CODE(PCIE_COMPLETER_ABORT, + "PCIe completer abort") +SENSE_CODE(PCIE_POISONED_TLP_RECEIVED, + "PCIe poisoned tlp received") +SENSE_CODE(PCIE_ECRC_CHECK_FAILED, + "PCIe eCRC check failed") +SENSE_CODE(PCIE_UNSUPPORTED_REQUEST, + "PCIe unsupported request") +SENSE_CODE(PCIE_ACS_VIOLATION, + "PCIe acs violation") +SENSE_CODE(PCIE_TLP_PREFIX_BLOCKED, + "PCIe tlp prefix blocked") + +SENSE_CODE(LU_FAILED_SELF_CONFIGURATION, + "Logical unit failed self-configuration") + /* - * SENSE_CODE(0x4DNN, "Tagged overlapped commands (nn = queue tag)") + * SENSE_CODE(0x4DNN, "Tagged overlapped commands (nn = queue tag)") */ -SENSE_CODE(0x4E00, "Overlapped commands attempted") - -SENSE_CODE(0x5000, "Write append error") -SENSE_CODE(0x5001, "Write append position error") -SENSE_CODE(0x5002, "Position error related to timing") - -SENSE_CODE(0x5100, "Erase failure") -SENSE_CODE(0x5101, "Erase failure - incomplete erase operation detected") - -SENSE_CODE(0x5200, "Cartridge fault") - -SENSE_CODE(0x5300, "Media load or eject failed") -SENSE_CODE(0x5301, "Unload tape failure") -SENSE_CODE(0x5302, "Medium removal prevented") -SENSE_CODE(0x5303, "Medium removal prevented by data transfer element") -SENSE_CODE(0x5304, "Medium thread or unthread failure") -SENSE_CODE(0x5305, "Volume identifier invalid") -SENSE_CODE(0x5306, "Volume identifier missing") -SENSE_CODE(0x5307, "Duplicate volume identifier") -SENSE_CODE(0x5308, "Element status unknown") -SENSE_CODE(0x5309, "Data transfer device error - load failed") -SENSE_CODE(0x530a, "Data transfer device error - unload failed") -SENSE_CODE(0x530b, "Data transfer device error - unload missing") -SENSE_CODE(0x530c, "Data transfer device error - eject failed") -SENSE_CODE(0x530d, "Data transfer device error - library communication failed") - -SENSE_CODE(0x5400, "Scsi to host system interface failure") - -SENSE_CODE(0x5500, "System resource failure") -SENSE_CODE(0x5501, "System buffer full") -SENSE_CODE(0x5502, "Insufficient reservation resources") -SENSE_CODE(0x5503, "Insufficient resources") -SENSE_CODE(0x5504, "Insufficient registration resources") -SENSE_CODE(0x5505, "Insufficient access control resources") -SENSE_CODE(0x5506, "Auxiliary memory out of space") -SENSE_CODE(0x5507, "Quota error") -SENSE_CODE(0x5508, "Maximum number of supplemental decryption keys exceeded") -SENSE_CODE(0x5509, "Medium auxiliary memory not accessible") -SENSE_CODE(0x550A, "Data currently unavailable") -SENSE_CODE(0x550B, "Insufficient power for operation") -SENSE_CODE(0x550C, "Insufficient resources to create rod") -SENSE_CODE(0x550D, "Insufficient resources to create rod token") -SENSE_CODE(0x550E, "Insufficient zone resources") -SENSE_CODE(0x550F, "Insufficient zone resources to complete write") -SENSE_CODE(0x5510, "Maximum number of streams open") -SENSE_CODE(0x5511, "Insufficient resources to bind") - -SENSE_CODE(0x5700, "Unable to recover table-of-contents") - -SENSE_CODE(0x5800, "Generation does not exist") - -SENSE_CODE(0x5900, "Updated block read") - -SENSE_CODE(0x5A00, "Operator request or state change input") -SENSE_CODE(0x5A01, "Operator medium removal request") -SENSE_CODE(0x5A02, "Operator selected write protect") -SENSE_CODE(0x5A03, "Operator selected write permit") - -SENSE_CODE(0x5B00, "Log exception") -SENSE_CODE(0x5B01, "Threshold condition met") -SENSE_CODE(0x5B02, "Log counter at maximum") -SENSE_CODE(0x5B03, "Log list codes exhausted") - -SENSE_CODE(0x5C00, "Rpl status change") -SENSE_CODE(0x5C01, "Spindles synchronized") -SENSE_CODE(0x5C02, "Spindles not synchronized") - -SENSE_CODE(0x5D00, "Failure prediction threshold exceeded") -SENSE_CODE(0x5D01, "Media failure prediction threshold exceeded") -SENSE_CODE(0x5D02, "Logical unit failure prediction threshold exceeded") -SENSE_CODE(0x5D03, "Spare area exhaustion prediction threshold exceeded") -SENSE_CODE(0x5D10, "Hardware impending failure general hard drive failure") -SENSE_CODE(0x5D11, "Hardware impending failure drive error rate too high") -SENSE_CODE(0x5D12, "Hardware impending failure data error rate too high") -SENSE_CODE(0x5D13, "Hardware impending failure seek error rate too high") -SENSE_CODE(0x5D14, "Hardware impending failure too many block reassigns") -SENSE_CODE(0x5D15, "Hardware impending failure access times too high") -SENSE_CODE(0x5D16, "Hardware impending failure start unit times too high") -SENSE_CODE(0x5D17, "Hardware impending failure channel parametrics") -SENSE_CODE(0x5D18, "Hardware impending failure controller detected") -SENSE_CODE(0x5D19, "Hardware impending failure throughput performance") -SENSE_CODE(0x5D1A, "Hardware impending failure seek time performance") -SENSE_CODE(0x5D1B, "Hardware impending failure spin-up retry count") -SENSE_CODE(0x5D1C, "Hardware impending failure drive calibration retry count") -SENSE_CODE(0x5D20, "Controller impending failure general hard drive failure") -SENSE_CODE(0x5D21, "Controller impending failure drive error rate too high") -SENSE_CODE(0x5D22, "Controller impending failure data error rate too high") -SENSE_CODE(0x5D23, "Controller impending failure seek error rate too high") -SENSE_CODE(0x5D24, "Controller impending failure too many block reassigns") -SENSE_CODE(0x5D25, "Controller impending failure access times too high") -SENSE_CODE(0x5D26, "Controller impending failure start unit times too high") -SENSE_CODE(0x5D27, "Controller impending failure channel parametrics") -SENSE_CODE(0x5D28, "Controller impending failure controller detected") -SENSE_CODE(0x5D29, "Controller impending failure throughput performance") -SENSE_CODE(0x5D2A, "Controller impending failure seek time performance") -SENSE_CODE(0x5D2B, "Controller impending failure spin-up retry count") -SENSE_CODE(0x5D2C, "Controller impending failure drive calibration retry count") -SENSE_CODE(0x5D30, "Data channel impending failure general hard drive failure") -SENSE_CODE(0x5D31, "Data channel impending failure drive error rate too high") -SENSE_CODE(0x5D32, "Data channel impending failure data error rate too high") -SENSE_CODE(0x5D33, "Data channel impending failure seek error rate too high") -SENSE_CODE(0x5D34, "Data channel impending failure too many block reassigns") -SENSE_CODE(0x5D35, "Data channel impending failure access times too high") -SENSE_CODE(0x5D36, "Data channel impending failure start unit times too high") -SENSE_CODE(0x5D37, "Data channel impending failure channel parametrics") -SENSE_CODE(0x5D38, "Data channel impending failure controller detected") -SENSE_CODE(0x5D39, "Data channel impending failure throughput performance") -SENSE_CODE(0x5D3A, "Data channel impending failure seek time performance") -SENSE_CODE(0x5D3B, "Data channel impending failure spin-up retry count") -SENSE_CODE(0x5D3C, "Data channel impending failure drive calibration retry count") -SENSE_CODE(0x5D40, "Servo impending failure general hard drive failure") -SENSE_CODE(0x5D41, "Servo impending failure drive error rate too high") -SENSE_CODE(0x5D42, "Servo impending failure data error rate too high") -SENSE_CODE(0x5D43, "Servo impending failure seek error rate too high") -SENSE_CODE(0x5D44, "Servo impending failure too many block reassigns") -SENSE_CODE(0x5D45, "Servo impending failure access times too high") -SENSE_CODE(0x5D46, "Servo impending failure start unit times too high") -SENSE_CODE(0x5D47, "Servo impending failure channel parametrics") -SENSE_CODE(0x5D48, "Servo impending failure controller detected") -SENSE_CODE(0x5D49, "Servo impending failure throughput performance") -SENSE_CODE(0x5D4A, "Servo impending failure seek time performance") -SENSE_CODE(0x5D4B, "Servo impending failure spin-up retry count") -SENSE_CODE(0x5D4C, "Servo impending failure drive calibration retry count") -SENSE_CODE(0x5D50, "Spindle impending failure general hard drive failure") -SENSE_CODE(0x5D51, "Spindle impending failure drive error rate too high") -SENSE_CODE(0x5D52, "Spindle impending failure data error rate too high") -SENSE_CODE(0x5D53, "Spindle impending failure seek error rate too high") -SENSE_CODE(0x5D54, "Spindle impending failure too many block reassigns") -SENSE_CODE(0x5D55, "Spindle impending failure access times too high") -SENSE_CODE(0x5D56, "Spindle impending failure start unit times too high") -SENSE_CODE(0x5D57, "Spindle impending failure channel parametrics") -SENSE_CODE(0x5D58, "Spindle impending failure controller detected") -SENSE_CODE(0x5D59, "Spindle impending failure throughput performance") -SENSE_CODE(0x5D5A, "Spindle impending failure seek time performance") -SENSE_CODE(0x5D5B, "Spindle impending failure spin-up retry count") -SENSE_CODE(0x5D5C, "Spindle impending failure drive calibration retry count") -SENSE_CODE(0x5D60, "Firmware impending failure general hard drive failure") -SENSE_CODE(0x5D61, "Firmware impending failure drive error rate too high") -SENSE_CODE(0x5D62, "Firmware impending failure data error rate too high") -SENSE_CODE(0x5D63, "Firmware impending failure seek error rate too high") -SENSE_CODE(0x5D64, "Firmware impending failure too many block reassigns") -SENSE_CODE(0x5D65, "Firmware impending failure access times too high") -SENSE_CODE(0x5D66, "Firmware impending failure start unit times too high") -SENSE_CODE(0x5D67, "Firmware impending failure channel parametrics") -SENSE_CODE(0x5D68, "Firmware impending failure controller detected") -SENSE_CODE(0x5D69, "Firmware impending failure throughput performance") -SENSE_CODE(0x5D6A, "Firmware impending failure seek time performance") -SENSE_CODE(0x5D6B, "Firmware impending failure spin-up retry count") -SENSE_CODE(0x5D6C, "Firmware impending failure drive calibration retry count") -SENSE_CODE(0x5D73, "Media impending failure endurance limit met") -SENSE_CODE(0x5DFF, "Failure prediction threshold exceeded (false)") - -SENSE_CODE(0x5E00, "Low power condition on") -SENSE_CODE(0x5E01, "Idle condition activated by timer") -SENSE_CODE(0x5E02, "Standby condition activated by timer") -SENSE_CODE(0x5E03, "Idle condition activated by command") -SENSE_CODE(0x5E04, "Standby condition activated by command") -SENSE_CODE(0x5E05, "Idle_b condition activated by timer") -SENSE_CODE(0x5E06, "Idle_b condition activated by command") -SENSE_CODE(0x5E07, "Idle_c condition activated by timer") -SENSE_CODE(0x5E08, "Idle_c condition activated by command") -SENSE_CODE(0x5E09, "Standby_y condition activated by timer") -SENSE_CODE(0x5E0A, "Standby_y condition activated by command") -SENSE_CODE(0x5E41, "Power state change to active") -SENSE_CODE(0x5E42, "Power state change to idle") -SENSE_CODE(0x5E43, "Power state change to standby") -SENSE_CODE(0x5E45, "Power state change to sleep") -SENSE_CODE(0x5E47, "Power state change to device control") - -SENSE_CODE(0x6000, "Lamp failure") - -SENSE_CODE(0x6100, "Video acquisition error") -SENSE_CODE(0x6101, "Unable to acquire video") -SENSE_CODE(0x6102, "Out of focus") - -SENSE_CODE(0x6200, "Scan head positioning error") - -SENSE_CODE(0x6300, "End of user area encountered on this track") -SENSE_CODE(0x6301, "Packet does not fit in available space") - -SENSE_CODE(0x6400, "Illegal mode for this track") -SENSE_CODE(0x6401, "Invalid packet size") - -SENSE_CODE(0x6500, "Voltage fault") - -SENSE_CODE(0x6600, "Automatic document feeder cover up") -SENSE_CODE(0x6601, "Automatic document feeder lift up") -SENSE_CODE(0x6602, "Document jam in automatic document feeder") -SENSE_CODE(0x6603, "Document miss feed automatic in document feeder") - -SENSE_CODE(0x6700, "Configuration failure") -SENSE_CODE(0x6701, "Configuration of incapable logical units failed") -SENSE_CODE(0x6702, "Add logical unit failed") -SENSE_CODE(0x6703, "Modification of logical unit failed") -SENSE_CODE(0x6704, "Exchange of logical unit failed") -SENSE_CODE(0x6705, "Remove of logical unit failed") -SENSE_CODE(0x6706, "Attachment of logical unit failed") -SENSE_CODE(0x6707, "Creation of logical unit failed") -SENSE_CODE(0x6708, "Assign failure occurred") -SENSE_CODE(0x6709, "Multiply assigned logical unit") -SENSE_CODE(0x670A, "Set target port groups command failed") -SENSE_CODE(0x670B, "ATA device feature not enabled") -SENSE_CODE(0x670C, "Command rejected") -SENSE_CODE(0x670D, "Explicit bind not allowed") - -SENSE_CODE(0x6800, "Logical unit not configured") -SENSE_CODE(0x6801, "Subsidiary logical unit not configured") - -SENSE_CODE(0x6900, "Data loss on logical unit") -SENSE_CODE(0x6901, "Multiple logical unit failures") -SENSE_CODE(0x6902, "Parity/data mismatch") - -SENSE_CODE(0x6A00, "Informational, refer to log") - -SENSE_CODE(0x6B00, "State change has occurred") -SENSE_CODE(0x6B01, "Redundancy level got better") -SENSE_CODE(0x6B02, "Redundancy level got worse") - -SENSE_CODE(0x6C00, "Rebuild failure occurred") - -SENSE_CODE(0x6D00, "Recalculate failure occurred") - -SENSE_CODE(0x6E00, "Command to logical unit failed") - -SENSE_CODE(0x6F00, "Copy protection key exchange failure - authentication failure") -SENSE_CODE(0x6F01, "Copy protection key exchange failure - key not present") -SENSE_CODE(0x6F02, "Copy protection key exchange failure - key not established") -SENSE_CODE(0x6F03, "Read of scrambled sector without authentication") -SENSE_CODE(0x6F04, "Media region code is mismatched to logical unit region") -SENSE_CODE(0x6F05, "Drive region must be permanent/region reset count error") -SENSE_CODE(0x6F06, "Insufficient block count for binding nonce recording") -SENSE_CODE(0x6F07, "Conflict in binding nonce recording") -SENSE_CODE(0x6F08, "Insufficient permission") -SENSE_CODE(0x6F09, "Invalid drive-host pairing server") -SENSE_CODE(0x6F0A, "Drive-host pairing suspended") + +SENSE_CODE(OVERLAPPED_COMMANDS_ATTEMPTED, + "Overlapped commands attempted") + +SENSE_CODE(WRITE_APPEND_ERROR, + "Write append error") +SENSE_CODE(WRITE_APPEND_POSITION_ERROR, + "Write append position error") +SENSE_CODE(POSITION_ERROR_RELATED_TO_TIMING, + "Position error related to timing") + +SENSE_CODE(ERASE_FAILURE, + "Erase failure") +SENSE_CODE(ERASE_FAILURE_INCOMPLETE_ERASE_OP_DETECTED, + "Erase failure - incomplete erase operation detected") + +SENSE_CODE(CARTRIDGE_FAULT, + "Cartridge fault") + +SENSE_CODE(MEDIA_LOAD_OR_EJECT_FAILED, + "Media load or eject failed") +SENSE_CODE(UNLOAD_TAPE_FAILURE, + "Unload tape failure") +SENSE_CODE(MEDIUM_REMOVAL_PREVENTED, + "Medium removal prevented") +SENSE_CODE(MEDIUM_REMOVAL_PREVENTED_BY_DATA_TRANSFER_ELEMENT, + "Medium removal prevented by data transfer element") +SENSE_CODE(MEDIUM_THREAD_OR_UNTHREAD_FAILURE, + "Medium thread or unthread failure") +SENSE_CODE(VOLUME_IDENTIFIER_INVALID, + "Volume identifier invalid") +SENSE_CODE(VOLUME_IDENTIFIER_MISSING, + "Volume identifier missing") +SENSE_CODE(DUPLICATE_VOLUME_IDENTIFIER, + "Duplicate volume identifier") +SENSE_CODE(ELEMENT_STATUS_UNKNOWN, + "Element status unknown") +SENSE_CODE(DATA_TRANSFER_DEVICE_ERR_LOAD_FAILED, + "Data transfer device error - load failed") +SENSE_CODE(DATA_TRANSFER_DEVICE_ERR_UNLOAD_FAILED, + "Data transfer device error - unload failed") +SENSE_CODE(DATA_TRANSFER_DEVICE_ERR_UNLOAD_MISSING, + "Data transfer device error - unload missing") +SENSE_CODE(DATA_TRANSFER_DEVICE_ERR_EJECT_FAILED, + "Data transfer device error - eject failed") +SENSE_CODE(DATA_TRANSFER_DEVICE_ERR_LIBRARY_COMMUNICATION_FAILED, + "Data transfer device error - library communication failed") + +SENSE_CODE(SCSI_TO_HOST_SYSTEM_INTERFACE_FAILURE, + "Scsi to host system interface failure") + +SENSE_CODE(SYSTEM_RESOURCE_FAILURE, + "System resource failure") +SENSE_CODE(SYSTEM_BUFFER_FULL, + "System buffer full") +SENSE_CODE(INSUFFICIENT_RESERVATION_RESOURCES, + "Insufficient reservation resources") +SENSE_CODE(INSUFFICIENT_RESOURCES, + "Insufficient resources") +SENSE_CODE(INSUFFICIENT_REGISTRATION_RESOURCES, + "Insufficient registration resources") +SENSE_CODE(INSUFFICIENT_ACCESS_CONTROL_RESOURCES, + "Insufficient access control resources") +SENSE_CODE(AUXILIARY_MEMORY_OUT_OF_SPACE, + "Auxiliary memory out of space") +SENSE_CODE(QUOTA_ERROR, + "Quota error") +SENSE_CODE(MAXIMUM_NUMBER_OF_SUPPLEMENTAL_DECRYPTION_KEYS_EXCEEDED, + "Maximum number of supplemental decryption keys exceeded") +SENSE_CODE(MEDIUM_AUXILIARY_MEMORY_NOT_ACCESSIBLE, + "Medium auxiliary memory not accessible") +SENSE_CODE(DATA_CURRENTLY_UNAVAILABLE, + "Data currently unavailable") +SENSE_CODE(INSUFFICIENT_POWER_FOR_OPERATION, + "Insufficient power for operation") +SENSE_CODE(INSUFFICIENT_RESOURCES_TO_CREATE_ROD, + "Insufficient resources to create rod") +SENSE_CODE(INSUFFICIENT_RESOURCES_TO_CREATE_ROD_TOKEN, + "Insufficient resources to create rod token") +SENSE_CODE(INSUFFICIENT_ZONE_RESOURCES, + "Insufficient zone resources") +SENSE_CODE(INSUFFICIENT_ZONE_RESOURCES_TO_COMPLETE_WRITE, + "Insufficient zone resources to complete write") +SENSE_CODE(MAXIMUM_NUMBER_OF_STREAMS_OPEN, + "Maximum number of streams open") +SENSE_CODE(INSUFFICIENT_RESOURCES_TO_BIND, + "Insufficient resources to bind") + +SENSE_CODE(UNABLE_TO_RECOVER_TABLE_OF_CONTENTS, + "Unable to recover table-of-contents") + +SENSE_CODE(GENERATION_DOES_NOT_EXIST, + "Generation does not exist") + +SENSE_CODE(UPDATED_BLOCK_READ, + "Updated block read") + +SENSE_CODE(OPERATOR_REQUEST_OR_STATE_CHANGE_INPUT, + "Operator request or state change input") +SENSE_CODE(OPERATOR_MEDIUM_REMOVAL_REQUEST, + "Operator medium removal request") +SENSE_CODE(OPERATOR_SELECTED_WRITE_PROTECT, + "Operator selected write protect") +SENSE_CODE(OPERATOR_SELECTED_WRITE_PERMIT, + "Operator selected write permit") + +SENSE_CODE(LOG_EXCEPTION, + "Log exception") +SENSE_CODE(THRESHOLD_CONDITION_MET, + "Threshold condition met") +SENSE_CODE(LOG_COUNTER_AT_MAXIMUM, + "Log counter at maximum") +SENSE_CODE(LOG_LIST_CODES_EXHAUSTED, + "Log list codes exhausted") + +SENSE_CODE(RPL_STATUS_CHANGE, + "Rpl status change") +SENSE_CODE(SPINDLES_SYNCHRONIZED, + "Spindles synchronized") +SENSE_CODE(SPINDLES_NOT_SYNCHRONIZED, + "Spindles not synchronized") + +SENSE_CODE(FAILURE_PREDICTION_THRESHOLD_EXCEEDED, + "Failure prediction threshold exceeded") +SENSE_CODE(MEDIA_FAILURE_PREDICTION_THRESHOLD_EXCEEDED, + "Media failure prediction threshold exceeded") +SENSE_CODE(LU_FAILURE_PREDICTION_THRESHOLD_EXCEEDED, + "Logical unit failure prediction threshold exceeded") +SENSE_CODE(SPARE_AREA_EXHAUSTION_PREDICTION_THRESHOLD_EXCEEDED, + "Spare area exhaustion prediction threshold exceeded") +SENSE_CODE(HW_IMPENDING_FAILURE_GENERAL_HARD_DRIVE_FAILURE, + "Hardware impending failure general hard drive failure") +SENSE_CODE(HW_IMPENDING_FAILURE_DRIVE_ERROR_RATE_TOO_HIGH, + "Hardware impending failure drive error rate too high") +SENSE_CODE(HW_IMPENDING_FAILURE_DATA_ERROR_RATE_TOO_HIGH, + "Hardware impending failure data error rate too high") +SENSE_CODE(HW_IMPENDING_FAILURE_SEEK_ERROR_RATE_TOO_HIGH, + "Hardware impending failure seek error rate too high") +SENSE_CODE(HW_IMPENDING_FAILURE_TOO_MANY_BLOCK_REASSIGNS, + "Hardware impending failure too many block reassigns") +SENSE_CODE(HW_IMPENDING_FAILURE_ACCESS_TIMES_TOO_HIGH, + "Hardware impending failure access times too high") +SENSE_CODE(HW_IMPENDING_FAILURE_START_UNIT_TIMES_TOO_HIGH, + "Hardware impending failure start unit times too high") +SENSE_CODE(HW_IMPENDING_FAILURE_CHANNEL_PARAMETRICS, + "Hardware impending failure channel parametrics") +SENSE_CODE(HW_IMPENDING_FAILURE_CONTROLLER_DETECTED, + "Hardware impending failure controller detected") +SENSE_CODE(HW_IMPENDING_FAILURE_THROUGHPUT_PERFORMANCE, + "Hardware impending failure throughput performance") +SENSE_CODE(HW_IMPENDING_FAILURE_SEEK_TIME_PERFORMANCE, + "Hardware impending failure seek time performance") +SENSE_CODE(HW_IMPENDING_FAILURE_SPINUP_RETRY_COUNT, + "Hardware impending failure spin-up retry count") +SENSE_CODE(HW_IMPENDING_FAILURE_DRIVE_CALIBRATION_RETRY_COUNT, + "Hardware impending failure drive calibration retry count") +SENSE_CODE(CONTROLLER_IMPENDING_FAILURE_GENERAL_HARD_DRIVE_FAILURE, + "Controller impending failure general hard drive failure") +SENSE_CODE(CONTROLLER_IMPENDING_FAILURE_DRIVE_ERROR_RATE_TOO_HIGH, + "Controller impending failure drive error rate too high") +SENSE_CODE(CONTROLLER_IMPENDING_FAILURE_DATA_ERROR_RATE_TOO_HIGH, + "Controller impending failure data error rate too high") +SENSE_CODE(CONTROLLER_IMPENDING_FAILURE_SEEK_ERROR_RATE_TOO_HIGH, + "Controller impending failure seek error rate too high") +SENSE_CODE(CONTROLLER_IMPENDING_FAILURE_TOO_MANY_BLOCK_REASSIGNS, + "Controller impending failure too many block reassigns") +SENSE_CODE(CONTROLLER_IMPENDING_FAILURE_ACCESS_TIMES_TOO_HIGH, + "Controller impending failure access times too high") +SENSE_CODE(CONTROLLER_IMPENDING_FAILURE_START_UNIT_TIMES_TOO_HIGH, + "Controller impending failure start unit times too high") +SENSE_CODE(CONTROLLER_IMPENDING_FAILURE_CHANNEL_PARAMETRICS, + "Controller impending failure channel parametrics") +SENSE_CODE(CONTROLLER_IMPENDING_FAILURE_CONTROLLER_DETECTED, + "Controller impending failure controller detected") +SENSE_CODE(CONTROLLER_IMPENDING_FAILURE_THROUGHPUT_PERFORMANCE, + "Controller impending failure throughput performance") +SENSE_CODE(CONTROLLER_IMPENDING_FAILURE_SEEK_TIME_PERFORMANCE, + "Controller impending failure seek time performance") +SENSE_CODE(CONTROLLER_IMPENDING_FAILURE_SPINUP_RETRY_COUNT, + "Controller impending failure spin-up retry count") +SENSE_CODE(CONTROLLER_IMPENDING_FAILURE_DRIVE_CALIBRATION_RETRY_COUNT, + "Controller impending failure drive calibration retry count") +SENSE_CODE(DATA_CHANNEL_IMPENDING_FAILURE_GENERAL_HARD_DRIVE_FAILURE, + "Data channel impending failure general hard drive failure") +SENSE_CODE(DATA_CHANNEL_IMPENDING_FAILURE_DRIVE_ERROR_RATE_TOO_HIGH, + "Data channel impending failure drive error rate too high") +SENSE_CODE(DATA_CHANNEL_IMPENDING_FAILURE_DATA_ERROR_RATE_TOO_HIGH, + "Data channel impending failure data error rate too high") +SENSE_CODE(DATA_CHANNEL_IMPENDING_FAILURE_SEEK_ERROR_RATE_TOO_HIGH, + "Data channel impending failure seek error rate too high") +SENSE_CODE(DATA_CHANNEL_IMPENDING_FAILURE_TOO_MANY_BLOCK_REASSIGNS, + "Data channel impending failure too many block reassigns") +SENSE_CODE(DATA_CHANNEL_IMPENDING_FAILURE_ACCESS_TIMES_TOO_HIGH, + "Data channel impending failure access times too high") +SENSE_CODE(DATA_CHANNEL_IMPENDING_FAILURE_START_UNIT_TIMES_TOO_HIGH, + "Data channel impending failure start unit times too high") +SENSE_CODE(DATA_CHANNEL_IMPENDING_FAILURE_CHANNEL_PARAMETRICS, + "Data channel impending failure channel parametrics") +SENSE_CODE(DATA_CHANNEL_IMPENDING_FAILURE_CONTROLLER_DETECTED, + "Data channel impending failure controller detected") +SENSE_CODE(DATA_CHANNEL_IMPENDING_FAILURE_THROUGHPUT_PERFORMANCE, + "Data channel impending failure throughput performance") +SENSE_CODE(DATA_CHANNEL_IMPENDING_FAILURE_SEEK_TIME_PERFORMANCE, + "Data channel impending failure seek time performance") +SENSE_CODE(DATA_CHANNEL_IMPENDING_FAILURE_SPINUP_RETRY_COUNT, + "Data channel impending failure spin-up retry count") +SENSE_CODE(DATA_CHANNEL_IMPENDING_FAILURE_DRIVE_CALIBRATION_RETRY_COUNT, + "Data channel impending failure drive calibration retry count") +SENSE_CODE(SERVO_IMPENDING_FAILURE_GENERAL_HARD_DRIVE_FAILURE, + "Servo impending failure general hard drive failure") +SENSE_CODE(SERVO_IMPENDING_FAILURE_DRIVE_ERROR_RATE_TOO_HIGH, + "Servo impending failure drive error rate too high") +SENSE_CODE(SERVO_IMPENDING_FAILURE_DATA_ERROR_RATE_TOO_HIGH, + "Servo impending failure data error rate too high") +SENSE_CODE(SERVO_IMPENDING_FAILURE_SEEK_ERROR_RATE_TOO_HIGH, + "Servo impending failure seek error rate too high") +SENSE_CODE(SERVO_IMPENDING_FAILURE_TOO_MANY_BLOCK_REASSIGNS, + "Servo impending failure too many block reassigns") +SENSE_CODE(SERVO_IMPENDING_FAILURE_ACCESS_TIMES_TOO_HIGH, + "Servo impending failure access times too high") +SENSE_CODE(SERVO_IMPENDING_FAILURE_START_UNIT_TIMES_TOO_HIGH, + "Servo impending failure start unit times too high") +SENSE_CODE(SERVO_IMPENDING_FAILURE_CHANNEL_PARAMETRICS, + "Servo impending failure channel parametrics") +SENSE_CODE(SERVO_IMPENDING_FAILURE_CONTROLLER_DETECTED, + "Servo impending failure controller detected") +SENSE_CODE(SERVO_IMPENDING_FAILURE_THROUGHPUT_PERFORMANCE, + "Servo impending failure throughput performance") +SENSE_CODE(SERVO_IMPENDING_FAILURE_SEEK_TIME_PERFORMANCE, + "Servo impending failure seek time performance") +SENSE_CODE(SERVO_IMPENDING_FAILURE_SPINUP_RETRY_COUNT, + "Servo impending failure spin-up retry count") +SENSE_CODE(SERVO_IMPENDING_FAILURE_DRIVE_CALIBRATION_RETRY_COUNT, + "Servo impending failure drive calibration retry count") +SENSE_CODE(SPINDLE_IMPENDING_FAILURE_GENERAL_HARD_DRIVE_FAILURE, + "Spindle impending failure general hard drive failure") +SENSE_CODE(SPINDLE_IMPENDING_FAILURE_DRIVE_ERROR_RATE_TOO_HIGH, + "Spindle impending failure drive error rate too high") +SENSE_CODE(SPINDLE_IMPENDING_FAILURE_DATA_ERROR_RATE_TOO_HIGH, + "Spindle impending failure data error rate too high") +SENSE_CODE(SPINDLE_IMPENDING_FAILURE_SEEK_ERROR_RATE_TOO_HIGH, + "Spindle impending failure seek error rate too high") +SENSE_CODE(SPINDLE_IMPENDING_FAILURE_TOO_MANY_BLOCK_REASSIGNS, + "Spindle impending failure too many block reassigns") +SENSE_CODE(SPINDLE_IMPENDING_FAILURE_ACCESS_TIMES_TOO_HIGH, + "Spindle impending failure access times too high") +SENSE_CODE(SPINDLE_IMPENDING_FAILURE_START_UNIT_TIMES_TOO_HIGH, + "Spindle impending failure start unit times too high") +SENSE_CODE(SPINDLE_IMPENDING_FAILURE_CHANNEL_PARAMETRICS, + "Spindle impending failure channel parametrics") +SENSE_CODE(SPINDLE_IMPENDING_FAILURE_CONTROLLER_DETECTED, + "Spindle impending failure controller detected") +SENSE_CODE(SPINDLE_IMPENDING_FAILURE_THROUGHPUT_PERFORMANCE, + "Spindle impending failure throughput performance") +SENSE_CODE(SPINDLE_IMPENDING_FAILURE_SEEK_TIME_PERFORMANCE, + "Spindle impending failure seek time performance") +SENSE_CODE(SPINDLE_IMPENDING_FAILURE_SPINUP_RETRY_COUNT, + "Spindle impending failure spin-up retry count") +SENSE_CODE(SPINDLE_IMPENDING_FAILURE_DRIVE_CALIBRATION_RETRY_COUNT, + "Spindle impending failure drive calibration retry count") +SENSE_CODE(FW_IMPENDING_FAILURE_GENERAL_HARD_DRIVE_FAILURE, + "Firmware impending failure general hard drive failure") +SENSE_CODE(FW_IMPENDING_FAILURE_DRIVE_ERROR_RATE_TOO_HIGH, + "Firmware impending failure drive error rate too high") +SENSE_CODE(FW_IMPENDING_FAILURE_DATA_ERROR_RATE_TOO_HIGH, + "Firmware impending failure data error rate too high") +SENSE_CODE(FW_IMPENDING_FAILURE_SEEK_ERROR_RATE_TOO_HIGH, + "Firmware impending failure seek error rate too high") +SENSE_CODE(FW_IMPENDING_FAILURE_TOO_MANY_BLOCK_REASSIGNS, + "Firmware impending failure too many block reassigns") +SENSE_CODE(FW_IMPENDING_FAILURE_ACCESS_TIMES_TOO_HIGH, + "Firmware impending failure access times too high") +SENSE_CODE(FW_IMPENDING_FAILURE_START_UNIT_TIMES_TOO_HIGH, + "Firmware impending failure start unit times too high") +SENSE_CODE(FW_IMPENDING_FAILURE_CHANNEL_PARAMETRICS, + "Firmware impending failure channel parametrics") +SENSE_CODE(FW_IMPENDING_FAILURE_CONTROLLER_DETECTED, + "Firmware impending failure controller detected") +SENSE_CODE(FW_IMPENDING_FAILURE_THROUGHPUT_PERFORMANCE, + "Firmware impending failure throughput performance") +SENSE_CODE(FW_IMPENDING_FAILURE_SEEK_TIME_PERFORMANCE, + "Firmware impending failure seek time performance") +SENSE_CODE(FW_IMPENDING_FAILURE_SPINUP_RETRY_COUNT, + "Firmware impending failure spin-up retry count") +SENSE_CODE(FW_IMPENDING_FAILURE_DRIVE_CALIBRATION_RETRY_COUNT, + "Firmware impending failure drive calibration retry count") +SENSE_CODE(MEDIA_IMPENDING_FAILURE_ENDURANCE_LIMIT_MET, + "Media impending failure endurance limit met") +SENSE_CODE(FAILURE_PREDICTION_THRESHOLD_EXCEEDED_FALSE, + "Failure prediction threshold exceeded (false)") + +SENSE_CODE(LOW_POWER_CONDITION_ON, + "Low power condition on") +SENSE_CODE(IDLE_CONDITION_ACTIVATED_BY_TIMER, + "Idle condition activated by timer") +SENSE_CODE(STANDBY_CONDITION_ACTIVATED_BY_TIMER, + "Standby condition activated by timer") +SENSE_CODE(IDLE_CONDITION_ACTIVATED_BY_COMMAND, + "Idle condition activated by command") +SENSE_CODE(STANDBY_CONDITION_ACTIVATED_BY_COMMAND, + "Standby condition activated by command") +SENSE_CODE(IDLE_B_CONDITION_ACTIVATED_BY_TIMER, + "Idle_b condition activated by timer") +SENSE_CODE(IDLE_B_CONDITION_ACTIVATED_BY_COMMAND, + "Idle_b condition activated by command") +SENSE_CODE(IDLE_C_CONDITION_ACTIVATED_BY_TIMER, + "Idle_c condition activated by timer") +SENSE_CODE(IDLE_C_CONDITION_ACTIVATED_BY_COMMAND, + "Idle_c condition activated by command") +SENSE_CODE(STANDBY_Y_CONDITION_ACTIVATED_BY_TIMER, + "Standby_y condition activated by timer") +SENSE_CODE(STANDBY_Y_CONDITION_ACTIVATED_BY_COMMAND, + "Standby_y condition activated by command") +SENSE_CODE(POWER_STATE_CHANGE_TO_ACTIVE, + "Power state change to active") +SENSE_CODE(POWER_STATE_CHANGE_TO_IDLE, + "Power state change to idle") +SENSE_CODE(POWER_STATE_CHANGE_TO_STANDBY, + "Power state change to standby") +SENSE_CODE(POWER_STATE_CHANGE_TO_SLEEP, + "Power state change to sleep") +SENSE_CODE(POWER_STATE_CHANGE_TO_DEVICE_CONTROL, + "Power state change to device control") + +SENSE_CODE(LAMP_FAILURE, + "Lamp failure") + +SENSE_CODE(VIDEO_ACQUISITION_ERROR, + "Video acquisition error") +SENSE_CODE(UNABLE_TO_ACQUIRE_VIDEO, + "Unable to acquire video") +SENSE_CODE(OUT_OF_FOCUS, + "Out of focus") + +SENSE_CODE(SCAN_HEAD_POSITIONING_ERROR, + "Scan head positioning error") + +SENSE_CODE(END_OF_USER_AREA_ENCOUNTERED_ON_THIS_TRACK, + "End of user area encountered on this track") +SENSE_CODE(PACKET_DOES_NOT_FIT_IN_AVAILABLE_SPACE, + "Packet does not fit in available space") + +SENSE_CODE(ILLEGAL_MODE_FOR_THIS_TRACK, + "Illegal mode for this track") +SENSE_CODE(INVALID_PACKET_SIZE, + "Invalid packet size") + +SENSE_CODE(VOLTAGE_FAULT, + "Voltage fault") + +SENSE_CODE(AUTOMATIC_DOCUMENT_FEEDER_COVER_UP, + "Automatic document feeder cover up") +SENSE_CODE(AUTOMATIC_DOCUMENT_FEEDER_LIFT_UP, + "Automatic document feeder lift up") +SENSE_CODE(DOCUMENT_JAM_IN_AUTOMATIC_DOCUMENT_FEEDER, + "Document jam in automatic document feeder") +SENSE_CODE(DOCUMENT_MISS_FEED_AUTOMATIC_IN_DOCUMENT_FEEDER, + "Document miss feed automatic in document feeder") + +SENSE_CODE(CONFIG_FAILURE, + "Configuration failure") +SENSE_CODE(CONFIG_OF_INCAPABLE_LOGICAL_UNITS_FAILED, + "Configuration of incapable logical units failed") +SENSE_CODE(ADD_LU_FAILED, + "Add logical unit failed") +SENSE_CODE(MODIFICATION_OF_LU_FAILED, + "Modification of logical unit failed") +SENSE_CODE(EXCHANGE_OF_LU_FAILED, + "Exchange of logical unit failed") +SENSE_CODE(REMOVE_OF_LU_FAILED, + "Remove of logical unit failed") +SENSE_CODE(ATTACHMENT_OF_LU_FAILED, + "Attachment of logical unit failed") +SENSE_CODE(CREATION_OF_LU_FAILED, + "Creation of logical unit failed") +SENSE_CODE(ASSIGN_FAILURE_OCCURRED, + "Assign failure occurred") +SENSE_CODE(MULTIPLY_ASSIGNED_LOGICAL_UNIT, + "Multiply assigned logical unit") +SENSE_CODE(SET_TARGET_PORT_GROUPS_COMMAND_FAILED, + "Set target port groups command failed") +SENSE_CODE(ATA_DEVICE_FEATURE_NOT_ENABLED, + "ATA device feature not enabled") +SENSE_CODE(COMMAND_REJECTED, + "Command rejected") +SENSE_CODE(EXPLICIT_BIND_NOT_ALLOWED, + "Explicit bind not allowed") + +SENSE_CODE(LU_NOT_CONFIGURED, + "Logical unit not configured") +SENSE_CODE(SUBSIDIARY_LU_NOT_CONFIGURED, + "Subsidiary logical unit not configured") + +SENSE_CODE(DATA_LOSS_ON_LOGICAL_UNIT, + "Data loss on logical unit") +SENSE_CODE(MULTIPLE_LU_FAILURES, + "Multiple logical unit failures") +SENSE_CODE(PARITY_DATA_MISMATCH, + "Parity/data mismatch") + +SENSE_CODE(INFORMATIONAL_REFER_TO_LOG, + "Informational, refer to log") + +SENSE_CODE(STATE_CHANGE_HAS_OCCURRED, + "State change has occurred") +SENSE_CODE(REDUNDANCY_LEVEL_GOT_BETTER, + "Redundancy level got better") +SENSE_CODE(REDUNDANCY_LEVEL_GOT_WORSE, + "Redundancy level got worse") + +SENSE_CODE(REBUILD_FAILURE_OCCURRED, + "Rebuild failure occurred") + +SENSE_CODE(RECALCULATE_FAILURE_OCCURRED, + "Recalculate failure occurred") + +SENSE_CODE(COMMAND_TO_LU_FAILED, + "Command to logical unit failed") + +SENSE_CODE(COPY_PROTECTION_KEY_EXCHANGE_FAILURE_AUTHENTICATION_FAILURE, + "Copy protection key exchange failure - authentication failure") +SENSE_CODE(COPY_PROTECTION_KEY_EXCHANGE_FAILURE_KEY_NOT_PRESENT, + "Copy protection key exchange failure - key not present") +SENSE_CODE(COPY_PROTECTION_KEY_EXCHANGE_FAILURE_KEY_NOT_ESTABLISHED, + "Copy protection key exchange failure - key not established") +SENSE_CODE(READ_OF_SCRAMBLED_SECTOR_WITHOUT_AUTHENTICATION, + "Read of scrambled sector without authentication") +SENSE_CODE(MEDIA_REGION_CODE_IS_MISMATCHED_TO_LU_REGION, + "Media region code is mismatched to logical unit region") +SENSE_CODE(DRIVE_REGION_MUST_BE_PERMANENT_REGION_RESET_COUNT_ERROR, + "Drive region must be permanent/region reset count error") +SENSE_CODE(INSUFFICIENT_BLOCK_COUNT_FOR_BINDING_NONCE_RECORDING, + "Insufficient block count for binding nonce recording") +SENSE_CODE(CONFLICT_IN_BINDING_NONCE_RECORDING, + "Conflict in binding nonce recording") +SENSE_CODE(INSUFFICIENT_PERMISSION, + "Insufficient permission") +SENSE_CODE(INVALID_DRIVE_HOST_PAIRING_SERVER, + "Invalid drive-host pairing server") +SENSE_CODE(DRIVE_HOST_PAIRING_SUSPENDED, + "Drive-host pairing suspended") /* - * SENSE_CODE(0x70NN, "Decompression exception short algorithm id of nn") + * SENSE_CODE(0x70NN, "Decompression exception short algorithm id of nn") */ -SENSE_CODE(0x7100, "Decompression exception long algorithm id") - -SENSE_CODE(0x7200, "Session fixation error") -SENSE_CODE(0x7201, "Session fixation error writing lead-in") -SENSE_CODE(0x7202, "Session fixation error writing lead-out") -SENSE_CODE(0x7203, "Session fixation error - incomplete track in session") -SENSE_CODE(0x7204, "Empty or partially written reserved track") -SENSE_CODE(0x7205, "No more track reservations allowed") -SENSE_CODE(0x7206, "RMZ extension is not allowed") -SENSE_CODE(0x7207, "No more test zone extensions are allowed") - -SENSE_CODE(0x7300, "Cd control error") -SENSE_CODE(0x7301, "Power calibration area almost full") -SENSE_CODE(0x7302, "Power calibration area is full") -SENSE_CODE(0x7303, "Power calibration area error") -SENSE_CODE(0x7304, "Program memory area update failure") -SENSE_CODE(0x7305, "Program memory area is full") -SENSE_CODE(0x7306, "RMA/PMA is almost full") -SENSE_CODE(0x7310, "Current power calibration area almost full") -SENSE_CODE(0x7311, "Current power calibration area is full") -SENSE_CODE(0x7317, "RDZ is full") - -SENSE_CODE(0x7400, "Security error") -SENSE_CODE(0x7401, "Unable to decrypt data") -SENSE_CODE(0x7402, "Unencrypted data encountered while decrypting") -SENSE_CODE(0x7403, "Incorrect data encryption key") -SENSE_CODE(0x7404, "Cryptographic integrity validation failed") -SENSE_CODE(0x7405, "Error decrypting data") -SENSE_CODE(0x7406, "Unknown signature verification key") -SENSE_CODE(0x7407, "Encryption parameters not useable") -SENSE_CODE(0x7408, "Digital signature validation failure") -SENSE_CODE(0x7409, "Encryption mode mismatch on read") -SENSE_CODE(0x740A, "Encrypted block not raw read enabled") -SENSE_CODE(0x740B, "Incorrect Encryption parameters") -SENSE_CODE(0x740C, "Unable to decrypt parameter list") -SENSE_CODE(0x740D, "Encryption algorithm disabled") -SENSE_CODE(0x7410, "SA creation parameter value invalid") -SENSE_CODE(0x7411, "SA creation parameter value rejected") -SENSE_CODE(0x7412, "Invalid SA usage") -SENSE_CODE(0x7421, "Data Encryption configuration prevented") -SENSE_CODE(0x7430, "SA creation parameter not supported") -SENSE_CODE(0x7440, "Authentication failed") -SENSE_CODE(0x7461, "External data encryption key manager access error") -SENSE_CODE(0x7462, "External data encryption key manager error") -SENSE_CODE(0x7463, "External data encryption key not found") -SENSE_CODE(0x7464, "External data encryption request not authorized") -SENSE_CODE(0x746E, "External data encryption control timeout") -SENSE_CODE(0x746F, "External data encryption control error") -SENSE_CODE(0x7471, "Logical unit access not authorized") -SENSE_CODE(0x7479, "Security conflict in translated device") + +SENSE_CODE(DECOMPRESSION_EXCEPTION_LONG_ALGORITHM_ID, + "Decompression exception long algorithm id") + +SENSE_CODE(SESSION_FIXATION_ERROR, + "Session fixation error") +SENSE_CODE(SESSION_FIXATION_ERROR_WRITING_LEAD_IN, + "Session fixation error writing lead-in") +SENSE_CODE(SESSION_FIXATION_ERROR_WRITING_LEAD_OUT, + "Session fixation error writing lead-out") +SENSE_CODE(SESSION_FIXATION_ERROR_INCOMPLETE_TRACK_IN_SESSION, + "Session fixation error - incomplete track in session") +SENSE_CODE(EMPTY_OR_PARTIALLY_WRITTEN_RESERVED_TRACK, + "Empty or partially written reserved track") +SENSE_CODE(NO_MORE_TRACK_RESERVATIONS_ALLOWED, + "No more track reservations allowed") +SENSE_CODE(RMZ_EXTENSION_IS_NOT_ALLOWED, + "RMZ extension is not allowed") +SENSE_CODE(NO_MORE_TEST_ZONE_EXTENSIONS_ARE_ALLOWED, + "No more test zone extensions are allowed") + +SENSE_CODE(CD_CONTROL_ERROR, + "Cd control error") +SENSE_CODE(POWER_CALIBRATION_AREA_ALMOST_FULL, + "Power calibration area almost full") +SENSE_CODE(POWER_CALIBRATION_AREA_IS_FULL, + "Power calibration area is full") +SENSE_CODE(POWER_CALIBRATION_AREA_ERROR, + "Power calibration area error") +SENSE_CODE(PROGRAM_MEMORY_AREA_UPDATE_FAILURE, + "Program memory area update failure") +SENSE_CODE(PROGRAM_MEMORY_AREA_IS_FULL, + "Program memory area is full") +SENSE_CODE(RMA_PMA_IS_ALMOST_FULL, + "RMA/PMA is almost full") +SENSE_CODE(CURRENT_POWER_CALIBRATION_AREA_ALMOST_FULL, + "Current power calibration area almost full") +SENSE_CODE(CURRENT_POWER_CALIBRATION_AREA_IS_FULL, + "Current power calibration area is full") +SENSE_CODE(RDZ_IS_FULL, + "RDZ is full") + +SENSE_CODE(SECURITY_ERROR, + "Security error") +SENSE_CODE(UNABLE_TO_DECRYPT_DATA, + "Unable to decrypt data") +SENSE_CODE(UNENCRYPTED_DATA_ENCOUNTERED_WHILE_DECRYPTING, + "Unencrypted data encountered while decrypting") +SENSE_CODE(INCORRECT_DATA_ENCRYPTION_KEY, + "Incorrect data encryption key") +SENSE_CODE(CRYPTOGRAPHIC_INTEGRITY_VALIDATION_FAILED, + "Cryptographic integrity validation failed") +SENSE_CODE(ERROR_DECRYPTING_DATA, + "Error decrypting data") +SENSE_CODE(UNKNOWN_SIGNATURE_VERIFICATION_KEY, + "Unknown signature verification key") +SENSE_CODE(ENCRYPTION_PARAMS_NOT_USEABLE, + "Encryption parameters not useable") +SENSE_CODE(DIGITAL_SIGNATURE_VALIDATION_FAILURE, + "Digital signature validation failure") +SENSE_CODE(ENCRYPTION_MODE_MISMATCH_ON_READ, + "Encryption mode mismatch on read") +SENSE_CODE(ENCRYPTED_BLOCK_NOT_RAW_READ_ENABLED, + "Encrypted block not raw read enabled") +SENSE_CODE(INCORRECT_ENCRYPTION_PARAMS, + "Incorrect Encryption parameters") +SENSE_CODE(UNABLE_TO_DECRYPT_PARAMETER_LIST, + "Unable to decrypt parameter list") +SENSE_CODE(ENCRYPTION_ALGORITHM_DISABLED, + "Encryption algorithm disabled") +SENSE_CODE(SA_CREATION_PARAMETER_VALUE_INVALID, + "SA creation parameter value invalid") +SENSE_CODE(SA_CREATION_PARAMETER_VALUE_REJECTED, + "SA creation parameter value rejected") +SENSE_CODE(INVALID_SA_USAGE, + "Invalid SA usage") +SENSE_CODE(DATA_ENCRYPTION_CONFIG_PREVENTED, + "Data Encryption configuration prevented") +SENSE_CODE(SA_CREATION_PARAMETER_NOT_SUPPORTED, + "SA creation parameter not supported") +SENSE_CODE(AUTHENTICATION_FAILED, + "Authentication failed") +SENSE_CODE(EXTERNAL_DATA_ENCRYPTION_KEY_MANAGER_ACCESS_ERROR, + "External data encryption key manager access error") +SENSE_CODE(EXTERNAL_DATA_ENCRYPTION_KEY_MANAGER_ERROR, + "External data encryption key manager error") +SENSE_CODE(EXTERNAL_DATA_ENCRYPTION_KEY_NOT_FOUND, + "External data encryption key not found") +SENSE_CODE(EXTERNAL_DATA_ENCRYPTION_REQUEST_NOT_AUTHORIZED, + "External data encryption request not authorized") +SENSE_CODE(EXTERNAL_DATA_ENCRYPTION_CONTROL_TIMEOUT, + "External data encryption control timeout") +SENSE_CODE(EXTERNAL_DATA_ENCRYPTION_CONTROL_ERROR, + "External data encryption control error") +SENSE_CODE(LU_ACCESS_NOT_AUTHORIZED, + "Logical unit access not authorized") +SENSE_CODE(SECURITY_CONFLICT_IN_TRANSLATED_DEVICE, + "Security conflict in translated device") diff --git a/drivers/scsi/ses.c b/drivers/scsi/ses.c index 4c348645b04e..eefeb8b9a75c 100644 --- a/drivers/scsi/ses.c +++ b/drivers/scsi/ses.c @@ -72,6 +72,9 @@ static void init_device_slot_control(unsigned char *dest_desc, dest_desc[3] &= 0x3c; } +#define POWER_ON_RESET_ANY \ + scsi_sense_code(ASC_POWER_ON_RESET_OR_BUS_DEVICE_RESET_OCCURRED, \ + SCMD_FAILURE_ASCQ_ANY) static int ses_recv_diag(struct scsi_device *sdev, int page_code, void *buf, int bufflen) @@ -88,16 +91,14 @@ static int ses_recv_diag(struct scsi_device *sdev, int page_code, unsigned char recv_page_code; struct scsi_failure failure_defs[] = { { - .sense = UNIT_ATTENTION, - .asc = 0x29, - .ascq = SCMD_FAILURE_ASCQ_ANY, + .sense_key = UNIT_ATTENTION, + .sense_code = POWER_ON_RESET_ANY, .allowed = SES_RETRIES, .result = SAM_STAT_CHECK_CONDITION, }, { - .sense = NOT_READY, - .asc = SCMD_FAILURE_ASC_ANY, - .ascq = SCMD_FAILURE_ASCQ_ANY, + .sense_key = NOT_READY, + .sense_code = SCMD_FAILURE_SENSE_CODE_ANY, .allowed = SES_RETRIES, .result = SAM_STAT_CHECK_CONDITION, }, @@ -145,16 +146,14 @@ static int ses_send_diag(struct scsi_device *sdev, int page_code, }; struct scsi_failure failure_defs[] = { { - .sense = UNIT_ATTENTION, - .asc = 0x29, - .ascq = SCMD_FAILURE_ASCQ_ANY, + .sense_key = UNIT_ATTENTION, + .sense_code = POWER_ON_RESET_ANY, .allowed = SES_RETRIES, .result = SAM_STAT_CHECK_CONDITION, }, { - .sense = NOT_READY, - .asc = SCMD_FAILURE_ASC_ANY, - .ascq = SCMD_FAILURE_ASCQ_ANY, + .sense_key = NOT_READY, + .sense_code = SCMD_FAILURE_SENSE_CODE_ANY, .allowed = SES_RETRIES, .result = SAM_STAT_CHECK_CONDITION, }, diff --git a/drivers/scsi/sg.c b/drivers/scsi/sg.c index 5408f002e6c0..714ae6f0cf18 100644 --- a/drivers/scsi/sg.c +++ b/drivers/scsi/sg.c @@ -245,6 +245,7 @@ static int sg_allow_access(struct file *filp, unsigned char *cmd) static int open_wait(Sg_device *sdp, int flags) + __must_hold(&sdp->open_rel_lock) { int retval = 0; diff --git a/drivers/scsi/sgiwd93.c b/drivers/scsi/sgiwd93.c index 6594661db5f4..455208776239 100644 --- a/drivers/scsi/sgiwd93.c +++ b/drivers/scsi/sgiwd93.c @@ -59,9 +59,9 @@ static irqreturn_t sgiwd93_intr(int irq, void *dev_id) struct Scsi_Host * host = dev_id; unsigned long flags; - spin_lock_irqsave(host->host_lock, flags); + spin_lock_irqsave(&host->host_lock, flags); wd33c93_intr(host); - spin_unlock_irqrestore(host->host_lock, flags); + spin_unlock_irqrestore(&host->host_lock, flags); return IRQ_HANDLED; } diff --git a/drivers/scsi/smartpqi/Makefile b/drivers/scsi/smartpqi/Makefile index 28985e508b5c..71db5cd96284 100644 --- a/drivers/scsi/smartpqi/Makefile +++ b/drivers/scsi/smartpqi/Makefile @@ -1,3 +1,6 @@ # SPDX-License-Identifier: GPL-2.0 + +CONTEXT_ANALYSIS := y + obj-$(CONFIG_SCSI_SMARTPQI) += smartpqi.o smartpqi-objs := smartpqi_init.o smartpqi_sis.o smartpqi_sas_transport.o diff --git a/drivers/scsi/smartpqi/smartpqi_init.c b/drivers/scsi/smartpqi/smartpqi_init.c index 140e8a6addbe..9401d9347404 100644 --- a/drivers/scsi/smartpqi/smartpqi_init.c +++ b/drivers/scsi/smartpqi/smartpqi_init.c @@ -97,8 +97,12 @@ static int pqi_aio_submit_r56_write_io(struct pqi_ctrl_info *ctrl_info, struct scsi_cmnd *scmd, struct pqi_queue_group *queue_group, struct pqi_encryption_info *encryption_info, struct pqi_scsi_dev *device, struct pqi_scsi_dev_raid_map_data *rmd); -static void pqi_ofa_ctrl_quiesce(struct pqi_ctrl_info *ctrl_info); -static void pqi_ofa_ctrl_unquiesce(struct pqi_ctrl_info *ctrl_info); +static void pqi_ofa_ctrl_quiesce(struct pqi_ctrl_info *ctrl_info) + __acquires(&ctrl_info->scan_mutex) + __acquires(&ctrl_info->lun_reset_mutex); +static void pqi_ofa_ctrl_unquiesce(struct pqi_ctrl_info *ctrl_info) + __releases(&ctrl_info->lun_reset_mutex) + __releases(&ctrl_info->scan_mutex); static int pqi_ofa_ctrl_restart(struct pqi_ctrl_info *ctrl_info, unsigned int delay_secs); static void pqi_host_setup_buffer(struct pqi_ctrl_info *ctrl_info, struct pqi_host_memory_descriptor *host_memory_descriptor, u32 total_size, u32 min_size); static void pqi_host_free_buffer(struct pqi_ctrl_info *ctrl_info, struct pqi_host_memory_descriptor *host_memory_descriptor); @@ -312,12 +316,14 @@ static inline void pqi_save_fw_triage_setting(struct pqi_ctrl_info *ctrl_info, b } static inline void pqi_ctrl_block_scan(struct pqi_ctrl_info *ctrl_info) + __acquires(&ctrl_info->scan_mutex) { ctrl_info->scan_blocked = true; mutex_lock(&ctrl_info->scan_mutex); } static inline void pqi_ctrl_unblock_scan(struct pqi_ctrl_info *ctrl_info) + __releases(&ctrl_info->scan_mutex) { ctrl_info->scan_blocked = false; mutex_unlock(&ctrl_info->scan_mutex); @@ -329,11 +335,13 @@ static inline bool pqi_ctrl_scan_blocked(struct pqi_ctrl_info *ctrl_info) } static inline void pqi_ctrl_block_device_reset(struct pqi_ctrl_info *ctrl_info) + __acquires(&ctrl_info->lun_reset_mutex) { mutex_lock(&ctrl_info->lun_reset_mutex); } static inline void pqi_ctrl_unblock_device_reset(struct pqi_ctrl_info *ctrl_info) + __releases(&ctrl_info->lun_reset_mutex) { mutex_unlock(&ctrl_info->lun_reset_mutex); } @@ -436,11 +444,13 @@ static inline bool pqi_device_offline(struct pqi_scsi_dev *device) } static inline void pqi_ctrl_ofa_start(struct pqi_ctrl_info *ctrl_info) + __acquires(&ctrl_info->ofa_mutex) { mutex_lock(&ctrl_info->ofa_mutex); } static inline void pqi_ctrl_ofa_done(struct pqi_ctrl_info *ctrl_info) + __releases(&ctrl_info->ofa_mutex) { mutex_unlock(&ctrl_info->ofa_mutex); } @@ -2305,6 +2315,8 @@ static void pqi_update_device_list(struct pqi_ctrl_info *ctrl_info, * requests before removal. */ if (pqi_ofa_in_progress(ctrl_info)) { + /* What guarantees that &ctrl_info->lun_reset_mutex is held here? */ + __acquire(&ctrl_info->lun_reset_mutex); list_for_each_entry_safe(device, next, &delete_list, delete_list_entry) if (pqi_is_device_added(device)) pqi_device_remove_start(device); @@ -3249,15 +3261,15 @@ static void pqi_process_raid_io_error(struct pqi_io_request *io_request) sense_data_length = sizeof(error_info->data); if (scsi_status == SAM_STAT_CHECK_CONDITION && - scsi_normalize_sense(error_info->data, - sense_data_length, &sshdr) && - sshdr.sense_key == HARDWARE_ERROR && - sshdr.asc == 0x3e) { + scsi_normalize_sense(error_info->data, + sense_data_length, &sshdr) && + sshdr.sense_key == HARDWARE_ERROR && + scsi_sense_asc(&sshdr) == ASC_LU_HAS_NOT_SELF_CONFIGURED_YET) { struct pqi_ctrl_info *ctrl_info = shost_to_hba(scmd->device->host); struct pqi_scsi_dev *device = scmd->device->hostdata; - switch (sshdr.ascq) { - case 0x1: /* LOGICAL UNIT FAILURE */ + switch (sshdr.sense_code) { + case LU_FAILURE: if (printk_ratelimit()) scmd_printk(KERN_ERR, scmd, "received 'logical unit failure' from controller for scsi %d:%d:%d:%d\n", ctrl_info->scsi_host->host_no, device->bus, device->target, device->lun); @@ -3265,10 +3277,15 @@ static void pqi_process_raid_io_error(struct pqi_io_request *io_request) host_byte = DID_NO_CONNECT; break; - default: /* See http://www.t10.org/lists/asc-num.htm#ASC_3E */ + default: + /* include/scsi/scsi_sense.h */ if (printk_ratelimit()) - scmd_printk(KERN_ERR, scmd, "received unhandled error %d from controller for scsi %d:%d:%d:%d\n", - sshdr.ascq, ctrl_info->scsi_host->host_no, device->bus, device->target, device->lun); + scmd_printk(KERN_ERR, scmd, + "received unhandled error %d from controller for scsi %d:%d:%d:%d\n", + scsi_sense_ascq(&sshdr), + ctrl_info->scsi_host->host_no, + device->bus, device->target, + device->lun); break; } } @@ -3286,11 +3303,11 @@ static void pqi_process_raid_io_error(struct pqi_io_request *io_request) sense_data_length && scsi_normalize_sense(error_info->data, sense_data_length, &sshdr) && sshdr.sense_key == ILLEGAL_REQUEST && - sshdr.asc == 0x26 && - sshdr.ascq == 0x0) { + sshdr.sense_code == INVALID_FIELD_IN_PARAMETER_LIST) { host_byte = DID_NO_CONNECT; pqi_take_device_offline(scmd->device, "AIO"); - scsi_build_sense_buffer(0, scmd->sense_buffer, HARDWARE_ERROR, 0x3e, 0x1); + scsi_set_sense_buffer(0, scmd->sense_buffer, HARDWARE_ERROR, + LU_FAILURE); } scmd->result = scsi_status; @@ -3380,7 +3397,7 @@ static void pqi_process_aio_io_error(struct pqi_io_request *io_request) } if (device_offline && sense_data_length == 0) - scsi_build_sense(scmd, 0, HARDWARE_ERROR, 0x3e, 0x1); + scsi_set_sense(scmd, 0, HARDWARE_ERROR, LU_FAILURE); scmd->result = scsi_status; set_host_byte(scmd, host_byte); @@ -3667,6 +3684,8 @@ static void pqi_process_soft_reset(struct pqi_ctrl_info *ctrl_info) pqi_save_ctrl_mode(ctrl_info, SIS_MODE); rc = pqi_ofa_ctrl_restart(ctrl_info, delay_secs); pqi_host_free_buffer(ctrl_info, &ctrl_info->ofa_memory); + /* What guarantees that &ctrl_info->ofa_mutex is held here? */ + __acquire(&ctrl_info->ofa_mutex); pqi_ctrl_ofa_done(ctrl_info); dev_info(&ctrl_info->pci_dev->dev, "Online Firmware Activation: %s\n", @@ -3678,6 +3697,10 @@ static void pqi_process_soft_reset(struct pqi_ctrl_info *ctrl_info) if (ctrl_info->soft_reset_handshake_supported) pqi_clear_soft_reset_status(ctrl_info); pqi_host_free_buffer(ctrl_info, &ctrl_info->ofa_memory); + /* What guarantees that these mutexes are held here? */ + __acquire(&ctrl_info->lun_reset_mutex); + __acquire(&ctrl_info->ofa_mutex); + __acquire(&ctrl_info->scan_mutex); pqi_ctrl_ofa_done(ctrl_info); pqi_ofa_ctrl_unquiesce(ctrl_info); break; @@ -3688,6 +3711,10 @@ static void pqi_process_soft_reset(struct pqi_ctrl_info *ctrl_info) "unexpected Online Firmware Activation reset status: 0x%x\n", reset_status); pqi_host_free_buffer(ctrl_info, &ctrl_info->ofa_memory); + /* What guarantees that these mutexes are held here? */ + __acquire(&ctrl_info->lun_reset_mutex); + __acquire(&ctrl_info->ofa_mutex); + __acquire(&ctrl_info->scan_mutex); pqi_ctrl_ofa_done(ctrl_info); pqi_ofa_ctrl_unquiesce(ctrl_info); pqi_take_ctrl_offline(ctrl_info, PQI_OFA_RESPONSE_TIMEOUT); @@ -3695,25 +3722,32 @@ static void pqi_process_soft_reset(struct pqi_ctrl_info *ctrl_info) } } -static void pqi_ofa_memory_alloc_worker(struct work_struct *work) +static inline struct pqi_ctrl_info *alloc_work_to_ctrl_info(struct work_struct *work) { - struct pqi_ctrl_info *ctrl_info; + return container_of(work, struct pqi_ctrl_info, ofa_memory_alloc_work); +} - ctrl_info = container_of(work, struct pqi_ctrl_info, ofa_memory_alloc_work); +static void pqi_ofa_memory_alloc_worker(struct work_struct *work) + __acquires(&alloc_work_to_ctrl_info(work)->ofa_mutex) +{ + struct pqi_ctrl_info *ctrl_info = alloc_work_to_ctrl_info(work); pqi_ctrl_ofa_start(ctrl_info); pqi_host_setup_buffer(ctrl_info, &ctrl_info->ofa_memory, ctrl_info->ofa_bytes_requested, ctrl_info->ofa_bytes_requested); pqi_host_memory_update(ctrl_info, &ctrl_info->ofa_memory, PQI_VENDOR_GENERAL_OFA_MEMORY_UPDATE); } -static void pqi_ofa_quiesce_worker(struct work_struct *work) +static inline struct pqi_ctrl_info *quiesce_work_to_ctrl_info(struct work_struct *work) { - struct pqi_ctrl_info *ctrl_info; - struct pqi_event *event; - - ctrl_info = container_of(work, struct pqi_ctrl_info, ofa_quiesce_work); + return container_of(work, struct pqi_ctrl_info, ofa_quiesce_work); +} - event = &ctrl_info->events[pqi_event_type_to_event_index(PQI_EVENT_TYPE_OFA)]; +static void pqi_ofa_quiesce_worker(struct work_struct *work) + __acquires(&quiesce_work_to_ctrl_info(work)->scan_mutex) + __acquires(&quiesce_work_to_ctrl_info(work)->lun_reset_mutex) +{ + struct pqi_ctrl_info *ctrl_info = quiesce_work_to_ctrl_info(work); + struct pqi_event *event = &ctrl_info->events[pqi_event_type_to_event_index(PQI_EVENT_TYPE_OFA)]; pqi_ofa_ctrl_quiesce(ctrl_info); pqi_acknowledge_event(ctrl_info, event); @@ -3744,6 +3778,8 @@ static bool pqi_ofa_process_event(struct pqi_ctrl_info *ctrl_info, "received Online Firmware Activation cancel request: reason: %u\n", ctrl_info->ofa_cancel_reason); pqi_host_free_buffer(ctrl_info, &ctrl_info->ofa_memory); + /* What guarantees that &ctrl_info->ofa_mutex is held here? */ + __acquire(&ctrl_info->ofa_mutex); pqi_ctrl_ofa_done(ctrl_info); break; default: @@ -8888,6 +8924,8 @@ static int pqi_ctrl_init_resume(struct pqi_ctrl_info *ctrl_info) } if (pqi_ofa_in_progress(ctrl_info)) { + /* What guarantees that &ctrl_info->scan_mutex is held here? */ + __acquire(&ctrl_info->scan_mutex); pqi_ctrl_unblock_scan(ctrl_info); if (ctrl_info->ctrl_logging_supported) { if (!ctrl_info->ctrl_log_memory.host_memory) @@ -9648,7 +9686,11 @@ static inline enum bmic_flush_cache_shutdown_event pqi_get_flush_cache_shutdown_ return SUSPEND; } +#define TO_CTRL_INFO(dev) ((struct pqi_ctrl_info *)pci_get_drvdata(to_pci_dev(dev))) + static int pqi_suspend_or_freeze(struct device *dev, bool suspend) + __acquires(&TO_CTRL_INFO(dev)->scan_mutex) + __acquires(&TO_CTRL_INFO(dev)->lun_reset_mutex) { struct pci_dev *pci_dev; struct pqi_ctrl_info *ctrl_info; @@ -9682,11 +9724,15 @@ static int pqi_suspend_or_freeze(struct device *dev, bool suspend) } static __maybe_unused int pqi_suspend(struct device *dev) + __acquires(&TO_CTRL_INFO(dev)->scan_mutex) + __acquires(&TO_CTRL_INFO(dev)->lun_reset_mutex) { return pqi_suspend_or_freeze(dev, true); } static int pqi_resume_or_restore(struct device *dev) + __cond_releases(0, &TO_CTRL_INFO(dev)->lun_reset_mutex) + __cond_releases(0, &TO_CTRL_INFO(dev)->scan_mutex) { int rc; struct pci_dev *pci_dev; @@ -9710,11 +9756,15 @@ static int pqi_resume_or_restore(struct device *dev) } static int pqi_freeze(struct device *dev) + __acquires(&TO_CTRL_INFO(dev)->scan_mutex) + __acquires(&TO_CTRL_INFO(dev)->lun_reset_mutex) { return pqi_suspend_or_freeze(dev, false); } static int pqi_thaw(struct device *dev) + __cond_releases(0, &TO_CTRL_INFO(dev)->lun_reset_mutex) + __cond_releases(0, &TO_CTRL_INFO(dev)->scan_mutex) { int rc; struct pci_dev *pci_dev; diff --git a/drivers/scsi/snic/Makefile b/drivers/scsi/snic/Makefile index 41546e3cb701..b12563cb174d 100644 --- a/drivers/scsi/snic/Makefile +++ b/drivers/scsi/snic/Makefile @@ -1,4 +1,7 @@ # SPDX-License-Identifier: GPL-2.0 + +CONTEXT_ANALYSIS := y + obj-$(CONFIG_SCSI_SNIC) += snic.o snic-y := \ diff --git a/drivers/scsi/snic/snic_disc.c b/drivers/scsi/snic/snic_disc.c index 71d34a702f2a..8c262b4bbb83 100644 --- a/drivers/scsi/snic/snic_disc.c +++ b/drivers/scsi/snic/snic_disc.c @@ -160,9 +160,9 @@ snic_scsi_scan_tgt(struct work_struct *work) SCAN_WILD_CARD, SCSI_SCAN_RESCAN); - spin_lock_irqsave(shost->host_lock, flags); + spin_lock_irqsave(&shost->host_lock, flags); tgt->flags &= ~SNIC_TGT_SCAN_PENDING; - spin_unlock_irqrestore(shost->host_lock, flags); + spin_unlock_irqrestore(&shost->host_lock, flags); } /* end of snic_scsi_scan_tgt */ /* @@ -287,11 +287,11 @@ snic_tgt_create(struct snic *snic, struct snic_tgt_id *tgtid) break; } - spin_lock_irqsave(snic->shost->host_lock, flags); + spin_lock_irqsave(&snic->shost->host_lock, flags); list_add_tail(&tgt->list, &snic->disc.tgt_list); tgt->scsi_tgt_id = snic->disc.nxt_tgt_id++; tgt->state = SNIC_TGT_STAT_ONLINE; - spin_unlock_irqrestore(snic->shost->host_lock, flags); + spin_unlock_irqrestore(&snic->shost->host_lock, flags); SNIC_HOST_INFO(snic->shost, "Tgt %d, type = %s detected. Adding..\n", @@ -304,9 +304,9 @@ snic_tgt_create(struct snic *snic, struct snic_tgt_id *tgtid) ret); put_device(&snic->shost->shost_gendev); - spin_lock_irqsave(snic->shost->host_lock, flags); + spin_lock_irqsave(&snic->shost->host_lock, flags); list_del(&tgt->list); - spin_unlock_irqrestore(snic->shost->host_lock, flags); + spin_unlock_irqrestore(&snic->shost->host_lock, flags); put_device(&tgt->dev); tgt = NULL; @@ -537,7 +537,7 @@ snic_tgt_del_all(struct snic *snic) scsi_flush_work(snic->shost); mutex_lock(&snic->disc.mutex); - spin_lock_irqsave(snic->shost->host_lock, flags); + spin_lock_irqsave(&snic->shost->host_lock, flags); list_for_each_safe(cur, nxt, &snic->disc.tgt_list) { tgt = list_entry(cur, struct snic_tgt, list); @@ -547,7 +547,7 @@ snic_tgt_del_all(struct snic *snic) queue_work(snic_glob->event_q, &tgt->del_work); tgt = NULL; } - spin_unlock_irqrestore(snic->shost->host_lock, flags); + spin_unlock_irqrestore(&snic->shost->host_lock, flags); mutex_unlock(&snic->disc.mutex); flush_workqueue(snic_glob->event_q); diff --git a/drivers/scsi/sr.c b/drivers/scsi/sr.c index c36c54ecd354..4f2e8d1be6da 100644 --- a/drivers/scsi/sr.c +++ b/drivers/scsi/sr.c @@ -253,7 +253,8 @@ static unsigned int sr_check_events(struct cdrom_device_info *cdi, * (ASC 0x3a). */ cd->media_present = scsi_status_is_good(ret) || - (scsi_sense_valid(&sshdr) && sshdr.asc != 0x3a); + (scsi_sense_valid(&sshdr) && + scsi_sense_asc(&sshdr) != ASC_MEDIUM_NOT_PRESENT); if (last_present != cd->media_present) cd->device->changed = 1; diff --git a/drivers/scsi/sr_ioctl.c b/drivers/scsi/sr_ioctl.c index 089653018d32..e4ec0f63cdcc 100644 --- a/drivers/scsi/sr_ioctl.c +++ b/drivers/scsi/sr_ioctl.c @@ -226,9 +226,8 @@ int sr_do_ioctl(Scsi_CD *cd, struct packet_command *cgc) err = -ENOMEDIUM; break; case NOT_READY: /* This happens if there is no disc in drive */ - if (sshdr->asc == 0x04 && - sshdr->ascq == 0x01) { - /* sense: Logical unit is in process of becoming ready */ + if (sshdr->sense_code == + LU_IS_IN_PROCESS_OF_BECOMING_READY) { if (!cgc->quiet) sr_printk(KERN_INFO, cd, "CDROM not ready yet.\n"); @@ -250,9 +249,7 @@ int sr_do_ioctl(Scsi_CD *cd, struct packet_command *cgc) break; case ILLEGAL_REQUEST: err = -EIO; - if (sshdr->asc == 0x20 && - sshdr->ascq == 0x00) - /* sense: Invalid command operation code */ + if (sshdr->sense_code == INVALID_COMMAND_OP_CODE) err = -EDRIVE_CANT_DO_THIS; break; default: @@ -303,9 +300,8 @@ int sr_drive_status(struct cdrom_device_info *cdi, int slot) if (!scsi_test_unit_ready(cd->device, SR_TIMEOUT, MAX_RETRIES, &sshdr)) return CDS_DISC_OK; - /* SK/ASC/ASCQ of 2/4/1 means "unit is becoming ready" */ - if (scsi_sense_valid(&sshdr) && sshdr.sense_key == NOT_READY - && sshdr.asc == 0x04 && sshdr.ascq == 0x01) + if (scsi_sense_valid(&sshdr) && sshdr.sense_key == NOT_READY && + sshdr.sense_code == LU_IS_IN_PROCESS_OF_BECOMING_READY) return CDS_DRIVE_NOT_READY; if (!cdrom_get_media_event(cdi, &med)) { @@ -318,18 +314,18 @@ int sr_drive_status(struct cdrom_device_info *cdi, int slot) } /* - * SK/ASC/ASCQ of 2/4/2 means "initialization required" * Using CD_TRAY_OPEN results in an START_STOP_UNIT to close * the tray, which resolves the initialization requirement. */ - if (scsi_sense_valid(&sshdr) && sshdr.sense_key == NOT_READY - && sshdr.asc == 0x04 && sshdr.ascq == 0x02) + if (scsi_sense_valid(&sshdr) && sshdr.sense_key == NOT_READY && + sshdr.sense_code == LU_NOT_READY_INITIALIZING_COMMAND_REQUIRED) return CDS_TRAY_OPEN; /* * 0x04 is format in progress .. but there must be a disc present! */ - if (sshdr.sense_key == NOT_READY && sshdr.asc == 0x04) + if (sshdr.sense_key == NOT_READY && + scsi_sense_asc(&sshdr) == ASC_LU_NOT_READY) return CDS_DISC_OK; /* @@ -338,13 +334,10 @@ int sr_drive_status(struct cdrom_device_info *cdi, int slot) * any other way to detect this... */ if (scsi_sense_valid(&sshdr) && - /* 0x3a is medium not present */ - sshdr.asc == 0x3a) + scsi_sense_asc(&sshdr) == ASC_MEDIUM_NOT_PRESENT) return CDS_NO_DISC; - else - return CDS_TRAY_OPEN; - return CDS_DRIVE_NOT_READY; + return CDS_TRAY_OPEN; } int sr_disk_status(struct cdrom_device_info *cdi) diff --git a/drivers/scsi/st.c b/drivers/scsi/st.c index f1c3c4946637..e9d41e3cc2dd 100644 --- a/drivers/scsi/st.c +++ b/drivers/scsi/st.c @@ -368,6 +368,8 @@ static int st_chk_result(struct scsi_tape *STp, struct st_request * SRpnt) if (ctr != STp->por_ctr) { STp->por_ctr = ctr; STp->pos_unknown = 1; /* ASC => power on / reset */ + /* The reset allowed medium removal; relock at next access */ + STp->door_locked = ST_UNLOCKED; st_printk(KERN_WARNING, STp, "Power on/reset recognized."); } @@ -421,11 +423,14 @@ static int st_chk_result(struct scsi_tape *STp, struct st_request * SRpnt) STp->cln_sense_mask) != 0); } if (cmdstatp->have_sense && - cmdstatp->sense_hdr.asc == 0 && cmdstatp->sense_hdr.ascq == 0x17) - STp->cleaning_req = 1; /* ASC and ASCQ => cleaning requested */ + cmdstatp->sense_hdr.sense_code == CLEANING_REQUESTED) + STp->cleaning_req = 1; if (cmdstatp->have_sense && scode == UNIT_ATTENTION && - cmdstatp->sense_hdr.asc == 0x29 && !STp->pos_unknown) { - STp->pos_unknown = 1; /* ASC => power on / reset */ + scsi_sense_asc(&cmdstatp->sense_hdr) == + ASC_POWER_ON_RESET_OR_BUS_DEVICE_RESET_OCCURRED && + !STp->pos_unknown) { + STp->pos_unknown = 1; + STp->door_locked = ST_UNLOCKED; st_printk(KERN_WARNING, STp, "Power on/reset recognized."); } @@ -1003,7 +1008,8 @@ static int test_ready(struct scsi_tape *STp, int do_wait) scode = cmdstatp->sense_hdr.sense_key; if (scode == UNIT_ATTENTION) { /* New media? */ - if (cmdstatp->sense_hdr.asc == 0x28) { /* New media */ + if (scsi_sense_asc(&cmdstatp->sense_hdr) == + ASC_NOT_READY_TO_READY_CHANGE_MEDIUM_MAY_HAVE_CHANGED) { new_session = 1; DEBC_printk(STp, "New tape session."); } @@ -1026,14 +1032,13 @@ static int test_ready(struct scsi_tape *STp, int do_wait) waits++; continue; } - else { - if ((STp->device)->scsi_level >= SCSI_2 && - cmdstatp->sense_hdr.asc == 0x3a) /* Check ASC */ - retval = CHKRES_NO_TAPE; - else - retval = CHKRES_NOT_READY; - break; - } + if ((STp->device)->scsi_level >= SCSI_2 && + scsi_sense_asc(&cmdstatp->sense_hdr) == + ASC_MEDIUM_NOT_PRESENT) + retval = CHKRES_NO_TAPE; + else + retval = CHKRES_NOT_READY; + break; } } @@ -2686,6 +2691,30 @@ static int do_load_unload(struct scsi_tape *STp, struct file *filp, int load_cod else { STp->rew_at_close = STp->autorew_dev; retval = check_tape(STp, filp); + /* + * LOAD leaves the medium at the beginning of partition + * 0. check_tape() records that only for a new session; + * without a new-medium unit attention (the medium was + * already loaded) the partition and the partition state + * would be left as before the load. Reset them as a + * new session does, for all partitions: a stale + * ST_WRITING state would make st_flush() write a + * filemark at the beginning of partition 0. + */ + if (retval == CHKRES_READY) { + int i; + + STp->partition = STp->new_partition = 0; + for (i = 0; i < ST_NBR_PARTITIONS; i++) { + STps = &(STp->ps[i]); + STps->rw = ST_IDLE; + STps->eof = ST_NOEOF; + STps->at_sm = 0; + STps->last_block_valid = 0; + STps->drv_block = 0; + STps->drv_file = 0; + } + } if (retval > 0) retval = 0; } @@ -2939,9 +2968,11 @@ static int st_int_ioctl(struct scsi_tape *STp, unsigned int cmd_in, unsigned lon direction = DMA_TO_DEVICE; memset((STp->buffer)->b_data, 0, 12); - if (cmd_in == MTSETDRVBUFFER) + if (cmd_in == MTSETDRVBUFFER) { (STp->buffer)->b_data[2] = (arg & 7) << 4; - else + STp->drv_buffer_changed = 1; /* At least we tried ;-) */ + STp->changed_drv_buffer = arg & 7; + } else (STp->buffer)->b_data[2] = STp->drv_buffer << 4; (STp->buffer)->b_data[3] = 8; /* block descriptor length */ @@ -3105,9 +3136,10 @@ static int st_int_ioctl(struct scsi_tape *STp, unsigned int cmd_in, unsigned lon cmd_in == MTSETDRVBUFFER || cmd_in == SET_DENS_AND_BLK) { if (cmdstatp->sense_hdr.sense_key == ILLEGAL_REQUEST && - cmdstatp->sense_hdr.asc == 0x24 && - (STp->device)->scsi_level <= SCSI_2 && - !(STp->use_pf & PF_TESTED)) { + scsi_sense_asc(&cmdstatp->sense_hdr) == + ASC_INVALID_FIELD_IN_CDB && + (STp->device)->scsi_level <= SCSI_2 && + !(STp->use_pf & PF_TESTED)) { /* Try the other possible state of Page Format if not already tried */ STp->use_pf = (STp->use_pf ^ USE_PF) | PF_TESTED; @@ -3217,14 +3249,20 @@ static int set_location(struct scsi_tape *STp, unsigned int block, int partition partition >= ST_NBR_PARTITIONS) return (-EINVAL); if (partition != STp->partition) { - if (get_location(STp, &blk, &p, 1)) + /* + * Save the location for the partition the drive reports, + * not for STp->partition: after a reset STp->partition may + * not match the partition the drive is in. + */ + if (get_location(STp, &blk, &p, 1) || + p < 0 || p >= ST_NBR_PARTITIONS) STps->last_block_valid = 0; else { - STps->last_block_valid = 1; - STps->last_block_visited = blk; + STp->ps[p].last_block_valid = 1; + STp->ps[p].last_block_visited = blk; DEBC_printk(STp, "Visited block %d for " "partition %d saved.\n", - blk, STp->partition); + blk, p); } } @@ -3535,6 +3573,7 @@ static int partition_tape(struct scsi_tape *STp, int size) static long st_common_ioctl(struct scsi_tape *STp, struct st_modedef *STm, struct file *file, unsigned int cmd_in, unsigned long arg) + __releases(&STp->lock) { int i, retval = 0; @@ -3586,6 +3625,26 @@ static long st_common_ioctl(struct scsi_tape *STp, struct st_modedef *STm, return retval; } +/* + * Re-apply a drive buffering mode, density and block size that were changed + * by the user before a device reset (a negative value means "not changed"). + * The buffering mode goes first: the other MODE SELECTs send the current + * STp->drv_buffer. A unit attention still pending after the operation + * (e.g. new medium after a load) fails the first MODE SELECT, so retry each + * once. As in the other post-reset restore path, errors are ignored and one + * setting failing does not prevent restoring the others. + */ +static void st_restore_changed_settings(struct scsi_tape *STp, int drv_buffer, + int density, int blksize) +{ + if (drv_buffer >= 0 && st_int_ioctl(STp, MTSETDRVBUFFER, drv_buffer)) + st_int_ioctl(STp, MTSETDRVBUFFER, drv_buffer); + if (density >= 0 && st_int_ioctl(STp, MTSETDENSITY, density)) + st_int_ioctl(STp, MTSETDENSITY, density); + if (blksize >= 0 && st_int_ioctl(STp, MTSETBLK, blksize)) + st_int_ioctl(STp, MTSETBLK, blksize); +} + /* The ioctl command */ static long st_ioctl(struct file *file, unsigned int cmd_in, unsigned long arg) { @@ -3594,6 +3653,7 @@ static long st_ioctl(struct file *file, unsigned int cmd_in, unsigned long arg) int retval = 0; unsigned int blk; bool cmd_mtiocget; + int restore_drv_buffer = -1, restore_density = -1, restore_blksize = -1; struct scsi_tape *STp = file->private_data; struct st_modedef *STm; struct st_partstat *STps; @@ -3736,10 +3796,26 @@ static long st_ioctl(struct file *file, unsigned int cmd_in, unsigned long arg) STp->partition = 0; switch_partition(STp); } + if (STp->drv_buffer_changed) + st_int_ioctl(STp, MTSETDRVBUFFER, + STp->changed_drv_buffer); if (STp->density_changed) st_int_ioctl(STp, MTSETDENSITY, STp->changed_density); if (STp->blksize_changed) st_int_ioctl(STp, MTSETBLK, STp->changed_blksize); + } else if (mtc.mt_op == MTLOAD || mtc.mt_op == MTRETEN) { + /* + * The same medium ends up at BOT, so the settings + * apply as with MTREW. The operation may start a + * new session, which clears the "changed" flags: + * save the values and restore them afterwards. + */ + if (STp->drv_buffer_changed) + restore_drv_buffer = STp->changed_drv_buffer; + if (STp->density_changed) + restore_density = STp->changed_density; + if (STp->blksize_changed) + restore_blksize = STp->changed_blksize; } } @@ -3819,6 +3895,15 @@ static long st_ioctl(struct file *file, unsigned int cmd_in, unsigned long arg) if (mtc.mt_op == MTLOAD) { retval = do_load_unload(STp, file, max(1, mtc.mt_count)); + /* + * Restore only if the drive is ready: after an + * immediate-mode load with O_NONBLOCK, check_tape() + * does not wait and the drive may still be loading. + */ + if (!retval && STp->ready == ST_READY) + st_restore_changed_settings(STp, restore_drv_buffer, + restore_density, + restore_blksize); goto out; } @@ -3837,6 +3922,22 @@ static long st_ioctl(struct file *file, unsigned int cmd_in, unsigned long arg) retval = st_compression(STp, (mtc.mt_count & 1)); else retval = st_int_ioctl(STp, mtc.mt_op, mtc.mt_count); + if (!retval && mtc.mt_op == MTRETEN && !STp->immediate && + (restore_drv_buffer >= 0 || restore_density >= 0 || + restore_blksize >= 0)) { + /* + * Retension reloads the medium and the drive may + * report a new medium. Let check_tape() start the new + * session (applying the mode defaults) now, as for + * MTLOAD; otherwise it happens at the next open and + * overrides the restored settings. + */ + if (check_tape(STp, file) >= 0 && + STp->ready == ST_READY) + st_restore_changed_settings(STp, restore_drv_buffer, + restore_density, + restore_blksize); + } goto out; } if (!STm->defined) { @@ -4442,7 +4543,7 @@ static int st_probe(struct scsi_device *SDp) tpnt->modes[0].defined = 1; tpnt->density_changed = tpnt->compression_changed = - tpnt->blksize_changed = 0; + tpnt->blksize_changed = tpnt->drv_buffer_changed = 0; mutex_init(&tpnt->lock); idr_preload(GFP_KERNEL); @@ -4509,11 +4610,11 @@ static void st_remove(struct scsi_device *SDp) remove_cdevs(tpnt); mutex_lock(&st_ref_mutex); - kref_put(&tpnt->kref, scsi_tape_release); - mutex_unlock(&st_ref_mutex); spin_lock(&st_index_lock); idr_remove(&st_index_idr, index); spin_unlock(&st_index_lock); + kref_put(&tpnt->kref, scsi_tape_release); + mutex_unlock(&st_ref_mutex); } /** diff --git a/drivers/scsi/st.h b/drivers/scsi/st.h index 0d7c4b8c2c8a..c580024880c3 100644 --- a/drivers/scsi/st.h +++ b/drivers/scsi/st.h @@ -162,10 +162,12 @@ struct scsi_tape { unsigned char in_use; unsigned char blksize_changed; unsigned char density_changed; + unsigned char drv_buffer_changed; unsigned char compression_changed; unsigned char drv_buffer; unsigned char density; unsigned char changed_density; + unsigned char changed_drv_buffer; unsigned char door_locked; unsigned char autorew_dev; /* auto-rewind device */ unsigned char rew_at_close; /* rewind necessary at close */ diff --git a/drivers/scsi/stex.c b/drivers/scsi/stex.c index 6aeeb338633d..d4899816f7dc 100644 --- a/drivers/scsi/stex.c +++ b/drivers/scsi/stex.c @@ -401,8 +401,7 @@ static struct status_msg *stex_get_status(struct st_hba *hba) static void stex_invalid_field(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *)) { - /* "Invalid field in cdb" */ - scsi_build_sense(cmd, 0, ILLEGAL_REQUEST, 0x24, 0x0); + scsi_set_sense(cmd, 0, ILLEGAL_REQUEST, INVALID_FIELD_IN_CDB); done(cmd); } @@ -568,7 +567,7 @@ static void return_abnormal_state(struct st_hba *hba, int status) unsigned long flags; u16 tag; - spin_lock_irqsave(hba->host->host_lock, flags); + spin_lock_irqsave(&hba->host->host_lock, flags); for (tag = 0; tag < hba->host->can_queue; tag++) { ccb = &hba->ccb[tag]; if (ccb->req == NULL) @@ -581,7 +580,7 @@ static void return_abnormal_state(struct st_hba *hba, int status) ccb->cmd = NULL; } } - spin_unlock_irqrestore(hba->host->host_lock, flags); + spin_unlock_irqrestore(&hba->host->host_lock, flags); } static int stex_sdev_configure(struct scsi_device *sdev, struct queue_limits *lim) @@ -887,7 +886,7 @@ static irqreturn_t stex_intr(int irq, void *__hba) u32 data; unsigned long flags; - spin_lock_irqsave(hba->host->host_lock, flags); + spin_lock_irqsave(&hba->host->host_lock, flags); data = readl(base + ODBL); @@ -896,14 +895,14 @@ static irqreturn_t stex_intr(int irq, void *__hba) writel(data, base + ODBL); readl(base + ODBL); /* flush */ stex_mu_intr(hba, data); - spin_unlock_irqrestore(hba->host->host_lock, flags); + spin_unlock_irqrestore(&hba->host->host_lock, flags); if (unlikely(data & MU_OUTBOUND_DOORBELL_REQUEST_RESET && hba->cardtype == st_shasta)) queue_work(hba->work_q, &hba->reset_work); return IRQ_HANDLED; } - spin_unlock_irqrestore(hba->host->host_lock, flags); + spin_unlock_irqrestore(&hba->host->host_lock, flags); return IRQ_NONE; } @@ -988,7 +987,7 @@ static irqreturn_t stex_ss_intr(int irq, void *__hba) u32 data; unsigned long flags; - spin_lock_irqsave(hba->host->host_lock, flags); + spin_lock_irqsave(&hba->host->host_lock, flags); if (hba->cardtype == st_yel) { data = readl(base + YI2H_INT); @@ -996,7 +995,7 @@ static irqreturn_t stex_ss_intr(int irq, void *__hba) /* clear the interrupt */ writel(data, base + YI2H_INT_C); stex_ss_mu_intr(hba); - spin_unlock_irqrestore(hba->host->host_lock, flags); + spin_unlock_irqrestore(&hba->host->host_lock, flags); if (unlikely(data & SS_I2H_REQUEST_RESET)) queue_work(hba->work_q, &hba->reset_work); return IRQ_HANDLED; @@ -1010,14 +1009,14 @@ static irqreturn_t stex_ss_intr(int irq, void *__hba) writel((1 << 22), base + YH2I_INT); } stex_ss_mu_intr(hba); - spin_unlock_irqrestore(hba->host->host_lock, flags); + spin_unlock_irqrestore(&hba->host->host_lock, flags); if (unlikely(data & SS_I2H_REQUEST_RESET)) queue_work(hba->work_q, &hba->reset_work); return IRQ_HANDLED; } } - spin_unlock_irqrestore(hba->host->host_lock, flags); + spin_unlock_irqrestore(&hba->host->host_lock, flags); return IRQ_NONE; } @@ -1227,7 +1226,7 @@ static int stex_handshake(struct st_hba *hba) err = stex_ss_handshake(hba); else err = stex_common_handshake(hba); - spin_lock_irqsave(hba->host->host_lock, flags); + spin_lock_irqsave(&hba->host->host_lock, flags); mu_status = hba->mu_status; if (err == 0) { hba->req_head = 0; @@ -1240,7 +1239,7 @@ static int stex_handshake(struct st_hba *hba) hba->mu_status = MU_STATE_FAILED; if (mu_status == MU_STATE_RESETTING) wake_up_all(&hba->reset_waitq); - spin_unlock_irqrestore(hba->host->host_lock, flags); + spin_unlock_irqrestore(&hba->host->host_lock, flags); return err; } @@ -1257,7 +1256,7 @@ static int stex_abort(struct scsi_cmnd *cmd) scmd_printk(KERN_INFO, cmd, "aborting command\n"); base = hba->mmio_base; - spin_lock_irqsave(host->host_lock, flags); + spin_lock_irqsave(&host->host_lock, flags); if (tag < host->can_queue && hba->ccb[tag].req && hba->ccb[tag].cmd == cmd) hba->wait_ccb = &hba->ccb[tag]; @@ -1301,7 +1300,7 @@ static int stex_abort(struct scsi_cmnd *cmd) hba->wait_ccb = NULL; result = FAILED; out: - spin_unlock_irqrestore(host->host_lock, flags); + spin_unlock_irqrestore(&host->host_lock, flags); return result; } @@ -1364,13 +1363,13 @@ static int stex_yos_reset(struct st_hba *hba) msleep(1); } - spin_lock_irqsave(hba->host->host_lock, flags); + spin_lock_irqsave(&hba->host->host_lock, flags); if (ret == -1) hba->mu_status = MU_STATE_FAILED; else hba->mu_status = MU_STATE_STARTED; wake_up_all(&hba->reset_waitq); - spin_unlock_irqrestore(hba->host->host_lock, flags); + spin_unlock_irqrestore(&hba->host->host_lock, flags); return ret; } @@ -1393,29 +1392,29 @@ static int stex_do_reset(struct st_hba *hba) unsigned long flags; unsigned int mu_status = MU_STATE_RESETTING; - spin_lock_irqsave(hba->host->host_lock, flags); + spin_lock_irqsave(&hba->host->host_lock, flags); if (hba->mu_status == MU_STATE_STARTING) { - spin_unlock_irqrestore(hba->host->host_lock, flags); + spin_unlock_irqrestore(&hba->host->host_lock, flags); printk(KERN_INFO DRV_NAME "(%s): request reset during init\n", pci_name(hba->pdev)); return 0; } while (hba->mu_status == MU_STATE_RESETTING) { - spin_unlock_irqrestore(hba->host->host_lock, flags); + spin_unlock_irqrestore(&hba->host->host_lock, flags); wait_event_timeout(hba->reset_waitq, hba->mu_status != MU_STATE_RESETTING, MU_MAX_DELAY * HZ); - spin_lock_irqsave(hba->host->host_lock, flags); + spin_lock_irqsave(&hba->host->host_lock, flags); mu_status = hba->mu_status; } if (mu_status != MU_STATE_RESETTING) { - spin_unlock_irqrestore(hba->host->host_lock, flags); + spin_unlock_irqrestore(&hba->host->host_lock, flags); return (mu_status == MU_STATE_STARTED) ? 0 : -1; } hba->mu_status = MU_STATE_RESETTING; - spin_unlock_irqrestore(hba->host->host_lock, flags); + spin_unlock_irqrestore(&hba->host->host_lock, flags); if (hba->cardtype == st_yosemite) return stex_yos_reset(hba); @@ -1858,12 +1857,12 @@ static void stex_hba_stop(struct st_hba *hba, int st_sleep_mic) unsigned long before; u16 tag = 0; - spin_lock_irqsave(hba->host->host_lock, flags); + spin_lock_irqsave(&hba->host->host_lock, flags); if ((hba->cardtype == st_yel || hba->cardtype == st_P3) && hba->supports_pm == 1) { if (st_sleep_mic == ST_NOTHANDLED) { - spin_unlock_irqrestore(hba->host->host_lock, flags); + spin_unlock_irqrestore(&hba->host->host_lock, flags); return; } } @@ -1899,7 +1898,7 @@ static void stex_hba_stop(struct st_hba *hba, int st_sleep_mic) hba->ccb[tag].sense_buffer = NULL; hba->ccb[tag].req_type = PASSTHRU_REQ_TYPE; hba->send(hba, req, tag); - spin_unlock_irqrestore(hba->host->host_lock, flags); + spin_unlock_irqrestore(&hba->host->host_lock, flags); before = jiffies; while (hba->ccb[tag].req_type & PASSTHRU_REQ_TYPE) { if (time_after(jiffies, before + ST_INTERNAL_TIMEOUT * HZ)) { diff --git a/drivers/scsi/storvsc_drv.c b/drivers/scsi/storvsc_drv.c index ef3cd3bc7390..625db97d1a03 100644 --- a/drivers/scsi/storvsc_drv.c +++ b/drivers/scsi/storvsc_drv.c @@ -1016,7 +1016,7 @@ static int storvsc_channel_init(struct hv_device *device, bool is_fc) static void storvsc_handle_error(struct vmscsi_request *vm_srb, struct scsi_cmnd *scmnd, struct Scsi_Host *host, - u8 asc, u8 ascq) + struct scsi_sense_hdr *sshdr) { struct storvsc_scan_work *wrk; void (*process_err_fn)(struct work_struct *work); @@ -1033,7 +1033,7 @@ static void storvsc_handle_error(struct vmscsi_request *vm_srb, case SRB_STATUS_DATA_OVERRUN: if (vm_srb->srb_status & SRB_STATUS_AUTOSENSE_VALID) { /* Check for capacity change */ - if ((asc == 0x2a) && (ascq == 0x9)) { + if (sshdr->sense_code == CAPACITY_DATA_HAS_CHANGED) { process_err_fn = storvsc_device_scan; /* Retry the I/O that triggered this. */ set_host_byte(scmnd, DID_REQUEUE); @@ -1049,8 +1049,12 @@ static void storvsc_handle_error(struct vmscsi_request *vm_srb, * want scsi_report_sense() to output a message * that a sysadmin wouldn't know what to do with. */ - if ((asc == 0x3f) && (ascq != 0x03) && - (ascq != 0x0e)) { + if (scsi_sense_asc(sshdr) == + ASC_TARGET_OPERATING_CONDITIONS_HAVE_CHANGED && + sshdr->sense_code != + INQUIRY_DATA_HAS_CHANGED && + sshdr->sense_code != + REPORTED_LUNS_DATA_HAS_CHANGED) { process_err_fn = storvsc_device_scan; set_host_byte(scmnd, DID_REQUEUE); goto do_work; @@ -1141,8 +1145,7 @@ static void storvsc_command_completion(struct storvsc_cmd_request *cmd_request, } if (vm_srb->srb_status != SRB_STATUS_SUCCESS) { - storvsc_handle_error(vm_srb, scmnd, host, sense_hdr.asc, - sense_hdr.ascq); + storvsc_handle_error(vm_srb, scmnd, host, &sense_hdr); /* * The Windows driver set data_transfer_length on * SRB_STATUS_DATA_OVERRUN. On other errors, this value diff --git a/drivers/scsi/sym53c8xx_2/Makefile b/drivers/scsi/sym53c8xx_2/Makefile index 0751e2a0cd82..c28fb2b65622 100644 --- a/drivers/scsi/sym53c8xx_2/Makefile +++ b/drivers/scsi/sym53c8xx_2/Makefile @@ -1,5 +1,7 @@ # SPDX-License-Identifier: GPL-2.0-only # Makefile for the NCR/SYMBIOS/LSI 53C8XX PCI SCSI controllers driver. +CONTEXT_ANALYSIS := y + sym53c8xx-objs := sym_fw.o sym_glue.o sym_hipd.o sym_malloc.o sym_nvram.o obj-$(CONFIG_SCSI_SYM53C8XX_2) := sym53c8xx.o diff --git a/drivers/scsi/sym53c8xx_2/sym_glue.c b/drivers/scsi/sym53c8xx_2/sym_glue.c index 27e22acaf1a7..e3783c015b02 100644 --- a/drivers/scsi/sym53c8xx_2/sym_glue.c +++ b/drivers/scsi/sym53c8xx_2/sym_glue.c @@ -531,9 +531,9 @@ static irqreturn_t sym53c8xx_intr(int irq, void *dev_id) if (DEBUG_FLAGS & DEBUG_TINY) printf_debug ("["); - spin_lock(shost->host_lock); + spin_lock(&shost->host_lock); result = sym_interrupt(shost); - spin_unlock(shost->host_lock); + spin_unlock(&shost->host_lock); if (DEBUG_FLAGS & DEBUG_TINY) printf_debug ("]\n"); @@ -548,9 +548,9 @@ static void sym53c8xx_timer(struct timer_list *t) struct sym_hcb *np = timer_container_of(np, t, s.timer); unsigned long flags; - spin_lock_irqsave(np->s.host->host_lock, flags); + spin_lock_irqsave(&np->s.host->host_lock, flags); sym_timer(np); - spin_unlock_irqrestore(np->s.host->host_lock, flags); + spin_unlock_irqrestore(&np->s.host->host_lock, flags); } @@ -587,7 +587,7 @@ static int sym53c8xx_eh_abort_handler(struct scsi_cmnd *cmd) if (pci_channel_offline(pdev)) return SCSI_FAILED; - spin_lock_irq(shost->host_lock); + spin_lock_irq(&shost->host_lock); /* This one is queued in some place -> to wait for completion */ FOR_EACH_QUEUED_ELEMENT(&np->busy_ccbq, qp) { struct sym_ccb *cp = sym_que_entry(qp, struct sym_ccb, link_ccbq); @@ -605,13 +605,13 @@ static int sym53c8xx_eh_abort_handler(struct scsi_cmnd *cmd) if (cmd_queued) { init_completion(&eh_done); ucmd->eh_done = &eh_done; - spin_unlock_irq(shost->host_lock); + spin_unlock_irq(&shost->host_lock); if (!wait_for_completion_timeout(&eh_done, 5*HZ)) { ucmd->eh_done = NULL; sts = -2; } } else { - spin_unlock_irq(shost->host_lock); + spin_unlock_irq(&shost->host_lock); } dev_warn(&cmd->device->sdev_gendev, "ABORT operation %s.\n", @@ -639,7 +639,7 @@ static int sym53c8xx_eh_target_reset_handler(struct scsi_cmnd *cmd) if (pci_channel_offline(pdev)) return SCSI_FAILED; - spin_lock_irq(shost->host_lock); + spin_lock_irq(&shost->host_lock); sts = sym_reset_scsi_target(np, starget->id); if (!sts) { FOR_EACH_QUEUED_ELEMENT(&np->busy_ccbq, qp) { @@ -655,15 +655,15 @@ static int sym53c8xx_eh_target_reset_handler(struct scsi_cmnd *cmd) ucmd = SYM_UCMD_PTR(cmd); init_completion(&eh_done); ucmd->eh_done = &eh_done; - spin_unlock_irq(shost->host_lock); + spin_unlock_irq(&shost->host_lock); if (!wait_for_completion_timeout(&eh_done, 5*HZ)) { ucmd->eh_done = NULL; sts = -2; } - spin_lock_irq(shost->host_lock); + spin_lock_irq(&shost->host_lock); } } - spin_unlock_irq(shost->host_lock); + spin_unlock_irq(&shost->host_lock); starget_printk(KERN_WARNING, starget, "TARGET RESET operation %s.\n", sts==0 ? "complete" :sts==-2 ? "timed-out" : "failed"); @@ -685,9 +685,9 @@ static int sym53c8xx_eh_bus_reset_handler(struct scsi_cmnd *cmd) if (pci_channel_offline(pdev)) return SCSI_FAILED; - spin_lock_irq(shost->host_lock); + spin_lock_irq(&shost->host_lock); sym_reset_scsi_bus(np, 1); - spin_unlock_irq(shost->host_lock); + spin_unlock_irq(&shost->host_lock); dev_warn(&cmd->device->sdev_gendev, "BUS RESET operation complete.\n"); return SCSI_SUCCESS; @@ -713,21 +713,21 @@ static int sym53c8xx_eh_host_reset_handler(struct scsi_cmnd *cmd) #define WAIT_FOR_PCI_RECOVERY 35 if (pci_channel_offline(pdev)) { init_completion(&eh_done); - spin_lock_irq(shost->host_lock); + spin_lock_irq(&shost->host_lock); /* Make sure we didn't race */ if (pci_channel_offline(pdev)) { BUG_ON(sym_data->io_reset); sym_data->io_reset = &eh_done; finished_reset = 0; } - spin_unlock_irq(shost->host_lock); + spin_unlock_irq(&shost->host_lock); if (!finished_reset) finished_reset = wait_for_completion_timeout (sym_data->io_reset, WAIT_FOR_PCI_RECOVERY*HZ); - spin_lock_irq(shost->host_lock); + spin_lock_irq(&shost->host_lock); sym_data->io_reset = NULL; - spin_unlock_irq(shost->host_lock); + spin_unlock_irq(&shost->host_lock); } if (finished_reset) { @@ -776,7 +776,7 @@ static int sym53c8xx_sdev_init(struct scsi_device *sdev) if (sdev->id >= SYM_CONF_MAX_TARGET || sdev->lun >= SYM_CONF_MAX_LUN) return -ENXIO; - spin_lock_irqsave(np->s.host->host_lock, flags); + spin_lock_irqsave(&np->s.host->host_lock, flags); /* * Fail the device init if the device is flagged NOSCAN at BOOT in @@ -817,7 +817,7 @@ static int sym53c8xx_sdev_init(struct scsi_device *sdev) error = 0; out: - spin_unlock_irqrestore(np->s.host->host_lock, flags); + spin_unlock_irqrestore(&np->s.host->host_lock, flags); return error; } @@ -873,7 +873,7 @@ static void sym53c8xx_sdev_destroy(struct scsi_device *sdev) if (!lp) return; - spin_lock_irqsave(np->s.host->host_lock, flags); + spin_lock_irqsave(&np->s.host->host_lock, flags); if (lp->busy_itlq || lp->busy_itl) { /* @@ -896,7 +896,7 @@ static void sym53c8xx_sdev_destroy(struct scsi_device *sdev) tp->starget = NULL; } - spin_unlock_irqrestore(np->s.host->host_lock, flags); + spin_unlock_irqrestore(&np->s.host->host_lock, flags); } /* @@ -1191,9 +1191,9 @@ printk("sym_user_command: data=%ld\n", uc->data); else { unsigned long flags; - spin_lock_irqsave(shost->host_lock, flags); + spin_lock_irqsave(&shost->host_lock, flags); sym_exec_user_command(np, uc); - spin_unlock_irqrestore(shost->host_lock, flags); + spin_unlock_irqrestore(&shost->host_lock, flags); } return length; } @@ -1371,7 +1371,7 @@ static struct Scsi_Host *sym_attach(const struct scsi_host_template *tpnt, int u * After SCSI devices have been opened, we cannot * reset the bus safely, so we do it here. */ - spin_lock_irqsave(shost->host_lock, flags); + spin_lock_irqsave(&shost->host_lock, flags); if (sym_reset_scsi_bus(np, 0)) goto reset_failed; @@ -1407,14 +1407,14 @@ static struct Scsi_Host *sym_attach(const struct scsi_host_template *tpnt, int u if (pdev->device == PCI_DEVICE_ID_NCR_53C896 && pdev->revision < 2) shost->dma_boundary = 0xFFFFFF; - spin_unlock_irqrestore(shost->host_lock, flags); + spin_unlock_irqrestore(&shost->host_lock, flags); return shost; reset_failed: printf_err("%s: FATAL ERROR: CHECK SCSI BUS - CABLES, " "TERMINATION, DEVICE POWER etc.!\n", sym_name(np)); - spin_unlock_irqrestore(shost->host_lock, flags); + spin_unlock_irqrestore(&shost->host_lock, flags); attach_failed: printf_info("sym%d: giving up ...\n", unit); if (np) @@ -1903,10 +1903,10 @@ static void sym2_io_resume(struct pci_dev *pdev) struct Scsi_Host *shost = pci_get_drvdata(pdev); struct sym_data *sym_data = shost_priv(shost); - spin_lock_irq(shost->host_lock); + spin_lock_irq(&shost->host_lock); if (sym_data->io_reset) complete(sym_data->io_reset); - spin_unlock_irq(shost->host_lock); + spin_unlock_irq(&shost->host_lock); } static void sym2_get_signalling(struct Scsi_Host *shost) diff --git a/drivers/scsi/sym53c8xx_2/sym_hipd.h b/drivers/scsi/sym53c8xx_2/sym_hipd.h index 9231a2899064..aa365e8ba66f 100644 --- a/drivers/scsi/sym53c8xx_2/sym_hipd.h +++ b/drivers/scsi/sym53c8xx_2/sym_hipd.h @@ -1110,9 +1110,9 @@ sym_build_sge(struct sym_hcb *np, struct sym_tblmove *data, u64 badd, int len) */ #define sym_get_mem_cluster() \ - (void *) __get_free_pages(GFP_ATOMIC, SYM_MEM_PAGE_ORDER) + kmalloc(PAGE_SIZE << SYM_MEM_PAGE_ORDER, GFP_ATOMIC) #define sym_free_mem_cluster(p) \ - free_pages((unsigned long)p, SYM_MEM_PAGE_ORDER) + kfree(p) /* * Link between free memory chunks of a given size. diff --git a/drivers/scsi/wd33c93.c b/drivers/scsi/wd33c93.c index 1e49d0402f0b..2a698b93faf8 100644 --- a/drivers/scsi/wd33c93.c +++ b/drivers/scsi/wd33c93.c @@ -1515,7 +1515,7 @@ wd33c93_host_reset(struct scsi_cmnd * SCpnt) int i; instance = SCpnt->device->host; - spin_lock_irq(instance->host_lock); + spin_lock_irq(&instance->host_lock); hostdata = (struct WD33C93_hostdata *) instance->hostdata; printk("scsi%d: reset. ", instance->host_no); @@ -1541,7 +1541,7 @@ wd33c93_host_reset(struct scsi_cmnd * SCpnt) reset_wd33c93(instance); SCpnt->result = DID_RESET << 16; enable_irq(instance->irq); - spin_unlock_irq(instance->host_lock); + spin_unlock_irq(&instance->host_lock); return SUCCESS; } diff --git a/drivers/scsi/wd719x.c b/drivers/scsi/wd719x.c index 830d40f57f6a..85cf6c9d2ec9 100644 --- a/drivers/scsi/wd719x.c +++ b/drivers/scsi/wd719x.c @@ -270,11 +270,11 @@ static enum scsi_qc_status wd719x_queuecommand(struct Scsi_Host *sh, scb->data_p = 0; } - spin_lock_irqsave(wd->sh->host_lock, flags); + spin_lock_irqsave(&wd->sh->host_lock, flags); /* check if the Command register is free */ if (wd719x_readb(wd, WD719X_AMR_COMMAND) != WD719X_CMD_READY) { - spin_unlock_irqrestore(wd->sh->host_lock, flags); + spin_unlock_irqrestore(&wd->sh->host_lock, flags); return SCSI_MLQUEUE_HOST_BUSY; } @@ -285,7 +285,7 @@ static enum scsi_qc_status wd719x_queuecommand(struct Scsi_Host *sh, /* send SCB opcode */ wd719x_writeb(wd, WD719X_AMR_COMMAND, WD719X_CMD_PROCESS_SCB); - spin_unlock_irqrestore(wd->sh->host_lock, flags); + spin_unlock_irqrestore(&wd->sh->host_lock, flags); return 0; out_unmap_sense: @@ -473,12 +473,12 @@ static int wd719x_abort(struct scsi_cmnd *cmd) action = WD719X_CMD_ABORT; - spin_lock_irqsave(wd->sh->host_lock, flags); + spin_lock_irqsave(&wd->sh->host_lock, flags); result = wd719x_direct_cmd(wd, action, cmd->device->id, cmd->device->lun, scsi_cmd_to_rq(cmd)->tag, scb->phys, 0); wd719x_finish_cmd(scb, DID_ABORT); - spin_unlock_irqrestore(wd->sh->host_lock, flags); + spin_unlock_irqrestore(&wd->sh->host_lock, flags); if (result) return FAILED; @@ -495,7 +495,7 @@ static int wd719x_reset(struct scsi_cmnd *cmd, u8 opcode, u8 device) dev_info(&wd->pdev->dev, "%s reset requested\n", (opcode == WD719X_CMD_BUSRESET) ? "bus" : "device"); - spin_lock_irqsave(wd->sh->host_lock, flags); + spin_lock_irqsave(&wd->sh->host_lock, flags); result = wd719x_direct_cmd(wd, opcode, device, 0, 0, 0, WD719X_WAIT_FOR_SCSI_RESET); /* flush all SCBs (or all for a device if dev_reset) */ @@ -504,7 +504,7 @@ static int wd719x_reset(struct scsi_cmnd *cmd, u8 opcode, u8 device) scb->cmd->device->id == device) wd719x_finish_cmd(scb, DID_RESET); } - spin_unlock_irqrestore(wd->sh->host_lock, flags); + spin_unlock_irqrestore(&wd->sh->host_lock, flags); if (result) return FAILED; @@ -528,7 +528,7 @@ static int wd719x_host_reset(struct scsi_cmnd *cmd) unsigned long flags; dev_info(&wd->pdev->dev, "host reset requested\n"); - spin_lock_irqsave(wd->sh->host_lock, flags); + spin_lock_irqsave(&wd->sh->host_lock, flags); /* stop the RISC */ if (wd719x_direct_cmd(wd, WD719X_CMD_SLEEP, 0, 0, 0, 0, WD719X_WAIT_FOR_RISC)) @@ -539,7 +539,7 @@ static int wd719x_host_reset(struct scsi_cmnd *cmd) /* flush all SCBs */ list_for_each_entry_safe(scb, tmp, &wd->active_scbs, list) wd719x_finish_cmd(scb, DID_RESET); - spin_unlock_irqrestore(wd->sh->host_lock, flags); + spin_unlock_irqrestore(&wd->sh->host_lock, flags); /* Try to reinit the RISC */ return wd719x_chip_init(wd) == 0 ? SUCCESS : FAILED; @@ -663,7 +663,7 @@ static irqreturn_t wd719x_interrupt(int irq, void *dev_id) unsigned long flags; u32 SCB_out; - spin_lock_irqsave(wd->sh->host_lock, flags); + spin_lock_irqsave(&wd->sh->host_lock, flags); /* read SCB pointer back from card */ SCB_out = wd719x_readl(wd, WD719X_AMR_SCB_OUT); /* read all status info at once */ @@ -671,7 +671,7 @@ static irqreturn_t wd719x_interrupt(int irq, void *dev_id) switch (regs.bytes.INT) { case WD719X_INT_NONE: - spin_unlock_irqrestore(wd->sh->host_lock, flags); + spin_unlock_irqrestore(&wd->sh->host_lock, flags); return IRQ_NONE; case WD719X_INT_LINKNOSTATUS: dev_err(&wd->pdev->dev, "linked command completed with no status\n"); @@ -708,7 +708,7 @@ static irqreturn_t wd719x_interrupt(int irq, void *dev_id) } /* clear interrupt so another can happen */ wd719x_writeb(wd, WD719X_AMR_INT_STATUS, WD719X_INT_NONE); - spin_unlock_irqrestore(wd->sh->host_lock, flags); + spin_unlock_irqrestore(&wd->sh->host_lock, flags); return IRQ_HANDLED; } diff --git a/drivers/scsi/xen-scsifront.c b/drivers/scsi/xen-scsifront.c index 989bcaee42ca..5c053b972287 100644 --- a/drivers/scsi/xen-scsifront.c +++ b/drivers/scsi/xen-scsifront.c @@ -367,6 +367,7 @@ static void scsifront_do_response(struct vscsifrnt_info *info, struct vscsifrnt_shadow *shadow; if (ring_rsp->rqid >= VSCSIIF_MAX_REQS || + !info->shadow[ring_rsp->rqid] || !info->shadow[ring_rsp->rqid]->inflight) { scsifront_set_error(info, "illegal rqid returned by backend!"); return; @@ -417,13 +418,13 @@ static int scsifront_cmd_done(struct vscsifrnt_info *info, int more_to_do; unsigned long flags; - spin_lock_irqsave(info->host->host_lock, flags); + spin_lock_irqsave(&info->host->host_lock, flags); more_to_do = scsifront_ring_drain(info, eoiflag); info->wait_ring_available = 0; - spin_unlock_irqrestore(info->host->host_lock, flags); + spin_unlock_irqrestore(&info->host->host_lock, flags); wake_up(&info->wq_sync); @@ -619,9 +620,9 @@ static enum scsi_qc_status scsifront_queuecommand(struct Scsi_Host *shost, shadow->sc = sc; shadow->act = VSCSIIF_ACT_SCSI_CDB; - spin_lock_irqsave(shost->host_lock, flags); + spin_lock_irqsave(&shost->host_lock, flags); if (scsifront_enter(info)) { - spin_unlock_irqrestore(shost->host_lock, flags); + spin_unlock_irqrestore(&shost->host_lock, flags); return SCSI_MLQUEUE_HOST_BUSY; } @@ -629,7 +630,7 @@ static enum scsi_qc_status scsifront_queuecommand(struct Scsi_Host *shost, if (err < 0) { pr_debug("%s: err %d\n", __func__, err); scsifront_return(info); - spin_unlock_irqrestore(shost->host_lock, flags); + spin_unlock_irqrestore(&shost->host_lock, flags); if (err == -ENOMEM) return SCSI_MLQUEUE_HOST_BUSY; sc->result = DID_ERROR << 16; @@ -643,13 +644,13 @@ static enum scsi_qc_status scsifront_queuecommand(struct Scsi_Host *shost, } scsifront_return(info); - spin_unlock_irqrestore(shost->host_lock, flags); + spin_unlock_irqrestore(&shost->host_lock, flags); return 0; busy: scsifront_return(info); - spin_unlock_irqrestore(shost->host_lock, flags); + spin_unlock_irqrestore(&shost->host_lock, flags); pr_debug("%s: busy\n", __func__); return SCSI_MLQUEUE_HOST_BUSY; } @@ -679,7 +680,7 @@ static int scsifront_action_handler(struct scsi_cmnd *sc, uint8_t act) shadow->ref_rqid = s->rqid; init_waitqueue_head(&shadow->wq_reset); - spin_lock_irq(host->host_lock); + spin_lock_irq(&host->host_lock); for (;;) { if (scsifront_enter(info)) @@ -692,15 +693,15 @@ static int scsifront_action_handler(struct scsi_cmnd *sc, uint8_t act) if (err) goto fail; info->wait_ring_available = 1; - spin_unlock_irq(host->host_lock); + spin_unlock_irq(&host->host_lock); err = wait_event_interruptible(info->wq_sync, !info->wait_ring_available); - spin_lock_irq(host->host_lock); + spin_lock_irq(&host->host_lock); } - spin_unlock_irq(host->host_lock); + spin_unlock_irq(&host->host_lock); err = wait_event_interruptible(shadow->wq_reset, shadow->wait_reset); - spin_lock_irq(host->host_lock); + spin_lock_irq(&host->host_lock); if (!err) { err = shadow->rslt_reset; @@ -714,11 +715,11 @@ static int scsifront_action_handler(struct scsi_cmnd *sc, uint8_t act) } scsifront_return(info); - spin_unlock_irq(host->host_lock); + spin_unlock_irq(&host->host_lock); return err; fail: - spin_unlock_irq(host->host_lock); + spin_unlock_irq(&host->host_lock); kfree(shadow); return FAILED; } @@ -953,12 +954,12 @@ static int scsifront_resume(struct xenbus_device *dev) struct Scsi_Host *host = info->host; int err; - spin_lock_irq(host->host_lock); + spin_lock_irq(&host->host_lock); /* Finish all still pending commands. */ scsifront_finish_all(info); - spin_unlock_irq(host->host_lock); + spin_unlock_irq(&host->host_lock); /* Reconnect to dom0. */ scsifront_free_ring(info); @@ -981,18 +982,18 @@ static int scsifront_suspend(struct xenbus_device *dev) int err = 0; /* No new commands for the backend. */ - spin_lock_irq(host->host_lock); + spin_lock_irq(&host->host_lock); info->pause = 1; while (info->callers && !err) { info->waiting_pause = 1; info->wait_ring_available = 0; - spin_unlock_irq(host->host_lock); + spin_unlock_irq(&host->host_lock); wake_up(&info->wq_sync); err = wait_event_interruptible(info->wq_pause, !info->waiting_pause); - spin_lock_irq(host->host_lock); + spin_lock_irq(&host->host_lock); } - spin_unlock_irq(host->host_lock); + spin_unlock_irq(&host->host_lock); return err; } diff --git a/drivers/scsi/zorro7xx.c b/drivers/scsi/zorro7xx.c index 21c769dc1ecb..89475632675c 100644 --- a/drivers/scsi/zorro7xx.c +++ b/drivers/scsi/zorro7xx.c @@ -35,38 +35,45 @@ static struct scsi_host_template zorro7xx_scsi_driver_template = { .module = THIS_MODULE, }; -static struct zorro_driver_data { +struct zorro_driver_data { const char *name; unsigned long offset; int absolute; /* offset is absolute address */ -} zorro7xx_driver_data[] = { - { .name = "PowerUP 603e+", .offset = 0xf40000, .absolute = 1 }, - { .name = "WarpEngine 40xx", .offset = 0x40000 }, - { .name = "A4091", .offset = 0x800000 }, - { .name = "GForce 040/060", .offset = 0x40000 }, - { 0 } +}; + +static const struct zorro_driver_data zorro7xx_blizzard_603e_plus_data = { + .name = "PowerUP 603e+", .offset = 0xf40000, .absolute = 1 +}; +static const struct zorro_driver_data zorro7xx_warp_engine_40xx_data = { + .name = "WarpEngine 40xx", .offset = 0x40000 +}; +static const struct zorro_driver_data zorro7xx_a4091_data = { + .name = "A4091", .offset = 0x800000 +}; +static const struct zorro_driver_data zorro7xx_gforce_040_060_data = { + .name = "GForce 040/060", .offset = 0x40000 }; static struct zorro_device_id zorro7xx_zorro_tbl[] = { { .id = ZORRO_PROD_PHASE5_BLIZZARD_603E_PLUS, - .driver_data_ptr = &zorro7xx_driver_data[0], + .driver_data_ptr = &zorro7xx_blizzard_603e_plus_data, }, { .id = ZORRO_PROD_MACROSYSTEMS_WARP_ENGINE_40xx, - .driver_data_ptr = &zorro7xx_driver_data[1], + .driver_data_ptr = &zorro7xx_warp_engine_40xx_data, }, { .id = ZORRO_PROD_CBM_A4091_1, - .driver_data_ptr = &zorro7xx_driver_data[2], + .driver_data_ptr = &zorro7xx_a4091_data, }, { .id = ZORRO_PROD_CBM_A4091_2, - .driver_data_ptr = &zorro7xx_driver_data[2], + .driver_data_ptr = &zorro7xx_a4091_data, }, { .id = ZORRO_PROD_GVP_GFORCE_040_060, - .driver_data_ptr = &zorro7xx_driver_data[3], + .driver_data_ptr = &zorro7xx_gforce_040_060_data, }, { } }; diff --git a/drivers/target/iscsi/Kconfig b/drivers/target/iscsi/Kconfig index 70d76f3dd693..44bbf1f32859 100644 --- a/drivers/target/iscsi/Kconfig +++ b/drivers/target/iscsi/Kconfig @@ -3,8 +3,11 @@ config ISCSI_TARGET tristate "SCSI Target Mode Stack" depends on INET select CRC32 - select CRYPTO - select CRYPTO_HASH + select CRYPTO_LIB_MD5 + select CRYPTO_LIB_SHA1 + select CRYPTO_LIB_SHA256 + select CRYPTO_LIB_SHA3 + select CRYPTO_LIB_UTILS help Say M to enable the SCSI target mode stack. A SCSI target mode stack is software that makes local storage available over a storage network diff --git a/drivers/target/iscsi/iscsi_target_auth.c b/drivers/target/iscsi/iscsi_target_auth.c index f3c0cdd31830..945dd6409723 100644 --- a/drivers/target/iscsi/iscsi_target_auth.c +++ b/drivers/target/iscsi/iscsi_target_auth.c @@ -8,31 +8,73 @@ * ******************************************************************************/ -#include +#include +#include +#include +#include #include +#include #include #include -#include #include #include -#include +#include #include #include "iscsi_target_nego.h" #include "iscsi_target_auth.h" -static char *chap_get_digest_name(const int digest_type) +static const struct { + const char *digest_name; /* Used only in log messages */ + unsigned int digest_size; +} chap_digest_algs[] = { + [CHAP_DIGEST_MD5] = { + .digest_name = "md5", + .digest_size = MD5_DIGEST_SIZE, + }, + [CHAP_DIGEST_SHA1] = { + .digest_name = "sha1", + .digest_size = SHA1_DIGEST_SIZE, + }, + [CHAP_DIGEST_SHA256] = { + .digest_name = "sha256", + .digest_size = SHA256_DIGEST_SIZE, + }, + [CHAP_DIGEST_SHA3_256] = { + .digest_name = "sha3-256", + .digest_size = SHA3_256_DIGEST_SIZE, + }, +}; + +static int chap_digest(int digest_type, u8 chap_id, const char *password, + const u8 *challenge, size_t challenge_len, + u8 *out_digest) { + size_t pass_len = strlen(password); + size_t data_len = 1 + pass_len + challenge_len; + u8 *data __free(kfree_sensitive) = kmalloc(data_len, GFP_KERNEL); + + if (!data) + return -ENOMEM; + data[0] = chap_id; + memcpy(&data[1], password, pass_len); + memcpy(&data[1 + pass_len], challenge, challenge_len); + switch (digest_type) { case CHAP_DIGEST_MD5: - return "md5"; + md5(data, data_len, out_digest); + return 0; case CHAP_DIGEST_SHA1: - return "sha1"; + sha1(data, data_len, out_digest); + return 0; case CHAP_DIGEST_SHA256: - return "sha256"; + sha256(data, data_len, out_digest); + return 0; case CHAP_DIGEST_SHA3_256: - return "sha3-256"; + sha3_256(data, data_len, out_digest); + return 0; default: - return NULL; + WARN_ON_ONCE(1); + return -EINVAL; } } @@ -72,21 +114,9 @@ static int chap_gen_challenge( return ret; } -static int chap_test_algorithm(const char *name) -{ - struct crypto_shash *tfm; - - tfm = crypto_alloc_shash(name, 0, 0); - if (IS_ERR(tfm)) - return -1; - - crypto_free_shash(tfm); - return 0; -} - static int chap_check_algorithm(const char *a_str) { - char *tmp, *orig, *token, *digest_name; + char *tmp, *orig, *token; long digest_type; int r = CHAP_DIGEST_UNKNOWN; @@ -113,17 +143,17 @@ static int chap_check_algorithm(const char *a_str) if (kstrtol(token, 10, &digest_type)) continue; - digest_name = chap_get_digest_name(digest_type); - if (!digest_name) + if (fips_enabled && digest_type == CHAP_DIGEST_MD5) continue; - pr_debug("Selected %s Algorithm\n", digest_name); - if (chap_test_algorithm(digest_name) < 0) { - pr_err("failed to allocate %s algo\n", digest_name); - } else { - r = digest_type; - goto out; - } + if (digest_type < 0 || + digest_type >= ARRAY_SIZE(chap_digest_algs) || + chap_digest_algs[digest_type].digest_name == NULL) + continue; + pr_debug("Selected %s Algorithm\n", + chap_digest_algs[digest_type].digest_name); + r = digest_type; + goto out; } out: kfree(orig); @@ -159,27 +189,15 @@ static struct iscsi_chap *chap_server_open( chap = conn->auth_protocol; digest_type = chap_check_algorithm(a_str); - switch (digest_type) { - case CHAP_DIGEST_MD5: - chap->digest_size = MD5_SIGNATURE_SIZE; - break; - case CHAP_DIGEST_SHA1: - chap->digest_size = SHA1_SIGNATURE_SIZE; - break; - case CHAP_DIGEST_SHA256: - chap->digest_size = SHA256_SIGNATURE_SIZE; - break; - case CHAP_DIGEST_SHA3_256: - chap->digest_size = SHA3_256_SIGNATURE_SIZE; - break; - case CHAP_DIGEST_UNKNOWN: - default: + if (digest_type == CHAP_DIGEST_UNKNOWN) { pr_err("Unsupported CHAP_A value\n"); chap_close(conn); return NULL; } - chap->digest_name = chap_get_digest_name(digest_type); + chap->digest_name = chap_digest_algs[digest_type].digest_name; + chap->digest_type = digest_type; + chap->digest_size = chap_digest_algs[digest_type].digest_size; /* Tie the challenge length to the digest size */ chap->challenge_len = chap->digest_size; @@ -247,7 +265,6 @@ static int chap_server_compute_hash( unsigned int *nr_out_len) { unsigned long id; - unsigned char id_as_uchar; unsigned char type; unsigned char identifier[10], *initiatorchg = NULL; unsigned char *initiatorchg_binhex = NULL; @@ -258,8 +275,6 @@ static int chap_server_compute_hash( unsigned char chap_n[MAX_CHAP_N_SIZE], chap_r[MAX_RESPONSE_LENGTH]; size_t compare_len; struct iscsi_chap *chap = conn->auth_protocol; - struct crypto_shash *tfm = NULL; - struct shash_desc *desc = NULL; int auth_ret = -1, ret, initiatorchg_len; digest = kzalloc(chap->digest_size, GFP_KERNEL); @@ -364,44 +379,10 @@ static int chap_server_compute_hash( pr_debug("[server] Got CHAP_R=%s\n", chap_r); - tfm = crypto_alloc_shash(chap->digest_name, 0, 0); - if (IS_ERR(tfm)) { - tfm = NULL; - pr_err("Unable to allocate struct crypto_shash\n"); - goto out; - } - - desc = kmalloc(sizeof(*desc) + crypto_shash_descsize(tfm), GFP_KERNEL); - if (!desc) { - pr_err("Unable to allocate struct shash_desc\n"); - goto out; - } - - desc->tfm = tfm; - - ret = crypto_shash_init(desc); - if (ret < 0) { - pr_err("crypto_shash_init() failed\n"); - goto out; - } - - ret = crypto_shash_update(desc, &chap->id, 1); - if (ret < 0) { - pr_err("crypto_shash_update() failed for id\n"); - goto out; - } - - ret = crypto_shash_update(desc, (char *)&auth->password, - strlen(auth->password)); - if (ret < 0) { - pr_err("crypto_shash_update() failed for password\n"); - goto out; - } - - ret = crypto_shash_finup(desc, chap->challenge, - chap->challenge_len, server_digest); + ret = chap_digest(chap->digest_type, chap->id, auth->password, + chap->challenge, chap->challenge_len, server_digest); if (ret < 0) { - pr_err("crypto_shash_finup() failed for challenge\n"); + pr_err("chap_digest() failed\n"); goto out; } @@ -530,40 +511,12 @@ static int chap_server_compute_hash( /* * Generate CHAP_N and CHAP_R for mutual authentication. */ - ret = crypto_shash_init(desc); + ret = chap_digest(chap->digest_type, id, auth->password_mutual, + initiatorchg_binhex, initiatorchg_len, digest); if (ret < 0) { - pr_err("crypto_shash_init() failed\n"); + pr_err("chap_digest() failed\n"); goto out; } - - /* To handle both endiannesses */ - id_as_uchar = id; - ret = crypto_shash_update(desc, &id_as_uchar, 1); - if (ret < 0) { - pr_err("crypto_shash_update() failed for id\n"); - goto out; - } - - ret = crypto_shash_update(desc, auth->password_mutual, - strlen(auth->password_mutual)); - if (ret < 0) { - pr_err("crypto_shash_update() failed for" - " password_mutual\n"); - goto out; - } - /* - * Convert received challenge to binary hex. - */ - ret = crypto_shash_finup(desc, initiatorchg_binhex, initiatorchg_len, - digest); - if (ret < 0) { - pr_err("crypto_shash_finup() failed for ma challenge\n"); - goto out; - } - - /* - * Generate CHAP_N and CHAP_R. - */ *nr_out_len = sprintf(nr_out_ptr, "CHAP_N=%s", auth->userid_mutual); *nr_out_len += 1; pr_debug("[server] Sending CHAP_N=%s\n", auth->userid_mutual); @@ -577,9 +530,6 @@ static int chap_server_compute_hash( pr_debug("[server] Sending CHAP_R=0x%s\n", response); auth_ret = 0; out: - kfree_sensitive(desc); - if (tfm) - crypto_free_shash(tfm); kfree(initiatorchg); kfree(initiatorchg_binhex); kfree(digest); diff --git a/drivers/target/iscsi/iscsi_target_auth.h b/drivers/target/iscsi/iscsi_target_auth.h index ceb9b7754770..7ed288936af2 100644 --- a/drivers/target/iscsi/iscsi_target_auth.h +++ b/drivers/target/iscsi/iscsi_target_auth.h @@ -15,11 +15,6 @@ #define MAX_RESPONSE_LENGTH 128 /* sufficient for SHA3 256 */ #define MAX_CHAP_N_SIZE 512 -#define MD5_SIGNATURE_SIZE 16 /* 16 bytes in a MD5 message digest */ -#define SHA1_SIGNATURE_SIZE 20 /* 20 bytes in a SHA1 message digest */ -#define SHA256_SIGNATURE_SIZE 32 /* 32 bytes in a SHA256 message digest */ -#define SHA3_256_SIGNATURE_SIZE 32 /* 32 bytes in a SHA3 256 message digest */ - #define CHAP_STAGE_CLIENT_A 1 #define CHAP_STAGE_SERVER_AIC 2 #define CHAP_STAGE_CLIENT_NR 3 @@ -36,7 +31,8 @@ struct iscsi_chap { unsigned char id; unsigned char challenge[MAX_CHAP_CHALLENGE_LEN]; unsigned int challenge_len; - unsigned char *digest_name; + const char *digest_name; + int digest_type; unsigned int digest_size; unsigned int authenticate_target; unsigned int chap_state; diff --git a/drivers/target/iscsi/iscsi_target_configfs.c b/drivers/target/iscsi/iscsi_target_configfs.c index 704ec94383c3..e1aa0af52c65 100644 --- a/drivers/target/iscsi/iscsi_target_configfs.c +++ b/drivers/target/iscsi/iscsi_target_configfs.c @@ -1306,17 +1306,24 @@ static ssize_t iscsi_disc_enforce_discovery_auth_store(struct config_item *item, return -EINVAL; } + if (iscsit_get_tpg(discovery_tpg) < 0) + return -EINVAL; + param = iscsi_find_param_from_key(AUTHMETHOD, discovery_tpg->param_list); - if (!param) - return -EINVAL; + if (!param) { + err = -EINVAL; + goto out; + } if (op) { /* * Reset the AuthMethod key to CHAP. */ - if (iscsi_update_param_value(param, CHAP) < 0) - return -EINVAL; + if (iscsi_update_param_value(param, CHAP) < 0) { + err = -EINVAL; + goto out; + } discovery_tpg->tpg_attrib.authentication = 1; iscsit_global->discovery_acl.node_auth.enforce_discovery_auth = 1; @@ -1327,8 +1334,10 @@ static ssize_t iscsi_disc_enforce_discovery_auth_store(struct config_item *item, /* * Reset the AuthMethod key to CHAP,None */ - if (iscsi_update_param_value(param, "CHAP,None") < 0) - return -EINVAL; + if (iscsi_update_param_value(param, "CHAP,None") < 0) { + err = -EINVAL; + goto out; + } discovery_tpg->tpg_attrib.authentication = 0; iscsit_global->discovery_acl.node_auth.enforce_discovery_auth = 0; @@ -1337,7 +1346,10 @@ static ssize_t iscsi_disc_enforce_discovery_auth_store(struct config_item *item, " Discovery TPG\n"); } - return count; + err = count; +out: + iscsit_put_tpg(discovery_tpg); + return err; } CONFIGFS_ATTR(iscsi_disc_, enforce_discovery_auth); diff --git a/drivers/target/target_core_file.c b/drivers/target/target_core_file.c index 62ced9f5102f..ab9824a4852f 100644 --- a/drivers/target/target_core_file.c +++ b/drivers/target/target_core_file.c @@ -516,7 +516,7 @@ fd_do_prot_unmap(struct se_cmd *cmd, sector_t lba, sector_t nolb) void *buf; int rc; - buf = (void *)__get_free_page(GFP_KERNEL); + buf = kmalloc(PAGE_SIZE, GFP_KERNEL); if (!buf) { pr_err("Unable to allocate FILEIO prot buf\n"); return -ENOMEM; @@ -524,7 +524,7 @@ fd_do_prot_unmap(struct se_cmd *cmd, sector_t lba, sector_t nolb) rc = fd_do_prot_fill(cmd->se_dev, lba, nolb, buf, PAGE_SIZE); - free_page((unsigned long)buf); + kfree(buf); return rc; } diff --git a/drivers/target/target_core_pscsi.c b/drivers/target/target_core_pscsi.c index 9ed2818c3028..fd1b82fc7290 100644 --- a/drivers/target/target_core_pscsi.c +++ b/drivers/target/target_core_pscsi.c @@ -348,7 +348,7 @@ static struct se_device *pscsi_alloc_device(struct se_hba *hba, * Called with struct Scsi_Host->host_lock called. */ static int pscsi_create_type_disk(struct se_device *dev, struct scsi_device *sd) - __releases(sh->host_lock) + __releases(&sh->host_lock) { struct pscsi_hba_virt *phv = dev->se_hba->hba_ptr; struct pscsi_dev_virt *pdv = PSCSI_DEV(dev); @@ -359,10 +359,10 @@ static int pscsi_create_type_disk(struct se_device *dev, struct scsi_device *sd) if (scsi_device_get(sd)) { pr_err("scsi_device_get() failed for %d:%d:%d:%llu\n", sh->host_no, sd->channel, sd->id, sd->lun); - spin_unlock_irq(sh->host_lock); + spin_unlock_irq(&sh->host_lock); return -EIO; } - spin_unlock_irq(sh->host_lock); + spin_unlock_irq(&sh->host_lock); /* * Claim exclusive struct block_device access to struct scsi_device * for TYPE_DISK and TYPE_ZBC using supplied udev_path @@ -393,7 +393,7 @@ static int pscsi_create_type_disk(struct se_device *dev, struct scsi_device *sd) * Called with struct Scsi_Host->host_lock called. */ static int pscsi_create_type_nondisk(struct se_device *dev, struct scsi_device *sd) - __releases(sh->host_lock) + __releases(&sh->host_lock) { struct pscsi_hba_virt *phv = dev->se_hba->hba_ptr; struct Scsi_Host *sh = sd->host; @@ -402,10 +402,10 @@ static int pscsi_create_type_nondisk(struct se_device *dev, struct scsi_device * if (scsi_device_get(sd)) { pr_err("scsi_device_get() failed for %d:%d:%d:%llu\n", sh->host_no, sd->channel, sd->id, sd->lun); - spin_unlock_irq(sh->host_lock); + spin_unlock_irq(&sh->host_lock); return -EIO; } - spin_unlock_irq(sh->host_lock); + spin_unlock_irq(&sh->host_lock); ret = pscsi_add_device_to_list(dev, sd); if (ret) { @@ -491,7 +491,7 @@ static int pscsi_configure_device(struct se_device *dev) } } - spin_lock_irq(sh->host_lock); + spin_lock_irq(&sh->host_lock); list_for_each_entry(sd, &sh->__devices, siblings) { if ((pdv->pdv_channel_id != sd->channel) || (pdv->pdv_target_id != sd->id) || @@ -524,7 +524,7 @@ static int pscsi_configure_device(struct se_device *dev) } return 0; } - spin_unlock_irq(sh->host_lock); + spin_unlock_irq(&sh->host_lock); pr_err("pSCSI: Unable to locate %d:%d:%d:%d\n", sh->host_no, pdv->pdv_channel_id, pdv->pdv_target_id, pdv->pdv_lun_id); diff --git a/drivers/target/target_core_spc.c b/drivers/target/target_core_spc.c index f964a531e053..b70e81af867e 100644 --- a/drivers/target/target_core_spc.c +++ b/drivers/target/target_core_spc.c @@ -1226,9 +1226,9 @@ static sense_reason_t spc_emulate_request_sense(struct se_cmd *cmd) { unsigned char *cdb = cmd->t_task_cdb; unsigned char *rbuf; - u8 ua_asc = 0, ua_ascq = 0; unsigned char buf[SE_SENSE_BUF]; bool desc_format = target_sense_desc_format(cmd->se_dev); + u16 sense_code = NO_ADDITIONAL_SENSE_INFORMATION; memset(buf, 0, SE_SENSE_BUF); @@ -1242,11 +1242,12 @@ static sense_reason_t spc_emulate_request_sense(struct se_cmd *cmd) if (!rbuf) return TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE; - if (!core_scsi3_ua_clear_for_request_sense(cmd, &ua_asc, &ua_ascq)) - scsi_build_sense_buffer(desc_format, buf, UNIT_ATTENTION, - ua_asc, ua_ascq); + if (!core_scsi3_ua_clear_for_request_sense(cmd, &sense_code)) + scsi_set_sense_buffer(desc_format, buf, UNIT_ATTENTION, + sense_code); else - scsi_build_sense_buffer(desc_format, buf, NO_SENSE, 0x0, 0x0); + scsi_set_sense_buffer(desc_format, buf, NO_SENSE, + NO_ADDITIONAL_SENSE_INFORMATION); memcpy(rbuf, buf, min_t(u32, sizeof(buf), cmd->data_length)); transport_kunmap_data_sg(cmd); diff --git a/drivers/target/target_core_transport.c b/drivers/target/target_core_transport.c index dcfe94594916..927861c30afc 100644 --- a/drivers/target/target_core_transport.c +++ b/drivers/target/target_core_transport.c @@ -2359,7 +2359,7 @@ void target_do_delayed_work(struct work_struct *work) struct se_device *dev = container_of(work, struct se_device, delayed_cmd_work); - spin_lock(&dev->delayed_cmd_lock); + spin_lock_irq(&dev->delayed_cmd_lock); while (!dev->ordered_sync_in_progress) { struct se_cmd *cmd; @@ -2380,12 +2380,12 @@ void target_do_delayed_work(struct work_struct *work) dev->ordered_sync_in_progress = true; list_del(&cmd->se_delayed_node); - spin_unlock(&dev->delayed_cmd_lock); + spin_unlock_irq(&dev->delayed_cmd_lock); __target_execute_cmd(cmd, true); - spin_lock(&dev->delayed_cmd_lock); + spin_lock_irq(&dev->delayed_cmd_lock); } - spin_unlock(&dev->delayed_cmd_lock); + spin_unlock_irq(&dev->delayed_cmd_lock); } static void transport_complete_ordered_sync(struct se_cmd *cmd) @@ -3555,7 +3555,8 @@ static void translate_sense_reason(struct se_cmd *cmd, sense_reason_t reason) const struct sense_detail *sd; u8 *buffer = cmd->sense_buffer; int r = (__force int)reason; - u8 key, asc, ascq; + u16 code; + u8 key; bool desc_format = target_sense_desc_format(cmd->se_dev); if (r < ARRAY_SIZE(sense_detail_table) && sense_detail_table[r].key) @@ -3566,21 +3567,19 @@ static void translate_sense_reason(struct se_cmd *cmd, sense_reason_t reason) key = sd->key; if (reason == TCM_CHECK_CONDITION_UNIT_ATTENTION) { - if (!core_scsi3_ua_for_check_condition(cmd, &key, &asc, - &ascq)) { + if (!core_scsi3_ua_for_check_condition(cmd, &key, &code)) { cmd->scsi_status = SAM_STAT_BUSY; return; } } else { WARN_ON_ONCE(sd->asc == 0); - asc = sd->asc; - ascq = sd->ascq; + code = scsi_sense_code(sd->asc, sd->ascq); } cmd->se_cmd_flags |= SCF_EMULATED_TASK_SENSE; cmd->scsi_status = SAM_STAT_CHECK_CONDITION; cmd->scsi_sense_length = TRANSPORT_SENSE_BUFFER; - scsi_build_sense_buffer(desc_format, buffer, key, asc, ascq); + scsi_set_sense_buffer(desc_format, buffer, key, code); if (sd->add_sense_info) WARN_ON_ONCE(scsi_set_sense_information(buffer, cmd->scsi_sense_length, diff --git a/drivers/target/target_core_ua.c b/drivers/target/target_core_ua.c index 4276690fb6cb..ea97b05d47ab 100644 --- a/drivers/target/target_core_ua.c +++ b/drivers/target/target_core_ua.c @@ -187,11 +187,10 @@ void core_scsi3_ua_release_all( /* * Dequeue a unit attention from the unit attention list. This function - * returns true if the dequeuing succeeded and if *@key, *@asc and *@ascq have + * returns true if the dequeuing succeeded and if *@key and *@code have * been set. */ -bool core_scsi3_ua_for_check_condition(struct se_cmd *cmd, u8 *key, u8 *asc, - u8 *ascq) +bool core_scsi3_ua_for_check_condition(struct se_cmd *cmd, u8 *key, u16 *code) { struct se_device *dev = cmd->se_dev; struct se_dev_entry *deve; @@ -214,8 +213,7 @@ bool core_scsi3_ua_for_check_condition(struct se_cmd *cmd, u8 *key, u8 *asc, if (!deve) { rcu_read_unlock(); *key = ILLEGAL_REQUEST; - *asc = 0x25; /* LOGICAL UNIT NOT SUPPORTED */ - *ascq = 0; + *code = LU_NOT_SUPPORTED; return true; } *key = UNIT_ATTENTION; @@ -232,8 +230,7 @@ bool core_scsi3_ua_for_check_condition(struct se_cmd *cmd, u8 *key, u8 *asc, * clearing it. */ if (!dev_ua_intlck_clear) { - *asc = ua->ua_asc; - *ascq = ua->ua_ascq; + *code = scsi_sense_code(ua->ua_asc, ua->ua_ascq); break; } /* @@ -242,8 +239,7 @@ bool core_scsi3_ua_for_check_condition(struct se_cmd *cmd, u8 *key, u8 *asc, * (head of the list) in the outgoing CHECK_CONDITION + sense. */ if (head) { - *asc = ua->ua_asc; - *ascq = ua->ua_ascq; + *code = scsi_sense_code(ua->ua_asc, ua->ua_ascq); head = 0; } list_del(&ua->ua_nacl_list); @@ -258,15 +254,13 @@ bool core_scsi3_ua_for_check_condition(struct se_cmd *cmd, u8 *key, u8 *asc, nacl->se_tpg->se_tpg_tfo->fabric_name, dev_ua_intlck_clear ? "Releasing" : "Reporting", dev->dev_attrib.emulate_ua_intlck_ctrl, - cmd->orig_fe_lun, cmd->t_task_cdb[0], *asc, *ascq); + cmd->orig_fe_lun, cmd->t_task_cdb[0], + scsi_sense_code_asc(*code), scsi_sense_code_ascq(*code)); return head == 0; } -int core_scsi3_ua_clear_for_request_sense( - struct se_cmd *cmd, - u8 *asc, - u8 *ascq) +int core_scsi3_ua_clear_for_request_sense(struct se_cmd *cmd, u16 *code) { struct se_dev_entry *deve; struct se_session *sess = cmd->se_sess; @@ -304,8 +298,7 @@ int core_scsi3_ua_clear_for_request_sense( spin_lock(&deve->ua_lock); list_for_each_entry_safe(ua, ua_p, &deve->ua_list, ua_nacl_list) { if (head) { - *asc = ua->ua_asc; - *ascq = ua->ua_ascq; + *code = scsi_sense_code(ua->ua_asc, ua->ua_ascq); head = 0; } list_del(&ua->ua_nacl_list); @@ -317,7 +310,8 @@ int core_scsi3_ua_clear_for_request_sense( pr_debug("[%s]: Released UNIT ATTENTION condition, mapped" " LUN: %llu, got REQUEST_SENSE reported ASC: 0x%02x," " ASCQ: 0x%02x\n", nacl->se_tpg->se_tpg_tfo->fabric_name, - cmd->orig_fe_lun, *asc, *ascq); + cmd->orig_fe_lun, scsi_sense_code_asc(*code), + scsi_sense_code_ascq(*code)); return (head) ? -EPERM : 0; } diff --git a/drivers/target/target_core_ua.h b/drivers/target/target_core_ua.h index 76487c9be090..6b636c13fee2 100644 --- a/drivers/target/target_core_ua.h +++ b/drivers/target/target_core_ua.h @@ -37,9 +37,8 @@ extern sense_reason_t target_scsi3_ua_check(struct se_cmd *); extern int core_scsi3_ua_allocate(struct se_dev_entry *, u8, u8); extern void target_ua_allocate_lun(struct se_node_acl *, u32, u8, u8); extern void core_scsi3_ua_release_all(struct se_dev_entry *); -extern bool core_scsi3_ua_for_check_condition(struct se_cmd *, u8 *, u8 *, - u8 *); -extern int core_scsi3_ua_clear_for_request_sense(struct se_cmd *, - u8 *, u8 *); +extern bool core_scsi3_ua_for_check_condition(struct se_cmd *cmd, u8 *key, + u16 *code); +extern int core_scsi3_ua_clear_for_request_sense(struct se_cmd *cmd, u16 *code); #endif /* TARGET_CORE_UA_H */ diff --git a/drivers/target/target_core_user.c b/drivers/target/target_core_user.c index edc2afd5f4ee..425ad1246a75 100644 --- a/drivers/target/target_core_user.c +++ b/drivers/target/target_core_user.c @@ -3006,10 +3006,7 @@ static ssize_t tcmu_tmr_notification_store(struct config_item *item, if (val > 1) return -EINVAL; - if (val) - set_bit(TCMU_DEV_BIT_TMR_NOTIFY, &udev->flags); - else - clear_bit(TCMU_DEV_BIT_TMR_NOTIFY, &udev->flags); + assign_bit(TCMU_DEV_BIT_TMR_NOTIFY, &udev->flags, val); return count; } CONFIGFS_ATTR(tcmu_, tmr_notification); diff --git a/drivers/ufs/Kconfig b/drivers/ufs/Kconfig index f662e7ce71f1..b62c00e7ff06 100644 --- a/drivers/ufs/Kconfig +++ b/drivers/ufs/Kconfig @@ -7,6 +7,7 @@ menuconfig SCSI_UFSHCD tristate "Universal Flash Storage Controller" depends on SCSI && SCSI_DMA depends on RPMB || !RPMB + select CRYPTO_LIB_BLAKE2B if RPMB select PM_DEVFREQ select DEVFREQ_GOV_SIMPLE_ONDEMAND select NLS diff --git a/drivers/ufs/core/ufs-debugfs.c b/drivers/ufs/core/ufs-debugfs.c index ed1de70e2ec1..9f83628f3e2c 100644 --- a/drivers/ufs/core/ufs-debugfs.c +++ b/drivers/ufs/core/ufs-debugfs.c @@ -177,7 +177,7 @@ static ssize_t ufs_saved_err_write(struct file *file, const char __user *buf, if (ret < 0) return ret; - spin_lock_irq(hba->host->host_lock); + spin_lock_irq(&hba->host->host_lock); if (strcmp(attr->name, "saved_err") == 0) { hba->saved_err = val; } else if (strcmp(attr->name, "saved_uic_err") == 0) { @@ -187,7 +187,7 @@ static ssize_t ufs_saved_err_write(struct file *file, const char __user *buf, } if (ret == 0) ufshcd_schedule_eh_work(hba); - spin_unlock_irq(hba->host->host_lock); + spin_unlock_irq(&hba->host->host_lock); return ret < 0 ? ret : count; } diff --git a/drivers/ufs/core/ufs-mcq.c b/drivers/ufs/core/ufs-mcq.c index 8106d55f4041..df293b66350d 100644 --- a/drivers/ufs/core/ufs-mcq.c +++ b/drivers/ufs/core/ufs-mcq.c @@ -312,20 +312,24 @@ static int ufshcd_mcq_get_tag(struct ufs_hba *hba, struct cq_entry *cqe) UFSHCD_NUM_RESERVED; } +static void ufshcd_mcq_compl_cqe(struct ufs_hba *hba, struct cq_entry *cqe) +{ + int tag = ufshcd_mcq_get_tag(hba, cqe); + + ufshcd_compl_one_cqe(hba, tag, cqe); + /* After processing the CQE, mark it as an empty (invalid) entry. */ + cqe->command_desc_base_addr = 0; +} + static void ufshcd_mcq_process_cqe(struct ufs_hba *hba, struct ufs_hw_queue *hwq) { struct cq_entry *cqe = ufshcd_mcq_cur_cqe(hwq); - if (cqe->command_desc_base_addr) { - int tag = ufshcd_mcq_get_tag(hba, cqe); - - ufshcd_compl_one_cqe(hba, tag, cqe); - /* After processed the cqe, mark it empty (invalid) entry */ - cqe->command_desc_base_addr = 0; - } else { + if (cqe->command_desc_base_addr) + ufshcd_mcq_compl_cqe(hba, cqe); + else dev_err(hba->dev, "Abnormal CQ entry!\n"); - } } /* @@ -333,7 +337,7 @@ static void ufshcd_mcq_process_cqe(struct ufs_hba *hba, * controller disabled (HCE = 0). Reading host controller registers, e.g. the * CQ tail pointer (CQTPy), may not be safe with the host controller disabled. * Hence, iterate over all completion queue entries. This won't result in - * double completions because ufshcd_mcq_process_cqe() clears a CQE after it + * double completions because ufshcd_mcq_compl_cqe() clears a CQE after it * has been processed. */ void ufshcd_mcq_compl_all_cqes_lock(struct ufs_hba *hba, @@ -344,13 +348,13 @@ void ufshcd_mcq_compl_all_cqes_lock(struct ufs_hba *hba, spin_lock_irqsave(&hwq->cq_lock, flags); while (entries > 0) { - ufshcd_mcq_process_cqe(hba, hwq); + struct cq_entry *cqe = ufshcd_mcq_cur_cqe(hwq); + + if (cqe->command_desc_base_addr) + ufshcd_mcq_compl_cqe(hba, cqe); ufshcd_mcq_inc_cq_head_slot(hwq); entries--; } - - ufshcd_mcq_update_cq_tail_slot(hwq); - hwq->cq_head_slot = hwq->cq_tail_slot; spin_unlock_irqrestore(&hwq->cq_lock, flags); } diff --git a/drivers/ufs/core/ufs-rpmb.c b/drivers/ufs/core/ufs-rpmb.c index aa925cbb07e8..65f2d71cf073 100644 --- a/drivers/ufs/core/ufs-rpmb.c +++ b/drivers/ufs/core/ufs-rpmb.c @@ -10,6 +10,7 @@ * Can Guo */ +#include #include #include #include @@ -21,6 +22,8 @@ #include #include "ufshcd-priv.h" +#define UFS_RPMB_ID_LEN 16 /* Match eMMC CID Length */ +#define UFS_RPMB_UA_RETRIES 3 /* Retries for the power-on UNIT ATTENTION */ #define UFS_RPMB_SEC_PROTOCOL 0xEC /* JEDEC UFS application */ #define UFS_RPMB_SEC_PROTOCOL_ID 0x01 /* JEDEC UFS RPMB protocol ID, CDB byte3 */ @@ -40,6 +43,23 @@ struct ufs_rpmb_dev { static int ufs_sec_submit(struct ufs_hba *hba, u16 spsp, void *buffer, size_t len, bool send) { struct scsi_device *sdev = hba->ufs_rpmb_wlun; + struct scsi_failure failure_defs[] = { + { + .sense_key = UNIT_ATTENTION, + .sense_code = + scsi_sense_code(ASC_POWER_ON_RESET_OR_BUS_DEVICE_RESET_OCCURRED, + SCMD_FAILURE_ASCQ_ANY), + .allowed = UFS_RPMB_UA_RETRIES, + .result = SAM_STAT_CHECK_CONDITION, + }, + {} + }; + struct scsi_failures failures = { + .failure_definitions = failure_defs, + }; + const struct scsi_exec_args exec_args = { + .failures = &failures, + }; u8 cdb[12] = { }; cdb[0] = send ? SECURITY_PROTOCOL_OUT : SECURITY_PROTOCOL_IN; @@ -48,7 +68,8 @@ static int ufs_sec_submit(struct ufs_hba *hba, u16 spsp, void *buffer, size_t le put_unaligned_be32(len, &cdb[6]); return scsi_execute_cmd(sdev, cdb, send ? REQ_OP_DRV_OUT : REQ_OP_DRV_IN, - buffer, len, /*timeout=*/30 * HZ, 0, NULL); + buffer, len, /*timeout=*/30 * HZ, /*retries=*/0, + &exec_args); } /* UFS RPMB route frames implementation */ @@ -139,6 +160,7 @@ static void ufs_rpmb_device_release(struct device *dev) int ufs_rpmb_probe(struct ufs_hba *hba) { struct ufs_rpmb_dev *ufs_rpmb, *it, *tmp; + u8 dev_id[UFS_RPMB_ID_LEN]; struct rpmb_dev *rdev; char *cid = NULL; int region; @@ -197,8 +219,10 @@ int ufs_rpmb_probe(struct ufs_hba *hba) goto err_out; } - descr.dev_id = cid; - descr.dev_id_len = strlen(cid); + blake2b(NULL, 0, cid, strlen(cid), dev_id, UFS_RPMB_ID_LEN); + + descr.dev_id = dev_id; + descr.dev_id_len = UFS_RPMB_ID_LEN; descr.capacity = cap; /* Register RPMB device */ diff --git a/drivers/ufs/core/ufs-sysfs.c b/drivers/ufs/core/ufs-sysfs.c index 63e670d1a9d9..cf49ad0258e1 100644 --- a/drivers/ufs/core/ufs-sysfs.c +++ b/drivers/ufs/core/ufs-sysfs.c @@ -150,12 +150,12 @@ static inline ssize_t ufs_sysfs_pm_lvl_store(struct device *dev, !(dev_info->wspecversion >= 0x310))) return -EINVAL; - spin_lock_irqsave(hba->host->host_lock, flags); + spin_lock_irqsave(&hba->host->host_lock, flags); if (rpm) hba->rpm_lvl = value; else hba->spm_lvl = value; - spin_unlock_irqrestore(hba->host->host_lock, flags); + spin_unlock_irqrestore(&hba->host->host_lock, flags); return count; } @@ -787,7 +787,7 @@ static ssize_t monitor_enable_store(struct device *dev, return -EINVAL; value = !!value; - spin_lock_irqsave(hba->host->host_lock, flags); + spin_lock_irqsave(&hba->host->host_lock, flags); if (value == hba->monitor.enabled) goto out_unlock; @@ -799,7 +799,7 @@ static ssize_t monitor_enable_store(struct device *dev, } out_unlock: - spin_unlock_irqrestore(hba->host->host_lock, flags); + spin_unlock_irqrestore(&hba->host->host_lock, flags); return count; } @@ -821,11 +821,11 @@ static ssize_t monitor_chunk_size_store(struct device *dev, if (kstrtoul(buf, 0, &value)) return -EINVAL; - spin_lock_irqsave(hba->host->host_lock, flags); + spin_lock_irqsave(&hba->host->host_lock, flags); /* Only allow chunk size change when monitor is disabled */ if (!hba->monitor.enabled) hba->monitor.chunk_size = value; - spin_unlock_irqrestore(hba->host->host_lock, flags); + spin_unlock_irqrestore(&hba->host->host_lock, flags); return count; } diff --git a/drivers/ufs/core/ufs_bsg.c b/drivers/ufs/core/ufs_bsg.c index 7a66917b3fc0..156637dd76c8 100644 --- a/drivers/ufs/core/ufs_bsg.c +++ b/drivers/ufs/core/ufs_bsg.c @@ -258,7 +258,7 @@ int ufs_bsg_probe(struct ufs_hba *hba) goto out; q = bsg_setup_queue(bsg_dev, dev_name(bsg_dev), NULL, ufs_bsg_request, - NULL, 0); + NULL, 0, sizeof(struct ufs_rpmb_reply)); if (IS_ERR(q)) { ret = PTR_ERR(q); device_del(bsg_dev); diff --git a/drivers/ufs/core/ufshcd.c b/drivers/ufs/core/ufshcd.c index 2ba244cf40ac..cc75384c6502 100644 --- a/drivers/ufs/core/ufshcd.c +++ b/drivers/ufs/core/ufshcd.c @@ -1273,10 +1273,10 @@ static u32 ufshcd_pending_cmds(struct ufs_hba *hba) unsigned long flags; u32 pending = 0; - spin_lock_irqsave(hba->host->host_lock, flags); + spin_lock_irqsave(&hba->host->host_lock, flags); __shost_for_each_device(sdev, hba->host) pending += scsi_device_busy(sdev); - spin_unlock_irqrestore(hba->host->host_lock, flags); + spin_unlock_irqrestore(&hba->host->host_lock, flags); return pending; } @@ -1681,11 +1681,6 @@ static int ufshcd_devfreq_get_dev_status(struct device *dev, if (!scaling->window_start_t) goto start_window; - /* - * If current frequency is 0, then the ondemand governor considers - * there's no initial frequency set. And it always requests to set - * to max. frequency. - */ if (hba->use_pm_opp) { stat->current_frequency = hba->clk_scaling.target_freq; } else { @@ -1716,6 +1711,26 @@ static int ufshcd_devfreq_get_dev_status(struct device *dev, return 0; } +static int ufshcd_devfreq_get_cur_freq(struct device *dev, unsigned long *freq) +{ + struct ufs_hba *hba = dev_get_drvdata(dev); + + if (!ufshcd_is_clkscaling_supported(hba)) + return -EINVAL; + + if (hba->use_pm_opp) { + *freq = hba->clk_scaling.target_freq; + } else { + struct ufs_clk_info *clki; + + clki = list_first_entry(&hba->clk_list_head, + struct ufs_clk_info, list); + *freq = clki->curr_freq; + } + + return 0; +} + static int ufshcd_devfreq_init(struct ufs_hba *hba) { struct list_head *clk_list = &hba->clk_list_head; @@ -1727,12 +1742,21 @@ static int ufshcd_devfreq_init(struct ufs_hba *hba) if (list_empty(clk_list)) return 0; + clki = list_first_entry(clk_list, struct ufs_clk_info, list); + if (!hba->use_pm_opp) { - clki = list_first_entry(clk_list, struct ufs_clk_info, list); dev_pm_opp_add(hba->dev, clki->min_freq, 0); dev_pm_opp_add(hba->dev, clki->max_freq, 0); } + /* + * ufshcd_init_clocks() has already set the clocks to the highest + * frequency, and nothing has changed them since. Save that frequency, + * so that devfreq and the clock scaling code know where we start. + */ + hba->clk_scaling.target_freq = clki->max_freq; + hba->vps->devfreq_profile.initial_freq = clki->max_freq; + ufshcd_vops_config_scaling_param(hba, &hba->vps->devfreq_profile, &hba->vps->ondemand_data); devfreq = devfreq_add_device(hba->dev, @@ -2061,7 +2085,7 @@ static void ufshcd_gate_work(struct work_struct *work) return; } - scoped_guard(spinlock_irqsave, hba->host->host_lock) { + scoped_guard(spinlock_irqsave, &hba->host->host_lock) { if (ufshcd_is_ufs_dev_busy(hba) || hba->ufshcd_state != UFSHCD_STATE_OPERATIONAL) return; @@ -2118,7 +2142,7 @@ static void __ufshcd_release(struct ufs_hba *hba) hba->clk_gating.state == CLKS_OFF) return; - scoped_guard(spinlock_irqsave, hba->host->host_lock) { + scoped_guard(spinlock_irqsave, &hba->host->host_lock) { if (ufshcd_has_pending_tasks(hba) || hba->ufshcd_state != UFSHCD_STATE_OPERATIONAL) return; @@ -2343,10 +2367,10 @@ static void ufshcd_start_monitor(struct ufs_hba *hba, struct scsi_cmnd *cmd) int dir = ufshcd_monitor_opcode2dir(cmd->cmnd[0]); unsigned long flags; - spin_lock_irqsave(hba->host->host_lock, flags); + spin_lock_irqsave(&hba->host->host_lock, flags); if (dir >= 0 && hba->monitor.nr_queued[dir]++ == 0) hba->monitor.busy_start_ts[dir] = ktime_get(); - spin_unlock_irqrestore(hba->host->host_lock, flags); + spin_unlock_irqrestore(&hba->host->host_lock, flags); } static void ufshcd_update_monitor(struct ufs_hba *hba, struct scsi_cmnd *cmd) @@ -2356,7 +2380,7 @@ static void ufshcd_update_monitor(struct ufs_hba *hba, struct scsi_cmnd *cmd) int dir = ufshcd_monitor_opcode2dir(cmd->cmnd[0]); unsigned long flags; - spin_lock_irqsave(hba->host->host_lock, flags); + spin_lock_irqsave(&hba->host->host_lock, flags); if (dir >= 0 && hba->monitor.nr_queued[dir] > 0) { struct ufs_hba_monitor *m = &hba->monitor; ktime_t now, inc, lat; @@ -2379,7 +2403,7 @@ static void ufshcd_update_monitor(struct ufs_hba *hba, struct scsi_cmnd *cmd) /* Push forward the busy start of monitor */ m->busy_start_ts[dir] = now; } - spin_unlock_irqrestore(hba->host->host_lock, flags); + spin_unlock_irqrestore(&hba->host->host_lock, flags); } /* Returns %true for SCSI commands and %false for device management commands. */ @@ -2636,9 +2660,9 @@ ufshcd_wait_for_uic_cmd(struct ufs_hba *hba, struct uic_command *uic_cmd) } } - spin_lock_irqsave(hba->host->host_lock, flags); + spin_lock_irqsave(&hba->host->host_lock, flags); hba->active_uic_cmd = NULL; - spin_unlock_irqrestore(hba->host->host_lock, flags); + spin_unlock_irqrestore(&hba->host->host_lock, flags); return ret; } @@ -2688,9 +2712,9 @@ int ufshcd_send_uic_cmd(struct ufs_hba *hba, struct uic_command *uic_cmd) mutex_lock(&hba->uic_cmd_mutex); ufshcd_add_delay_before_dme_cmd(hba); - spin_lock_irqsave(hba->host->host_lock, flags); + spin_lock_irqsave(&hba->host->host_lock, flags); ufshcd_enable_intr(hba, UIC_COMMAND_COMPL); - spin_unlock_irqrestore(hba->host->host_lock, flags); + spin_unlock_irqrestore(&hba->host->host_lock, flags); ret = __ufshcd_send_uic_cmd(hba, uic_cmd); if (!ret) @@ -3162,9 +3186,9 @@ static enum scsi_qc_status ufshcd_queuecommand(struct Scsi_Host *host, if (ufs_trigger_eh(hba)) { unsigned long flags; - spin_lock_irqsave(hba->host->host_lock, flags); + spin_lock_irqsave(&hba->host->host_lock, flags); ufshcd_schedule_eh_work(hba); - spin_unlock_irqrestore(hba->host->host_lock, flags); + spin_unlock_irqrestore(&hba->host->host_lock, flags); } return err; @@ -3284,6 +3308,11 @@ ufshcd_dev_cmd_completion(struct ufs_hba *hba, struct ufshcd_lrb *lrbp) if (response == 0) { err = ufshcd_copy_query_response(hba, lrbp); + } else if (response == QUERY_RESULT_INVALID_IDN) { + err = -EOPNOTSUPP; + dev_dbg(hba->dev, "%s: unsupported opcode 0x%x idn 0x%x\n", + __func__, lrbp->ucd_req_ptr->qr.opcode, + lrbp->ucd_req_ptr->qr.idn); } else { err = -EINVAL; dev_err(hba->dev, "%s: unexpected response in Query RSP: %x\n", @@ -3446,6 +3475,8 @@ static int ufshcd_query_flag_retry(struct ufs_hba *hba, for (retries = 0; retries < QUERY_REQ_RETRIES; retries++) { ret = ufshcd_query_flag(hba, opcode, idn, index, flag_res); + if (ret == -EOPNOTSUPP) + return ret; if (ret) dev_dbg(hba->dev, "%s: failed with error %d, retries %d\n", @@ -3512,7 +3543,8 @@ int ufshcd_query_flag(struct ufs_hba *hba, enum query_opcode opcode, } err = ufshcd_exec_dev_cmd(hba, DEV_CMD_TYPE_QUERY, timeout); - + if (err == -EOPNOTSUPP) + goto out_unlock; if (err) { dev_err(hba->dev, "%s: Sending flag query for idn %d failed, err = %d\n", @@ -3577,7 +3609,8 @@ int ufshcd_query_attr(struct ufs_hba *hba, enum query_opcode opcode, } err = ufshcd_exec_dev_cmd(hba, DEV_CMD_TYPE_QUERY, dev_cmd_timeout); - + if (err == -EOPNOTSUPP) + goto out_unlock; if (err) { dev_err(hba->dev, "%s: opcode 0x%.2x for idn %d failed, index %d, err = %d\n", __func__, opcode, idn, index, err); @@ -3615,6 +3648,8 @@ int ufshcd_query_attr_retry(struct ufs_hba *hba, for (retries = QUERY_REQ_RETRIES; retries > 0; retries--) { ret = ufshcd_query_attr(hba, opcode, idn, index, selector, attr_val); + if (ret == -EOPNOTSUPP) + return ret; if (ret) dev_dbg(hba->dev, "%s: failed with error %d, retries %d\n", __func__, ret, retries); @@ -3676,6 +3711,8 @@ int ufshcd_query_attr_qword(struct ufs_hba *hba, enum query_opcode opcode, } err = ufshcd_exec_dev_cmd(hba, DEV_CMD_TYPE_QUERY, dev_cmd_timeout); + if (err == -EOPNOTSUPP) + goto out_unlock; if (err) { dev_err(hba->dev, "%s: opcode 0x%.2x for idn %d failed, index %d, selector %d, err = %d\n", __func__, opcode, idn, index, sel, err); @@ -3739,7 +3776,8 @@ static int __ufshcd_query_descriptor(struct ufs_hba *hba, } err = ufshcd_exec_dev_cmd(hba, DEV_CMD_TYPE_QUERY, dev_cmd_timeout); - + if (err == -EOPNOTSUPP) + goto out_unlock; if (err) { dev_err(hba->dev, "%s: opcode 0x%.2x for idn %d failed, index %d, err = %d\n", __func__, opcode, idn, index, err); @@ -3782,7 +3820,7 @@ int ufshcd_query_descriptor_retry(struct ufs_hba *hba, for (retries = QUERY_REQ_RETRIES; retries > 0; retries--) { err = __ufshcd_query_descriptor(hba, opcode, idn, index, selector, desc_buf, buf_len); - if (!err || err == -EINVAL) + if (!err || err == -EINVAL || err == -EOPNOTSUPP) break; } @@ -3831,6 +3869,8 @@ int ufshcd_read_desc_param(struct ufs_hba *hba, ret = ufshcd_query_descriptor_retry(hba, UPIU_QUERY_OPCODE_READ_DESC, desc_id, desc_index, 0, desc_buf, &buff_len); + if (ret == -EOPNOTSUPP) + goto out; if (ret) { dev_err(hba->dev, "%s: Failed reading descriptor. desc_id %d, desc_index %d, param_offset %d, ret %d\n", __func__, desc_id, desc_index, param_offset, ret); @@ -3917,8 +3957,9 @@ int ufshcd_read_string_desc(struct ufs_hba *hba, u8 desc_index, u8 **buf, enum u ret = ufshcd_read_desc_param(hba, QUERY_DESC_IDN_STRING, desc_index, 0, (u8 *)uc_str, QUERY_DESC_MAX_SIZE); if (ret < 0) { - dev_err(hba->dev, "Reading String Desc failed after %d retries. err = %d\n", - QUERY_REQ_RETRIES, ret); + if (ret != -EOPNOTSUPP) + dev_err(hba->dev, "Reading String Desc failed after %d retries. err = %d\n", + QUERY_REQ_RETRIES, ret); str = NULL; goto out; } @@ -4498,14 +4539,14 @@ static int ufshcd_uic_pwr_ctrl(struct ufs_hba *hba, struct uic_command *cmd) mutex_lock(&hba->uic_cmd_mutex); ufshcd_add_delay_before_dme_cmd(hba); - spin_lock_irqsave(hba->host->host_lock, flags); + spin_lock_irqsave(&hba->host->host_lock, flags); if (ufshcd_is_link_broken(hba)) { ret = -ENOLINK; goto out_unlock; } hba->uic_async_done = &uic_async_done; ufshcd_disable_intr(hba, UIC_COMMAND_COMPL); - spin_unlock_irqrestore(hba->host->host_lock, flags); + spin_unlock_irqrestore(&hba->host->host_lock, flags); ret = __ufshcd_send_uic_cmd(hba, cmd); if (ret) { dev_err(hba->dev, @@ -4549,7 +4590,7 @@ static int ufshcd_uic_pwr_ctrl(struct ufs_hba *hba, struct uic_command *cmd) ufshcd_print_evt_hist(hba); } - spin_lock_irqsave(hba->host->host_lock, flags); + spin_lock_irqsave(&hba->host->host_lock, flags); hba->active_uic_cmd = NULL; hba->uic_async_done = NULL; if (ret && !hba->pm_op_in_progress) { @@ -4557,7 +4598,7 @@ static int ufshcd_uic_pwr_ctrl(struct ufs_hba *hba, struct uic_command *cmd) ufshcd_schedule_eh_work(hba); } out_unlock: - spin_unlock_irqrestore(hba->host->host_lock, flags); + spin_unlock_irqrestore(&hba->host->host_lock, flags); mutex_unlock(&hba->uic_cmd_mutex); return ret; @@ -4652,21 +4693,21 @@ int ufshcd_link_recovery(struct ufs_hba *hba) int ret; unsigned long flags; - spin_lock_irqsave(hba->host->host_lock, flags); + spin_lock_irqsave(&hba->host->host_lock, flags); hba->ufshcd_state = UFSHCD_STATE_RESET; ufshcd_set_eh_in_progress(hba); - spin_unlock_irqrestore(hba->host->host_lock, flags); + spin_unlock_irqrestore(&hba->host->host_lock, flags); /* Reset the attached device */ ufshcd_device_reset(hba); ret = ufshcd_host_reset_and_restore(hba); - spin_lock_irqsave(hba->host->host_lock, flags); + spin_lock_irqsave(&hba->host->host_lock, flags); if (ret) hba->ufshcd_state = UFSHCD_STATE_ERROR; ufshcd_clear_eh_in_progress(hba); - spin_unlock_irqrestore(hba->host->host_lock, flags); + spin_unlock_irqrestore(&hba->host->host_lock, flags); if (ret) dev_err(hba->dev, "%s: link recovery failed, err %d", @@ -4748,7 +4789,17 @@ void ufshcd_auto_hibern8_update(struct ufs_hba *hba, u32 ahit) if (!pm_runtime_suspended(&hba->ufs_device_wlun->sdev_gendev)) { ufshcd_rpm_get_sync(hba); ufshcd_hold(hba); - ufshcd_configure_auto_hibern8(hba); + /* + * Serialize with the host driver's AHIT control. Skip the + * register write while the driver has AHIT forced off; the + * driver programs hba->ahit back when it re-enables it. + * Mutex is taken here (not across the rpm calls above) so it + * never blocks a resume that the driver's path may need. + */ + mutex_lock(&hba->ahit_mutex); + if (!hba->ahit_disable_depth) + ufshcd_configure_auto_hibern8(hba); + mutex_unlock(&hba->ahit_mutex); ufshcd_release(hba); ufshcd_rpm_put_sync(hba); } @@ -4979,8 +5030,12 @@ int ufshcd_change_power_mode(struct ufs_hba *hba, ret = ufshcd_dme_change_power_mode(hba, pwr_mode, pmc_policy); - if (!ret) - ufshcd_vops_pwr_change_notify(hba, POST_CHANGE, pwr_mode); + /* + * Always notify POST_CHANGE to pair with PRE_CHANGE, even on failure. + * On failure, pass dev_req_params = NULL to indicate nothing to apply. + * POST_CHANGE return value is advisory and does not mask @ret. + */ + ufshcd_vops_pwr_change_notify(hba, POST_CHANGE, ret ? NULL : pwr_mode); return ret; } @@ -5667,19 +5722,19 @@ static void ufshcd_sdev_destroy(struct scsi_device *sdev) /* Drop the reference as it won't be needed anymore */ if (ufshcd_scsi_to_upiu_lun(sdev->lun) == UFS_UPIU_UFS_DEVICE_WLUN) { - spin_lock_irqsave(hba->host->host_lock, flags); + spin_lock_irqsave(&hba->host->host_lock, flags); hba->ufs_device_wlun = NULL; - spin_unlock_irqrestore(hba->host->host_lock, flags); + spin_unlock_irqrestore(&hba->host->host_lock, flags); } else if (hba->ufs_device_wlun) { struct device *supplier = NULL; /* Ensure UFS Device WLUN exists and does not disappear */ - spin_lock_irqsave(hba->host->host_lock, flags); + spin_lock_irqsave(&hba->host->host_lock, flags); if (hba->ufs_device_wlun) { supplier = &hba->ufs_device_wlun->sdev_gendev; get_device(supplier); } - spin_unlock_irqrestore(hba->host->host_lock, flags); + spin_unlock_irqrestore(&hba->host->host_lock, flags); if (supplier) { /* @@ -5872,7 +5927,7 @@ static irqreturn_t ufshcd_uic_cmd_compl(struct ufs_hba *hba, u32 intr_status) irqreturn_t retval = IRQ_NONE; struct uic_command *cmd; - guard(spinlock_irqsave)(hba->host->host_lock); + guard(spinlock_irqsave)(&hba->host->host_lock); cmd = hba->active_uic_cmd; if (!cmd) { dev_err(hba->dev, @@ -6044,8 +6099,6 @@ static bool ufshcd_mcq_force_compl_one(struct request *rq, void *priv) if (blk_mq_is_reserved_rq(rq) || !hwq) return true; - ufshcd_mcq_compl_all_cqes_lock(hba, hwq); - /* * For those cmds of which the cqes are not present in the cq, complete * them explicitly. @@ -6061,19 +6114,6 @@ static bool ufshcd_mcq_force_compl_one(struct request *rq, void *priv) return true; } -static bool ufshcd_mcq_compl_one(struct request *rq, void *priv) -{ - struct scsi_device *sdev = rq->q->queuedata; - struct Scsi_Host *shost = sdev->host; - struct ufs_hba *hba = shost_priv(shost); - struct ufs_hw_queue *hwq = ufshcd_mcq_req_to_hwq(hba, rq); - - if (!blk_mq_is_reserved_rq(rq) && hwq) - ufshcd_mcq_poll_cqe_lock(hba, hwq); - - return true; -} - /** * ufshcd_mcq_compl_pending_transfer - MCQ mode function. It is * invoked from the error handler context or ufshcd_host_reset_and_restore() @@ -6088,10 +6128,18 @@ static bool ufshcd_mcq_compl_one(struct request *rq, void *priv) static void ufshcd_mcq_compl_pending_transfer(struct ufs_hba *hba, bool force_compl) { - blk_mq_tagset_busy_iter(&hba->host->tag_set, - force_compl ? ufshcd_mcq_force_compl_one : - ufshcd_mcq_compl_one, - NULL); + int i; + + for (i = 0; i < hba->nr_hw_queues; i++) { + if (force_compl) + ufshcd_mcq_compl_all_cqes_lock(hba, &hba->uhq[i]); + else + ufshcd_mcq_poll_cqe_lock(hba, &hba->uhq[i]); + } + + if (force_compl) + blk_mq_tagset_busy_iter(&hba->host->tag_set, + ufshcd_mcq_force_compl_one, NULL); } /** @@ -6669,7 +6717,7 @@ static bool ufshcd_quirk_dl_nac_errors(struct ufs_hba *hba) unsigned long flags; bool err_handling = true; - spin_lock_irqsave(hba->host->host_lock, flags); + spin_lock_irqsave(&hba->host->host_lock, flags); /* * UFS_DEVICE_QUIRK_RECOVERY_FROM_DL_NAC_ERRORS only workaround the * device fatal error and/or DL NAC & REPLAY timeout errors. @@ -6688,9 +6736,9 @@ static bool ufshcd_quirk_dl_nac_errors(struct ufs_hba *hba) /* * wait for 50ms to see if we can get any other errors or not. */ - spin_unlock_irqrestore(hba->host->host_lock, flags); + spin_unlock_irqrestore(&hba->host->host_lock, flags); msleep(50); - spin_lock_irqsave(hba->host->host_lock, flags); + spin_lock_irqsave(&hba->host->host_lock, flags); /* * now check if we have got any other severe errors other than @@ -6708,9 +6756,9 @@ static bool ufshcd_quirk_dl_nac_errors(struct ufs_hba *hba) * - If we get response then clear the DL NAC error bit. */ - spin_unlock_irqrestore(hba->host->host_lock, flags); + spin_unlock_irqrestore(&hba->host->host_lock, flags); err = ufshcd_verify_dev_init(hba); - spin_lock_irqsave(hba->host->host_lock, flags); + spin_lock_irqsave(&hba->host->host_lock, flags); if (err) goto out; @@ -6724,7 +6772,7 @@ static bool ufshcd_quirk_dl_nac_errors(struct ufs_hba *hba) err_handling = false; } out: - spin_unlock_irqrestore(hba->host->host_lock, flags); + spin_unlock_irqrestore(&hba->host->host_lock, flags); return err_handling; } @@ -6737,7 +6785,7 @@ static inline bool ufshcd_is_saved_err_fatal(struct ufs_hba *hba) void ufshcd_schedule_eh_work(struct ufs_hba *hba) { - lockdep_assert_held(hba->host->host_lock); + lockdep_assert_held(&hba->host->host_lock); /* handle fatal errors only when link is not in error state */ if (hba->ufshcd_state != UFSHCD_STATE_ERROR) { @@ -6752,10 +6800,10 @@ void ufshcd_schedule_eh_work(struct ufs_hba *hba) void ufshcd_force_error_recovery(struct ufs_hba *hba) { - spin_lock_irq(hba->host->host_lock); + spin_lock_irq(&hba->host->host_lock); hba->force_reset = true; ufshcd_schedule_eh_work(hba); - spin_unlock_irq(hba->host->host_lock); + spin_unlock_irq(&hba->host->host_lock); } EXPORT_SYMBOL_GPL(ufshcd_force_error_recovery); @@ -6817,11 +6865,17 @@ static void ufshcd_err_handling_prepare(struct ufs_hba *hba) } /* Wait for ongoing ufshcd_queuecommand() calls to finish. */ blk_mq_quiesce_tagset(&hba->host->tag_set); + /* + * Internal commands are submitted on the pseudo SCSI device. Let them + * through so that the error handler can recover the link. + */ + blk_mq_unquiesce_queue(hba->host->pseudo_sdev->request_queue); cancel_work_sync(&hba->eeh_work); } static void ufshcd_err_handling_unprepare(struct ufs_hba *hba) { + blk_mq_quiesce_queue_nowait(hba->host->pseudo_sdev->request_queue); blk_mq_unquiesce_tagset(&hba->host->tag_set); ufshcd_release(hba); if (ufshcd_is_clkscaling_supported(hba)) @@ -6996,25 +7050,25 @@ static void ufshcd_err_handler(struct work_struct *work) } down(&hba->host_sem); - spin_lock_irqsave(hba->host->host_lock, flags); + spin_lock_irqsave(&hba->host->host_lock, flags); if (ufshcd_err_handling_should_stop(hba)) { if (hba->ufshcd_state != UFSHCD_STATE_ERROR) hba->ufshcd_state = UFSHCD_STATE_OPERATIONAL; - spin_unlock_irqrestore(hba->host->host_lock, flags); + spin_unlock_irqrestore(&hba->host->host_lock, flags); up(&hba->host_sem); return; } - spin_unlock_irqrestore(hba->host->host_lock, flags); + spin_unlock_irqrestore(&hba->host->host_lock, flags); ufshcd_err_handling_prepare(hba); - spin_lock_irqsave(hba->host->host_lock, flags); + spin_lock_irqsave(&hba->host->host_lock, flags); ufshcd_set_eh_in_progress(hba); - spin_unlock_irqrestore(hba->host->host_lock, flags); + spin_unlock_irqrestore(&hba->host->host_lock, flags); /* Complete requests that have door-bell cleared by h/w */ ufshcd_complete_requests(hba, false); - spin_lock_irqsave(hba->host->host_lock, flags); + spin_lock_irqsave(&hba->host->host_lock, flags); again: needs_restore = false; needs_reset = false; @@ -7032,10 +7086,10 @@ static void ufshcd_err_handler(struct work_struct *work) !hba->force_reset) { bool ret; - spin_unlock_irqrestore(hba->host->host_lock, flags); + spin_unlock_irqrestore(&hba->host->host_lock, flags); /* release the lock as ufshcd_quirk_dl_nac_errors() may sleep */ ret = ufshcd_quirk_dl_nac_errors(hba); - spin_lock_irqsave(hba->host->host_lock, flags); + spin_lock_irqsave(&hba->host->host_lock, flags); if (!ret && ufshcd_err_handling_should_stop(hba)) goto skip_err_handling; } @@ -7045,14 +7099,14 @@ static void ufshcd_err_handler(struct work_struct *work) (hba->saved_uic_err != UFSHCD_UIC_PA_GENERIC_ERROR))) { bool pr_prdt = !!(hba->saved_err & SYSTEM_BUS_FATAL_ERROR); - spin_unlock_irqrestore(hba->host->host_lock, flags); + spin_unlock_irqrestore(&hba->host->host_lock, flags); ufshcd_print_host_state(hba); ufshcd_print_pwr_info(hba); ufshcd_print_tx_eq_params(hba); ufshcd_print_evt_hist(hba); ufshcd_print_tmrs(hba, hba->outstanding_tasks); ufshcd_print_trs_all(hba, pr_prdt); - spin_lock_irqsave(hba->host->host_lock, flags); + spin_lock_irqsave(&hba->host->host_lock, flags); } /* @@ -7077,21 +7131,21 @@ static void ufshcd_err_handler(struct work_struct *work) hba->saved_uic_err &= ~UFSHCD_UIC_PA_GENERIC_ERROR; if (!hba->saved_uic_err) hba->saved_err &= ~UIC_ERROR; - spin_unlock_irqrestore(hba->host->host_lock, flags); + spin_unlock_irqrestore(&hba->host->host_lock, flags); if (ufshcd_is_pwr_mode_restore_needed(hba)) needs_restore = true; - spin_lock_irqsave(hba->host->host_lock, flags); + spin_lock_irqsave(&hba->host->host_lock, flags); if (!hba->saved_err && !needs_restore) goto skip_err_handling; } hba->silence_err_logs = true; /* release lock as clear command might sleep */ - spin_unlock_irqrestore(hba->host->host_lock, flags); + spin_unlock_irqrestore(&hba->host->host_lock, flags); needs_reset = ufshcd_abort_all(hba); - spin_lock_irqsave(hba->host->host_lock, flags); + spin_lock_irqsave(&hba->host->host_lock, flags); hba->silence_err_logs = false; if (needs_reset) goto do_reset; @@ -7101,7 +7155,7 @@ static void ufshcd_err_handler(struct work_struct *work) * now it is safe to retore power mode. */ if (needs_restore) { - spin_unlock_irqrestore(hba->host->host_lock, flags); + spin_unlock_irqrestore(&hba->host->host_lock, flags); /* * Hold the scaling lock just in case dev cmds * are sent via bsg and/or sysfs. @@ -7116,7 +7170,7 @@ static void ufshcd_err_handler(struct work_struct *work) } ufshcd_print_pwr_info(hba); up_write(&hba->clk_scaling_lock); - spin_lock_irqsave(hba->host->host_lock, flags); + spin_lock_irqsave(&hba->host->host_lock, flags); } do_reset: @@ -7125,14 +7179,14 @@ static void ufshcd_err_handler(struct work_struct *work) int err; hba->force_reset = false; - spin_unlock_irqrestore(hba->host->host_lock, flags); + spin_unlock_irqrestore(&hba->host->host_lock, flags); err = ufshcd_reset_and_restore(hba); if (err) dev_err(hba->dev, "%s: reset and restore failed with err %d\n", __func__, err); else ufshcd_recover_pm_error(hba); - spin_lock_irqsave(hba->host->host_lock, flags); + spin_lock_irqsave(&hba->host->host_lock, flags); } skip_err_handling: @@ -7151,7 +7205,7 @@ static void ufshcd_err_handler(struct work_struct *work) hba->ufshcd_state = UFSHCD_STATE_ERROR; } ufshcd_clear_eh_in_progress(hba); - spin_unlock_irqrestore(hba->host->host_lock, flags); + spin_unlock_irqrestore(&hba->host->host_lock, flags); ufshcd_err_handling_unprepare(hba); up(&hba->host_sem); @@ -7274,7 +7328,7 @@ static irqreturn_t ufshcd_check_errors(struct ufs_hba *hba, u32 intr_status) bool queue_eh_work = false; irqreturn_t retval = IRQ_NONE; - guard(spinlock_irqsave)(hba->host->host_lock); + guard(spinlock_irqsave)(&hba->host->host_lock); hba->errors |= UFSHCD_ERROR_MASK & intr_status; if (hba->errors & INT_FATAL_ERRORS) { @@ -7352,7 +7406,7 @@ static irqreturn_t ufshcd_tmc_handler(struct ufs_hba *hba) irqreturn_t ret = IRQ_NONE; int tag; - spin_lock_irqsave(hba->host->host_lock, flags); + spin_lock_irqsave(&hba->host->host_lock, flags); pending = ufshcd_readl(hba, REG_UTP_TASK_REQ_DOOR_BELL); issued = hba->outstanding_tasks & ~pending; for_each_set_bit(tag, &issued, hba->nutmrs) { @@ -7362,7 +7416,7 @@ static irqreturn_t ufshcd_tmc_handler(struct ufs_hba *hba) complete(c); ret = IRQ_HANDLED; } - spin_unlock_irqrestore(hba->host->host_lock, flags); + spin_unlock_irqrestore(&hba->host->host_lock, flags); return ret; } @@ -7532,7 +7586,7 @@ static int __ufshcd_issue_tm_cmd(struct ufs_hba *hba, req->end_io_data = &wait; ufshcd_hold(hba); - spin_lock_irqsave(host->host_lock, flags); + spin_lock_irqsave(&host->host_lock, flags); task_tag = req->tag; hba->tmf_rqs[req->tag] = req; @@ -7543,7 +7597,7 @@ static int __ufshcd_issue_tm_cmd(struct ufs_hba *hba, __set_bit(task_tag, &hba->outstanding_tasks); - spin_unlock_irqrestore(host->host_lock, flags); + spin_unlock_irqrestore(&host->host_lock, flags); /* send command to the controller */ ufshcd_writel(hba, 1 << task_tag, REG_UTP_TASK_REQ_DOOR_BELL); @@ -7568,10 +7622,10 @@ static int __ufshcd_issue_tm_cmd(struct ufs_hba *hba, ufshcd_add_tm_upiu_trace(hba, task_tag, UFS_TM_COMP); } - spin_lock_irqsave(hba->host->host_lock, flags); + spin_lock_irqsave(&hba->host->host_lock, flags); hba->tmf_rqs[req->tag] = NULL; __clear_bit(task_tag, &hba->outstanding_tasks); - spin_unlock_irqrestore(hba->host->host_lock, flags); + spin_unlock_irqrestore(&hba->host->host_lock, flags); ufshcd_release(hba); blk_mq_free_request(req); @@ -8119,10 +8173,10 @@ static int ufshcd_abort(struct scsi_cmnd *cmd) if (lrbp->lun == UFS_UPIU_UFS_DEVICE_WLUN) { ufshcd_update_evt_hist(hba, UFS_EVT_ABORT, lrbp->lun); - spin_lock_irqsave(host->host_lock, flags); + spin_lock_irqsave(&host->host_lock, flags); hba->force_reset = true; ufshcd_schedule_eh_work(hba); - spin_unlock_irqrestore(host->host_lock, flags); + spin_unlock_irqrestore(&host->host_lock, flags); goto release; } @@ -8180,12 +8234,12 @@ static void ufshcd_process_probe_result(struct ufs_hba *hba, { unsigned long flags; - spin_lock_irqsave(hba->host->host_lock, flags); + spin_lock_irqsave(&hba->host->host_lock, flags); if (ret) hba->ufshcd_state = UFSHCD_STATE_ERROR; else if (hba->ufshcd_state == UFSHCD_STATE_RESET) hba->ufshcd_state = UFSHCD_STATE_OPERATIONAL; - spin_unlock_irqrestore(hba->host->host_lock, flags); + spin_unlock_irqrestore(&hba->host->host_lock, flags); trace_ufshcd_init(hba, ret, ktime_to_us(ktime_sub(ktime_get(), probe_start)), @@ -8254,7 +8308,7 @@ static int ufshcd_reset_and_restore(struct ufs_hba *hba) unsigned long flags; int retries = MAX_HOST_RESET_RETRIES; - spin_lock_irqsave(hba->host->host_lock, flags); + spin_lock_irqsave(&hba->host->host_lock, flags); do { /* * This is a fresh start, cache and clear saved error first, @@ -8266,14 +8320,14 @@ static int ufshcd_reset_and_restore(struct ufs_hba *hba) hba->saved_uic_err = 0; hba->force_reset = false; hba->ufshcd_state = UFSHCD_STATE_RESET; - spin_unlock_irqrestore(hba->host->host_lock, flags); + spin_unlock_irqrestore(&hba->host->host_lock, flags); /* Reset the attached device */ ufshcd_device_reset(hba); err = ufshcd_host_reset_and_restore(hba); - spin_lock_irqsave(hba->host->host_lock, flags); + spin_lock_irqsave(&hba->host->host_lock, flags); if (err) continue; /* Do not exit unless operational or dead */ @@ -8293,7 +8347,7 @@ static int ufshcd_reset_and_restore(struct ufs_hba *hba) hba->saved_err |= saved_err; hba->saved_uic_err |= saved_uic_err; } - spin_unlock_irqrestore(hba->host->host_lock, flags); + spin_unlock_irqrestore(&hba->host->host_lock, flags); return err; } @@ -8325,18 +8379,18 @@ static int ufshcd_eh_host_reset_handler(struct scsi_cmnd *cmd) return err; } - spin_lock_irqsave(hba->host->host_lock, flags); + spin_lock_irqsave(&hba->host->host_lock, flags); hba->force_reset = true; ufshcd_schedule_eh_work(hba); dev_err(hba->dev, "%s: reset in progress - 1\n", __func__); - spin_unlock_irqrestore(hba->host->host_lock, flags); + spin_unlock_irqrestore(&hba->host->host_lock, flags); flush_work(&hba->eh_work); - spin_lock_irqsave(hba->host->host_lock, flags); + spin_lock_irqsave(&hba->host->host_lock, flags); if (hba->ufshcd_state == UFSHCD_STATE_ERROR) err = FAILED; - spin_unlock_irqrestore(hba->host->host_lock, flags); + spin_unlock_irqrestore(&hba->host->host_lock, flags); return err; } @@ -8926,6 +8980,9 @@ static int ufs_get_device_desc(struct ufs_hba *hba) ufs_fixup_device_setup(hba); + dev_info->timestamp_sup = dev_info->wspecversion >= 0x400 && + !(hba->dev_quirks & UFS_DEVICE_QUIRK_NO_TIMESTAMP_SUPPORT); + ufshcd_wb_probe(hba, desc_buf); ufshcd_temp_notif_probe(hba, desc_buf); @@ -9226,14 +9283,15 @@ static void ufshcd_set_timestamp_attr(struct ufs_hba *hba) u64 ts_ns; int err; - if (dev_info->wspecversion < 0x400 || - hba->dev_quirks & UFS_DEVICE_QUIRK_NO_TIMESTAMP_SUPPORT) + if (!dev_info->timestamp_sup) return; ts_ns = ktime_get_real_ns(); err = ufshcd_query_attr_qword(hba, UPIU_QUERY_OPCODE_WRITE_ATTR, QUERY_ATTR_IDN_TIMESTAMP, 0, 0, &ts_ns); - if (err) + if (err == -EOPNOTSUPP) + dev_info->timestamp_sup = false; + else if (err) dev_err(hba->dev, "%s: failed to set timestamp %d\n", __func__, err); } @@ -9550,6 +9608,7 @@ static void ufshcd_async_scan(void *data, async_cookie_t cookie) ret = ufshcd_add_lus(hba); out: + ufshcd_release(hba); pm_runtime_put_sync(hba->dev); if (ret) @@ -9612,6 +9671,7 @@ static struct ufs_hba_variant_params ufs_hba_vps = { .devfreq_profile.polling_ms = 100, .devfreq_profile.target = ufshcd_devfreq_target, .devfreq_profile.get_dev_status = ufshcd_devfreq_get_dev_status, + .devfreq_profile.get_cur_freq = ufshcd_devfreq_get_cur_freq, .ondemand_data.upthreshold = 70, .ondemand_data.downdifferential = 5, }; @@ -10081,13 +10141,13 @@ static int ufshcd_set_dev_pwr_mode(struct ufs_hba *hba, unsigned long flags; int ret; - spin_lock_irqsave(hba->host->host_lock, flags); + spin_lock_irqsave(&hba->host->host_lock, flags); sdp = hba->ufs_device_wlun; if (sdp && scsi_device_online(sdp)) ret = scsi_device_get(sdp); else ret = -ENODEV; - spin_unlock_irqrestore(hba->host->host_lock, flags); + spin_unlock_irqrestore(&hba->host->host_lock, flags); if (ret) return ret; @@ -11268,10 +11328,15 @@ int ufshcd_init(struct ufs_hba *hba, void __iomem *mmio_base, unsigned int irq) mutex_init(&hba->wb_mutex); + mutex_init(&hba->ahit_mutex); + init_rwsem(&hba->clk_scaling_lock); ufshcd_init_clk_gating(hba); + /* Released by ufshcd_async_scan(), or by out_release on failure. */ + ufshcd_hold(hba); + ufshcd_init_clk_scaling(hba); /* @@ -11292,7 +11357,7 @@ int ufshcd_init(struct ufs_hba *hba, void __iomem *mmio_base, unsigned int irq) err = devm_request_irq(dev, irq, ufshcd_intr, IRQF_SHARED, UFSHCD, hba); if (err) { dev_err(hba->dev, "request irq failed\n"); - goto out_disable; + goto out_release; } else { hba->is_irq_enabled = true; } @@ -11308,7 +11373,7 @@ int ufshcd_init(struct ufs_hba *hba, void __iomem *mmio_base, unsigned int irq) dev_err(hba->dev, "Host controller enable failed\n"); ufshcd_print_evt_hist(hba); ufshcd_print_host_state(hba); - goto out_disable; + goto out_release; } INIT_DELAYED_WORK(&hba->rpm_dev_flush_recheck_work, ufshcd_rpm_dev_flush_recheck_work); @@ -11322,7 +11387,7 @@ int ufshcd_init(struct ufs_hba *hba, void __iomem *mmio_base, unsigned int irq) err = ufshcd_add_scsi_host(hba); if (err) - goto out_disable; + goto out_release; /* Hold auto suspend until async scan completes */ pm_runtime_get_sync(dev); @@ -11342,7 +11407,7 @@ int ufshcd_init(struct ufs_hba *hba, void __iomem *mmio_base, unsigned int irq) err = ufshcd_link_startup(hba); if (err) - goto out_disable; + goto out_release; if (hba->mcq_enabled) ufshcd_config_mcq(hba); @@ -11359,23 +11424,23 @@ int ufshcd_init(struct ufs_hba *hba, void __iomem *mmio_base, unsigned int irq) /* Verify device initialization by sending NOP OUT UPIU */ err = ufshcd_verify_dev_init(hba); if (err) - goto out_disable; + goto out_release; /* Initiate UFS initialization, and waiting until completion */ err = ufshcd_complete_dev_init(hba); if (err) - goto out_disable; + goto out_release; err = ufshcd_device_params_init(hba); if (err) - goto out_disable; + goto out_release; err = ufshcd_post_device_init(hba); initialized: ufshcd_process_probe_result(hba, probe_start, err); if (err) - goto out_disable; + goto out_release; ufs_sysfs_add_nodes(hba->dev); hba->dme_qos_sysfs_handle = sysfs_get_dirent(hba->dev->kobj.sd, @@ -11386,6 +11451,8 @@ int ufshcd_init(struct ufs_hba *hba, void __iomem *mmio_base, unsigned int irq) ufshcd_pm_qos_init(hba); return 0; +out_release: + ufshcd_release(hba); out_disable: hba->is_irq_enabled = false; ufshcd_hba_exit(hba); diff --git a/drivers/ufs/host/ufs-exynos.c b/drivers/ufs/host/ufs-exynos.c index b2f65c465525..3bcbc9ebbb28 100644 --- a/drivers/ufs/host/ufs-exynos.c +++ b/drivers/ufs/host/ufs-exynos.c @@ -1782,7 +1782,9 @@ static int exynos_ufs_pwr_change_notify(struct ufs_hba *hba, ret = exynos_ufs_pre_pwr_mode(hba, dev_req_params); break; case POST_CHANGE: - ret = exynos_ufs_post_pwr_mode(hba, dev_req_params); + /* NULL when the gear switch failed: nothing to apply */ + if (dev_req_params) + ret = exynos_ufs_post_pwr_mode(hba, dev_req_params); break; } diff --git a/drivers/ufs/host/ufs-mediatek.c b/drivers/ufs/host/ufs-mediatek.c index 814c1b7343b9..5b6bff2cf9a2 100644 --- a/drivers/ufs/host/ufs-mediatek.c +++ b/drivers/ufs/host/ufs-mediatek.c @@ -509,6 +509,7 @@ static int ufs_mtk_mphy_power_on(struct ufs_hba *hba, bool on) struct ufs_mtk_host *host = ufshcd_get_variant(hba); struct phy *mphy = host->mphy; struct arm_smccc_res res; + int err; int ret = 0; if (!mphy || !(on ^ host->mphy_powered_on)) @@ -523,7 +524,18 @@ static int ufs_mtk_mphy_power_on(struct ufs_hba *hba, bool on) usleep_range(200, 210); ufs_mtk_va09_pwr_ctrl(res, 1); } - phy_power_on(mphy); + ret = phy_power_on(mphy); + if (ret) { + if (ufs_mtk_is_va09_supported(hba)) { + ufs_mtk_va09_pwr_ctrl(res, 0); + err = regulator_disable(host->reg_va09); + if (err) + dev_err(hba->dev, + "failed to unwind va09: %d\n", err); + } + dev_err(hba->dev, "failed to enable mphy: %d\n", ret); + return ret; + } } else { phy_power_off(mphy); if (ufs_mtk_is_va09_supported(hba)) { @@ -1124,9 +1136,9 @@ static void ufs_mtk_setup_clk_gating(struct ufs_hba *hba) ah_ms = ah_timer * scale_us[ah_scale] / 1000; } - spin_lock_irqsave(hba->host->host_lock, flags); + spin_lock_irqsave(&hba->host->host_lock, flags); hba->clk_gating.delay_ms = max(ah_ms, 10U); - spin_unlock_irqrestore(hba->host->host_lock, flags); + spin_unlock_irqrestore(&hba->host->host_lock, flags); } } @@ -1295,7 +1307,9 @@ static int ufs_mtk_init(struct ufs_hba *hba) * * Enable phy clocks specifically here. */ - ufs_mtk_mphy_power_on(hba, true); + err = ufs_mtk_mphy_power_on(hba, true); + if (err) + goto out_variant_clear; if (ufs_mtk_is_rtff_mtcmos(hba)) { /* First Restore here, to avoid backup unexpected value */ @@ -1507,19 +1521,27 @@ static int ufs_mtk_pwr_change_notify(struct ufs_hba *hba, struct ufs_pa_layer_attr *dev_req_params) { int ret = 0; - static u32 reg; switch (stage) { case PRE_CHANGE: if (ufshcd_is_auto_hibern8_supported(hba)) { - reg = ufshcd_readl(hba, REG_AUTO_HIBERNATE_IDLE_TIMER); + /* Block sysfs AHIT writes while we force AHIT off */ + mutex_lock(&hba->ahit_mutex); + hba->ahit_disable_depth++; + mutex_unlock(&hba->ahit_mutex); ufs_mtk_auto_hibern8_disable(hba); } ret = ufs_mtk_pre_pwr_change(hba, dev_req_params); break; case POST_CHANGE: - if (ufshcd_is_auto_hibern8_supported(hba)) - ufshcd_writel(hba, reg, REG_AUTO_HIBERNATE_IDLE_TIMER); + if (ufshcd_is_auto_hibern8_supported(hba)) { + mutex_lock(&hba->ahit_mutex); + /* re-enable only when the last disabler drops off */ + if (!--hba->ahit_disable_depth) + ufshcd_writel(hba, hba->ahit, + REG_AUTO_HIBERNATE_IDLE_TIMER); + mutex_unlock(&hba->ahit_mutex); + } break; default: ret = -EINVAL; diff --git a/drivers/ufs/host/ufs-qcom.c b/drivers/ufs/host/ufs-qcom.c index 954be9343f42..fcafba9c2995 100644 --- a/drivers/ufs/host/ufs-qcom.c +++ b/drivers/ufs/host/ufs-qcom.c @@ -347,7 +347,9 @@ static void ufs_qcom_disable_lane_clks(struct ufs_qcom_host *host) if (!host->is_lane_clks_enabled) return; - clk_bulk_disable_unprepare(host->num_clks, host->clks); + clk_disable_unprepare(host->rx_lane1_sync_clk); + clk_disable_unprepare(host->rx_lane0_sync_clk); + clk_disable_unprepare(host->tx_lane0_sync_clk); host->is_lane_clks_enabled = false; } @@ -356,28 +358,57 @@ static int ufs_qcom_enable_lane_clks(struct ufs_qcom_host *host) { int err; - err = clk_bulk_prepare_enable(host->num_clks, host->clks); + if (host->is_lane_clks_enabled) + return 0; + + err = clk_prepare_enable(host->tx_lane0_sync_clk); if (err) - return err; + goto out; + + err = clk_prepare_enable(host->rx_lane0_sync_clk); + if (err) + goto out_disable_tx_lane0; + + err = clk_prepare_enable(host->rx_lane1_sync_clk); + if (err) + goto out_disable_rx_lane0; host->is_lane_clks_enabled = true; return 0; + +out_disable_rx_lane0: + clk_disable_unprepare(host->rx_lane0_sync_clk); +out_disable_tx_lane0: + clk_disable_unprepare(host->tx_lane0_sync_clk); +out: + return err; } static int ufs_qcom_init_lane_clks(struct ufs_qcom_host *host) { - int err; struct device *dev = host->hba->dev; if (has_acpi_companion(dev)) return 0; - err = devm_clk_bulk_get_all(dev, &host->clks); - if (err <= 0) - return err; + host->tx_lane0_sync_clk = devm_clk_get(dev, "tx_lane0_sync_clk"); + if (IS_ERR(host->tx_lane0_sync_clk)) + return dev_err_probe(dev, PTR_ERR(host->tx_lane0_sync_clk), + "failed to get tx_lane0_sync_clk\n"); - host->num_clks = err; + host->rx_lane0_sync_clk = devm_clk_get(dev, "rx_lane0_sync_clk"); + if (IS_ERR(host->rx_lane0_sync_clk)) + return dev_err_probe(dev, PTR_ERR(host->rx_lane0_sync_clk), + "failed to get rx_lane0_sync_clk\n"); + + /* In case of single lane per direction, don't read lane1 clocks */ + if (host->hba->lanes_per_direction > 1) { + host->rx_lane1_sync_clk = devm_clk_get(dev, "rx_lane1_sync_clk"); + if (IS_ERR(host->rx_lane1_sync_clk)) + return dev_err_probe(dev, PTR_ERR(host->rx_lane1_sync_clk), + "failed to get rx_lane1_sync_clk\n"); + } return 0; } @@ -2407,6 +2438,7 @@ static irqreturn_t ufs_qcom_mcq_esi_handler(int irq, void *data) static int ufs_qcom_config_esi(struct ufs_hba *hba) { struct ufs_qcom_host *host = ufshcd_get_variant(hba); + struct ufs_qcom_irq *qi; int nr_irqs, ret; if (host->esi_enabled) @@ -2425,8 +2457,7 @@ static int ufs_qcom_config_esi(struct ufs_hba *hba) return ret; /* Continue without ESI */ } - struct ufs_qcom_irq *qi = devm_kcalloc(hba->dev, nr_irqs, sizeof(*qi), GFP_KERNEL); - + qi = devm_kcalloc(hba->dev, nr_irqs, sizeof(*qi), GFP_KERNEL); if (!qi) { platform_device_msi_free_irqs_all(hba->dev); return -ENOMEM; @@ -2957,6 +2988,11 @@ static const struct ufs_hba_variant_ops ufs_hba_qcom_sa8255p_vops = { .resume = ufs_qcom_fw_managed_resume, .dbg_register_dump = ufs_qcom_dump_dbg_regs, .device_reset = ufs_qcom_fw_managed_device_reset, + .mcq_config_resource = ufs_qcom_mcq_config_resource, + .get_hba_mac = ufs_qcom_get_hba_mac, + .op_runtime_config = ufs_qcom_op_runtime_config, + .get_outstanding_cqs = ufs_qcom_get_outstanding_cqs, + .config_esi = ufs_qcom_config_esi, }; /** diff --git a/drivers/ufs/host/ufs-qcom.h b/drivers/ufs/host/ufs-qcom.h index a5ad5ce44a19..944b2e532a09 100644 --- a/drivers/ufs/host/ufs-qcom.h +++ b/drivers/ufs/host/ufs-qcom.h @@ -330,8 +330,9 @@ struct ufs_qcom_host { struct phy *generic_phy; struct ufs_hba *hba; struct ufs_pa_layer_attr dev_req_params; - struct clk_bulk_data *clks; - u32 num_clks; + struct clk *tx_lane0_sync_clk; + struct clk *rx_lane0_sync_clk; + struct clk *rx_lane1_sync_clk; bool is_lane_clks_enabled; struct icc_path *icc_ddr; diff --git a/drivers/ufs/host/ufs-sprd.c b/drivers/ufs/host/ufs-sprd.c index a5e8c591bead..6862250c542e 100644 --- a/drivers/ufs/host/ufs-sprd.c +++ b/drivers/ufs/host/ufs-sprd.c @@ -181,9 +181,9 @@ static int ufs_sprd_suspend(struct ufs_hba *hba, enum ufs_pm_op pm_op, if (status == PRE_CHANGE) { if (ufshcd_is_auto_hibern8_supported(hba)) { - spin_lock_irqsave(hba->host->host_lock, flags); + spin_lock_irqsave(&hba->host->host_lock, flags); ufshcd_writel(hba, 0, REG_AUTO_HIBERNATE_IDLE_TIMER); - spin_unlock_irqrestore(hba->host->host_lock, flags); + spin_unlock_irqrestore(&hba->host->host_lock, flags); } } diff --git a/drivers/ufs/host/ufshcd-pci.c b/drivers/ufs/host/ufshcd-pci.c index 21bb11c724be..668b57403e62 100644 --- a/drivers/ufs/host/ufshcd-pci.c +++ b/drivers/ufs/host/ufshcd-pci.c @@ -166,7 +166,8 @@ static int ufs_intel_lkf_pwr_change_notify(struct ufs_hba *hba, ufs_intel_set_lanes(hba, 2); break; case POST_CHANGE: - if (ufshcd_is_hs_mode(dev_req_params)) { + /* NULL when the gear switch failed: nothing to apply */ + if (dev_req_params && ufshcd_is_hs_mode(dev_req_params)) { u32 peer_granularity; usleep_range(1000, 1250); diff --git a/drivers/ufs/host/ufshcd-pltfrm.c b/drivers/ufs/host/ufshcd-pltfrm.c index 5ac7afe75934..169dbc1a75fe 100644 --- a/drivers/ufs/host/ufshcd-pltfrm.c +++ b/drivers/ufs/host/ufshcd-pltfrm.c @@ -206,7 +206,11 @@ static void ufshcd_init_lanes_per_dir(struct ufs_hba *hba) dev_dbg(hba->dev, "%s: failed to read lanes-per-direction, ret=%d\n", __func__, ret); - hba->lanes_per_direction = UFSHCD_DEFAULT_LANES_PER_DIRECTION; + /* Old R-Car S4 DTBs lack "lanes-per-direction = <1>" */ + if (of_device_is_compatible(dev->of_node, "renesas,r8a779f0-ufs")) + hba->lanes_per_direction = 1; + else + hba->lanes_per_direction = UFSHCD_DEFAULT_LANES_PER_DIRECTION; } } diff --git a/drivers/usb/gadget/function/f_mass_storage.c b/drivers/usb/gadget/function/f_mass_storage.c index fc4818fb2a8b..9d7221e57f2c 100644 --- a/drivers/usb/gadget/function/f_mass_storage.c +++ b/drivers/usb/gadget/function/f_mass_storage.c @@ -1103,9 +1103,9 @@ static int do_request_sense(struct fsg_common *common, struct fsg_buffhd *bh) * FSG normally uses option a); enable this code to use option b). */ #if 0 - if (curlun && curlun->unit_attention_data != SS_NO_SENSE) { + if (curlun && curlun->unit_attention_data != NO_SENSE) { curlun->sense_data = curlun->unit_attention_data; - curlun->unit_attention_data = SS_NO_SENSE; + curlun->unit_attention_data = NO_SENSE; } #endif @@ -1118,18 +1118,18 @@ static int do_request_sense(struct fsg_common *common, struct fsg_buffhd *bh) sd = curlun->sense_data; sdinfo = curlun->sense_data_info; valid = curlun->info_valid << 7; - curlun->sense_data = SS_NO_SENSE; + curlun->sense_data = NO_SENSE; curlun->sense_data_info = 0; curlun->info_valid = 0; } memset(buf, 0, 18); buf[0] = valid | 0x70; /* Valid, current error */ - buf[2] = SK(sd); + buf[2] = usb_sense_key(sd); put_unaligned_be32(sdinfo, &buf[3]); /* Sense information */ buf[7] = 18 - 8; /* Additional sense length */ - buf[12] = ASC(sd); - buf[13] = ASCQ(sd); + buf[12] = usb_sense_asc(sd); + buf[13] = usb_sense_ascq(sd); return 18; } @@ -1678,21 +1678,23 @@ static void send_status(struct fsg_common *common) if (curlun) { sd = curlun->sense_data; sdinfo = curlun->sense_data_info; - } else if (common->bad_lun_okay) - sd = SS_NO_SENSE; - else + } else if (common->bad_lun_okay) { + sd = NO_SENSE; + } else { sd = SS_LOGICAL_UNIT_NOT_SUPPORTED; + } if (common->phase_error) { DBG(common, "sending phase-error status\n"); status = US_BULK_STAT_PHASE; sd = SS_INVALID_COMMAND; - } else if (sd != SS_NO_SENSE) { + } else if (sd != NO_SENSE) { DBG(common, "sending command-failure status\n"); status = US_BULK_STAT_FAIL; VDBG(common, " sense data: SK x%02x, ASC x%02x, ASCQ x%02x;" " info x%x\n", - SK(sd), ASC(sd), ASCQ(sd), sdinfo); + usb_sense_key(sd), usb_sense_asc(sd), + usb_sense_ascq(sd), sdinfo); } /* Store and send the Bulk-only CSW */ @@ -1798,7 +1800,7 @@ static int check_command(struct fsg_common *common, int cmnd_size, curlun = common->curlun; if (curlun) { if (common->cmnd[0] != REQUEST_SENSE) { - curlun->sense_data = SS_NO_SENSE; + curlun->sense_data = NO_SENSE; curlun->sense_data_info = 0; curlun->info_valid = 0; } @@ -1820,11 +1822,11 @@ static int check_command(struct fsg_common *common, int cmnd_size, * If a unit attention condition exists, only INQUIRY and * REQUEST SENSE commands are allowed; anything else must fail. */ - if (curlun && curlun->unit_attention_data != SS_NO_SENSE && + if (curlun && curlun->unit_attention_data != NO_SENSE && common->cmnd[0] != INQUIRY && common->cmnd[0] != REQUEST_SENSE) { curlun->sense_data = curlun->unit_attention_data; - curlun->unit_attention_data = SS_NO_SENSE; + curlun->unit_attention_data = NO_SENSE; return -EINVAL; } @@ -2501,8 +2503,8 @@ static void handle_exception(struct fsg_common *common) if (!curlun) continue; curlun->prevent_medium_removal = 0; - curlun->sense_data = SS_NO_SENSE; - curlun->unit_attention_data = SS_NO_SENSE; + curlun->sense_data = NO_SENSE; + curlun->unit_attention_data = NO_SENSE; curlun->sense_data_info = 0; curlun->info_valid = 0; } diff --git a/drivers/usb/gadget/function/storage_common.h b/drivers/usb/gadget/function/storage_common.h index 11ac785d5eee..e73a30cc553f 100644 --- a/drivers/usb/gadget/function/storage_common.h +++ b/drivers/usb/gadget/function/storage_common.h @@ -70,24 +70,59 @@ do { \ #define MAX_COMMAND_SIZE 16 /* SCSI Sense Key/Additional Sense Code/ASC Qualifier values */ -#define SS_NO_SENSE 0 -#define SS_COMMUNICATION_FAILURE 0x040800 -#define SS_INVALID_COMMAND 0x052000 -#define SS_INVALID_FIELD_IN_CDB 0x052400 -#define SS_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE 0x052100 -#define SS_LOGICAL_UNIT_NOT_SUPPORTED 0x052500 -#define SS_MEDIUM_NOT_PRESENT 0x023a00 -#define SS_MEDIUM_REMOVAL_PREVENTED 0x055302 -#define SS_NOT_READY_TO_READY_TRANSITION 0x062800 -#define SS_RESET_OCCURRED 0x062900 -#define SS_SAVING_PARAMETERS_NOT_SUPPORTED 0x053900 -#define SS_UNRECOVERED_READ_ERROR 0x031100 -#define SS_WRITE_ERROR 0x030c02 -#define SS_WRITE_PROTECTED 0x072700 - -#define SK(x) ((u8) ((x) >> 16)) /* Sense Key byte, etc. */ -#define ASC(x) ((u8) ((x) >> 8)) -#define ASCQ(x) ((u8) (x)) +static inline u32 usb_sense_kc(u8 sense_key, u16 sense_code) +{ + return ((u32)sense_key << 16) | (u32)sense_code; +} + +static inline u8 usb_sense_key(u32 kc) +{ + return kc >> 16; +} + +static inline u16 usb_sense_code(u32 kc) +{ + return kc & 0xFFFF; +} + +static inline u8 usb_sense_asc(u32 kc) +{ + return scsi_sense_code_asc(usb_sense_code(kc)); +} + +static inline u8 usb_sense_ascq(u32 kc) +{ + return scsi_sense_code_ascq(usb_sense_code(kc)); +} + +#define SS_COMMUNICATION_FAILURE \ + usb_sense_kc(HARDWARE_ERROR, LU_COMMUNICATION_FAILURE) +#define SS_INVALID_COMMAND \ + usb_sense_kc(ILLEGAL_REQUEST, INVALID_COMMAND_OP_CODE) +#define SS_INVALID_FIELD_IN_CDB \ + usb_sense_kc(ILLEGAL_REQUEST, INVALID_FIELD_IN_CDB) +#define SS_LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE \ + usb_sense_kc(ILLEGAL_REQUEST, LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE) +#define SS_LOGICAL_UNIT_NOT_SUPPORTED \ + usb_sense_kc(ILLEGAL_REQUEST, LU_NOT_SUPPORTED) +#define SS_MEDIUM_NOT_PRESENT \ + usb_sense_kc(NOT_READY, MEDIUM_NOT_PRESENT) +#define SS_MEDIUM_REMOVAL_PREVENTED \ + usb_sense_kc(ILLEGAL_REQUEST, MEDIUM_REMOVAL_PREVENTED) +#define SS_NOT_READY_TO_READY_TRANSITION \ + usb_sense_kc(UNIT_ATTENTION, \ + NOT_READY_TO_READY_CHANGE_MEDIUM_MAY_HAVE_CHANGED) +#define SS_RESET_OCCURRED \ + usb_sense_kc(UNIT_ATTENTION, \ + POWER_ON_RESET_OR_BUS_DEVICE_RESET_OCCURRED) +#define SS_SAVING_PARAMETERS_NOT_SUPPORTED \ + usb_sense_kc(ILLEGAL_REQUEST, SAVING_PARAMETERS_NOT_SUPPORTED) +#define SS_UNRECOVERED_READ_ERROR \ + usb_sense_kc(MEDIUM_ERROR, UNRECOVERED_READ_ERROR) +#define SS_WRITE_ERROR \ + usb_sense_kc(MEDIUM_ERROR, WRITE_ERROR_AUTO_REALLOCATION_FAILED) +#define SS_WRITE_PROTECTED \ + usb_sense_kc(DATA_PROTECT, WRITE_PROTECTED) /* * Vendor (8 chars), product (16 chars), release (4 hexadecimal digits) and NUL diff --git a/drivers/usb/storage/debug.c b/drivers/usb/storage/debug.c index dda610f689b7..71923cf28536 100644 --- a/drivers/usb/storage/debug.c +++ b/drivers/usb/storage/debug.c @@ -141,14 +141,12 @@ void usb_stor_show_command(const struct us_data *us, struct scsi_cmnd *srb) } void usb_stor_show_sense(const struct us_data *us, - unsigned char key, - unsigned char asc, - unsigned char ascq) + const struct scsi_sense_hdr *sshdr) { const char *what, *keystr, *fmt; - keystr = scsi_sense_key_string(key); - what = scsi_extd_sense_format(asc, ascq, &fmt); + keystr = scsi_sense_key_string(sshdr->sense_key); + what = scsi_extd_sense_format(sshdr, &fmt); if (keystr == NULL) keystr = "(Unknown Key)"; @@ -156,7 +154,8 @@ void usb_stor_show_sense(const struct us_data *us, what = "(unknown ASC/ASCQ)"; if (fmt) - usb_stor_dbg(us, "%s: %s (%s%x)\n", keystr, what, fmt, ascq); + usb_stor_dbg(us, "%s: %s (%s%x)\n", keystr, what, fmt, + scsi_sense_ascq(sshdr)); else usb_stor_dbg(us, "%s: %s\n", keystr, what); } diff --git a/drivers/usb/storage/debug.h b/drivers/usb/storage/debug.h index a6505ceb6693..34e20fff13b5 100644 --- a/drivers/usb/storage/debug.h +++ b/drivers/usb/storage/debug.h @@ -31,8 +31,8 @@ #ifdef CONFIG_USB_STORAGE_DEBUG void usb_stor_show_command(const struct us_data *us, struct scsi_cmnd *srb); -void usb_stor_show_sense(const struct us_data *us, unsigned char key, - unsigned char asc, unsigned char ascq); +void usb_stor_show_sense(const struct us_data *us, + const struct scsi_sense_hdr *sshdr); __printf(2, 3) void usb_stor_dbg(const struct us_data *us, const char *fmt, ...); diff --git a/drivers/usb/storage/transport.c b/drivers/usb/storage/transport.c index 9a4bf86e7b6a..8de3015bce05 100644 --- a/drivers/usb/storage/transport.c +++ b/drivers/usb/storage/transport.c @@ -803,9 +803,9 @@ void usb_stor_invoke_transport(struct scsi_cmnd *srb, struct us_data *us) temp_result); usb_stor_dbg(us, "-- code: 0x%x, key: 0x%x, ASC: 0x%x, ASCQ: 0x%x\n", sshdr.response_code, sshdr.sense_key, - sshdr.asc, sshdr.ascq); + scsi_sense_asc(&sshdr), scsi_sense_ascq(&sshdr)); #ifdef CONFIG_USB_STORAGE_DEBUG - usb_stor_show_sense(us, sshdr.sense_key, sshdr.asc, sshdr.ascq); + usb_stor_show_sense(us, &sshdr); #endif /* set the result so the higher layers expect this data */ @@ -820,7 +820,8 @@ void usb_stor_invoke_transport(struct scsi_cmnd *srb, struct us_data *us) * everything worked or that there was an unspecified * problem. We have to decide which. */ - if (sshdr.sense_key == 0 && sshdr.asc == 0 && sshdr.ascq == 0 && + if (sshdr.sense_key == NO_SENSE && + sshdr.sense_code == NO_ADDITIONAL_SENSE_INFORMATION && fm_ili == 0) { /* * If things are really okay, then let's show that. diff --git a/drivers/usb/storage/uas.c b/drivers/usb/storage/uas.c index 265162981269..8655edbd66b1 100644 --- a/drivers/usb/storage/uas.c +++ b/drivers/usb/storage/uas.c @@ -1130,9 +1130,9 @@ static int uas_pre_reset(struct usb_interface *intf) return 0; /* Block new requests */ - spin_lock_irqsave(shost->host_lock, flags); + spin_lock_irqsave(&shost->host_lock, flags); scsi_block_requests(shost); - spin_unlock_irqrestore(shost->host_lock, flags); + spin_unlock_irqrestore(&shost->host_lock, flags); if (uas_wait_for_pending_cmnds(devinfo) != 0) { shost_printk(KERN_ERR, shost, "%s: timed out\n", __func__); @@ -1162,9 +1162,9 @@ static int uas_post_reset(struct usb_interface *intf) __func__, err); /* we must unblock the host in every case lest we deadlock */ - spin_lock_irqsave(shost->host_lock, flags); + spin_lock_irqsave(&shost->host_lock, flags); scsi_report_bus_reset(shost, 0); - spin_unlock_irqrestore(shost->host_lock, flags); + spin_unlock_irqrestore(&shost->host_lock, flags); scsi_unblock_requests(shost); @@ -1204,9 +1204,9 @@ static int uas_reset_resume(struct usb_interface *intf) return -EIO; } - spin_lock_irqsave(shost->host_lock, flags); + spin_lock_irqsave(&shost->host_lock, flags); scsi_report_bus_reset(shost, 0); - spin_unlock_irqrestore(shost->host_lock, flags); + spin_unlock_irqrestore(&shost->host_lock, flags); return 0; } diff --git a/drivers/usb/storage/usb.h b/drivers/usb/storage/usb.h index 97c6196d639b..c26d008e5184 100644 --- a/drivers/usb/storage/usb.h +++ b/drivers/usb/storage/usb.h @@ -166,8 +166,8 @@ extern void fill_inquiry_response(struct us_data *us, * The scsi_lock() and scsi_unlock() macros protect the sm_state and the * single queue element srb for write access */ -#define scsi_unlock(host) spin_unlock_irq(host->host_lock) -#define scsi_lock(host) spin_lock_irq(host->host_lock) +#define scsi_unlock(host) spin_unlock_irq(&host->host_lock) +#define scsi_lock(host) spin_lock_irq(&host->host_lock) /* General routines provided by the usb-storage standard core */ #ifdef CONFIG_PM diff --git a/include/linux/bsg-lib.h b/include/linux/bsg-lib.h index 14fa93268630..a697246feeac 100644 --- a/include/linux/bsg-lib.h +++ b/include/linux/bsg-lib.h @@ -66,7 +66,8 @@ void bsg_job_done(struct bsg_job *job, int result, unsigned int reply_payload_rcv_len); struct request_queue *bsg_setup_queue(struct device *dev, const char *name, struct queue_limits *lim, bsg_job_fn *job_fn, - bsg_timeout_fn *timeout, int dd_job_size); + bsg_timeout_fn *timeout, int dd_job_size, + unsigned int reply_len); void bsg_remove_queue(struct request_queue *q); void bsg_job_put(struct bsg_job *job); int __must_check bsg_job_get(struct bsg_job *job); diff --git a/include/linux/pci.h b/include/linux/pci.h index d31a8d107b1e..68166c9f8158 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -611,7 +611,10 @@ static inline struct pci_dev *pci_physfn(struct pci_dev *dev) struct pci_dev *pci_alloc_dev(struct pci_bus *bus); -#define to_pci_dev(n) container_of(n, struct pci_dev, dev) +static inline struct pci_dev *to_pci_dev(const struct device *dev) +{ + return container_of(dev, struct pci_dev, dev); +} #define for_each_pci_dev(d) while ((d = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, d)) != NULL) #define for_each_pci_dev_reverse(d) \ while ((d = pci_get_device_reverse(PCI_ANY_ID, PCI_ANY_ID, d)) != NULL) diff --git a/include/scsi/libiscsi.h b/include/scsi/libiscsi.h index 3d765c77bcd9..e4ac4ec0ac3e 100644 --- a/include/scsi/libiscsi.h +++ b/include/scsi/libiscsi.h @@ -474,17 +474,26 @@ extern int iscsi_conn_send_pdu(struct iscsi_cls_conn *, struct iscsi_hdr *, char *, uint32_t); extern int iscsi_complete_pdu(struct iscsi_conn *, struct iscsi_hdr *, char *, int); -extern int __iscsi_complete_pdu(struct iscsi_conn *, struct iscsi_hdr *, - char *, int); +extern int __iscsi_complete_pdu(struct iscsi_session *session, + struct iscsi_conn *conn, struct iscsi_hdr *, + char *, int) + __must_hold(&session->back_lock); extern int iscsi_verify_itt(struct iscsi_conn *, itt_t); -extern struct iscsi_task *iscsi_itt_to_ctask(struct iscsi_conn *, itt_t); -extern struct iscsi_task *iscsi_itt_to_task(struct iscsi_conn *, itt_t); +struct iscsi_task *iscsi_itt_to_ctask(struct iscsi_session *session, + struct iscsi_conn *conn, itt_t itt) + __must_hold(&session->back_lock); +struct iscsi_task *iscsi_itt_to_task(struct iscsi_session *session, + struct iscsi_conn *conn, itt_t itt) + __must_hold(&session->back_lock); extern void iscsi_requeue_task(struct iscsi_task *task); extern void iscsi_put_task(struct iscsi_task *task); -extern void __iscsi_put_task(struct iscsi_task *task); +void __iscsi_put_task(struct iscsi_session *session, struct iscsi_task *task) + __must_hold(&session->back_lock); extern bool iscsi_get_task(struct iscsi_task *task); -extern void iscsi_complete_scsi_task(struct iscsi_task *task, - uint32_t exp_cmdsn, uint32_t max_cmdsn); +void iscsi_complete_scsi_task(struct iscsi_session *session, + struct iscsi_task *task, + uint32_t exp_cmdsn, uint32_t max_cmdsn) + __must_hold(&session->back_lock); /* * generic helpers diff --git a/include/scsi/scsi_cmnd.h b/include/scsi/scsi_cmnd.h index 8ecfb94049db..2f2364c96457 100644 --- a/include/scsi/scsi_cmnd.h +++ b/include/scsi/scsi_cmnd.h @@ -391,8 +391,7 @@ static inline unsigned scsi_transfer_length(struct scsi_cmnd *scmd) return xfer_len; } -extern void scsi_build_sense(struct scsi_cmnd *scmd, int desc, - u8 key, u8 asc, u8 ascq); +void scsi_set_sense(struct scsi_cmnd *scmd, int desc, u8 key, u16 code); struct request *scsi_alloc_request(struct request_queue *q, blk_opf_t opf, blk_mq_req_flags_t flags); diff --git a/include/scsi/scsi_common.h b/include/scsi/scsi_common.h index 00c8a16d3cd2..88a076c1a137 100644 --- a/include/scsi/scsi_common.h +++ b/include/scsi/scsi_common.h @@ -71,8 +71,7 @@ extern u64 scsilun_to_int(struct scsi_lun *); struct scsi_sense_hdr { /* See SPC-3 section 4.5 */ u8 response_code; /* permit: 0x0, 0x70, 0x71, 0x72, 0x73 */ u8 sense_key; - u8 asc; - u8 ascq; + u16 sense_code; u8 byte4; u8 byte5; u8 byte6; @@ -87,10 +86,21 @@ static inline bool scsi_sense_valid(const struct scsi_sense_hdr *sshdr) return (sshdr->response_code & 0x70) == 0x70; } +static inline u8 scsi_sense_asc(const struct scsi_sense_hdr *sshdr) +{ + return scsi_sense_code_asc(sshdr->sense_code); +} + +static inline u8 scsi_sense_ascq(const struct scsi_sense_hdr *sshdr) +{ + return scsi_sense_code_ascq(sshdr->sense_code); +} + extern bool scsi_normalize_sense(const u8 *sense_buffer, int sb_len, struct scsi_sense_hdr *sshdr); -extern void scsi_build_sense_buffer(int desc, u8 *buf, u8 key, u8 asc, u8 ascq); +void scsi_set_sense_buffer(int desc, u8 *buf, u8 key, u16 code); + int scsi_set_sense_information(u8 *buf, int buf_len, u64 info); int scsi_set_sense_field_pointer(u8 *buf, int buf_len, u16 fp, u8 bp, bool cd); extern const u8 * scsi_sense_desc_find(const u8 * sense_buffer, int sb_len, diff --git a/include/scsi/scsi_dbg.h b/include/scsi/scsi_dbg.h index efcdc78530d5..f21a5e3caca9 100644 --- a/include/scsi/scsi_dbg.h +++ b/include/scsi/scsi_dbg.h @@ -20,8 +20,8 @@ extern void scsi_print_result(struct scsi_cmnd *, const char *, int); #ifdef CONFIG_SCSI_CONSTANTS extern bool scsi_opcode_sa_name(int, int, const char **, const char **); extern const char *scsi_sense_key_string(unsigned char); -extern const char *scsi_extd_sense_format(unsigned char, unsigned char, - const char **); +extern const char *scsi_extd_sense_format(const struct scsi_sense_hdr *sshdr, + const char **fmt); extern const char *scsi_mlreturn_string(int); extern const char *scsi_hostbyte_string(int); #else @@ -57,7 +57,7 @@ scsi_sense_key_string(unsigned char key) } static inline const char * -scsi_extd_sense_format(unsigned char asc, unsigned char ascq, const char **fmt) +scsi_extd_sense_format(const struct scsi_sense_hdr *sshdr, const char **fmt) { *fmt = NULL; return NULL; diff --git a/include/scsi/scsi_device.h b/include/scsi/scsi_device.h index 8694eeadd753..e6fd6bc30644 100644 --- a/include/scsi/scsi_device.h +++ b/include/scsi/scsi_device.h @@ -514,20 +514,20 @@ extern void scsi_sanitize_inquiry_string(unsigned char *s, int len); */ #define SCMD_FAILURE_STAT_ANY 0xff /* - * The following can be set to the scsi_failure sense, asc and ascq fields to - * match on any sense, ASC, or ASCQ value. + * The following can be set to the scsi_failure sense key, asc and ascq fields + * to match any sense key, ASC, and ASCQ value. */ -#define SCMD_FAILURE_SENSE_ANY 0xff -#define SCMD_FAILURE_ASC_ANY 0xff -#define SCMD_FAILURE_ASCQ_ANY 0xff +#define SCMD_FAILURE_SENSE_KEY_ANY 0xff +#define SCMD_FAILURE_SENSE_CODE_ANY 0xffff +#define SCMD_FAILURE_ASC_ANY 0xff +#define SCMD_FAILURE_ASCQ_ANY 0xff /* Always retry a matching failure. */ #define SCMD_FAILURE_NO_LIMIT -1 struct scsi_failure { int result; - u8 sense; - u8 asc; - u8 ascq; + u8 sense_key; + u16 sense_code; /* * Number of times scsi_execute_cmd will retry the failure. It does * not count for the total_allowed. @@ -537,6 +537,16 @@ struct scsi_failure { s8 retries; }; +static inline u8 scsi_failure_asc(const struct scsi_failure *failure) +{ + return scsi_sense_code_asc(failure->sense_code); +} + +static inline u8 scsi_failure_ascq(const struct scsi_failure *failure) +{ + return scsi_sense_code_ascq(failure->sense_code); +} + struct scsi_failures { /* * If a scsi_failure does not have a retry limit setup this limit will diff --git a/include/scsi/scsi_host.h b/include/scsi/scsi_host.h index 16243ec376cd..daaf1247673f 100644 --- a/include/scsi/scsi_host.h +++ b/include/scsi/scsi_host.h @@ -534,9 +534,9 @@ struct scsi_host_template { unsigned long irq_flags; \ enum scsi_qc_status rc; \ \ - spin_lock_irqsave(shost->host_lock, irq_flags); \ + spin_lock_irqsave(&shost->host_lock, irq_flags); \ rc = func_name##_lck(cmd); \ - spin_unlock_irqrestore(shost->host_lock, irq_flags); \ + spin_unlock_irqrestore(&shost->host_lock, irq_flags); \ return rc; \ } @@ -570,8 +570,7 @@ struct Scsi_Host { struct list_head starved_list; - spinlock_t default_lock; - spinlock_t *host_lock; + spinlock_t host_lock; struct mutex scan_mutex;/* serialize scanning activity */ @@ -953,6 +952,6 @@ static inline unsigned char scsi_host_get_guard(struct Scsi_Host *shost) } int scsi_host_set_state(struct Scsi_Host *shost, enum scsi_host_state state) - __must_hold(shost->host_lock); + __must_hold(&shost->host_lock); #endif /* _SCSI_SCSI_HOST_H */ diff --git a/include/scsi/scsi_proto.h b/include/scsi/scsi_proto.h index c6b4a4dc8d9c..9c7d31aa6bae 100644 --- a/include/scsi/scsi_proto.h +++ b/include/scsi/scsi_proto.h @@ -12,6 +12,7 @@ #include #include +#include /* * SCSI opcodes @@ -218,76 +219,6 @@ enum sam_status { #define STATUS_MASK 0xfe -/* - * SENSE KEYS - */ -#define NO_SENSE 0x00 -#define RECOVERED_ERROR 0x01 -#define NOT_READY 0x02 -#define MEDIUM_ERROR 0x03 -#define HARDWARE_ERROR 0x04 -#define ILLEGAL_REQUEST 0x05 -#define UNIT_ATTENTION 0x06 -#define DATA_PROTECT 0x07 -#define BLANK_CHECK 0x08 -#define VENDOR_SPECIFIC 0x09 -#define COPY_ABORTED 0x0a -#define ABORTED_COMMAND 0x0b -#define VOLUME_OVERFLOW 0x0d -#define MISCOMPARE 0x0e -#define COMPLETED 0x0f - -/* - * Additional Sense Codes (ASC). - */ -#define NO_ADDITIONAL_SENSE 0x00 -#define OVERLAP_ATOMIC_COMMAND_ASC 0x00 -#define LOGICAL_UNIT_NOT_READY 0x04 -#define LOGICAL_UNIT_COMMUNICATION_FAILURE 0x8 -#define WRITE_ERROR_ASC 0x0c -#define UNRECOVERED_READ_ERR 0x11 -#define PARAMETER_LIST_LENGTH_ERR 0x1a -#define MISCOMPARE_VERIFY_ASC 0x1d -#define INVALID_OPCODE 0x20 -#define LBA_OUT_OF_RANGE 0x21 -#define INVALID_FIELD_IN_CDB 0x24 -#define INVALID_FIELD_IN_PARAM_LIST 0x26 -#define WRITE_PROTECTED 0x27 -#define UA_READY_ASC 0x28 -#define UA_RESET_ASC 0x29 -#define UA_CHANGED_ASC 0x2a -#define TOO_MANY_IN_PARTITION_ASC 0x3b -#define TARGET_CHANGED_ASC 0x3f -#define SAVING_PARAMS_UNSUP 0x39 -#define TRANSPORT_PROBLEM 0x4b -#define INSUFF_RES_ASC 0x55 -#define LOW_POWER_COND_ON 0x5e -#define THRESHOLD_EXCEEDED 0x5d - -/* - * Additional Sense Code Qualifiers (ASCQ). - */ -#define POWER_ON_RESET_ASCQ 0x00 -#define MODE_CHANGED_ASCQ 0x01 /* mode parameters changed */ -#define FILEMARK_DETECTED_ASCQ 0x01 -#define POWER_ON_OCCURRED_ASCQ 0x01 -#define MICROCODE_CHANGED_ASCQ 0x01 /* with TARGET_CHANGED_ASC */ -#define BUS_RESET_ASCQ 0x02 /* scsi bus reset occurred */ -#define EOP_EOM_DETECTED_ASCQ 0x02 -#define INSUFF_RES_ASCQ 0x03 -#define BEGINNING_OF_P_M_DETECTED_ASCQ 0x04 -#define UNALIGNED_WRITE_ASCQ 0x04 -#define EOD_DETECTED_ASCQ 0x05 -#define WRITE_BOUNDARY_ASCQ 0x05 -#define READ_INVDATA_ASCQ 0x06 -#define READ_BOUNDARY_ASCQ 0x07 -#define CAPACITY_CHANGED_ASCQ 0x09 -#define ATTEMPT_ACCESS_GAP 0x09 -#define LUNS_CHANGED_ASCQ 0x0e -#define INSUFF_ZONE_ASCQ 0x0e -#define MICROCODE_CHANGED_WO_RESET_ASCQ 0x16 -#define OVERLAP_ATOMIC_COMMAND_ASCQ 0x23 - /* * DEVICE TYPES * Please keep them in 0x%02x format for $MODALIAS to work diff --git a/include/scsi/scsi_sense.h b/include/scsi/scsi_sense.h new file mode 100644 index 000000000000..6e010a72482e --- /dev/null +++ b/include/scsi/scsi_sense.h @@ -0,0 +1,950 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Definitions of SCSI sense keys, additional sense codes and additional sense + * code qualifiers. + */ +#ifndef _SCSI_SENSE_H_ +#define _SCSI_SENSE_H_ + +#include + +/* + * Sense keys. + * See: https://www.t10.org/lists/2sensekey.htm + */ +enum scsi_sense_key { + NO_SENSE = 0x00, + RECOVERED_ERROR = 0x01, + NOT_READY = 0x02, + MEDIUM_ERROR = 0x03, + HARDWARE_ERROR = 0x04, + ILLEGAL_REQUEST = 0x05, + UNIT_ATTENTION = 0x06, + DATA_PROTECT = 0x07, + BLANK_CHECK = 0x08, + VENDOR_SPECIFIC = 0x09, + COPY_ABORTED = 0x0a, + ABORTED_COMMAND = 0x0b, + VOLUME_OVERFLOW = 0x0d, + MISCOMPARE = 0x0e, + COMPLETED = 0x0f, +}; + +#define SCSI_ASC_DEF(name) ASC_##name +#define SCSI_ASC(name, code) \ + SCSI_ASC_DEF(name) = (code), \ + name = ((code) << 8) | 0x00 + +/* + * SCSI additional sense codes and sense codes qualifiers. + * See: https://www.t10.org/lists/asc-num.txt + * Additional sense codes and their qualifiers are combined as a single value + * equal to (ASC << 8) | ASCQ. + * + * The definitions are sorted in increasing sense code value order with a naming + * following as close as possible the exact naming used in T10. To avoid + * excessively long code lines when using these macros, some long ASC/ASCQ + * combination names are shortened (E.g. LOGICAL_UNIT_xxx -> LU_xxx). + * Very generic ASC names that potentially may clash with other macros elsewhere + * are prefixed with "SSC_" (e.g. WARNING and WRITE_ERROR). + */ +enum scsi_sense_code { + SCSI_ASC(NO_ADDITIONAL_SENSE_INFORMATION, 0x00), + FILEMARK_DETECTED = 0x0001, + END_OF_PARTITION_MEDIUM_DETECTED = 0x0002, + SETMARK_DETECTED = 0x0003, + BEGINNING_OF_PARTITION_MEDIUM_DETECTED = 0x0004, + END_OF_DATA_DETECTED = 0x0005, + IO_PROCESS_TERMINATED = 0x0006, + PROGRAMMABLE_EARLY_WARNING_DETECTED = 0x0007, + AUDIO_PLAY_OP_IN_PROGRESS = 0x0011, + AUDIO_PLAY_OP_PAUSED = 0x0012, + AUDIO_PLAY_OP_SUCCESSFULLY_COMPLETED = 0x0013, + AUDIO_PLAY_OP_STOPPED_DUE_TO_ERROR = 0x0014, + NO_CURRENT_AUDIO_STATUS_TO_RETURN = 0x0015, + OP_IN_PROGRESS = 0x0016, + CLEANING_REQUESTED = 0x0017, + ERASE_OP_IN_PROGRESS = 0x0018, + LOCATE_OP_IN_PROGRESS = 0x0019, + REWIND_OP_IN_PROGRESS = 0x001A, + SET_CAPACITY_OP_IN_PROGRESS = 0x001B, + VERIFY_OP_IN_PROGRESS = 0x001C, + ATA_PASS_THROUGH_INFORMATION_AVAILABLE = 0x001D, + CONFLICTING_SA_CREATION_REQUEST = 0x001E, + LU_TRANSITIONING_TO_ANOTHER_POWER_CONDITION = 0x001F, + EXTENDED_COPY_INFORMATION_AVAILABLE = 0x0020, + ATOMIC_COMMAND_ABORTED_DUE_TO_ACA = 0x0021, + DEFERRED_MICROCODE_IS_PENDING = 0x0022, + OVERLAPPING_ATOMIC_COMMAND_IN_PROGRESS = 0x0023, + + SCSI_ASC(NO_INDEX_SECTOR_SIGNAL, 0x01), + + SCSI_ASC(NO_SEEK_COMPLETE, 0x02), + + SCSI_ASC(PERIPHERAL_DEVICE_WRITE_FAULT, 0x03), + NO_WRITE_CURRENT = 0x0301, + EXCESSIVE_WRITE_ERRORS = 0x0302, + + SCSI_ASC(LU_NOT_READY, 0x04), + LU_IS_IN_PROCESS_OF_BECOMING_READY = 0x0401, + LU_NOT_READY_INITIALIZING_COMMAND_REQUIRED = 0x0402, + LU_NOT_READY_MANUAL_INTERVENTION_REQUIRED = 0x0403, + LU_NOT_READY_FORMAT_IN_PROGRESS = 0x0404, + LU_NOT_READY_REBUILD_IN_PROGRESS = 0x0405, + LU_NOT_READY_RECALCULATION_IN_PROGRESS = 0x0406, + LU_NOT_READY_OP_IN_PROGRESS = 0x0407, + LU_NOT_READY_LONG_WRITE_IN_PROGRESS = 0x0408, + LU_NOT_READY_SELFTEST_IN_PROGRESS = 0x0409, + LU_NOT_ACCESSIBLE_ASYMMETRIC_ACCESS_STATE_TRANSITION = 0x040A, + LU_NOT_ACCESSIBLE_TARGET_PORT_IN_STANDBY_STATE = 0x040B, + LU_NOT_ACCESSIBLE_TARGET_PORT_IN_UNAVAILABLE_STATE = 0x040C, + LU_NOT_READY_STRUCTURE_CHECK_REQUIRED = 0x040D, + LU_NOT_READY_SECURITY_SESSION_IN_PROGRESS = 0x040E, + LU_NOT_READY_AUXILIARY_MEMORY_NOT_ACCESSIBLE = 0x0410, + LU_NOT_READY_NOTIFY_REQUIRED = 0x0411, + LU_NOT_READY_OFFLINE = 0x0412, + LU_NOT_READY_SA_CREATION_IN_PROGRESS = 0x0413, + LU_NOT_READY_SPACE_ALLOCATION_IN_PROGRESS = 0x0414, + LU_NOT_READY_ROBOTICS_DISABLED = 0x0415, + LU_NOT_READY_CONFIG_REQUIRED = 0x0416, + LU_NOT_READY_CALIBRATION_REQUIRED = 0x0417, + LU_NOT_READY_A_DOOR_IS_OPEN = 0x0418, + LU_NOT_READY_OPERATING_IN_SEQUENTIAL_MODE = 0x0419, + LU_NOT_READY_START_STOP_UNIT_COMMAND_IN_PROGRESS = 0x041A, + LU_NOT_READY_SANITIZE_IN_PROGRESS = 0x041B, + LU_NOT_READY_ADDITIONAL_POWER_USE_NOT_YET_GRANTED = 0x041C, + LU_NOT_READY_CONFIG_IN_PROGRESS = 0x041D, + LU_NOT_READY_MICROCODE_ACTIVATION_REQUIRED = 0x041E, + LU_NOT_READY_MICROCODE_DOWNLOAD_REQUIRED = 0x041F, + LU_NOT_READY_LU_RESET_REQUIRED = 0x0420, + LU_NOT_READY_HARD_RESET_REQUIRED = 0x0421, + LU_NOT_READY_POWER_CYCLE_REQUIRED = 0x0422, + LU_NOT_READY_AFFILIATION_REQUIRED = 0x0423, + DEPOPULATION_IN_PROGRESS = 0x0424, + DEPOPULATION_RESTORATION_IN_PROGRESS = 0x0425, + + SCSI_ASC(LU_DOES_NOT_RESPOND_TO_SELECTION, 0x05), + + SCSI_ASC(NO_REFERENCE_POSITION_FOUND, 0x06), + + SCSI_ASC(MULTIPLE_PERIPHERAL_DEVICES_SELECTED, 0x07), + + SCSI_ASC(LU_COMMUNICATION_FAILURE, 0x08), + LU_COMMUNICATION_TIMEOUT = 0x0801, + LU_COMMUNICATION_PARITY_ERROR = 0x0802, + LU_COMMUNICATION_CRC_ERROR = 0x0803, + UNREACHABLE_COPY_TARGET = 0x0804, + + SCSI_ASC(TRACK_FOLLOWING_ERROR, 0x09), + TRACKING_SERVO_FAILURE = 0x0901, + FOCUS_SERVO_FAILURE = 0x0902, + SPINDLE_SERVO_FAILURE = 0x0903, + HEAD_SELECT_FAULT = 0x0904, + VIBRATION_INDUCED_TRACKING_ERROR = 0x0905, + + SCSI_ASC(ERROR_LOG_OVERFLOW, 0x0A), + + SCSI_ASC(SSC_WARNING, 0x0B), + WARNING_SPECIFIED_TEMPERATURE_EXCEEDED = 0x0B01, + WARNING_ENCLOSURE_DEGRADED = 0x0B02, + WARNING_BACKGROUND_SELFTEST_FAILED = 0x0B03, + WARNING_BACKGROUND_PRESCAN_DETECTED_MEDIUM_ERROR = 0x0B04, + WARNING_BACKGROUND_MEDIUM_SCAN_DETECTED_MEDIUM_ERROR = 0x0B05, + WARNING_NONVOLATILE_CACHE_NOW_VOLATILE = 0x0B06, + WARNING_DEGRADED_POWER_TO_NONVOLATILE_CACHE = 0x0B07, + WARNING_POWER_LOSS_EXPECTED = 0x0B08, + WARNING_DEVICE_STATISTICS_NOTIFICATION_ACTIVE = 0x0B09, + WARNING_HIGH_CRITICAL_TEMPERATURE_LIMIT_EXCEEDED = 0x0B0A, + WARNING_LOW_CRITICAL_TEMPERATURE_LIMIT_EXCEEDED = 0x0B0B, + WARNING_HIGH_OPERATING_TEMPERATURE_LIMIT_EXCEEDED = 0x0B0C, + WARNING_LOW_OPERATING_TEMPERATURE_LIMIT_EXCEEDED = 0x0B0D, + WARNING_HIGH_CRITICAL_HUMIDITY_LIMIT_EXCEEDED = 0x0B0E, + WARNING_LOW_CRITICAL_HUMIDITY_LIMIT_EXCEEDED = 0x0B0F, + WARNING_HIGH_OPERATING_HUMIDITY_LIMIT_EXCEEDED = 0x0B10, + WARNING_LOW_OPERATING_HUMIDITY_LIMIT_EXCEEDED = 0x0B11, + WARNING_MICROCODE_SECURITY_AT_RISK = 0x0B12, + WARNING_MICROCODE_DIGITAL_SIGNATURE_VALIDATION_FAILURE = 0x0B13, + WARNING_PHYSICAL_ELEMENT_STATUS_CHANGE = 0x0B14, + + /* Defined as "WRITE ERROR" in T10. */ + SCSI_ASC(SSC_WRITE_ERROR, 0x0C), + WRITE_ERROR_RECOVERED_WITH_AUTO_REALLOCATION = 0x0C01, + WRITE_ERROR_AUTO_REALLOCATION_FAILED = 0x0C02, + WRITE_ERROR_RECOMMEND_REASSIGNMENT = 0x0C03, + COMPRESSION_CHECK_MISCOMPARE_ERROR = 0x0C04, + DATA_EXPANSION_OCCURRED_DURING_COMPRESSION = 0x0C05, + BLOCK_NOT_COMPRESSIBLE = 0x0C06, + WRITE_ERROR_RECOVERY_NEEDED = 0x0C07, + WRITE_ERROR_RECOVERY_FAILED = 0x0C08, + WRITE_ERROR_LOSS_OF_STREAMING = 0x0C09, + WRITE_ERROR_PADDING_BLOCKS_ADDED = 0x0C0A, + AUXILIARY_MEMORY_WRITE_ERROR = 0x0C0B, + WRITE_ERROR_UNEXPECTED_UNSOLICITED_DATA = 0x0C0C, + WRITE_ERROR_NOT_ENOUGH_UNSOLICITED_DATA = 0x0C0D, + MULTIPLE_WRITE_ERRORS = 0x0C0E, + DEFECTS_IN_ERROR_WINDOW = 0x0C0F, + INCOMPLETE_MULTIPLE_ATOMIC_WRITE_OPERATIONS = 0x0C10, + WRITE_ERROR_RECOVERY_SCAN_NEEDED = 0x0C11, + WRITE_ERROR_INSUFFICIENT_ZONE_RESOURCES = 0x0C12, + + SCSI_ASC(ERROR_DETECTED_BY_THIRD_PARTY_TEMPORARY_INITIATOR, 0x0D), + THIRD_PARTY_DEVICE_FAILURE = 0x0D01, + COPY_TARGET_DEVICE_NOT_REACHABLE = 0x0D02, + INCORRECT_COPY_TARGET_DEVICE_TYPE = 0x0D03, + COPY_TARGET_DEVICE_DATA_UNDERRUN = 0x0D04, + COPY_TARGET_DEVICE_DATA_OVERRUN = 0x0D05, + + SCSI_ASC(INVALID_INFORMATION_UNIT, 0x0E), + INFORMATION_UNIT_TOO_SHORT = 0x0E01, + INFORMATION_UNIT_TOO_LONG = 0x0E02, + INVALID_FIELD_IN_COMMAND_INFORMATION_UNIT = 0x0E03, + + SCSI_ASC(ID_CRC_OR_ECC_ERROR, 0x10), + LOGICAL_BLOCK_GUARD_CHECK_FAILED = 0x1001, + LOGICAL_BLOCK_APPLICATION_TAG_CHECK_FAILED = 0x1002, + LOGICAL_BLOCK_REFERENCE_TAG_CHECK_FAILED = 0x1003, + LOGICAL_BLOCK_PROTECTION_ERROR_ON_RECOVER_BUFFERED_DATA = 0x1004, + LOGICAL_BLOCK_PROTECTION_METHOD_ERROR = 0x1005, + + SCSI_ASC(UNRECOVERED_READ_ERROR, 0x11), + READ_RETRIES_EXHAUSTED = 0x1101, + ERROR_TOO_LONG_TO_CORRECT = 0x1102, + MULTIPLE_READ_ERRORS = 0x1103, + UNRECOVERED_READ_ERROR_AUTO_REALLOCATE_FAILED = 0x1104, + LEC_UNCORRECTABLE_ERROR = 0x1105, + CIRC_UNRECOVERED_ERROR = 0x1106, + DATA_RESYNCHRONIZATION_ERROR = 0x1107, + INCOMPLETE_BLOCK_READ = 0x1108, + NO_GAP_FOUND = 0x1109, + MISCORRECTED_ERROR = 0x110A, + UNRECOVERED_READ_ERROR_RECOMMEND_REASSIGNMENT = 0x110B, + UNRECOVERED_READ_ERROR_RECOMMEND_REWRITE_THE_DATA = 0x110C, + DECOMPRESSION_CRC_ERROR = 0x110D, + CANNOT_DECOMPRESS_USING_DECLARED_ALGORITHM = 0x110E, + ERROR_READING_UPC_EAN_NUMBER = 0x110F, + ERROR_READING_ISRC_NUMBER = 0x1110, + READ_ERROR_LOSS_OF_STREAMING = 0x1111, + AUXILIARY_MEMORY_READ_ERROR = 0x1112, + READ_ERROR_FAILED_RETRANSMISSION_REQUEST = 0x1113, + READ_ERROR_LBA_MARKED_BAD_BY_APPLICATION_CLIENT = 0x1114, + WRITE_AFTER_SANITIZE_REQUIRED = 0x1115, + + SCSI_ASC(ADDRESS_MARK_NOT_FOUND_FOR_ID_FIELD, 0x12), + + SCSI_ASC(ADDRESS_MARK_NOT_FOUND_FOR_DATA_FIELD, 0x13), + + SCSI_ASC(RECORDED_ENTITY_NOT_FOUND, 0x14), + RECORD_NOT_FOUND = 0x1401, + FILEMARK_OR_SETMARK_NOT_FOUND = 0x1402, + END_OF_DATA_NOT_FOUND = 0x1403, + BLOCK_SEQUENCE_ERROR = 0x1404, + RECORD_NOT_FOUND_RECOMMEND_REASSIGNMENT = 0x1405, + RECORD_NOT_FOUND_DATA_AUTO_REALLOCATED = 0x1406, + LOCATE_OPERATION_FAILURE = 0x1407, + + SCSI_ASC(RANDOM_POSITIONING_ERROR, 0x15), + MECHANICAL_POSITIONING_ERROR = 0x1501, + POSITIONING_ERROR_DETECTED_BY_READ_OF_MEDIUM = 0x1502, + + SCSI_ASC(DATA_SYNCHRONIZATION_MARK_ERROR, 0x16), + DATA_SYNC_ERROR_DATA_REWRITTEN = 0x1601, + DATA_SYNC_ERROR_RECOMMEND_REWRITE = 0x1602, + DATA_SYNC_ERROR_DATA_AUTO_REALLOCATED = 0x1603, + DATA_SYNC_ERROR_RECOMMEND_REASSIGNMENT = 0x1604, + + SCSI_ASC(RECOVERED_DATA_WITH_NO_ERROR_CORRECTION_APPLIED, 0x17), + RECOVERED_DATA_WITH_RETRIES = 0x1701, + RECOVERED_DATA_WITH_POSITIVE_HEAD_OFFSET = 0x1702, + RECOVERED_DATA_WITH_NEGATIVE_HEAD_OFFSET = 0x1703, + RECOVERED_DATA_WITH_RETRIES_AND_OR_CIRC_APPLIED = 0x1704, + RECOVERED_DATA_USING_PREVIOUS_SECTOR_ID = 0x1705, + RECOVERED_DATA_WITHOUT_ECC_DATA_AUTO_REALLOCATED = 0x1706, + RECOVERED_DATA_WITHOUT_ECC_RECOMMEND_REASSIGNMENT = 0x1707, + RECOVERED_DATA_WITHOUT_ECC_RECOMMEND_REWRITE = 0x1708, + RECOVERED_DATA_WITHOUT_ECC_DATA_REWRITTEN = 0x1709, + + SCSI_ASC(RECOVERED_DATA_WITH_ERROR_CORRECTION_APPLIED, 0x18), + RECOVERED_DATA_WITH_ERROR_CORRECTION_RETRIES_APPLIED = 0x1801, + RECOVERED_DATA_DATA_AUTO_REALLOCATED = 0x1802, + RECOVERED_DATA_WITH_CIRC = 0x1803, + RECOVERED_DATA_WITH_LEC = 0x1804, + RECOVERED_DATA_RECOMMEND_REASSIGNMENT = 0x1805, + RECOVERED_DATA_RECOMMEND_REWRITE = 0x1806, + RECOVERED_DATA_WITH_ECC_DATA_REWRITTEN = 0x1807, + RECOVERED_DATA_WITH_LINKING = 0x1808, + + SCSI_ASC(DEFECT_LIST_ERROR, 0x19), + DEFECT_LIST_NOT_AVAILABLE = 0x1901, + DEFECT_LIST_ERROR_IN_PRIMARY_LIST = 0x1902, + DEFECT_LIST_ERROR_IN_GROWN_LIST = 0x1903, + + SCSI_ASC(PARAMETER_LIST_LENGTH_ERROR, 0x1A), + + SCSI_ASC(SYNCHRONOUS_DATA_TRANSFER_ERROR, 0x1B), + + SCSI_ASC(DEFECT_LIST_NOT_FOUND, 0x1C), + PRIMARY_DEFECT_LIST_NOT_FOUND = 0x1C01, + GROWN_DEFECT_LIST_NOT_FOUND = 0x1C02, + + SCSI_ASC(MISCOMPARE_DURING_VERIFY_OPERATION, 0x1D), + MISCOMPARE_VERIFY_OF_UNMAPPED_LBA = 0x1D01, + + SCSI_ASC(RECOVERED_ID_WITH_ECC_CORRECTION, 0x1E), + + SCSI_ASC(PARTIAL_DEFECT_LIST_TRANSFER, 0x1F), + + SCSI_ASC(INVALID_COMMAND_OP_CODE, 0x20), + ACCESS_DENIED_INITIATOR_PENDING_ENROLLED = 0x2001, + ACCESS_DENIED_NO_ACCESS_RIGHTS = 0x2002, + ACCESS_DENIED_INVALID_MGMT_ID_KEY = 0x2003, + ILLEGAL_COMMAND_WHILE_IN_WRITE_CAPABLE_STATE = 0x2004, + ILLEGAL_COMMAND_WHILE_IN_EXPLICIT_ADDRESS_MODE = 0x2006, + ILLEGAL_COMMAND_WHILE_IN_IMPLICIT_ADDRESS_MODE = 0x2007, + ACCESS_DENIED_ENROLLMENT_CONFLICT = 0x2008, + ACCESS_DENIED_INVALID_LU_IDENTIFIER = 0x2009, + ACCESS_DENIED_INVALID_PROXY_TOKEN = 0x200A, + ACCESS_DENIED_ACL_LUN_CONFLICT = 0x200B, + ILLEGAL_COMMAND_WHEN_NOT_IN_APPEND_ONLY_MODE = 0x200C, + NOT_AN_ADMINISTRATIVE_LOGICAL_UNIT = 0x200D, + NOT_A_SUBSIDIARY_LOGICAL_UNIT = 0x200E, + NOT_A_CONGLOMERATE_LOGICAL_UNIT = 0x200F, + + SCSI_ASC(LOGICAL_BLOCK_ADDRESS_OUT_OF_RANGE, 0x21), + INVALID_ELEMENT_ADDRESS = 0x2101, + INVALID_ADDRESS_FOR_WRITE = 0x2102, + INVALID_WRITE_CROSSING_LAYER_JUMP = 0x2103, + UNALIGNED_WRITE_COMMAND = 0x2104, + WRITE_BOUNDARY_VIOLATION = 0x2105, + ATTEMPT_TO_READ_INVALID_DATA = 0x2106, + READ_BOUNDARY_VIOLATION = 0x2107, + MISALIGNED_WRITE_COMMAND = 0x2108, + ATTEMPT_TO_ACCESS_GAP_ZONE = 0x2109, + + SCSI_ASC(ILLEGAL_FUNCTION, 0x22), + + SCSI_ASC(INVALID_TOKEN_OP, 0x23), + INVALID_TOKEN_OP_UNSUPPORTED_TOKEN_TYPE = 0x2301, + INVALID_TOKEN_OP_REMOTE_TOKEN_USAGE_NOT_SUPPORTED = 0x2302, + INVALID_TOKEN_OP_REMOTE_ROD_TOKEN_CREATION_NOT_SUPPORTED = 0x2303, + INVALID_TOKEN_OP_TOKEN_UNKNOWN = 0x2304, + INVALID_TOKEN_OP_TOKEN_CORRUPT = 0x2305, + INVALID_TOKEN_OP_TOKEN_REVOKED = 0x2306, + INVALID_TOKEN_OP_TOKEN_EXPIRED = 0x2307, + INVALID_TOKEN_OP_TOKEN_CANCELLED = 0x2308, + INVALID_TOKEN_OP_TOKEN_DELETED = 0x2309, + INVALID_TOKEN_OP_INVALID_TOKEN_LENGTH = 0x230A, + + SCSI_ASC(INVALID_FIELD_IN_CDB, 0x24), + CDB_DECRYPTION_ERROR = 0x2401, + SECURITY_AUDIT_VALUE_FROZEN = 0x2404, + SECURITY_WORKING_KEY_FROZEN = 0x2405, + NONCE_NOT_UNIQUE = 0x2406, + NONCE_TIMESTAMP_OUT_OF_RANGE = 0x2407, + INVALID_XCDB = 0x2408, + INVALID_FAST_FORMAT = 0x2409, + + SCSI_ASC(LU_NOT_SUPPORTED, 0x25), + + SCSI_ASC(INVALID_FIELD_IN_PARAMETER_LIST, 0x26), + PARAMETER_NOT_SUPPORTED = 0x2601, + PARAMETER_VALUE_INVALID = 0x2602, + THRESHOLD_PARAMETERS_NOT_SUPPORTED = 0x2603, + INVALID_RELEASE_OF_PERSISTENT_RESERVATION = 0x2604, + DATA_DECRYPTION_ERROR = 0x2605, + TOO_MANY_TARGET_DESCRIPTORS = 0x2606, + UNSUPPORTED_TARGET_DESCRIPTOR_TYPE_CODE = 0x2607, + TOO_MANY_SEGMENT_DESCRIPTORS = 0x2608, + UNSUPPORTED_SEGMENT_DESCRIPTOR_TYPE_CODE = 0x2609, + UNEXPECTED_INEXACT_SEGMENT = 0x260A, + INLINE_DATA_LENGTH_EXCEEDED = 0x260B, + INVALID_OP_FOR_COPY_SOURCE_OR_DESTINATION = 0x260C, + COPY_SEGMENT_GRANULARITY_VIOLATION = 0x260D, + INVALID_PARAMETER_WHILE_PORT_IS_ENABLED = 0x260E, + INVALID_DATA_OUT_BUFFER_INTEGRITY_CHECK_VALUE = 0x260F, + DATA_DECRYPTION_KEY_FAIL_LIMIT_REACHED = 0x2610, + INCOMPLETE_KEY_ASSOCIATED_DATA_SET = 0x2611, + VENDOR_SPECIFIC_KEY_REFERENCE_NOT_FOUND = 0x2612, + APPLICATION_TAG_MODE_PAGE_IS_INVALID = 0x2613, + TAPE_STREAM_MIRRORING_PREVENTED = 0x2614, + COPY_SOURCE_OR_COPY_DESTINATION_NOT_AUTHORIZED = 0x2615, + FAST_COPY_NOT_POSSIBLE = 0x2616, + + SCSI_ASC(WRITE_PROTECTED, 0x27), + HW_WRITE_PROTECTED = 0x2701, + LU_SOFTWARE_WRITE_PROTECTED = 0x2702, + ASSOCIATED_WRITE_PROTECT = 0x2703, + PERSISTENT_WRITE_PROTECT = 0x2704, + PERMANENT_WRITE_PROTECT = 0x2705, + CONDITIONAL_WRITE_PROTECT = 0x2706, + SPACE_ALLOCATION_FAILED_WRITE_PROTECT = 0x2707, + ZONE_IS_READ_ONLY = 0x2708, + + SCSI_ASC(NOT_READY_TO_READY_CHANGE_MEDIUM_MAY_HAVE_CHANGED, 0x28), + IMPORT_OR_EXPORT_ELEMENT_ACCESSED = 0x2801, + FORMAT_LAYER_MAY_HAVE_CHANGED = 0x2802, + IMPORT_EXPORT_ELEMENT_ACCESSED_MEDIUM_CHANGED = 0x2803, + + SCSI_ASC(POWER_ON_RESET_OR_BUS_DEVICE_RESET_OCCURRED, 0x29), + POWER_ON_OCCURRED = 0x2901, + SCSI_BUS_RESET_OCCURRED = 0x2902, + BUS_DEVICE_RESET_FUNCTION_OCCURRED = 0x2903, + DEVICE_INTERNAL_RESET = 0x2904, + TRANSCEIVER_MODE_CHANGED_TO_SINGLE_ENDED = 0x2905, + TRANSCEIVER_MODE_CHANGED_TO_LVD = 0x2906, + I_T_NEXUS_LOSS_OCCURRED = 0x2907, + + SCSI_ASC(PARAMETERS_CHANGED, 0x2A), + MODE_PARAMETERS_CHANGED = 0x2A01, + LOG_PARAMETERS_CHANGED = 0x2A02, + RESERVATIONS_PREEMPTED = 0x2A03, + RESERVATIONS_RELEASED = 0x2A04, + REGISTRATIONS_PREEMPTED = 0x2A05, + ASYMMETRIC_ACCESS_STATE_CHANGED = 0x2A06, + IMPLICIT_ASYMMETRIC_ACCESS_STATE_TRANSITION_FAILED = 0x2A07, + PRIORITY_CHANGED = 0x2A08, + CAPACITY_DATA_HAS_CHANGED = 0x2A09, + ERROR_HISTORY_I_T_NEXUS_CLEARED = 0x2A0A, + ERROR_HISTORY_SNAPSHOT_RELEASED = 0x2A0B, + ERROR_RECOVERY_ATTRIBUTES_HAVE_CHANGED = 0x2A0C, + DATA_ENCRYPTION_CAPABILITIES_CHANGED = 0x2A0D, + TIMESTAMP_CHANGED = 0x2A10, + DATA_ENCRYPTION_PARAMS_CHANGED_BY_ANOTHER_I_T_NEXUS = 0x2A11, + DATA_ENCRYPTION_PARAMS_CHANGED_BY_VENDOR_SPECIFIC_EVENT = 0x2A12, + DATA_ENCRYPTION_KEY_INSTANCE_COUNTER_HAS_CHANGED = 0x2A13, + SA_CREATION_CAPABILITIES_DATA_HAS_CHANGED = 0x2A14, + MEDIUM_REMOVAL_PREVENTION_PREEMPTED = 0x2A15, + ZONE_RESET_WRITE_POINTER_RECOMMENDED = 0x2A16, + + SCSI_ASC(COPY_CANNOT_EXECUTE_SINCE_HOST_CANNOT_DISCONNECT, 0x2B), + + SCSI_ASC(COMMAND_SEQUENCE_ERROR, 0x2C), + TOO_MANY_WINDOWS_SPECIFIED = 0x2C01, + INVALID_COMBINATION_OF_WINDOWS_SPECIFIED = 0x2C02, + CURRENT_PROGRAM_AREA_IS_NOT_EMPTY = 0x2C03, + CURRENT_PROGRAM_AREA_IS_EMPTY = 0x2C04, + ILLEGAL_POWER_CONDITION_REQUEST = 0x2C05, + PERSISTENT_PREVENT_CONFLICT = 0x2C06, + PREVIOUS_BUSY_STATUS = 0x2C07, + PREVIOUS_TASK_SET_FULL_STATUS = 0x2C08, + PREVIOUS_RESERVATION_CONFLICT_STATUS = 0x2C09, + PARTITION_OR_COLLECTION_CONTAINS_USER_OBJECTS = 0x2C0A, + NOT_RESERVED = 0x2C0B, + ORWRITE_GENERATION_DOES_NOT_MATCH = 0x2C0C, + RESET_WRITE_POINTER_NOT_ALLOWED = 0x2C0D, + ZONE_IS_OFFLINE = 0x2C0E, + STREAM_NOT_OPEN = 0x2C0F, + UNWRITTEN_DATA_IN_ZONE = 0x2C10, + DESCRIPTOR_FORMAT_SENSE_DATA_REQUIRED = 0x2C11, + ZONE_IS_INACTIVE = 0x2C12, + WELL_KNOWN_LU_ACCESS_REQUIRED = 0x2C13, + + SCSI_ASC(OVERWRITE_ERROR_ON_UPDATE_IN_PLACE, 0x2D), + + SCSI_ASC(INSUFFICIENT_TIME_FOR_OPERATION, 0x2E), + COMMAND_TIMEOUT_BEFORE_PROCESSING = 0x2E01, + COMMAND_TIMEOUT_DURING_PROCESSING = 0x2E02, + COMMAND_TIMEOUT_DURING_PROCESSING_DUE_TO_ERROR_RECOVERY = 0x2E03, + + SCSI_ASC(COMMANDS_CLEARED_BY_ANOTHER_INITIATOR, 0x2F), + COMMANDS_CLEARED_BY_POWER_LOSS_NOTIFICATION = 0x2F01, + COMMANDS_CLEARED_BY_DEVICE_SERVER = 0x2F02, + SOME_COMMANDS_CLEARED_BY_QUEUING_LAYER_EVENT = 0x2F03, + + SCSI_ASC(INCOMPATIBLE_MEDIUM_INSTALLED, 0x30), + CANNOT_READ_MEDIUM_UNKNOWN_FORMAT = 0x3001, + CANNOT_READ_MEDIUM_INCOMPATIBLE_FORMAT = 0x3002, + CLEANING_CARTRIDGE_INSTALLED = 0x3003, + CANNOT_WRITE_MEDIUM_UNKNOWN_FORMAT = 0x3004, + CANNOT_WRITE_MEDIUM_INCOMPATIBLE_FORMAT = 0x3005, + CANNOT_FORMAT_MEDIUM_INCOMPATIBLE_MEDIUM = 0x3006, + CLEANING_FAILURE = 0x3007, + CANNOT_WRITE_APPLICATION_CODE_MISMATCH = 0x3008, + CURRENT_SESSION_NOT_FIXATED_FOR_APPEND = 0x3009, + CLEANING_REQUEST_REJECTED = 0x300A, + WORM_MEDIUM_OVERWRITE_ATTEMPTED = 0x300C, + WORM_MEDIUM_INTEGRITY_CHECK = 0x300D, + MEDIUM_NOT_FORMATTED = 0x3010, + INCOMPATIBLE_VOLUME_TYPE = 0x3011, + INCOMPATIBLE_VOLUME_QUALIFIER = 0x3012, + CLEANING_VOLUME_EXPIRED = 0x3013, + + SCSI_ASC(MEDIUM_FORMAT_CORRUPTED, 0x31), + FORMAT_COMMAND_FAILED = 0x3101, + ZONED_FORMATTING_FAILED_DUE_TO_SPARE_LINKING = 0x3102, + SANITIZE_COMMAND_FAILED = 0x3103, + DEPOPULATION_FAILED = 0x3104, + DEPOPULATION_RESTORATION_FAILED = 0x3105, + + SCSI_ASC(NO_DEFECT_SPARE_LOCATION_AVAILABLE, 0x32), + DEFECT_LIST_UPDATE_FAILURE = 0x3201, + + SCSI_ASC(TAPE_LENGTH_ERROR, 0x33), + + SCSI_ASC(ENCLOSURE_FAILURE, 0x34), + + SCSI_ASC(ENCLOSURE_SERVICES_FAILURE, 0x35), + UNSUPPORTED_ENCLOSURE_FUNCTION = 0x3501, + ENCLOSURE_SERVICES_UNAVAILABLE = 0x3502, + ENCLOSURE_SERVICES_TRANSFER_FAILURE = 0x3503, + ENCLOSURE_SERVICES_TRANSFER_REFUSED = 0x3504, + ENCLOSURE_SERVICES_CHECKSUM_ERROR = 0x3505, + + SCSI_ASC(RIBBON_INK_OR_TONER_FAILURE, 0x36), + + SCSI_ASC(ROUNDED_PARAMETER, 0x37), + + SCSI_ASC(EVENT_STATUS_NOTIFICATION, 0x38), + ESN_POWER_MANAGEMENT_CLASS_EVENT = 0x3802, + ESN_MEDIA_CLASS_EVENT = 0x3804, + ESN_DEVICE_BUSY_CLASS_EVENT = 0x3806, + THIN_PROVISIONING_SOFT_THRESHOLD_REACHED = 0x3807, + DEPOPULATION_INTERRUPTED = 0x3808, + DEPOPULATION_RESTORATION_INTERRUPTED = 0x3809, + + SCSI_ASC(SAVING_PARAMETERS_NOT_SUPPORTED, 0x39), + + SCSI_ASC(MEDIUM_NOT_PRESENT, 0x3A), + MEDIUM_NOT_PRESENT_TRAY_CLOSED = 0x3A01, + MEDIUM_NOT_PRESENT_TRAY_OPEN = 0x3A02, + MEDIUM_NOT_PRESENT_LOADABLE = 0x3A03, + MEDIUM_NOT_PRESENT_MEDIUM_AUXILIARY_MEMORY_ACCESSIBLE = 0x3A04, + + SCSI_ASC(SEQUENTIAL_POSITIONING_ERROR, 0x3B), + TAPE_POSITION_ERROR_AT_BEGINNING_OF_MEDIUM = 0x3B01, + TAPE_POSITION_ERROR_AT_END_OF_MEDIUM = 0x3B02, + TAPE_OR_ELECTRONIC_VERTICAL_FORMS_UNIT_NOT_READY = 0x3B03, + SLEW_FAILURE = 0x3B04, + PAPER_JAM = 0x3B05, + FAILED_TO_SENSE_TOP_OF_FORM = 0x3B06, + FAILED_TO_SENSE_BOTTOM_OF_FORM = 0x3B07, + REPOSITION_ERROR = 0x3B08, + READ_PAST_END_OF_MEDIUM = 0x3B09, + READ_PAST_BEGINNING_OF_MEDIUM = 0x3B0A, + POSITION_PAST_END_OF_MEDIUM = 0x3B0B, + POSITION_PAST_BEGINNING_OF_MEDIUM = 0x3B0C, + MEDIUM_DESTINATION_ELEMENT_FULL = 0x3B0D, + MEDIUM_SOURCE_ELEMENT_EMPTY = 0x3B0E, + END_OF_MEDIUM_REACHED = 0x3B0F, + MEDIUM_MAGAZINE_NOT_ACCESSIBLE = 0x3B11, + MEDIUM_MAGAZINE_REMOVED = 0x3B12, + MEDIUM_MAGAZINE_INSERTED = 0x3B13, + MEDIUM_MAGAZINE_LOCKED = 0x3B14, + MEDIUM_MAGAZINE_UNLOCKED = 0x3B15, + MECHANICAL_POSITIONING_OR_CHANGER_ERROR = 0x3B16, + READ_PAST_END_OF_USER_OBJECT = 0x3B17, + ELEMENT_DISABLED = 0x3B18, + ELEMENT_ENABLED = 0x3B19, + DATA_TRANSFER_DEVICE_REMOVED = 0x3B1A, + DATA_TRANSFER_DEVICE_INSERTED = 0x3B1B, + TOO_MANY_LOGICAL_OBJECTS_ON_PARTITION_TO_SUPPORT_OP = 0x3B1C, + ELEMENT_STATIC_INFORMATION_CHANGED = 0x3B20, + + SCSI_ASC(INVALID_BITS_IN_IDENTIFY_MESSAGE, 0x3D), + + SCSI_ASC(LU_HAS_NOT_SELF_CONFIGURED_YET, 0x3E), + LU_FAILURE = 0x3E01, + TIMEOUT_ON_LOGICAL_UNIT = 0x3E02, + LU_FAILED_SELF_TEST = 0x3E03, + LU_UNABLE_TO_UPDATE_SELFTEST_LOG = 0x3E04, + + SCSI_ASC(TARGET_OPERATING_CONDITIONS_HAVE_CHANGED, 0x3F), + MICROCODE_HAS_BEEN_CHANGED = 0x3F01, + CHANGED_OPERATING_DEFINITION = 0x3F02, + INQUIRY_DATA_HAS_CHANGED = 0x3F03, + COMPONENT_DEVICE_ATTACHED = 0x3F04, + DEVICE_IDENTIFIER_CHANGED = 0x3F05, + REDUNDANCY_GROUP_CREATED_OR_MODIFIED = 0x3F06, + REDUNDANCY_GROUP_DELETED = 0x3F07, + SPARE_CREATED_OR_MODIFIED = 0x3F08, + SPARE_DELETED = 0x3F09, + VOLUME_SET_CREATED_OR_MODIFIED = 0x3F0A, + VOLUME_SET_DELETED = 0x3F0B, + VOLUME_SET_DEASSIGNED = 0x3F0C, + VOLUME_SET_REASSIGNED = 0x3F0D, + REPORTED_LUNS_DATA_HAS_CHANGED = 0x3F0E, + ECHO_BUFFER_OVERWRITTEN = 0x3F0F, + MEDIUM_LOADABLE = 0x3F10, + MEDIUM_AUXILIARY_MEMORY_ACCESSIBLE = 0x3F11, + iSCSI_IP_ADDRESS_ADDED = 0x3F12, + iSCSI_IP_ADDRESS_REMOVED = 0x3F13, + iSCSI_IP_ADDRESS_CHANGED = 0x3F14, + INSPECT_REFERRALS_SENSE_DESCRIPTORS = 0x3F15, + MICROCODE_HAS_BEEN_CHANGED_WITHOUT_RESET = 0x3F16, + ZONE_TRANSITION_TO_FULL = 0x3F17, + BIND_COMPLETED = 0x3F18, + BIND_REDIRECTED = 0x3F19, + SUBSIDIARY_BINDING_CHANGED = 0x3F1A, + + SCSI_ASC(RAM_FAILURE, 0x40), + /* DIAGNOSTIC_FAILURE_ON_COMPONENT_NN = 0x40NN */ + + SCSI_ASC(DATA_PATH_FAILURE, 0x41), + + SCSI_ASC(POWER_ON_OR_SELFTEST_FAILURE, 0x42), + + SCSI_ASC(MESSAGE_ERROR, 0x43), + + SCSI_ASC(INTERNAL_TARGET_FAILURE, 0x44), + PERSISTENT_RESERVATION_INFORMATION_LOST = 0x4401, + ATA_DEVICE_FAILED_SET_FEATURES = 0x4471, + + SCSI_ASC(SELECT_OR_RESELECT_FAILURE, 0x45), + + SCSI_ASC(UNSUCCESSFUL_SOFT_RESET, 0x46), + + SCSI_ASC(SCSI_PARITY_ERROR, 0x47), + DATA_PHASE_CRC_ERROR_DETECTED = 0x4701, + SCSI_PARITY_ERROR_DETECTED_DURING_ST_DATA_PHASE = 0x4702, + INFORMATION_UNIT_iuCRC_ERROR_DETECTED = 0x4703, + ASYNCHRONOUS_INFORMATION_PROTECTION_ERROR_DETECTED = 0x4704, + PROTOCOL_SERVICE_CRC_ERROR = 0x4705, + PHY_TEST_FUNCTION_IN_PROGRESS = 0x4706, + SOME_COMMANDS_CLEARED_BY_ISCSI_PROTOCOL_EVENT = 0x477F, + + SCSI_ASC(INITIATOR_DETECTED_ERROR_MESSAGE_RECEIVED, 0x48), + + SCSI_ASC(INVALID_MESSAGE_ERROR, 0x49), + + SCSI_ASC(COMMAND_PHASE_ERROR, 0x4A), + + SCSI_ASC(DATA_PHASE_ERROR, 0x4B), + INVALID_TARGET_PORT_TRANSFER_TAG_RECEIVED = 0x4B01, + TOO_MUCH_WRITE_DATA = 0x4B02, + ACK_NAK_TIMEOUT = 0x4B03, + NAK_RECEIVED = 0x4B04, + DATA_OFFSET_ERROR = 0x4B05, + INITIATOR_RESPONSE_TIMEOUT = 0x4B06, + CONNECTION_LOST = 0x4B07, + DATA_IN_BUFFER_OVERFLOW_BUFFER_SIZE = 0x4B08, + DATA_IN_BUFFER_OVERFLOW_BUFFER_DESCRIPTOR_AREA = 0x4B09, + DATA_IN_BUFFER_ERROR = 0x4B0A, + DATA_OUT_BUFFER_OVERFLOW_BUFFER_SIZE = 0x4B0B, + DATA_OUT_BUFFER_OVERFLOW_BUFFER_DESCRIPTOR_AREA = 0x4B0C, + DATA_OUT_BUFFER_ERROR = 0x4B0D, + PCIE_FABRIC_ERROR = 0x4B0E, + PCIE_COMPLETION_TIMEOUT = 0x4B0F, + PCIE_COMPLETER_ABORT = 0x4B10, + PCIE_POISONED_TLP_RECEIVED = 0x4B11, + PCIE_ECRC_CHECK_FAILED = 0x4B12, + PCIE_UNSUPPORTED_REQUEST = 0x4B13, + PCIE_ACS_VIOLATION = 0x4B14, + PCIE_TLP_PREFIX_BLOCKED = 0x4B15, + + SCSI_ASC(LU_FAILED_SELF_CONFIGURATION, 0x4C), + + SCSI_ASC(TAGGED_OVERLAPPED_COMMANDS, 0x4D), + + SCSI_ASC(OVERLAPPED_COMMANDS_ATTEMPTED, 0x4E), + + SCSI_ASC(WRITE_APPEND_ERROR, 0x50), + WRITE_APPEND_POSITION_ERROR = 0x5001, + POSITION_ERROR_RELATED_TO_TIMING = 0x5002, + + SCSI_ASC(ERASE_FAILURE, 0x51), + ERASE_FAILURE_INCOMPLETE_ERASE_OP_DETECTED = 0x5101, + + SCSI_ASC(CARTRIDGE_FAULT, 0x52), + + SCSI_ASC(MEDIA_LOAD_OR_EJECT_FAILED, 0x53), + UNLOAD_TAPE_FAILURE = 0x5301, + MEDIUM_REMOVAL_PREVENTED = 0x5302, + MEDIUM_REMOVAL_PREVENTED_BY_DATA_TRANSFER_ELEMENT = 0x5303, + MEDIUM_THREAD_OR_UNTHREAD_FAILURE = 0x5304, + VOLUME_IDENTIFIER_INVALID = 0x5305, + VOLUME_IDENTIFIER_MISSING = 0x5306, + DUPLICATE_VOLUME_IDENTIFIER = 0x5307, + ELEMENT_STATUS_UNKNOWN = 0x5308, + DATA_TRANSFER_DEVICE_ERR_LOAD_FAILED = 0x5309, + DATA_TRANSFER_DEVICE_ERR_UNLOAD_FAILED = 0x530A, + DATA_TRANSFER_DEVICE_ERR_UNLOAD_MISSING = 0x530B, + DATA_TRANSFER_DEVICE_ERR_EJECT_FAILED = 0x530C, + DATA_TRANSFER_DEVICE_ERR_LIBRARY_COMMUNICATION_FAILED = 0x530D, + + SCSI_ASC(SCSI_TO_HOST_SYSTEM_INTERFACE_FAILURE, 0x54), + + SCSI_ASC(SYSTEM_RESOURCE_FAILURE, 0x55), + SYSTEM_BUFFER_FULL = 0x5501, + INSUFFICIENT_RESERVATION_RESOURCES = 0x5502, + INSUFFICIENT_RESOURCES = 0x5503, + INSUFFICIENT_REGISTRATION_RESOURCES = 0x5504, + INSUFFICIENT_ACCESS_CONTROL_RESOURCES = 0x5505, + AUXILIARY_MEMORY_OUT_OF_SPACE = 0x5506, + QUOTA_ERROR = 0x5507, + MAXIMUM_NUMBER_OF_SUPPLEMENTAL_DECRYPTION_KEYS_EXCEEDED = 0x5508, + MEDIUM_AUXILIARY_MEMORY_NOT_ACCESSIBLE = 0x5509, + DATA_CURRENTLY_UNAVAILABLE = 0x550A, + INSUFFICIENT_POWER_FOR_OPERATION = 0x550B, + INSUFFICIENT_RESOURCES_TO_CREATE_ROD = 0x550C, + INSUFFICIENT_RESOURCES_TO_CREATE_ROD_TOKEN = 0x550D, + INSUFFICIENT_ZONE_RESOURCES = 0x550E, + INSUFFICIENT_ZONE_RESOURCES_TO_COMPLETE_WRITE = 0x550F, + MAXIMUM_NUMBER_OF_STREAMS_OPEN = 0x5510, + INSUFFICIENT_RESOURCES_TO_BIND = 0x5511, + + SCSI_ASC(UNABLE_TO_RECOVER_TABLE_OF_CONTENTS, 0x57), + + SCSI_ASC(GENERATION_DOES_NOT_EXIST, 0x58), + + SCSI_ASC(UPDATED_BLOCK_READ, 0x59), + + SCSI_ASC(OPERATOR_REQUEST_OR_STATE_CHANGE_INPUT, 0x5A), + OPERATOR_MEDIUM_REMOVAL_REQUEST = 0x5A01, + OPERATOR_SELECTED_WRITE_PROTECT = 0x5A02, + OPERATOR_SELECTED_WRITE_PERMIT = 0x5A03, + + SCSI_ASC(LOG_EXCEPTION, 0x5B), + THRESHOLD_CONDITION_MET = 0x5B01, + LOG_COUNTER_AT_MAXIMUM = 0x5B02, + LOG_LIST_CODES_EXHAUSTED = 0x5B03, + + SCSI_ASC(RPL_STATUS_CHANGE, 0x5C), + SPINDLES_SYNCHRONIZED = 0x5C01, + SPINDLES_NOT_SYNCHRONIZED = 0x5C02, + + SCSI_ASC(FAILURE_PREDICTION_THRESHOLD_EXCEEDED, 0x5D), + MEDIA_FAILURE_PREDICTION_THRESHOLD_EXCEEDED = 0x5D01, + LU_FAILURE_PREDICTION_THRESHOLD_EXCEEDED = 0x5D02, + SPARE_AREA_EXHAUSTION_PREDICTION_THRESHOLD_EXCEEDED = 0x5D03, + HW_IMPENDING_FAILURE_GENERAL_HARD_DRIVE_FAILURE = 0x5D10, + HW_IMPENDING_FAILURE_DRIVE_ERROR_RATE_TOO_HIGH = 0x5D11, + HW_IMPENDING_FAILURE_DATA_ERROR_RATE_TOO_HIGH = 0x5D12, + HW_IMPENDING_FAILURE_SEEK_ERROR_RATE_TOO_HIGH = 0x5D13, + HW_IMPENDING_FAILURE_TOO_MANY_BLOCK_REASSIGNS = 0x5D14, + HW_IMPENDING_FAILURE_ACCESS_TIMES_TOO_HIGH = 0x5D15, + HW_IMPENDING_FAILURE_START_UNIT_TIMES_TOO_HIGH = 0x5D16, + HW_IMPENDING_FAILURE_CHANNEL_PARAMETRICS = 0x5D17, + HW_IMPENDING_FAILURE_CONTROLLER_DETECTED = 0x5D18, + HW_IMPENDING_FAILURE_THROUGHPUT_PERFORMANCE = 0x5D19, + HW_IMPENDING_FAILURE_SEEK_TIME_PERFORMANCE = 0x5D1A, + HW_IMPENDING_FAILURE_SPINUP_RETRY_COUNT = 0x5D1B, + HW_IMPENDING_FAILURE_DRIVE_CALIBRATION_RETRY_COUNT = 0x5D1C, + HW_IMPENDING_FAILURE_POWER_LOSS_PROTECTION_CIRCUIT = 0x5D1D, + CONTROLLER_IMPENDING_FAILURE_GENERAL_HARD_DRIVE_FAILURE = 0x5D20, + CONTROLLER_IMPENDING_FAILURE_DRIVE_ERROR_RATE_TOO_HIGH = 0x5D21, + CONTROLLER_IMPENDING_FAILURE_DATA_ERROR_RATE_TOO_HIGH = 0x5D22, + CONTROLLER_IMPENDING_FAILURE_SEEK_ERROR_RATE_TOO_HIGH = 0x5D23, + CONTROLLER_IMPENDING_FAILURE_TOO_MANY_BLOCK_REASSIGNS = 0x5D24, + CONTROLLER_IMPENDING_FAILURE_ACCESS_TIMES_TOO_HIGH = 0x5D25, + CONTROLLER_IMPENDING_FAILURE_START_UNIT_TIMES_TOO_HIGH = 0x5D26, + CONTROLLER_IMPENDING_FAILURE_CHANNEL_PARAMETRICS = 0x5D27, + CONTROLLER_IMPENDING_FAILURE_CONTROLLER_DETECTED = 0x5D28, + CONTROLLER_IMPENDING_FAILURE_THROUGHPUT_PERFORMANCE = 0x5D29, + CONTROLLER_IMPENDING_FAILURE_SEEK_TIME_PERFORMANCE = 0x5D2A, + CONTROLLER_IMPENDING_FAILURE_SPINUP_RETRY_COUNT = 0x5D2B, + CONTROLLER_IMPENDING_FAILURE_DRIVE_CALIBRATION_RETRY_COUNT = 0x5D2C, + DATA_CHANNEL_IMPENDING_FAILURE_GENERAL_HARD_DRIVE_FAILURE = 0x5D30, + DATA_CHANNEL_IMPENDING_FAILURE_DRIVE_ERROR_RATE_TOO_HIGH = 0x5D31, + DATA_CHANNEL_IMPENDING_FAILURE_DATA_ERROR_RATE_TOO_HIGH = 0x5D32, + DATA_CHANNEL_IMPENDING_FAILURE_SEEK_ERROR_RATE_TOO_HIGH = 0x5D33, + DATA_CHANNEL_IMPENDING_FAILURE_TOO_MANY_BLOCK_REASSIGNS = 0x5D34, + DATA_CHANNEL_IMPENDING_FAILURE_ACCESS_TIMES_TOO_HIGH = 0x5D35, + DATA_CHANNEL_IMPENDING_FAILURE_START_UNIT_TIMES_TOO_HIGH = 0x5D36, + DATA_CHANNEL_IMPENDING_FAILURE_CHANNEL_PARAMETRICS = 0x5D37, + DATA_CHANNEL_IMPENDING_FAILURE_CONTROLLER_DETECTED = 0x5D38, + DATA_CHANNEL_IMPENDING_FAILURE_THROUGHPUT_PERFORMANCE = 0x5D39, + DATA_CHANNEL_IMPENDING_FAILURE_SEEK_TIME_PERFORMANCE = 0x5D3A, + DATA_CHANNEL_IMPENDING_FAILURE_SPINUP_RETRY_COUNT = 0x5D3B, + DATA_CHANNEL_IMPENDING_FAILURE_DRIVE_CALIBRATION_RETRY_COUNT = 0x5D3C, + SERVO_IMPENDING_FAILURE_GENERAL_HARD_DRIVE_FAILURE = 0x5D40, + SERVO_IMPENDING_FAILURE_DRIVE_ERROR_RATE_TOO_HIGH = 0x5D41, + SERVO_IMPENDING_FAILURE_DATA_ERROR_RATE_TOO_HIGH = 0x5D42, + SERVO_IMPENDING_FAILURE_SEEK_ERROR_RATE_TOO_HIGH = 0x5D43, + SERVO_IMPENDING_FAILURE_TOO_MANY_BLOCK_REASSIGNS = 0x5D44, + SERVO_IMPENDING_FAILURE_ACCESS_TIMES_TOO_HIGH = 0x5D45, + SERVO_IMPENDING_FAILURE_START_UNIT_TIMES_TOO_HIGH = 0x5D46, + SERVO_IMPENDING_FAILURE_CHANNEL_PARAMETRICS = 0x5D47, + SERVO_IMPENDING_FAILURE_CONTROLLER_DETECTED = 0x5D48, + SERVO_IMPENDING_FAILURE_THROUGHPUT_PERFORMANCE = 0x5D49, + SERVO_IMPENDING_FAILURE_SEEK_TIME_PERFORMANCE = 0x5D4A, + SERVO_IMPENDING_FAILURE_SPINUP_RETRY_COUNT = 0x5D4B, + SERVO_IMPENDING_FAILURE_DRIVE_CALIBRATION_RETRY_COUNT = 0x5D4C, + SPINDLE_IMPENDING_FAILURE_GENERAL_HARD_DRIVE_FAILURE = 0x5D50, + SPINDLE_IMPENDING_FAILURE_DRIVE_ERROR_RATE_TOO_HIGH = 0x5D51, + SPINDLE_IMPENDING_FAILURE_DATA_ERROR_RATE_TOO_HIGH = 0x5D52, + SPINDLE_IMPENDING_FAILURE_SEEK_ERROR_RATE_TOO_HIGH = 0x5D53, + SPINDLE_IMPENDING_FAILURE_TOO_MANY_BLOCK_REASSIGNS = 0x5D54, + SPINDLE_IMPENDING_FAILURE_ACCESS_TIMES_TOO_HIGH = 0x5D55, + SPINDLE_IMPENDING_FAILURE_START_UNIT_TIMES_TOO_HIGH = 0x5D56, + SPINDLE_IMPENDING_FAILURE_CHANNEL_PARAMETRICS = 0x5D57, + SPINDLE_IMPENDING_FAILURE_CONTROLLER_DETECTED = 0x5D58, + SPINDLE_IMPENDING_FAILURE_THROUGHPUT_PERFORMANCE = 0x5D59, + SPINDLE_IMPENDING_FAILURE_SEEK_TIME_PERFORMANCE = 0x5D5A, + SPINDLE_IMPENDING_FAILURE_SPINUP_RETRY_COUNT = 0x5D5B, + SPINDLE_IMPENDING_FAILURE_DRIVE_CALIBRATION_RETRY_COUNT = 0x5D5C, + FW_IMPENDING_FAILURE_GENERAL_HARD_DRIVE_FAILURE = 0x5D60, + FW_IMPENDING_FAILURE_DRIVE_ERROR_RATE_TOO_HIGH = 0x5D61, + FW_IMPENDING_FAILURE_DATA_ERROR_RATE_TOO_HIGH = 0x5D62, + FW_IMPENDING_FAILURE_SEEK_ERROR_RATE_TOO_HIGH = 0x5D63, + FW_IMPENDING_FAILURE_TOO_MANY_BLOCK_REASSIGNS = 0x5D64, + FW_IMPENDING_FAILURE_ACCESS_TIMES_TOO_HIGH = 0x5D65, + FW_IMPENDING_FAILURE_START_UNIT_TIMES_TOO_HIGH = 0x5D66, + FW_IMPENDING_FAILURE_CHANNEL_PARAMETRICS = 0x5D67, + FW_IMPENDING_FAILURE_CONTROLLER_DETECTED = 0x5D68, + FW_IMPENDING_FAILURE_THROUGHPUT_PERFORMANCE = 0x5D69, + FW_IMPENDING_FAILURE_SEEK_TIME_PERFORMANCE = 0x5D6A, + FW_IMPENDING_FAILURE_SPINUP_RETRY_COUNT = 0x5D6B, + FW_IMPENDING_FAILURE_DRIVE_CALIBRATION_RETRY_COUNT = 0x5D6C, + MEDIA_IMPENDING_FAILURE_ENDURANCE_LIMIT_MET = 0x5D73, + FAILURE_PREDICTION_THRESHOLD_EXCEEDED_FALSE = 0x5DFF, + + SCSI_ASC(LOW_POWER_CONDITION_ON, 0x5E), + IDLE_CONDITION_ACTIVATED_BY_TIMER = 0x5E01, + STANDBY_CONDITION_ACTIVATED_BY_TIMER = 0x5E02, + IDLE_CONDITION_ACTIVATED_BY_COMMAND = 0x5E03, + STANDBY_CONDITION_ACTIVATED_BY_COMMAND = 0x5E04, + IDLE_B_CONDITION_ACTIVATED_BY_TIMER = 0x5E05, + IDLE_B_CONDITION_ACTIVATED_BY_COMMAND = 0x5E06, + IDLE_C_CONDITION_ACTIVATED_BY_TIMER = 0x5E07, + IDLE_C_CONDITION_ACTIVATED_BY_COMMAND = 0x5E08, + STANDBY_Y_CONDITION_ACTIVATED_BY_TIMER = 0x5E09, + STANDBY_Y_CONDITION_ACTIVATED_BY_COMMAND = 0x5E0A, + POWER_STATE_CHANGE_TO_ACTIVE = 0x5E41, + POWER_STATE_CHANGE_TO_IDLE = 0x5E42, + POWER_STATE_CHANGE_TO_STANDBY = 0x5E43, + POWER_STATE_CHANGE_TO_SLEEP = 0x5E45, + POWER_STATE_CHANGE_TO_DEVICE_CONTROL = 0x5E47, + + SCSI_ASC(LAMP_FAILURE, 0x60), + + SCSI_ASC(VIDEO_ACQUISITION_ERROR, 0x61), + UNABLE_TO_ACQUIRE_VIDEO = 0x6101, + OUT_OF_FOCUS = 0x6102, + + SCSI_ASC(SCAN_HEAD_POSITIONING_ERROR, 0x62), + + SCSI_ASC(END_OF_USER_AREA_ENCOUNTERED_ON_THIS_TRACK, 0x63), + PACKET_DOES_NOT_FIT_IN_AVAILABLE_SPACE = 0x6301, + + SCSI_ASC(ILLEGAL_MODE_FOR_THIS_TRACK, 0x64), + INVALID_PACKET_SIZE = 0x6401, + + SCSI_ASC(VOLTAGE_FAULT, 0x65), + + SCSI_ASC(AUTOMATIC_DOCUMENT_FEEDER_COVER_UP, 0x66), + AUTOMATIC_DOCUMENT_FEEDER_LIFT_UP = 0x6601, + DOCUMENT_JAM_IN_AUTOMATIC_DOCUMENT_FEEDER = 0x6602, + DOCUMENT_MISS_FEED_AUTOMATIC_IN_DOCUMENT_FEEDER = 0x6603, + + SCSI_ASC(CONFIG_FAILURE, 0x67), + CONFIG_OF_INCAPABLE_LOGICAL_UNITS_FAILED = 0x6701, + ADD_LU_FAILED = 0x6702, + MODIFICATION_OF_LU_FAILED = 0x6703, + EXCHANGE_OF_LU_FAILED = 0x6704, + REMOVE_OF_LU_FAILED = 0x6705, + ATTACHMENT_OF_LU_FAILED = 0x6706, + CREATION_OF_LU_FAILED = 0x6707, + ASSIGN_FAILURE_OCCURRED = 0x6708, + MULTIPLY_ASSIGNED_LOGICAL_UNIT = 0x6709, + SET_TARGET_PORT_GROUPS_COMMAND_FAILED = 0x670A, + ATA_DEVICE_FEATURE_NOT_ENABLED = 0x670B, + COMMAND_REJECTED = 0x670C, + EXPLICIT_BIND_NOT_ALLOWED = 0x670D, + FEATURE_NOT_ENABLED = 0x670E, + + SCSI_ASC(LU_NOT_CONFIGURED, 0x68), + SUBSIDIARY_LU_NOT_CONFIGURED = 0x6801, + + SCSI_ASC(DATA_LOSS_ON_LOGICAL_UNIT, 0x69), + MULTIPLE_LU_FAILURES = 0x6901, + PARITY_DATA_MISMATCH = 0x6902, + + SCSI_ASC(INFORMATIONAL_REFER_TO_LOG, 0x6A), + + SCSI_ASC(STATE_CHANGE_HAS_OCCURRED, 0x6B), + REDUNDANCY_LEVEL_GOT_BETTER = 0x6B01, + REDUNDANCY_LEVEL_GOT_WORSE = 0x6B02, + + SCSI_ASC(REBUILD_FAILURE_OCCURRED, 0x6C), + + SCSI_ASC(RECALCULATE_FAILURE_OCCURRED, 0x6D), + + SCSI_ASC(COMMAND_TO_LU_FAILED, 0x6E), + + SCSI_ASC(COPY_PROTECTION_KEY_EXCHANGE_FAILURE_AUTHENTICATION_FAILURE, 0x6F), + COPY_PROTECTION_KEY_EXCHANGE_FAILURE_KEY_NOT_PRESENT = 0x6F01, + COPY_PROTECTION_KEY_EXCHANGE_FAILURE_KEY_NOT_ESTABLISHED = 0x6F02, + READ_OF_SCRAMBLED_SECTOR_WITHOUT_AUTHENTICATION = 0x6F03, + MEDIA_REGION_CODE_IS_MISMATCHED_TO_LU_REGION = 0x6F04, + DRIVE_REGION_MUST_BE_PERMANENT_REGION_RESET_COUNT_ERROR = 0x6F05, + INSUFFICIENT_BLOCK_COUNT_FOR_BINDING_NONCE_RECORDING = 0x6F06, + CONFLICT_IN_BINDING_NONCE_RECORDING = 0x6F07, + INSUFFICIENT_PERMISSION = 0x6F08, + INVALID_DRIVE_HOST_PAIRING_SERVER = 0x6F09, + DRIVE_HOST_PAIRING_SUSPENDED = 0x6F0A, + + SCSI_ASC(DECOMPRESSION_EXCEPTION_SHORT_ALGORITHM_ID, 0x70), + + SCSI_ASC(DECOMPRESSION_EXCEPTION_LONG_ALGORITHM_ID, 0x71), + + SCSI_ASC(SESSION_FIXATION_ERROR, 0x72), + SESSION_FIXATION_ERROR_WRITING_LEAD_IN = 0x7201, + SESSION_FIXATION_ERROR_WRITING_LEAD_OUT = 0x7202, + SESSION_FIXATION_ERROR_INCOMPLETE_TRACK_IN_SESSION = 0x7203, + EMPTY_OR_PARTIALLY_WRITTEN_RESERVED_TRACK = 0x7204, + NO_MORE_TRACK_RESERVATIONS_ALLOWED = 0x7205, + RMZ_EXTENSION_IS_NOT_ALLOWED = 0x7206, + NO_MORE_TEST_ZONE_EXTENSIONS_ARE_ALLOWED = 0x7207, + + SCSI_ASC(CD_CONTROL_ERROR, 0x73), + POWER_CALIBRATION_AREA_ALMOST_FULL = 0x7301, + POWER_CALIBRATION_AREA_IS_FULL = 0x7302, + POWER_CALIBRATION_AREA_ERROR = 0x7303, + PROGRAM_MEMORY_AREA_UPDATE_FAILURE = 0x7304, + PROGRAM_MEMORY_AREA_IS_FULL = 0x7305, + RMA_PMA_IS_ALMOST_FULL = 0x7306, + CURRENT_POWER_CALIBRATION_AREA_ALMOST_FULL = 0x7310, + CURRENT_POWER_CALIBRATION_AREA_IS_FULL = 0x7311, + RDZ_IS_FULL = 0x7317, + + SCSI_ASC(SECURITY_ERROR, 0x74), + UNABLE_TO_DECRYPT_DATA = 0x7401, + UNENCRYPTED_DATA_ENCOUNTERED_WHILE_DECRYPTING = 0x7402, + INCORRECT_DATA_ENCRYPTION_KEY = 0x7403, + CRYPTOGRAPHIC_INTEGRITY_VALIDATION_FAILED = 0x7404, + ERROR_DECRYPTING_DATA = 0x7405, + UNKNOWN_SIGNATURE_VERIFICATION_KEY = 0x7406, + ENCRYPTION_PARAMS_NOT_USEABLE = 0x7407, + DIGITAL_SIGNATURE_VALIDATION_FAILURE = 0x7408, + ENCRYPTION_MODE_MISMATCH_ON_READ = 0x7409, + ENCRYPTED_BLOCK_NOT_RAW_READ_ENABLED = 0x740A, + INCORRECT_ENCRYPTION_PARAMS = 0x740B, + UNABLE_TO_DECRYPT_PARAMETER_LIST = 0x740C, + ENCRYPTION_ALGORITHM_DISABLED = 0x740D, + SA_CREATION_PARAMETER_VALUE_INVALID = 0x7410, + SA_CREATION_PARAMETER_VALUE_REJECTED = 0x7411, + INVALID_SA_USAGE = 0x7412, + DATA_ENCRYPTION_CONFIG_PREVENTED = 0x7421, + SA_CREATION_PARAMETER_NOT_SUPPORTED = 0x7430, + AUTHENTICATION_FAILED = 0x7440, + EXTERNAL_DATA_ENCRYPTION_KEY_MANAGER_ACCESS_ERROR = 0x7461, + EXTERNAL_DATA_ENCRYPTION_KEY_MANAGER_ERROR = 0x7462, + EXTERNAL_DATA_ENCRYPTION_KEY_NOT_FOUND = 0x7463, + EXTERNAL_DATA_ENCRYPTION_REQUEST_NOT_AUTHORIZED = 0x7464, + EXTERNAL_DATA_ENCRYPTION_CONTROL_TIMEOUT = 0x746E, + EXTERNAL_DATA_ENCRYPTION_CONTROL_ERROR = 0x746F, + LU_ACCESS_NOT_AUTHORIZED = 0x7471, + SECURITY_CONFLICT_IN_TRANSLATED_DEVICE = 0x7479, +}; + +#undef SCSI_ASC_DEF +#undef SCSI_ASC + +/* + * Use this to build non-standard sense codes. + * Note: this is defined as a macro instead of an inline function so that it can + * be used to define SCSI failures array variables (see struct scsi_failure). + */ +#define scsi_sense_code(asc, ascq) \ + ((((asc) & 0xff) << 8) | ((ascq) & 0xff)) + +static inline u8 scsi_sense_code_asc(u16 code) +{ + return (code >> 8) & 0xff; +} + +static inline u8 scsi_sense_code_ascq(u16 code) +{ + return code & 0xff; +} + +#endif /* _SCSI_SENSE_H_ */ diff --git a/include/trace/events/scsi.h b/include/trace/events/scsi.h index c36c72ab7f2b..e8328df587c3 100644 --- a/include/trace/events/scsi.h +++ b/include/trace/events/scsi.h @@ -303,8 +303,8 @@ DECLARE_EVENT_CLASS(scsi_cmd_done_timeout_template, if (cmd->sense_buffer && SCSI_SENSE_VALID(cmd) && scsi_command_normalize_sense(cmd, &sshdr)) { __entry->sense_key = sshdr.sense_key; - __entry->asc = sshdr.asc; - __entry->ascq = sshdr.ascq; + __entry->asc = scsi_sense_asc(&sshdr); + __entry->ascq = scsi_sense_ascq(&sshdr); } else { __entry->sense_key = 0; __entry->asc = 0; diff --git a/include/ufs/ufs.h b/include/ufs/ufs.h index afbb32654fab..b0207e694911 100644 --- a/include/ufs/ufs.h +++ b/include/ufs/ufs.h @@ -662,6 +662,7 @@ struct ufs_dev_info { u8 rtt_cap; /* bDeviceRTTCap */ bool hid_sup; + bool timestamp_sup; /* Unique device ID string (manufacturer+model+serial+version+date) */ char *device_id; diff --git a/include/ufs/ufshcd.h b/include/ufs/ufshcd.h index dfd302f2dc7c..be62165b785e 100644 --- a/include/ufs/ufshcd.h +++ b/include/ufs/ufshcd.h @@ -1132,6 +1132,14 @@ struct ufs_hba { /* Auto-Hibernate Idle Timer register value */ u32 ahit; + /* Serializes AHIT register access between sysfs and the host driver */ + struct mutex ahit_mutex; + /* + * Nesting count of host-driver paths that have AHIT forced off. + * Non-zero blocks sysfs AHIT writes; AHIT is reprogrammed only when + * the last disabler drops it back to zero. Guarded by ahit_mutex. + */ + int ahit_disable_depth; unsigned long outstanding_tasks; spinlock_t outstanding_lock;