162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-or-later 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * libata-scsi.c - helper library for ATA 462306a36Sopenharmony_ci * 562306a36Sopenharmony_ci * Copyright 2003-2004 Red Hat, Inc. All rights reserved. 662306a36Sopenharmony_ci * Copyright 2003-2004 Jeff Garzik 762306a36Sopenharmony_ci * 862306a36Sopenharmony_ci * libata documentation is available via 'make {ps|pdf}docs', 962306a36Sopenharmony_ci * as Documentation/driver-api/libata.rst 1062306a36Sopenharmony_ci * 1162306a36Sopenharmony_ci * Hardware documentation available from 1262306a36Sopenharmony_ci * - http://www.t10.org/ 1362306a36Sopenharmony_ci * - http://www.t13.org/ 1462306a36Sopenharmony_ci */ 1562306a36Sopenharmony_ci 1662306a36Sopenharmony_ci#include <linux/compat.h> 1762306a36Sopenharmony_ci#include <linux/slab.h> 1862306a36Sopenharmony_ci#include <linux/kernel.h> 1962306a36Sopenharmony_ci#include <linux/blkdev.h> 2062306a36Sopenharmony_ci#include <linux/spinlock.h> 2162306a36Sopenharmony_ci#include <linux/export.h> 2262306a36Sopenharmony_ci#include <scsi/scsi.h> 2362306a36Sopenharmony_ci#include <scsi/scsi_host.h> 2462306a36Sopenharmony_ci#include <scsi/scsi_cmnd.h> 2562306a36Sopenharmony_ci#include <scsi/scsi_eh.h> 2662306a36Sopenharmony_ci#include <scsi/scsi_device.h> 2762306a36Sopenharmony_ci#include <scsi/scsi_tcq.h> 2862306a36Sopenharmony_ci#include <scsi/scsi_transport.h> 2962306a36Sopenharmony_ci#include <linux/libata.h> 3062306a36Sopenharmony_ci#include <linux/hdreg.h> 3162306a36Sopenharmony_ci#include <linux/uaccess.h> 3262306a36Sopenharmony_ci#include <linux/suspend.h> 3362306a36Sopenharmony_ci#include <asm/unaligned.h> 3462306a36Sopenharmony_ci#include <linux/ioprio.h> 3562306a36Sopenharmony_ci#include <linux/of.h> 3662306a36Sopenharmony_ci 3762306a36Sopenharmony_ci#include "libata.h" 3862306a36Sopenharmony_ci#include "libata-transport.h" 3962306a36Sopenharmony_ci 4062306a36Sopenharmony_ci#define ATA_SCSI_RBUF_SIZE 2048 4162306a36Sopenharmony_ci 4262306a36Sopenharmony_cistatic DEFINE_SPINLOCK(ata_scsi_rbuf_lock); 4362306a36Sopenharmony_cistatic u8 ata_scsi_rbuf[ATA_SCSI_RBUF_SIZE]; 4462306a36Sopenharmony_ci 4562306a36Sopenharmony_citypedef unsigned int (*ata_xlat_func_t)(struct ata_queued_cmd *qc); 4662306a36Sopenharmony_ci 4762306a36Sopenharmony_cistatic struct ata_device *__ata_scsi_find_dev(struct ata_port *ap, 4862306a36Sopenharmony_ci const struct scsi_device *scsidev); 4962306a36Sopenharmony_ci 5062306a36Sopenharmony_ci#define RW_RECOVERY_MPAGE 0x1 5162306a36Sopenharmony_ci#define RW_RECOVERY_MPAGE_LEN 12 5262306a36Sopenharmony_ci#define CACHE_MPAGE 0x8 5362306a36Sopenharmony_ci#define CACHE_MPAGE_LEN 20 5462306a36Sopenharmony_ci#define CONTROL_MPAGE 0xa 5562306a36Sopenharmony_ci#define CONTROL_MPAGE_LEN 12 5662306a36Sopenharmony_ci#define ALL_MPAGES 0x3f 5762306a36Sopenharmony_ci#define ALL_SUB_MPAGES 0xff 5862306a36Sopenharmony_ci#define CDL_T2A_SUB_MPAGE 0x07 5962306a36Sopenharmony_ci#define CDL_T2B_SUB_MPAGE 0x08 6062306a36Sopenharmony_ci#define CDL_T2_SUB_MPAGE_LEN 232 6162306a36Sopenharmony_ci#define ATA_FEATURE_SUB_MPAGE 0xf2 6262306a36Sopenharmony_ci#define ATA_FEATURE_SUB_MPAGE_LEN 16 6362306a36Sopenharmony_ci 6462306a36Sopenharmony_cistatic const u8 def_rw_recovery_mpage[RW_RECOVERY_MPAGE_LEN] = { 6562306a36Sopenharmony_ci RW_RECOVERY_MPAGE, 6662306a36Sopenharmony_ci RW_RECOVERY_MPAGE_LEN - 2, 6762306a36Sopenharmony_ci (1 << 7), /* AWRE */ 6862306a36Sopenharmony_ci 0, /* read retry count */ 6962306a36Sopenharmony_ci 0, 0, 0, 0, 7062306a36Sopenharmony_ci 0, /* write retry count */ 7162306a36Sopenharmony_ci 0, 0, 0 7262306a36Sopenharmony_ci}; 7362306a36Sopenharmony_ci 7462306a36Sopenharmony_cistatic const u8 def_cache_mpage[CACHE_MPAGE_LEN] = { 7562306a36Sopenharmony_ci CACHE_MPAGE, 7662306a36Sopenharmony_ci CACHE_MPAGE_LEN - 2, 7762306a36Sopenharmony_ci 0, /* contains WCE, needs to be 0 for logic */ 7862306a36Sopenharmony_ci 0, 0, 0, 0, 0, 0, 0, 0, 0, 7962306a36Sopenharmony_ci 0, /* contains DRA, needs to be 0 for logic */ 8062306a36Sopenharmony_ci 0, 0, 0, 0, 0, 0, 0 8162306a36Sopenharmony_ci}; 8262306a36Sopenharmony_ci 8362306a36Sopenharmony_cistatic const u8 def_control_mpage[CONTROL_MPAGE_LEN] = { 8462306a36Sopenharmony_ci CONTROL_MPAGE, 8562306a36Sopenharmony_ci CONTROL_MPAGE_LEN - 2, 8662306a36Sopenharmony_ci 2, /* DSENSE=0, GLTSD=1 */ 8762306a36Sopenharmony_ci 0, /* [QAM+QERR may be 1, see 05-359r1] */ 8862306a36Sopenharmony_ci 0, 0, 0, 0, 0xff, 0xff, 8962306a36Sopenharmony_ci 0, 30 /* extended self test time, see 05-359r1 */ 9062306a36Sopenharmony_ci}; 9162306a36Sopenharmony_ci 9262306a36Sopenharmony_cistatic ssize_t ata_scsi_park_show(struct device *device, 9362306a36Sopenharmony_ci struct device_attribute *attr, char *buf) 9462306a36Sopenharmony_ci{ 9562306a36Sopenharmony_ci struct scsi_device *sdev = to_scsi_device(device); 9662306a36Sopenharmony_ci struct ata_port *ap; 9762306a36Sopenharmony_ci struct ata_link *link; 9862306a36Sopenharmony_ci struct ata_device *dev; 9962306a36Sopenharmony_ci unsigned long now; 10062306a36Sopenharmony_ci unsigned int msecs; 10162306a36Sopenharmony_ci int rc = 0; 10262306a36Sopenharmony_ci 10362306a36Sopenharmony_ci ap = ata_shost_to_port(sdev->host); 10462306a36Sopenharmony_ci 10562306a36Sopenharmony_ci spin_lock_irq(ap->lock); 10662306a36Sopenharmony_ci dev = ata_scsi_find_dev(ap, sdev); 10762306a36Sopenharmony_ci if (!dev) { 10862306a36Sopenharmony_ci rc = -ENODEV; 10962306a36Sopenharmony_ci goto unlock; 11062306a36Sopenharmony_ci } 11162306a36Sopenharmony_ci if (dev->flags & ATA_DFLAG_NO_UNLOAD) { 11262306a36Sopenharmony_ci rc = -EOPNOTSUPP; 11362306a36Sopenharmony_ci goto unlock; 11462306a36Sopenharmony_ci } 11562306a36Sopenharmony_ci 11662306a36Sopenharmony_ci link = dev->link; 11762306a36Sopenharmony_ci now = jiffies; 11862306a36Sopenharmony_ci if (ap->pflags & ATA_PFLAG_EH_IN_PROGRESS && 11962306a36Sopenharmony_ci link->eh_context.unloaded_mask & (1 << dev->devno) && 12062306a36Sopenharmony_ci time_after(dev->unpark_deadline, now)) 12162306a36Sopenharmony_ci msecs = jiffies_to_msecs(dev->unpark_deadline - now); 12262306a36Sopenharmony_ci else 12362306a36Sopenharmony_ci msecs = 0; 12462306a36Sopenharmony_ci 12562306a36Sopenharmony_ciunlock: 12662306a36Sopenharmony_ci spin_unlock_irq(ap->lock); 12762306a36Sopenharmony_ci 12862306a36Sopenharmony_ci return rc ? rc : sysfs_emit(buf, "%u\n", msecs); 12962306a36Sopenharmony_ci} 13062306a36Sopenharmony_ci 13162306a36Sopenharmony_cistatic ssize_t ata_scsi_park_store(struct device *device, 13262306a36Sopenharmony_ci struct device_attribute *attr, 13362306a36Sopenharmony_ci const char *buf, size_t len) 13462306a36Sopenharmony_ci{ 13562306a36Sopenharmony_ci struct scsi_device *sdev = to_scsi_device(device); 13662306a36Sopenharmony_ci struct ata_port *ap; 13762306a36Sopenharmony_ci struct ata_device *dev; 13862306a36Sopenharmony_ci int input; 13962306a36Sopenharmony_ci unsigned long flags; 14062306a36Sopenharmony_ci int rc; 14162306a36Sopenharmony_ci 14262306a36Sopenharmony_ci rc = kstrtoint(buf, 10, &input); 14362306a36Sopenharmony_ci if (rc) 14462306a36Sopenharmony_ci return rc; 14562306a36Sopenharmony_ci if (input < -2) 14662306a36Sopenharmony_ci return -EINVAL; 14762306a36Sopenharmony_ci if (input > ATA_TMOUT_MAX_PARK) { 14862306a36Sopenharmony_ci rc = -EOVERFLOW; 14962306a36Sopenharmony_ci input = ATA_TMOUT_MAX_PARK; 15062306a36Sopenharmony_ci } 15162306a36Sopenharmony_ci 15262306a36Sopenharmony_ci ap = ata_shost_to_port(sdev->host); 15362306a36Sopenharmony_ci 15462306a36Sopenharmony_ci spin_lock_irqsave(ap->lock, flags); 15562306a36Sopenharmony_ci dev = ata_scsi_find_dev(ap, sdev); 15662306a36Sopenharmony_ci if (unlikely(!dev)) { 15762306a36Sopenharmony_ci rc = -ENODEV; 15862306a36Sopenharmony_ci goto unlock; 15962306a36Sopenharmony_ci } 16062306a36Sopenharmony_ci if (dev->class != ATA_DEV_ATA && 16162306a36Sopenharmony_ci dev->class != ATA_DEV_ZAC) { 16262306a36Sopenharmony_ci rc = -EOPNOTSUPP; 16362306a36Sopenharmony_ci goto unlock; 16462306a36Sopenharmony_ci } 16562306a36Sopenharmony_ci 16662306a36Sopenharmony_ci if (input >= 0) { 16762306a36Sopenharmony_ci if (dev->flags & ATA_DFLAG_NO_UNLOAD) { 16862306a36Sopenharmony_ci rc = -EOPNOTSUPP; 16962306a36Sopenharmony_ci goto unlock; 17062306a36Sopenharmony_ci } 17162306a36Sopenharmony_ci 17262306a36Sopenharmony_ci dev->unpark_deadline = ata_deadline(jiffies, input); 17362306a36Sopenharmony_ci dev->link->eh_info.dev_action[dev->devno] |= ATA_EH_PARK; 17462306a36Sopenharmony_ci ata_port_schedule_eh(ap); 17562306a36Sopenharmony_ci complete(&ap->park_req_pending); 17662306a36Sopenharmony_ci } else { 17762306a36Sopenharmony_ci switch (input) { 17862306a36Sopenharmony_ci case -1: 17962306a36Sopenharmony_ci dev->flags &= ~ATA_DFLAG_NO_UNLOAD; 18062306a36Sopenharmony_ci break; 18162306a36Sopenharmony_ci case -2: 18262306a36Sopenharmony_ci dev->flags |= ATA_DFLAG_NO_UNLOAD; 18362306a36Sopenharmony_ci break; 18462306a36Sopenharmony_ci } 18562306a36Sopenharmony_ci } 18662306a36Sopenharmony_ciunlock: 18762306a36Sopenharmony_ci spin_unlock_irqrestore(ap->lock, flags); 18862306a36Sopenharmony_ci 18962306a36Sopenharmony_ci return rc ? rc : len; 19062306a36Sopenharmony_ci} 19162306a36Sopenharmony_ciDEVICE_ATTR(unload_heads, S_IRUGO | S_IWUSR, 19262306a36Sopenharmony_ci ata_scsi_park_show, ata_scsi_park_store); 19362306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(dev_attr_unload_heads); 19462306a36Sopenharmony_ci 19562306a36Sopenharmony_cibool ata_scsi_sense_is_valid(u8 sk, u8 asc, u8 ascq) 19662306a36Sopenharmony_ci{ 19762306a36Sopenharmony_ci /* 19862306a36Sopenharmony_ci * If sk == NO_SENSE, and asc + ascq == NO ADDITIONAL SENSE INFORMATION, 19962306a36Sopenharmony_ci * then there is no sense data to add. 20062306a36Sopenharmony_ci */ 20162306a36Sopenharmony_ci if (sk == 0 && asc == 0 && ascq == 0) 20262306a36Sopenharmony_ci return false; 20362306a36Sopenharmony_ci 20462306a36Sopenharmony_ci /* If sk > COMPLETED, sense data is bogus. */ 20562306a36Sopenharmony_ci if (sk > COMPLETED) 20662306a36Sopenharmony_ci return false; 20762306a36Sopenharmony_ci 20862306a36Sopenharmony_ci return true; 20962306a36Sopenharmony_ci} 21062306a36Sopenharmony_ci 21162306a36Sopenharmony_civoid ata_scsi_set_sense(struct ata_device *dev, struct scsi_cmnd *cmd, 21262306a36Sopenharmony_ci u8 sk, u8 asc, u8 ascq) 21362306a36Sopenharmony_ci{ 21462306a36Sopenharmony_ci bool d_sense = (dev->flags & ATA_DFLAG_D_SENSE); 21562306a36Sopenharmony_ci 21662306a36Sopenharmony_ci scsi_build_sense(cmd, d_sense, sk, asc, ascq); 21762306a36Sopenharmony_ci} 21862306a36Sopenharmony_ci 21962306a36Sopenharmony_civoid ata_scsi_set_sense_information(struct ata_device *dev, 22062306a36Sopenharmony_ci struct scsi_cmnd *cmd, 22162306a36Sopenharmony_ci const struct ata_taskfile *tf) 22262306a36Sopenharmony_ci{ 22362306a36Sopenharmony_ci u64 information; 22462306a36Sopenharmony_ci 22562306a36Sopenharmony_ci information = ata_tf_read_block(tf, dev); 22662306a36Sopenharmony_ci if (information == U64_MAX) 22762306a36Sopenharmony_ci return; 22862306a36Sopenharmony_ci 22962306a36Sopenharmony_ci scsi_set_sense_information(cmd->sense_buffer, 23062306a36Sopenharmony_ci SCSI_SENSE_BUFFERSIZE, information); 23162306a36Sopenharmony_ci} 23262306a36Sopenharmony_ci 23362306a36Sopenharmony_cistatic void ata_scsi_set_invalid_field(struct ata_device *dev, 23462306a36Sopenharmony_ci struct scsi_cmnd *cmd, u16 field, u8 bit) 23562306a36Sopenharmony_ci{ 23662306a36Sopenharmony_ci ata_scsi_set_sense(dev, cmd, ILLEGAL_REQUEST, 0x24, 0x0); 23762306a36Sopenharmony_ci /* "Invalid field in CDB" */ 23862306a36Sopenharmony_ci scsi_set_sense_field_pointer(cmd->sense_buffer, SCSI_SENSE_BUFFERSIZE, 23962306a36Sopenharmony_ci field, bit, 1); 24062306a36Sopenharmony_ci} 24162306a36Sopenharmony_ci 24262306a36Sopenharmony_cistatic void ata_scsi_set_invalid_parameter(struct ata_device *dev, 24362306a36Sopenharmony_ci struct scsi_cmnd *cmd, u16 field) 24462306a36Sopenharmony_ci{ 24562306a36Sopenharmony_ci /* "Invalid field in parameter list" */ 24662306a36Sopenharmony_ci ata_scsi_set_sense(dev, cmd, ILLEGAL_REQUEST, 0x26, 0x0); 24762306a36Sopenharmony_ci scsi_set_sense_field_pointer(cmd->sense_buffer, SCSI_SENSE_BUFFERSIZE, 24862306a36Sopenharmony_ci field, 0xff, 0); 24962306a36Sopenharmony_ci} 25062306a36Sopenharmony_ci 25162306a36Sopenharmony_cistatic struct attribute *ata_common_sdev_attrs[] = { 25262306a36Sopenharmony_ci &dev_attr_unload_heads.attr, 25362306a36Sopenharmony_ci NULL 25462306a36Sopenharmony_ci}; 25562306a36Sopenharmony_ci 25662306a36Sopenharmony_cistatic const struct attribute_group ata_common_sdev_attr_group = { 25762306a36Sopenharmony_ci .attrs = ata_common_sdev_attrs 25862306a36Sopenharmony_ci}; 25962306a36Sopenharmony_ci 26062306a36Sopenharmony_ciconst struct attribute_group *ata_common_sdev_groups[] = { 26162306a36Sopenharmony_ci &ata_common_sdev_attr_group, 26262306a36Sopenharmony_ci NULL 26362306a36Sopenharmony_ci}; 26462306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(ata_common_sdev_groups); 26562306a36Sopenharmony_ci 26662306a36Sopenharmony_ci/** 26762306a36Sopenharmony_ci * ata_std_bios_param - generic bios head/sector/cylinder calculator used by sd. 26862306a36Sopenharmony_ci * @sdev: SCSI device for which BIOS geometry is to be determined 26962306a36Sopenharmony_ci * @bdev: block device associated with @sdev 27062306a36Sopenharmony_ci * @capacity: capacity of SCSI device 27162306a36Sopenharmony_ci * @geom: location to which geometry will be output 27262306a36Sopenharmony_ci * 27362306a36Sopenharmony_ci * Generic bios head/sector/cylinder calculator 27462306a36Sopenharmony_ci * used by sd. Most BIOSes nowadays expect a XXX/255/16 (CHS) 27562306a36Sopenharmony_ci * mapping. Some situations may arise where the disk is not 27662306a36Sopenharmony_ci * bootable if this is not used. 27762306a36Sopenharmony_ci * 27862306a36Sopenharmony_ci * LOCKING: 27962306a36Sopenharmony_ci * Defined by the SCSI layer. We don't really care. 28062306a36Sopenharmony_ci * 28162306a36Sopenharmony_ci * RETURNS: 28262306a36Sopenharmony_ci * Zero. 28362306a36Sopenharmony_ci */ 28462306a36Sopenharmony_ciint ata_std_bios_param(struct scsi_device *sdev, struct block_device *bdev, 28562306a36Sopenharmony_ci sector_t capacity, int geom[]) 28662306a36Sopenharmony_ci{ 28762306a36Sopenharmony_ci geom[0] = 255; 28862306a36Sopenharmony_ci geom[1] = 63; 28962306a36Sopenharmony_ci sector_div(capacity, 255*63); 29062306a36Sopenharmony_ci geom[2] = capacity; 29162306a36Sopenharmony_ci 29262306a36Sopenharmony_ci return 0; 29362306a36Sopenharmony_ci} 29462306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(ata_std_bios_param); 29562306a36Sopenharmony_ci 29662306a36Sopenharmony_ci/** 29762306a36Sopenharmony_ci * ata_scsi_unlock_native_capacity - unlock native capacity 29862306a36Sopenharmony_ci * @sdev: SCSI device to adjust device capacity for 29962306a36Sopenharmony_ci * 30062306a36Sopenharmony_ci * This function is called if a partition on @sdev extends beyond 30162306a36Sopenharmony_ci * the end of the device. It requests EH to unlock HPA. 30262306a36Sopenharmony_ci * 30362306a36Sopenharmony_ci * LOCKING: 30462306a36Sopenharmony_ci * Defined by the SCSI layer. Might sleep. 30562306a36Sopenharmony_ci */ 30662306a36Sopenharmony_civoid ata_scsi_unlock_native_capacity(struct scsi_device *sdev) 30762306a36Sopenharmony_ci{ 30862306a36Sopenharmony_ci struct ata_port *ap = ata_shost_to_port(sdev->host); 30962306a36Sopenharmony_ci struct ata_device *dev; 31062306a36Sopenharmony_ci unsigned long flags; 31162306a36Sopenharmony_ci 31262306a36Sopenharmony_ci spin_lock_irqsave(ap->lock, flags); 31362306a36Sopenharmony_ci 31462306a36Sopenharmony_ci dev = ata_scsi_find_dev(ap, sdev); 31562306a36Sopenharmony_ci if (dev && dev->n_sectors < dev->n_native_sectors) { 31662306a36Sopenharmony_ci dev->flags |= ATA_DFLAG_UNLOCK_HPA; 31762306a36Sopenharmony_ci dev->link->eh_info.action |= ATA_EH_RESET; 31862306a36Sopenharmony_ci ata_port_schedule_eh(ap); 31962306a36Sopenharmony_ci } 32062306a36Sopenharmony_ci 32162306a36Sopenharmony_ci spin_unlock_irqrestore(ap->lock, flags); 32262306a36Sopenharmony_ci ata_port_wait_eh(ap); 32362306a36Sopenharmony_ci} 32462306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(ata_scsi_unlock_native_capacity); 32562306a36Sopenharmony_ci 32662306a36Sopenharmony_ci/** 32762306a36Sopenharmony_ci * ata_get_identity - Handler for HDIO_GET_IDENTITY ioctl 32862306a36Sopenharmony_ci * @ap: target port 32962306a36Sopenharmony_ci * @sdev: SCSI device to get identify data for 33062306a36Sopenharmony_ci * @arg: User buffer area for identify data 33162306a36Sopenharmony_ci * 33262306a36Sopenharmony_ci * LOCKING: 33362306a36Sopenharmony_ci * Defined by the SCSI layer. We don't really care. 33462306a36Sopenharmony_ci * 33562306a36Sopenharmony_ci * RETURNS: 33662306a36Sopenharmony_ci * Zero on success, negative errno on error. 33762306a36Sopenharmony_ci */ 33862306a36Sopenharmony_cistatic int ata_get_identity(struct ata_port *ap, struct scsi_device *sdev, 33962306a36Sopenharmony_ci void __user *arg) 34062306a36Sopenharmony_ci{ 34162306a36Sopenharmony_ci struct ata_device *dev = ata_scsi_find_dev(ap, sdev); 34262306a36Sopenharmony_ci u16 __user *dst = arg; 34362306a36Sopenharmony_ci char buf[40]; 34462306a36Sopenharmony_ci 34562306a36Sopenharmony_ci if (!dev) 34662306a36Sopenharmony_ci return -ENOMSG; 34762306a36Sopenharmony_ci 34862306a36Sopenharmony_ci if (copy_to_user(dst, dev->id, ATA_ID_WORDS * sizeof(u16))) 34962306a36Sopenharmony_ci return -EFAULT; 35062306a36Sopenharmony_ci 35162306a36Sopenharmony_ci ata_id_string(dev->id, buf, ATA_ID_PROD, ATA_ID_PROD_LEN); 35262306a36Sopenharmony_ci if (copy_to_user(dst + ATA_ID_PROD, buf, ATA_ID_PROD_LEN)) 35362306a36Sopenharmony_ci return -EFAULT; 35462306a36Sopenharmony_ci 35562306a36Sopenharmony_ci ata_id_string(dev->id, buf, ATA_ID_FW_REV, ATA_ID_FW_REV_LEN); 35662306a36Sopenharmony_ci if (copy_to_user(dst + ATA_ID_FW_REV, buf, ATA_ID_FW_REV_LEN)) 35762306a36Sopenharmony_ci return -EFAULT; 35862306a36Sopenharmony_ci 35962306a36Sopenharmony_ci ata_id_string(dev->id, buf, ATA_ID_SERNO, ATA_ID_SERNO_LEN); 36062306a36Sopenharmony_ci if (copy_to_user(dst + ATA_ID_SERNO, buf, ATA_ID_SERNO_LEN)) 36162306a36Sopenharmony_ci return -EFAULT; 36262306a36Sopenharmony_ci 36362306a36Sopenharmony_ci return 0; 36462306a36Sopenharmony_ci} 36562306a36Sopenharmony_ci 36662306a36Sopenharmony_ci/** 36762306a36Sopenharmony_ci * ata_cmd_ioctl - Handler for HDIO_DRIVE_CMD ioctl 36862306a36Sopenharmony_ci * @scsidev: Device to which we are issuing command 36962306a36Sopenharmony_ci * @arg: User provided data for issuing command 37062306a36Sopenharmony_ci * 37162306a36Sopenharmony_ci * LOCKING: 37262306a36Sopenharmony_ci * Defined by the SCSI layer. We don't really care. 37362306a36Sopenharmony_ci * 37462306a36Sopenharmony_ci * RETURNS: 37562306a36Sopenharmony_ci * Zero on success, negative errno on error. 37662306a36Sopenharmony_ci */ 37762306a36Sopenharmony_ciint ata_cmd_ioctl(struct scsi_device *scsidev, void __user *arg) 37862306a36Sopenharmony_ci{ 37962306a36Sopenharmony_ci int rc = 0; 38062306a36Sopenharmony_ci u8 sensebuf[SCSI_SENSE_BUFFERSIZE]; 38162306a36Sopenharmony_ci u8 scsi_cmd[MAX_COMMAND_SIZE]; 38262306a36Sopenharmony_ci u8 args[4], *argbuf = NULL; 38362306a36Sopenharmony_ci int argsize = 0; 38462306a36Sopenharmony_ci struct scsi_sense_hdr sshdr; 38562306a36Sopenharmony_ci const struct scsi_exec_args exec_args = { 38662306a36Sopenharmony_ci .sshdr = &sshdr, 38762306a36Sopenharmony_ci .sense = sensebuf, 38862306a36Sopenharmony_ci .sense_len = sizeof(sensebuf), 38962306a36Sopenharmony_ci }; 39062306a36Sopenharmony_ci int cmd_result; 39162306a36Sopenharmony_ci 39262306a36Sopenharmony_ci if (arg == NULL) 39362306a36Sopenharmony_ci return -EINVAL; 39462306a36Sopenharmony_ci 39562306a36Sopenharmony_ci if (copy_from_user(args, arg, sizeof(args))) 39662306a36Sopenharmony_ci return -EFAULT; 39762306a36Sopenharmony_ci 39862306a36Sopenharmony_ci memset(sensebuf, 0, sizeof(sensebuf)); 39962306a36Sopenharmony_ci memset(scsi_cmd, 0, sizeof(scsi_cmd)); 40062306a36Sopenharmony_ci 40162306a36Sopenharmony_ci if (args[3]) { 40262306a36Sopenharmony_ci argsize = ATA_SECT_SIZE * args[3]; 40362306a36Sopenharmony_ci argbuf = kmalloc(argsize, GFP_KERNEL); 40462306a36Sopenharmony_ci if (argbuf == NULL) { 40562306a36Sopenharmony_ci rc = -ENOMEM; 40662306a36Sopenharmony_ci goto error; 40762306a36Sopenharmony_ci } 40862306a36Sopenharmony_ci 40962306a36Sopenharmony_ci scsi_cmd[1] = (4 << 1); /* PIO Data-in */ 41062306a36Sopenharmony_ci scsi_cmd[2] = 0x0e; /* no off.line or cc, read from dev, 41162306a36Sopenharmony_ci block count in sector count field */ 41262306a36Sopenharmony_ci } else { 41362306a36Sopenharmony_ci scsi_cmd[1] = (3 << 1); /* Non-data */ 41462306a36Sopenharmony_ci scsi_cmd[2] = 0x20; /* cc but no off.line or data xfer */ 41562306a36Sopenharmony_ci } 41662306a36Sopenharmony_ci 41762306a36Sopenharmony_ci scsi_cmd[0] = ATA_16; 41862306a36Sopenharmony_ci 41962306a36Sopenharmony_ci scsi_cmd[4] = args[2]; 42062306a36Sopenharmony_ci if (args[0] == ATA_CMD_SMART) { /* hack -- ide driver does this too */ 42162306a36Sopenharmony_ci scsi_cmd[6] = args[3]; 42262306a36Sopenharmony_ci scsi_cmd[8] = args[1]; 42362306a36Sopenharmony_ci scsi_cmd[10] = ATA_SMART_LBAM_PASS; 42462306a36Sopenharmony_ci scsi_cmd[12] = ATA_SMART_LBAH_PASS; 42562306a36Sopenharmony_ci } else { 42662306a36Sopenharmony_ci scsi_cmd[6] = args[1]; 42762306a36Sopenharmony_ci } 42862306a36Sopenharmony_ci scsi_cmd[14] = args[0]; 42962306a36Sopenharmony_ci 43062306a36Sopenharmony_ci /* Good values for timeout and retries? Values below 43162306a36Sopenharmony_ci from scsi_ioctl_send_command() for default case... */ 43262306a36Sopenharmony_ci cmd_result = scsi_execute_cmd(scsidev, scsi_cmd, REQ_OP_DRV_IN, argbuf, 43362306a36Sopenharmony_ci argsize, 10 * HZ, 5, &exec_args); 43462306a36Sopenharmony_ci if (cmd_result < 0) { 43562306a36Sopenharmony_ci rc = cmd_result; 43662306a36Sopenharmony_ci goto error; 43762306a36Sopenharmony_ci } 43862306a36Sopenharmony_ci if (scsi_sense_valid(&sshdr)) {/* sense data available */ 43962306a36Sopenharmony_ci u8 *desc = sensebuf + 8; 44062306a36Sopenharmony_ci 44162306a36Sopenharmony_ci /* If we set cc then ATA pass-through will cause a 44262306a36Sopenharmony_ci * check condition even if no error. Filter that. */ 44362306a36Sopenharmony_ci if (scsi_status_is_check_condition(cmd_result)) { 44462306a36Sopenharmony_ci if (sshdr.sense_key == RECOVERED_ERROR && 44562306a36Sopenharmony_ci sshdr.asc == 0 && sshdr.ascq == 0x1d) 44662306a36Sopenharmony_ci cmd_result &= ~SAM_STAT_CHECK_CONDITION; 44762306a36Sopenharmony_ci } 44862306a36Sopenharmony_ci 44962306a36Sopenharmony_ci /* Send userspace a few ATA registers (same as drivers/ide) */ 45062306a36Sopenharmony_ci if (sensebuf[0] == 0x72 && /* format is "descriptor" */ 45162306a36Sopenharmony_ci desc[0] == 0x09) { /* code is "ATA Descriptor" */ 45262306a36Sopenharmony_ci args[0] = desc[13]; /* status */ 45362306a36Sopenharmony_ci args[1] = desc[3]; /* error */ 45462306a36Sopenharmony_ci args[2] = desc[5]; /* sector count (0:7) */ 45562306a36Sopenharmony_ci if (copy_to_user(arg, args, sizeof(args))) 45662306a36Sopenharmony_ci rc = -EFAULT; 45762306a36Sopenharmony_ci } 45862306a36Sopenharmony_ci } 45962306a36Sopenharmony_ci 46062306a36Sopenharmony_ci 46162306a36Sopenharmony_ci if (cmd_result) { 46262306a36Sopenharmony_ci rc = -EIO; 46362306a36Sopenharmony_ci goto error; 46462306a36Sopenharmony_ci } 46562306a36Sopenharmony_ci 46662306a36Sopenharmony_ci if ((argbuf) 46762306a36Sopenharmony_ci && copy_to_user(arg + sizeof(args), argbuf, argsize)) 46862306a36Sopenharmony_ci rc = -EFAULT; 46962306a36Sopenharmony_cierror: 47062306a36Sopenharmony_ci kfree(argbuf); 47162306a36Sopenharmony_ci return rc; 47262306a36Sopenharmony_ci} 47362306a36Sopenharmony_ci 47462306a36Sopenharmony_ci/** 47562306a36Sopenharmony_ci * ata_task_ioctl - Handler for HDIO_DRIVE_TASK ioctl 47662306a36Sopenharmony_ci * @scsidev: Device to which we are issuing command 47762306a36Sopenharmony_ci * @arg: User provided data for issuing command 47862306a36Sopenharmony_ci * 47962306a36Sopenharmony_ci * LOCKING: 48062306a36Sopenharmony_ci * Defined by the SCSI layer. We don't really care. 48162306a36Sopenharmony_ci * 48262306a36Sopenharmony_ci * RETURNS: 48362306a36Sopenharmony_ci * Zero on success, negative errno on error. 48462306a36Sopenharmony_ci */ 48562306a36Sopenharmony_ciint ata_task_ioctl(struct scsi_device *scsidev, void __user *arg) 48662306a36Sopenharmony_ci{ 48762306a36Sopenharmony_ci int rc = 0; 48862306a36Sopenharmony_ci u8 sensebuf[SCSI_SENSE_BUFFERSIZE]; 48962306a36Sopenharmony_ci u8 scsi_cmd[MAX_COMMAND_SIZE]; 49062306a36Sopenharmony_ci u8 args[7]; 49162306a36Sopenharmony_ci struct scsi_sense_hdr sshdr; 49262306a36Sopenharmony_ci int cmd_result; 49362306a36Sopenharmony_ci const struct scsi_exec_args exec_args = { 49462306a36Sopenharmony_ci .sshdr = &sshdr, 49562306a36Sopenharmony_ci .sense = sensebuf, 49662306a36Sopenharmony_ci .sense_len = sizeof(sensebuf), 49762306a36Sopenharmony_ci }; 49862306a36Sopenharmony_ci 49962306a36Sopenharmony_ci if (arg == NULL) 50062306a36Sopenharmony_ci return -EINVAL; 50162306a36Sopenharmony_ci 50262306a36Sopenharmony_ci if (copy_from_user(args, arg, sizeof(args))) 50362306a36Sopenharmony_ci return -EFAULT; 50462306a36Sopenharmony_ci 50562306a36Sopenharmony_ci memset(sensebuf, 0, sizeof(sensebuf)); 50662306a36Sopenharmony_ci memset(scsi_cmd, 0, sizeof(scsi_cmd)); 50762306a36Sopenharmony_ci scsi_cmd[0] = ATA_16; 50862306a36Sopenharmony_ci scsi_cmd[1] = (3 << 1); /* Non-data */ 50962306a36Sopenharmony_ci scsi_cmd[2] = 0x20; /* cc but no off.line or data xfer */ 51062306a36Sopenharmony_ci scsi_cmd[4] = args[1]; 51162306a36Sopenharmony_ci scsi_cmd[6] = args[2]; 51262306a36Sopenharmony_ci scsi_cmd[8] = args[3]; 51362306a36Sopenharmony_ci scsi_cmd[10] = args[4]; 51462306a36Sopenharmony_ci scsi_cmd[12] = args[5]; 51562306a36Sopenharmony_ci scsi_cmd[13] = args[6] & 0x4f; 51662306a36Sopenharmony_ci scsi_cmd[14] = args[0]; 51762306a36Sopenharmony_ci 51862306a36Sopenharmony_ci /* Good values for timeout and retries? Values below 51962306a36Sopenharmony_ci from scsi_ioctl_send_command() for default case... */ 52062306a36Sopenharmony_ci cmd_result = scsi_execute_cmd(scsidev, scsi_cmd, REQ_OP_DRV_IN, NULL, 52162306a36Sopenharmony_ci 0, 10 * HZ, 5, &exec_args); 52262306a36Sopenharmony_ci if (cmd_result < 0) { 52362306a36Sopenharmony_ci rc = cmd_result; 52462306a36Sopenharmony_ci goto error; 52562306a36Sopenharmony_ci } 52662306a36Sopenharmony_ci if (scsi_sense_valid(&sshdr)) {/* sense data available */ 52762306a36Sopenharmony_ci u8 *desc = sensebuf + 8; 52862306a36Sopenharmony_ci 52962306a36Sopenharmony_ci /* If we set cc then ATA pass-through will cause a 53062306a36Sopenharmony_ci * check condition even if no error. Filter that. */ 53162306a36Sopenharmony_ci if (cmd_result & SAM_STAT_CHECK_CONDITION) { 53262306a36Sopenharmony_ci if (sshdr.sense_key == RECOVERED_ERROR && 53362306a36Sopenharmony_ci sshdr.asc == 0 && sshdr.ascq == 0x1d) 53462306a36Sopenharmony_ci cmd_result &= ~SAM_STAT_CHECK_CONDITION; 53562306a36Sopenharmony_ci } 53662306a36Sopenharmony_ci 53762306a36Sopenharmony_ci /* Send userspace ATA registers */ 53862306a36Sopenharmony_ci if (sensebuf[0] == 0x72 && /* format is "descriptor" */ 53962306a36Sopenharmony_ci desc[0] == 0x09) {/* code is "ATA Descriptor" */ 54062306a36Sopenharmony_ci args[0] = desc[13]; /* status */ 54162306a36Sopenharmony_ci args[1] = desc[3]; /* error */ 54262306a36Sopenharmony_ci args[2] = desc[5]; /* sector count (0:7) */ 54362306a36Sopenharmony_ci args[3] = desc[7]; /* lbal */ 54462306a36Sopenharmony_ci args[4] = desc[9]; /* lbam */ 54562306a36Sopenharmony_ci args[5] = desc[11]; /* lbah */ 54662306a36Sopenharmony_ci args[6] = desc[12]; /* select */ 54762306a36Sopenharmony_ci if (copy_to_user(arg, args, sizeof(args))) 54862306a36Sopenharmony_ci rc = -EFAULT; 54962306a36Sopenharmony_ci } 55062306a36Sopenharmony_ci } 55162306a36Sopenharmony_ci 55262306a36Sopenharmony_ci if (cmd_result) { 55362306a36Sopenharmony_ci rc = -EIO; 55462306a36Sopenharmony_ci goto error; 55562306a36Sopenharmony_ci } 55662306a36Sopenharmony_ci 55762306a36Sopenharmony_ci error: 55862306a36Sopenharmony_ci return rc; 55962306a36Sopenharmony_ci} 56062306a36Sopenharmony_ci 56162306a36Sopenharmony_cistatic bool ata_ioc32(struct ata_port *ap) 56262306a36Sopenharmony_ci{ 56362306a36Sopenharmony_ci if (ap->flags & ATA_FLAG_PIO_DMA) 56462306a36Sopenharmony_ci return true; 56562306a36Sopenharmony_ci if (ap->pflags & ATA_PFLAG_PIO32) 56662306a36Sopenharmony_ci return true; 56762306a36Sopenharmony_ci return false; 56862306a36Sopenharmony_ci} 56962306a36Sopenharmony_ci 57062306a36Sopenharmony_ci/* 57162306a36Sopenharmony_ci * This handles both native and compat commands, so anything added 57262306a36Sopenharmony_ci * here must have a compatible argument, or check in_compat_syscall() 57362306a36Sopenharmony_ci */ 57462306a36Sopenharmony_ciint ata_sas_scsi_ioctl(struct ata_port *ap, struct scsi_device *scsidev, 57562306a36Sopenharmony_ci unsigned int cmd, void __user *arg) 57662306a36Sopenharmony_ci{ 57762306a36Sopenharmony_ci unsigned long val; 57862306a36Sopenharmony_ci int rc = -EINVAL; 57962306a36Sopenharmony_ci unsigned long flags; 58062306a36Sopenharmony_ci 58162306a36Sopenharmony_ci switch (cmd) { 58262306a36Sopenharmony_ci case HDIO_GET_32BIT: 58362306a36Sopenharmony_ci spin_lock_irqsave(ap->lock, flags); 58462306a36Sopenharmony_ci val = ata_ioc32(ap); 58562306a36Sopenharmony_ci spin_unlock_irqrestore(ap->lock, flags); 58662306a36Sopenharmony_ci#ifdef CONFIG_COMPAT 58762306a36Sopenharmony_ci if (in_compat_syscall()) 58862306a36Sopenharmony_ci return put_user(val, (compat_ulong_t __user *)arg); 58962306a36Sopenharmony_ci#endif 59062306a36Sopenharmony_ci return put_user(val, (unsigned long __user *)arg); 59162306a36Sopenharmony_ci 59262306a36Sopenharmony_ci case HDIO_SET_32BIT: 59362306a36Sopenharmony_ci val = (unsigned long) arg; 59462306a36Sopenharmony_ci rc = 0; 59562306a36Sopenharmony_ci spin_lock_irqsave(ap->lock, flags); 59662306a36Sopenharmony_ci if (ap->pflags & ATA_PFLAG_PIO32CHANGE) { 59762306a36Sopenharmony_ci if (val) 59862306a36Sopenharmony_ci ap->pflags |= ATA_PFLAG_PIO32; 59962306a36Sopenharmony_ci else 60062306a36Sopenharmony_ci ap->pflags &= ~ATA_PFLAG_PIO32; 60162306a36Sopenharmony_ci } else { 60262306a36Sopenharmony_ci if (val != ata_ioc32(ap)) 60362306a36Sopenharmony_ci rc = -EINVAL; 60462306a36Sopenharmony_ci } 60562306a36Sopenharmony_ci spin_unlock_irqrestore(ap->lock, flags); 60662306a36Sopenharmony_ci return rc; 60762306a36Sopenharmony_ci 60862306a36Sopenharmony_ci case HDIO_GET_IDENTITY: 60962306a36Sopenharmony_ci return ata_get_identity(ap, scsidev, arg); 61062306a36Sopenharmony_ci 61162306a36Sopenharmony_ci case HDIO_DRIVE_CMD: 61262306a36Sopenharmony_ci if (!capable(CAP_SYS_ADMIN) || !capable(CAP_SYS_RAWIO)) 61362306a36Sopenharmony_ci return -EACCES; 61462306a36Sopenharmony_ci return ata_cmd_ioctl(scsidev, arg); 61562306a36Sopenharmony_ci 61662306a36Sopenharmony_ci case HDIO_DRIVE_TASK: 61762306a36Sopenharmony_ci if (!capable(CAP_SYS_ADMIN) || !capable(CAP_SYS_RAWIO)) 61862306a36Sopenharmony_ci return -EACCES; 61962306a36Sopenharmony_ci return ata_task_ioctl(scsidev, arg); 62062306a36Sopenharmony_ci 62162306a36Sopenharmony_ci default: 62262306a36Sopenharmony_ci rc = -ENOTTY; 62362306a36Sopenharmony_ci break; 62462306a36Sopenharmony_ci } 62562306a36Sopenharmony_ci 62662306a36Sopenharmony_ci return rc; 62762306a36Sopenharmony_ci} 62862306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(ata_sas_scsi_ioctl); 62962306a36Sopenharmony_ci 63062306a36Sopenharmony_ciint ata_scsi_ioctl(struct scsi_device *scsidev, unsigned int cmd, 63162306a36Sopenharmony_ci void __user *arg) 63262306a36Sopenharmony_ci{ 63362306a36Sopenharmony_ci return ata_sas_scsi_ioctl(ata_shost_to_port(scsidev->host), 63462306a36Sopenharmony_ci scsidev, cmd, arg); 63562306a36Sopenharmony_ci} 63662306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(ata_scsi_ioctl); 63762306a36Sopenharmony_ci 63862306a36Sopenharmony_ci/** 63962306a36Sopenharmony_ci * ata_scsi_qc_new - acquire new ata_queued_cmd reference 64062306a36Sopenharmony_ci * @dev: ATA device to which the new command is attached 64162306a36Sopenharmony_ci * @cmd: SCSI command that originated this ATA command 64262306a36Sopenharmony_ci * 64362306a36Sopenharmony_ci * Obtain a reference to an unused ata_queued_cmd structure, 64462306a36Sopenharmony_ci * which is the basic libata structure representing a single 64562306a36Sopenharmony_ci * ATA command sent to the hardware. 64662306a36Sopenharmony_ci * 64762306a36Sopenharmony_ci * If a command was available, fill in the SCSI-specific 64862306a36Sopenharmony_ci * portions of the structure with information on the 64962306a36Sopenharmony_ci * current command. 65062306a36Sopenharmony_ci * 65162306a36Sopenharmony_ci * LOCKING: 65262306a36Sopenharmony_ci * spin_lock_irqsave(host lock) 65362306a36Sopenharmony_ci * 65462306a36Sopenharmony_ci * RETURNS: 65562306a36Sopenharmony_ci * Command allocated, or %NULL if none available. 65662306a36Sopenharmony_ci */ 65762306a36Sopenharmony_cistatic struct ata_queued_cmd *ata_scsi_qc_new(struct ata_device *dev, 65862306a36Sopenharmony_ci struct scsi_cmnd *cmd) 65962306a36Sopenharmony_ci{ 66062306a36Sopenharmony_ci struct ata_port *ap = dev->link->ap; 66162306a36Sopenharmony_ci struct ata_queued_cmd *qc; 66262306a36Sopenharmony_ci int tag; 66362306a36Sopenharmony_ci 66462306a36Sopenharmony_ci if (unlikely(ata_port_is_frozen(ap))) 66562306a36Sopenharmony_ci goto fail; 66662306a36Sopenharmony_ci 66762306a36Sopenharmony_ci if (ap->flags & ATA_FLAG_SAS_HOST) { 66862306a36Sopenharmony_ci /* 66962306a36Sopenharmony_ci * SAS hosts may queue > ATA_MAX_QUEUE commands so use 67062306a36Sopenharmony_ci * unique per-device budget token as a tag. 67162306a36Sopenharmony_ci */ 67262306a36Sopenharmony_ci if (WARN_ON_ONCE(cmd->budget_token >= ATA_MAX_QUEUE)) 67362306a36Sopenharmony_ci goto fail; 67462306a36Sopenharmony_ci tag = cmd->budget_token; 67562306a36Sopenharmony_ci } else { 67662306a36Sopenharmony_ci tag = scsi_cmd_to_rq(cmd)->tag; 67762306a36Sopenharmony_ci } 67862306a36Sopenharmony_ci 67962306a36Sopenharmony_ci qc = __ata_qc_from_tag(ap, tag); 68062306a36Sopenharmony_ci qc->tag = qc->hw_tag = tag; 68162306a36Sopenharmony_ci qc->ap = ap; 68262306a36Sopenharmony_ci qc->dev = dev; 68362306a36Sopenharmony_ci 68462306a36Sopenharmony_ci ata_qc_reinit(qc); 68562306a36Sopenharmony_ci 68662306a36Sopenharmony_ci qc->scsicmd = cmd; 68762306a36Sopenharmony_ci qc->scsidone = scsi_done; 68862306a36Sopenharmony_ci 68962306a36Sopenharmony_ci qc->sg = scsi_sglist(cmd); 69062306a36Sopenharmony_ci qc->n_elem = scsi_sg_count(cmd); 69162306a36Sopenharmony_ci 69262306a36Sopenharmony_ci if (scsi_cmd_to_rq(cmd)->rq_flags & RQF_QUIET) 69362306a36Sopenharmony_ci qc->flags |= ATA_QCFLAG_QUIET; 69462306a36Sopenharmony_ci 69562306a36Sopenharmony_ci return qc; 69662306a36Sopenharmony_ci 69762306a36Sopenharmony_cifail: 69862306a36Sopenharmony_ci set_host_byte(cmd, DID_OK); 69962306a36Sopenharmony_ci set_status_byte(cmd, SAM_STAT_TASK_SET_FULL); 70062306a36Sopenharmony_ci scsi_done(cmd); 70162306a36Sopenharmony_ci return NULL; 70262306a36Sopenharmony_ci} 70362306a36Sopenharmony_ci 70462306a36Sopenharmony_cistatic void ata_qc_set_pc_nbytes(struct ata_queued_cmd *qc) 70562306a36Sopenharmony_ci{ 70662306a36Sopenharmony_ci struct scsi_cmnd *scmd = qc->scsicmd; 70762306a36Sopenharmony_ci 70862306a36Sopenharmony_ci qc->extrabytes = scmd->extra_len; 70962306a36Sopenharmony_ci qc->nbytes = scsi_bufflen(scmd) + qc->extrabytes; 71062306a36Sopenharmony_ci} 71162306a36Sopenharmony_ci 71262306a36Sopenharmony_ci/** 71362306a36Sopenharmony_ci * ata_to_sense_error - convert ATA error to SCSI error 71462306a36Sopenharmony_ci * @id: ATA device number 71562306a36Sopenharmony_ci * @drv_stat: value contained in ATA status register 71662306a36Sopenharmony_ci * @drv_err: value contained in ATA error register 71762306a36Sopenharmony_ci * @sk: the sense key we'll fill out 71862306a36Sopenharmony_ci * @asc: the additional sense code we'll fill out 71962306a36Sopenharmony_ci * @ascq: the additional sense code qualifier we'll fill out 72062306a36Sopenharmony_ci * 72162306a36Sopenharmony_ci * Converts an ATA error into a SCSI error. Fill out pointers to 72262306a36Sopenharmony_ci * SK, ASC, and ASCQ bytes for later use in fixed or descriptor 72362306a36Sopenharmony_ci * format sense blocks. 72462306a36Sopenharmony_ci * 72562306a36Sopenharmony_ci * LOCKING: 72662306a36Sopenharmony_ci * spin_lock_irqsave(host lock) 72762306a36Sopenharmony_ci */ 72862306a36Sopenharmony_cistatic void ata_to_sense_error(unsigned id, u8 drv_stat, u8 drv_err, u8 *sk, 72962306a36Sopenharmony_ci u8 *asc, u8 *ascq) 73062306a36Sopenharmony_ci{ 73162306a36Sopenharmony_ci int i; 73262306a36Sopenharmony_ci 73362306a36Sopenharmony_ci /* Based on the 3ware driver translation table */ 73462306a36Sopenharmony_ci static const unsigned char sense_table[][4] = { 73562306a36Sopenharmony_ci /* BBD|ECC|ID|MAR */ 73662306a36Sopenharmony_ci {0xd1, ABORTED_COMMAND, 0x00, 0x00}, 73762306a36Sopenharmony_ci // Device busy Aborted command 73862306a36Sopenharmony_ci /* BBD|ECC|ID */ 73962306a36Sopenharmony_ci {0xd0, ABORTED_COMMAND, 0x00, 0x00}, 74062306a36Sopenharmony_ci // Device busy Aborted command 74162306a36Sopenharmony_ci /* ECC|MC|MARK */ 74262306a36Sopenharmony_ci {0x61, HARDWARE_ERROR, 0x00, 0x00}, 74362306a36Sopenharmony_ci // Device fault Hardware error 74462306a36Sopenharmony_ci /* ICRC|ABRT */ /* NB: ICRC & !ABRT is BBD */ 74562306a36Sopenharmony_ci {0x84, ABORTED_COMMAND, 0x47, 0x00}, 74662306a36Sopenharmony_ci // Data CRC error SCSI parity error 74762306a36Sopenharmony_ci /* MC|ID|ABRT|TRK0|MARK */ 74862306a36Sopenharmony_ci {0x37, NOT_READY, 0x04, 0x00}, 74962306a36Sopenharmony_ci // Unit offline Not ready 75062306a36Sopenharmony_ci /* MCR|MARK */ 75162306a36Sopenharmony_ci {0x09, NOT_READY, 0x04, 0x00}, 75262306a36Sopenharmony_ci // Unrecovered disk error Not ready 75362306a36Sopenharmony_ci /* Bad address mark */ 75462306a36Sopenharmony_ci {0x01, MEDIUM_ERROR, 0x13, 0x00}, 75562306a36Sopenharmony_ci // Address mark not found for data field 75662306a36Sopenharmony_ci /* TRK0 - Track 0 not found */ 75762306a36Sopenharmony_ci {0x02, HARDWARE_ERROR, 0x00, 0x00}, 75862306a36Sopenharmony_ci // Hardware error 75962306a36Sopenharmony_ci /* Abort: 0x04 is not translated here, see below */ 76062306a36Sopenharmony_ci /* Media change request */ 76162306a36Sopenharmony_ci {0x08, NOT_READY, 0x04, 0x00}, 76262306a36Sopenharmony_ci // FIXME: faking offline 76362306a36Sopenharmony_ci /* SRV/IDNF - ID not found */ 76462306a36Sopenharmony_ci {0x10, ILLEGAL_REQUEST, 0x21, 0x00}, 76562306a36Sopenharmony_ci // Logical address out of range 76662306a36Sopenharmony_ci /* MC - Media Changed */ 76762306a36Sopenharmony_ci {0x20, UNIT_ATTENTION, 0x28, 0x00}, 76862306a36Sopenharmony_ci // Not ready to ready change, medium may have changed 76962306a36Sopenharmony_ci /* ECC - Uncorrectable ECC error */ 77062306a36Sopenharmony_ci {0x40, MEDIUM_ERROR, 0x11, 0x04}, 77162306a36Sopenharmony_ci // Unrecovered read error 77262306a36Sopenharmony_ci /* BBD - block marked bad */ 77362306a36Sopenharmony_ci {0x80, MEDIUM_ERROR, 0x11, 0x04}, 77462306a36Sopenharmony_ci // Block marked bad Medium error, unrecovered read error 77562306a36Sopenharmony_ci {0xFF, 0xFF, 0xFF, 0xFF}, // END mark 77662306a36Sopenharmony_ci }; 77762306a36Sopenharmony_ci static const unsigned char stat_table[][4] = { 77862306a36Sopenharmony_ci /* Must be first because BUSY means no other bits valid */ 77962306a36Sopenharmony_ci {0x80, ABORTED_COMMAND, 0x47, 0x00}, 78062306a36Sopenharmony_ci // Busy, fake parity for now 78162306a36Sopenharmony_ci {0x40, ILLEGAL_REQUEST, 0x21, 0x04}, 78262306a36Sopenharmony_ci // Device ready, unaligned write command 78362306a36Sopenharmony_ci {0x20, HARDWARE_ERROR, 0x44, 0x00}, 78462306a36Sopenharmony_ci // Device fault, internal target failure 78562306a36Sopenharmony_ci {0x08, ABORTED_COMMAND, 0x47, 0x00}, 78662306a36Sopenharmony_ci // Timed out in xfer, fake parity for now 78762306a36Sopenharmony_ci {0x04, RECOVERED_ERROR, 0x11, 0x00}, 78862306a36Sopenharmony_ci // Recovered ECC error Medium error, recovered 78962306a36Sopenharmony_ci {0xFF, 0xFF, 0xFF, 0xFF}, // END mark 79062306a36Sopenharmony_ci }; 79162306a36Sopenharmony_ci 79262306a36Sopenharmony_ci /* 79362306a36Sopenharmony_ci * Is this an error we can process/parse 79462306a36Sopenharmony_ci */ 79562306a36Sopenharmony_ci if (drv_stat & ATA_BUSY) { 79662306a36Sopenharmony_ci drv_err = 0; /* Ignore the err bits, they're invalid */ 79762306a36Sopenharmony_ci } 79862306a36Sopenharmony_ci 79962306a36Sopenharmony_ci if (drv_err) { 80062306a36Sopenharmony_ci /* Look for drv_err */ 80162306a36Sopenharmony_ci for (i = 0; sense_table[i][0] != 0xFF; i++) { 80262306a36Sopenharmony_ci /* Look for best matches first */ 80362306a36Sopenharmony_ci if ((sense_table[i][0] & drv_err) == 80462306a36Sopenharmony_ci sense_table[i][0]) { 80562306a36Sopenharmony_ci *sk = sense_table[i][1]; 80662306a36Sopenharmony_ci *asc = sense_table[i][2]; 80762306a36Sopenharmony_ci *ascq = sense_table[i][3]; 80862306a36Sopenharmony_ci return; 80962306a36Sopenharmony_ci } 81062306a36Sopenharmony_ci } 81162306a36Sopenharmony_ci } 81262306a36Sopenharmony_ci 81362306a36Sopenharmony_ci /* 81462306a36Sopenharmony_ci * Fall back to interpreting status bits. Note that if the drv_err 81562306a36Sopenharmony_ci * has only the ABRT bit set, we decode drv_stat. ABRT by itself 81662306a36Sopenharmony_ci * is not descriptive enough. 81762306a36Sopenharmony_ci */ 81862306a36Sopenharmony_ci for (i = 0; stat_table[i][0] != 0xFF; i++) { 81962306a36Sopenharmony_ci if (stat_table[i][0] & drv_stat) { 82062306a36Sopenharmony_ci *sk = stat_table[i][1]; 82162306a36Sopenharmony_ci *asc = stat_table[i][2]; 82262306a36Sopenharmony_ci *ascq = stat_table[i][3]; 82362306a36Sopenharmony_ci return; 82462306a36Sopenharmony_ci } 82562306a36Sopenharmony_ci } 82662306a36Sopenharmony_ci 82762306a36Sopenharmony_ci /* 82862306a36Sopenharmony_ci * We need a sensible error return here, which is tricky, and one 82962306a36Sopenharmony_ci * that won't cause people to do things like return a disk wrongly. 83062306a36Sopenharmony_ci */ 83162306a36Sopenharmony_ci *sk = ABORTED_COMMAND; 83262306a36Sopenharmony_ci *asc = 0x00; 83362306a36Sopenharmony_ci *ascq = 0x00; 83462306a36Sopenharmony_ci} 83562306a36Sopenharmony_ci 83662306a36Sopenharmony_ci/* 83762306a36Sopenharmony_ci * ata_gen_passthru_sense - Generate check condition sense block. 83862306a36Sopenharmony_ci * @qc: Command that completed. 83962306a36Sopenharmony_ci * 84062306a36Sopenharmony_ci * This function is specific to the ATA descriptor format sense 84162306a36Sopenharmony_ci * block specified for the ATA pass through commands. Regardless 84262306a36Sopenharmony_ci * of whether the command errored or not, return a sense 84362306a36Sopenharmony_ci * block. Copy all controller registers into the sense 84462306a36Sopenharmony_ci * block. If there was no error, we get the request from an ATA 84562306a36Sopenharmony_ci * passthrough command, so we use the following sense data: 84662306a36Sopenharmony_ci * sk = RECOVERED ERROR 84762306a36Sopenharmony_ci * asc,ascq = ATA PASS-THROUGH INFORMATION AVAILABLE 84862306a36Sopenharmony_ci * 84962306a36Sopenharmony_ci * 85062306a36Sopenharmony_ci * LOCKING: 85162306a36Sopenharmony_ci * None. 85262306a36Sopenharmony_ci */ 85362306a36Sopenharmony_cistatic void ata_gen_passthru_sense(struct ata_queued_cmd *qc) 85462306a36Sopenharmony_ci{ 85562306a36Sopenharmony_ci struct scsi_cmnd *cmd = qc->scsicmd; 85662306a36Sopenharmony_ci struct ata_taskfile *tf = &qc->result_tf; 85762306a36Sopenharmony_ci unsigned char *sb = cmd->sense_buffer; 85862306a36Sopenharmony_ci unsigned char *desc = sb + 8; 85962306a36Sopenharmony_ci u8 sense_key, asc, ascq; 86062306a36Sopenharmony_ci 86162306a36Sopenharmony_ci memset(sb, 0, SCSI_SENSE_BUFFERSIZE); 86262306a36Sopenharmony_ci 86362306a36Sopenharmony_ci /* 86462306a36Sopenharmony_ci * Use ata_to_sense_error() to map status register bits 86562306a36Sopenharmony_ci * onto sense key, asc & ascq. 86662306a36Sopenharmony_ci */ 86762306a36Sopenharmony_ci if (qc->err_mask || 86862306a36Sopenharmony_ci tf->status & (ATA_BUSY | ATA_DF | ATA_ERR | ATA_DRQ)) { 86962306a36Sopenharmony_ci ata_to_sense_error(qc->ap->print_id, tf->status, tf->error, 87062306a36Sopenharmony_ci &sense_key, &asc, &ascq); 87162306a36Sopenharmony_ci ata_scsi_set_sense(qc->dev, cmd, sense_key, asc, ascq); 87262306a36Sopenharmony_ci } else { 87362306a36Sopenharmony_ci /* 87462306a36Sopenharmony_ci * ATA PASS-THROUGH INFORMATION AVAILABLE 87562306a36Sopenharmony_ci * Always in descriptor format sense. 87662306a36Sopenharmony_ci */ 87762306a36Sopenharmony_ci scsi_build_sense(cmd, 1, RECOVERED_ERROR, 0, 0x1D); 87862306a36Sopenharmony_ci } 87962306a36Sopenharmony_ci 88062306a36Sopenharmony_ci if ((cmd->sense_buffer[0] & 0x7f) >= 0x72) { 88162306a36Sopenharmony_ci u8 len; 88262306a36Sopenharmony_ci 88362306a36Sopenharmony_ci /* descriptor format */ 88462306a36Sopenharmony_ci len = sb[7]; 88562306a36Sopenharmony_ci desc = (char *)scsi_sense_desc_find(sb, len + 8, 9); 88662306a36Sopenharmony_ci if (!desc) { 88762306a36Sopenharmony_ci if (SCSI_SENSE_BUFFERSIZE < len + 14) 88862306a36Sopenharmony_ci return; 88962306a36Sopenharmony_ci sb[7] = len + 14; 89062306a36Sopenharmony_ci desc = sb + 8 + len; 89162306a36Sopenharmony_ci } 89262306a36Sopenharmony_ci desc[0] = 9; 89362306a36Sopenharmony_ci desc[1] = 12; 89462306a36Sopenharmony_ci /* 89562306a36Sopenharmony_ci * Copy registers into sense buffer. 89662306a36Sopenharmony_ci */ 89762306a36Sopenharmony_ci desc[2] = 0x00; 89862306a36Sopenharmony_ci desc[3] = tf->error; 89962306a36Sopenharmony_ci desc[5] = tf->nsect; 90062306a36Sopenharmony_ci desc[7] = tf->lbal; 90162306a36Sopenharmony_ci desc[9] = tf->lbam; 90262306a36Sopenharmony_ci desc[11] = tf->lbah; 90362306a36Sopenharmony_ci desc[12] = tf->device; 90462306a36Sopenharmony_ci desc[13] = tf->status; 90562306a36Sopenharmony_ci 90662306a36Sopenharmony_ci /* 90762306a36Sopenharmony_ci * Fill in Extend bit, and the high order bytes 90862306a36Sopenharmony_ci * if applicable. 90962306a36Sopenharmony_ci */ 91062306a36Sopenharmony_ci if (tf->flags & ATA_TFLAG_LBA48) { 91162306a36Sopenharmony_ci desc[2] |= 0x01; 91262306a36Sopenharmony_ci desc[4] = tf->hob_nsect; 91362306a36Sopenharmony_ci desc[6] = tf->hob_lbal; 91462306a36Sopenharmony_ci desc[8] = tf->hob_lbam; 91562306a36Sopenharmony_ci desc[10] = tf->hob_lbah; 91662306a36Sopenharmony_ci } 91762306a36Sopenharmony_ci } else { 91862306a36Sopenharmony_ci /* Fixed sense format */ 91962306a36Sopenharmony_ci desc[0] = tf->error; 92062306a36Sopenharmony_ci desc[1] = tf->status; 92162306a36Sopenharmony_ci desc[2] = tf->device; 92262306a36Sopenharmony_ci desc[3] = tf->nsect; 92362306a36Sopenharmony_ci desc[7] = 0; 92462306a36Sopenharmony_ci if (tf->flags & ATA_TFLAG_LBA48) { 92562306a36Sopenharmony_ci desc[8] |= 0x80; 92662306a36Sopenharmony_ci if (tf->hob_nsect) 92762306a36Sopenharmony_ci desc[8] |= 0x40; 92862306a36Sopenharmony_ci if (tf->hob_lbal || tf->hob_lbam || tf->hob_lbah) 92962306a36Sopenharmony_ci desc[8] |= 0x20; 93062306a36Sopenharmony_ci } 93162306a36Sopenharmony_ci desc[9] = tf->lbal; 93262306a36Sopenharmony_ci desc[10] = tf->lbam; 93362306a36Sopenharmony_ci desc[11] = tf->lbah; 93462306a36Sopenharmony_ci } 93562306a36Sopenharmony_ci} 93662306a36Sopenharmony_ci 93762306a36Sopenharmony_ci/** 93862306a36Sopenharmony_ci * ata_gen_ata_sense - generate a SCSI fixed sense block 93962306a36Sopenharmony_ci * @qc: Command that we are erroring out 94062306a36Sopenharmony_ci * 94162306a36Sopenharmony_ci * Generate sense block for a failed ATA command @qc. Descriptor 94262306a36Sopenharmony_ci * format is used to accommodate LBA48 block address. 94362306a36Sopenharmony_ci * 94462306a36Sopenharmony_ci * LOCKING: 94562306a36Sopenharmony_ci * None. 94662306a36Sopenharmony_ci */ 94762306a36Sopenharmony_cistatic void ata_gen_ata_sense(struct ata_queued_cmd *qc) 94862306a36Sopenharmony_ci{ 94962306a36Sopenharmony_ci struct ata_device *dev = qc->dev; 95062306a36Sopenharmony_ci struct scsi_cmnd *cmd = qc->scsicmd; 95162306a36Sopenharmony_ci struct ata_taskfile *tf = &qc->result_tf; 95262306a36Sopenharmony_ci unsigned char *sb = cmd->sense_buffer; 95362306a36Sopenharmony_ci u64 block; 95462306a36Sopenharmony_ci u8 sense_key, asc, ascq; 95562306a36Sopenharmony_ci 95662306a36Sopenharmony_ci memset(sb, 0, SCSI_SENSE_BUFFERSIZE); 95762306a36Sopenharmony_ci 95862306a36Sopenharmony_ci if (ata_dev_disabled(dev)) { 95962306a36Sopenharmony_ci /* Device disabled after error recovery */ 96062306a36Sopenharmony_ci /* LOGICAL UNIT NOT READY, HARD RESET REQUIRED */ 96162306a36Sopenharmony_ci ata_scsi_set_sense(dev, cmd, NOT_READY, 0x04, 0x21); 96262306a36Sopenharmony_ci return; 96362306a36Sopenharmony_ci } 96462306a36Sopenharmony_ci /* Use ata_to_sense_error() to map status register bits 96562306a36Sopenharmony_ci * onto sense key, asc & ascq. 96662306a36Sopenharmony_ci */ 96762306a36Sopenharmony_ci if (qc->err_mask || 96862306a36Sopenharmony_ci tf->status & (ATA_BUSY | ATA_DF | ATA_ERR | ATA_DRQ)) { 96962306a36Sopenharmony_ci ata_to_sense_error(qc->ap->print_id, tf->status, tf->error, 97062306a36Sopenharmony_ci &sense_key, &asc, &ascq); 97162306a36Sopenharmony_ci ata_scsi_set_sense(dev, cmd, sense_key, asc, ascq); 97262306a36Sopenharmony_ci } else { 97362306a36Sopenharmony_ci /* Could not decode error */ 97462306a36Sopenharmony_ci ata_dev_warn(dev, "could not decode error status 0x%x err_mask 0x%x\n", 97562306a36Sopenharmony_ci tf->status, qc->err_mask); 97662306a36Sopenharmony_ci ata_scsi_set_sense(dev, cmd, ABORTED_COMMAND, 0, 0); 97762306a36Sopenharmony_ci return; 97862306a36Sopenharmony_ci } 97962306a36Sopenharmony_ci 98062306a36Sopenharmony_ci block = ata_tf_read_block(&qc->result_tf, dev); 98162306a36Sopenharmony_ci if (block == U64_MAX) 98262306a36Sopenharmony_ci return; 98362306a36Sopenharmony_ci 98462306a36Sopenharmony_ci scsi_set_sense_information(sb, SCSI_SENSE_BUFFERSIZE, block); 98562306a36Sopenharmony_ci} 98662306a36Sopenharmony_ci 98762306a36Sopenharmony_civoid ata_scsi_sdev_config(struct scsi_device *sdev) 98862306a36Sopenharmony_ci{ 98962306a36Sopenharmony_ci sdev->use_10_for_rw = 1; 99062306a36Sopenharmony_ci sdev->use_10_for_ms = 1; 99162306a36Sopenharmony_ci sdev->no_write_same = 1; 99262306a36Sopenharmony_ci 99362306a36Sopenharmony_ci /* Schedule policy is determined by ->qc_defer() callback and 99462306a36Sopenharmony_ci * it needs to see every deferred qc. Set dev_blocked to 1 to 99562306a36Sopenharmony_ci * prevent SCSI midlayer from automatically deferring 99662306a36Sopenharmony_ci * requests. 99762306a36Sopenharmony_ci */ 99862306a36Sopenharmony_ci sdev->max_device_blocked = 1; 99962306a36Sopenharmony_ci} 100062306a36Sopenharmony_ci 100162306a36Sopenharmony_ci/** 100262306a36Sopenharmony_ci * ata_scsi_dma_need_drain - Check whether data transfer may overflow 100362306a36Sopenharmony_ci * @rq: request to be checked 100462306a36Sopenharmony_ci * 100562306a36Sopenharmony_ci * ATAPI commands which transfer variable length data to host 100662306a36Sopenharmony_ci * might overflow due to application error or hardware bug. This 100762306a36Sopenharmony_ci * function checks whether overflow should be drained and ignored 100862306a36Sopenharmony_ci * for @request. 100962306a36Sopenharmony_ci * 101062306a36Sopenharmony_ci * LOCKING: 101162306a36Sopenharmony_ci * None. 101262306a36Sopenharmony_ci * 101362306a36Sopenharmony_ci * RETURNS: 101462306a36Sopenharmony_ci * 1 if ; otherwise, 0. 101562306a36Sopenharmony_ci */ 101662306a36Sopenharmony_cibool ata_scsi_dma_need_drain(struct request *rq) 101762306a36Sopenharmony_ci{ 101862306a36Sopenharmony_ci struct scsi_cmnd *scmd = blk_mq_rq_to_pdu(rq); 101962306a36Sopenharmony_ci 102062306a36Sopenharmony_ci return atapi_cmd_type(scmd->cmnd[0]) == ATAPI_MISC; 102162306a36Sopenharmony_ci} 102262306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(ata_scsi_dma_need_drain); 102362306a36Sopenharmony_ci 102462306a36Sopenharmony_ciint ata_scsi_dev_config(struct scsi_device *sdev, struct ata_device *dev) 102562306a36Sopenharmony_ci{ 102662306a36Sopenharmony_ci struct request_queue *q = sdev->request_queue; 102762306a36Sopenharmony_ci int depth = 1; 102862306a36Sopenharmony_ci 102962306a36Sopenharmony_ci if (!ata_id_has_unload(dev->id)) 103062306a36Sopenharmony_ci dev->flags |= ATA_DFLAG_NO_UNLOAD; 103162306a36Sopenharmony_ci 103262306a36Sopenharmony_ci /* configure max sectors */ 103362306a36Sopenharmony_ci dev->max_sectors = min(dev->max_sectors, sdev->host->max_sectors); 103462306a36Sopenharmony_ci blk_queue_max_hw_sectors(q, dev->max_sectors); 103562306a36Sopenharmony_ci 103662306a36Sopenharmony_ci if (dev->class == ATA_DEV_ATAPI) { 103762306a36Sopenharmony_ci sdev->sector_size = ATA_SECT_SIZE; 103862306a36Sopenharmony_ci 103962306a36Sopenharmony_ci /* set DMA padding */ 104062306a36Sopenharmony_ci blk_queue_update_dma_pad(q, ATA_DMA_PAD_SZ - 1); 104162306a36Sopenharmony_ci 104262306a36Sopenharmony_ci /* make room for appending the drain */ 104362306a36Sopenharmony_ci blk_queue_max_segments(q, queue_max_segments(q) - 1); 104462306a36Sopenharmony_ci 104562306a36Sopenharmony_ci sdev->dma_drain_len = ATAPI_MAX_DRAIN; 104662306a36Sopenharmony_ci sdev->dma_drain_buf = kmalloc(sdev->dma_drain_len, GFP_NOIO); 104762306a36Sopenharmony_ci if (!sdev->dma_drain_buf) { 104862306a36Sopenharmony_ci ata_dev_err(dev, "drain buffer allocation failed\n"); 104962306a36Sopenharmony_ci return -ENOMEM; 105062306a36Sopenharmony_ci } 105162306a36Sopenharmony_ci } else { 105262306a36Sopenharmony_ci sdev->sector_size = ata_id_logical_sector_size(dev->id); 105362306a36Sopenharmony_ci 105462306a36Sopenharmony_ci /* 105562306a36Sopenharmony_ci * Ask the sd driver to issue START STOP UNIT on runtime suspend 105662306a36Sopenharmony_ci * and resume and shutdown only. For system level suspend/resume, 105762306a36Sopenharmony_ci * devices power state is handled directly by libata EH. 105862306a36Sopenharmony_ci * Given that disks are always spun up on system resume, also 105962306a36Sopenharmony_ci * make sure that the sd driver forces runtime suspended disks 106062306a36Sopenharmony_ci * to be resumed to correctly reflect the power state of the 106162306a36Sopenharmony_ci * device. 106262306a36Sopenharmony_ci */ 106362306a36Sopenharmony_ci sdev->manage_runtime_start_stop = 1; 106462306a36Sopenharmony_ci sdev->manage_shutdown = 1; 106562306a36Sopenharmony_ci sdev->force_runtime_start_on_system_start = 1; 106662306a36Sopenharmony_ci } 106762306a36Sopenharmony_ci 106862306a36Sopenharmony_ci /* 106962306a36Sopenharmony_ci * ata_pio_sectors() expects buffer for each sector to not cross 107062306a36Sopenharmony_ci * page boundary. Enforce it by requiring buffers to be sector 107162306a36Sopenharmony_ci * aligned, which works iff sector_size is not larger than 107262306a36Sopenharmony_ci * PAGE_SIZE. ATAPI devices also need the alignment as 107362306a36Sopenharmony_ci * IDENTIFY_PACKET is executed as ATA_PROT_PIO. 107462306a36Sopenharmony_ci */ 107562306a36Sopenharmony_ci if (sdev->sector_size > PAGE_SIZE) 107662306a36Sopenharmony_ci ata_dev_warn(dev, 107762306a36Sopenharmony_ci "sector_size=%u > PAGE_SIZE, PIO may malfunction\n", 107862306a36Sopenharmony_ci sdev->sector_size); 107962306a36Sopenharmony_ci 108062306a36Sopenharmony_ci blk_queue_update_dma_alignment(q, sdev->sector_size - 1); 108162306a36Sopenharmony_ci 108262306a36Sopenharmony_ci if (dev->flags & ATA_DFLAG_AN) 108362306a36Sopenharmony_ci set_bit(SDEV_EVT_MEDIA_CHANGE, sdev->supported_events); 108462306a36Sopenharmony_ci 108562306a36Sopenharmony_ci if (ata_ncq_supported(dev)) 108662306a36Sopenharmony_ci depth = min(sdev->host->can_queue, ata_id_queue_depth(dev->id)); 108762306a36Sopenharmony_ci depth = min(ATA_MAX_QUEUE, depth); 108862306a36Sopenharmony_ci scsi_change_queue_depth(sdev, depth); 108962306a36Sopenharmony_ci 109062306a36Sopenharmony_ci if (dev->flags & ATA_DFLAG_TRUSTED) 109162306a36Sopenharmony_ci sdev->security_supported = 1; 109262306a36Sopenharmony_ci 109362306a36Sopenharmony_ci dev->sdev = sdev; 109462306a36Sopenharmony_ci return 0; 109562306a36Sopenharmony_ci} 109662306a36Sopenharmony_ci 109762306a36Sopenharmony_ci/** 109862306a36Sopenharmony_ci * ata_scsi_slave_alloc - Early setup of SCSI device 109962306a36Sopenharmony_ci * @sdev: SCSI device to examine 110062306a36Sopenharmony_ci * 110162306a36Sopenharmony_ci * This is called from scsi_alloc_sdev() when the scsi device 110262306a36Sopenharmony_ci * associated with an ATA device is scanned on a port. 110362306a36Sopenharmony_ci * 110462306a36Sopenharmony_ci * LOCKING: 110562306a36Sopenharmony_ci * Defined by SCSI layer. We don't really care. 110662306a36Sopenharmony_ci */ 110762306a36Sopenharmony_ci 110862306a36Sopenharmony_ciint ata_scsi_slave_alloc(struct scsi_device *sdev) 110962306a36Sopenharmony_ci{ 111062306a36Sopenharmony_ci struct ata_port *ap = ata_shost_to_port(sdev->host); 111162306a36Sopenharmony_ci struct device_link *link; 111262306a36Sopenharmony_ci 111362306a36Sopenharmony_ci ata_scsi_sdev_config(sdev); 111462306a36Sopenharmony_ci 111562306a36Sopenharmony_ci /* 111662306a36Sopenharmony_ci * Create a link from the ata_port device to the scsi device to ensure 111762306a36Sopenharmony_ci * that PM does suspend/resume in the correct order: the scsi device is 111862306a36Sopenharmony_ci * consumer (child) and the ata port the supplier (parent). 111962306a36Sopenharmony_ci */ 112062306a36Sopenharmony_ci link = device_link_add(&sdev->sdev_gendev, &ap->tdev, 112162306a36Sopenharmony_ci DL_FLAG_STATELESS | 112262306a36Sopenharmony_ci DL_FLAG_PM_RUNTIME | DL_FLAG_RPM_ACTIVE); 112362306a36Sopenharmony_ci if (!link) { 112462306a36Sopenharmony_ci ata_port_err(ap, "Failed to create link to scsi device %s\n", 112562306a36Sopenharmony_ci dev_name(&sdev->sdev_gendev)); 112662306a36Sopenharmony_ci return -ENODEV; 112762306a36Sopenharmony_ci } 112862306a36Sopenharmony_ci 112962306a36Sopenharmony_ci return 0; 113062306a36Sopenharmony_ci} 113162306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(ata_scsi_slave_alloc); 113262306a36Sopenharmony_ci 113362306a36Sopenharmony_ci/** 113462306a36Sopenharmony_ci * ata_scsi_slave_config - Set SCSI device attributes 113562306a36Sopenharmony_ci * @sdev: SCSI device to examine 113662306a36Sopenharmony_ci * 113762306a36Sopenharmony_ci * This is called before we actually start reading 113862306a36Sopenharmony_ci * and writing to the device, to configure certain 113962306a36Sopenharmony_ci * SCSI mid-layer behaviors. 114062306a36Sopenharmony_ci * 114162306a36Sopenharmony_ci * LOCKING: 114262306a36Sopenharmony_ci * Defined by SCSI layer. We don't really care. 114362306a36Sopenharmony_ci */ 114462306a36Sopenharmony_ci 114562306a36Sopenharmony_ciint ata_scsi_slave_config(struct scsi_device *sdev) 114662306a36Sopenharmony_ci{ 114762306a36Sopenharmony_ci struct ata_port *ap = ata_shost_to_port(sdev->host); 114862306a36Sopenharmony_ci struct ata_device *dev = __ata_scsi_find_dev(ap, sdev); 114962306a36Sopenharmony_ci 115062306a36Sopenharmony_ci if (dev) 115162306a36Sopenharmony_ci return ata_scsi_dev_config(sdev, dev); 115262306a36Sopenharmony_ci 115362306a36Sopenharmony_ci return 0; 115462306a36Sopenharmony_ci} 115562306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(ata_scsi_slave_config); 115662306a36Sopenharmony_ci 115762306a36Sopenharmony_ci/** 115862306a36Sopenharmony_ci * ata_scsi_slave_destroy - SCSI device is about to be destroyed 115962306a36Sopenharmony_ci * @sdev: SCSI device to be destroyed 116062306a36Sopenharmony_ci * 116162306a36Sopenharmony_ci * @sdev is about to be destroyed for hot/warm unplugging. If 116262306a36Sopenharmony_ci * this unplugging was initiated by libata as indicated by NULL 116362306a36Sopenharmony_ci * dev->sdev, this function doesn't have to do anything. 116462306a36Sopenharmony_ci * Otherwise, SCSI layer initiated warm-unplug is in progress. 116562306a36Sopenharmony_ci * Clear dev->sdev, schedule the device for ATA detach and invoke 116662306a36Sopenharmony_ci * EH. 116762306a36Sopenharmony_ci * 116862306a36Sopenharmony_ci * LOCKING: 116962306a36Sopenharmony_ci * Defined by SCSI layer. We don't really care. 117062306a36Sopenharmony_ci */ 117162306a36Sopenharmony_civoid ata_scsi_slave_destroy(struct scsi_device *sdev) 117262306a36Sopenharmony_ci{ 117362306a36Sopenharmony_ci struct ata_port *ap = ata_shost_to_port(sdev->host); 117462306a36Sopenharmony_ci unsigned long flags; 117562306a36Sopenharmony_ci struct ata_device *dev; 117662306a36Sopenharmony_ci 117762306a36Sopenharmony_ci device_link_remove(&sdev->sdev_gendev, &ap->tdev); 117862306a36Sopenharmony_ci 117962306a36Sopenharmony_ci spin_lock_irqsave(ap->lock, flags); 118062306a36Sopenharmony_ci dev = __ata_scsi_find_dev(ap, sdev); 118162306a36Sopenharmony_ci if (dev && dev->sdev) { 118262306a36Sopenharmony_ci /* SCSI device already in CANCEL state, no need to offline it */ 118362306a36Sopenharmony_ci dev->sdev = NULL; 118462306a36Sopenharmony_ci dev->flags |= ATA_DFLAG_DETACH; 118562306a36Sopenharmony_ci ata_port_schedule_eh(ap); 118662306a36Sopenharmony_ci } 118762306a36Sopenharmony_ci spin_unlock_irqrestore(ap->lock, flags); 118862306a36Sopenharmony_ci 118962306a36Sopenharmony_ci kfree(sdev->dma_drain_buf); 119062306a36Sopenharmony_ci} 119162306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(ata_scsi_slave_destroy); 119262306a36Sopenharmony_ci 119362306a36Sopenharmony_ci/** 119462306a36Sopenharmony_ci * ata_scsi_start_stop_xlat - Translate SCSI START STOP UNIT command 119562306a36Sopenharmony_ci * @qc: Storage for translated ATA taskfile 119662306a36Sopenharmony_ci * 119762306a36Sopenharmony_ci * Sets up an ATA taskfile to issue STANDBY (to stop) or READ VERIFY 119862306a36Sopenharmony_ci * (to start). Perhaps these commands should be preceded by 119962306a36Sopenharmony_ci * CHECK POWER MODE to see what power mode the device is already in. 120062306a36Sopenharmony_ci * [See SAT revision 5 at www.t10.org] 120162306a36Sopenharmony_ci * 120262306a36Sopenharmony_ci * LOCKING: 120362306a36Sopenharmony_ci * spin_lock_irqsave(host lock) 120462306a36Sopenharmony_ci * 120562306a36Sopenharmony_ci * RETURNS: 120662306a36Sopenharmony_ci * Zero on success, non-zero on error. 120762306a36Sopenharmony_ci */ 120862306a36Sopenharmony_cistatic unsigned int ata_scsi_start_stop_xlat(struct ata_queued_cmd *qc) 120962306a36Sopenharmony_ci{ 121062306a36Sopenharmony_ci struct scsi_cmnd *scmd = qc->scsicmd; 121162306a36Sopenharmony_ci struct ata_taskfile *tf = &qc->tf; 121262306a36Sopenharmony_ci const u8 *cdb = scmd->cmnd; 121362306a36Sopenharmony_ci u16 fp; 121462306a36Sopenharmony_ci u8 bp = 0xff; 121562306a36Sopenharmony_ci 121662306a36Sopenharmony_ci if (scmd->cmd_len < 5) { 121762306a36Sopenharmony_ci fp = 4; 121862306a36Sopenharmony_ci goto invalid_fld; 121962306a36Sopenharmony_ci } 122062306a36Sopenharmony_ci 122162306a36Sopenharmony_ci tf->flags |= ATA_TFLAG_DEVICE | ATA_TFLAG_ISADDR; 122262306a36Sopenharmony_ci tf->protocol = ATA_PROT_NODATA; 122362306a36Sopenharmony_ci if (cdb[1] & 0x1) { 122462306a36Sopenharmony_ci ; /* ignore IMMED bit, violates sat-r05 */ 122562306a36Sopenharmony_ci } 122662306a36Sopenharmony_ci if (cdb[4] & 0x2) { 122762306a36Sopenharmony_ci fp = 4; 122862306a36Sopenharmony_ci bp = 1; 122962306a36Sopenharmony_ci goto invalid_fld; /* LOEJ bit set not supported */ 123062306a36Sopenharmony_ci } 123162306a36Sopenharmony_ci if (((cdb[4] >> 4) & 0xf) != 0) { 123262306a36Sopenharmony_ci fp = 4; 123362306a36Sopenharmony_ci bp = 3; 123462306a36Sopenharmony_ci goto invalid_fld; /* power conditions not supported */ 123562306a36Sopenharmony_ci } 123662306a36Sopenharmony_ci 123762306a36Sopenharmony_ci if (cdb[4] & 0x1) { 123862306a36Sopenharmony_ci tf->nsect = 1; /* 1 sector, lba=0 */ 123962306a36Sopenharmony_ci 124062306a36Sopenharmony_ci if (qc->dev->flags & ATA_DFLAG_LBA) { 124162306a36Sopenharmony_ci tf->flags |= ATA_TFLAG_LBA; 124262306a36Sopenharmony_ci 124362306a36Sopenharmony_ci tf->lbah = 0x0; 124462306a36Sopenharmony_ci tf->lbam = 0x0; 124562306a36Sopenharmony_ci tf->lbal = 0x0; 124662306a36Sopenharmony_ci tf->device |= ATA_LBA; 124762306a36Sopenharmony_ci } else { 124862306a36Sopenharmony_ci /* CHS */ 124962306a36Sopenharmony_ci tf->lbal = 0x1; /* sect */ 125062306a36Sopenharmony_ci tf->lbam = 0x0; /* cyl low */ 125162306a36Sopenharmony_ci tf->lbah = 0x0; /* cyl high */ 125262306a36Sopenharmony_ci } 125362306a36Sopenharmony_ci 125462306a36Sopenharmony_ci tf->command = ATA_CMD_VERIFY; /* READ VERIFY */ 125562306a36Sopenharmony_ci } else { 125662306a36Sopenharmony_ci /* Some odd clown BIOSen issue spindown on power off (ACPI S4 125762306a36Sopenharmony_ci * or S5) causing some drives to spin up and down again. 125862306a36Sopenharmony_ci */ 125962306a36Sopenharmony_ci if ((qc->ap->flags & ATA_FLAG_NO_POWEROFF_SPINDOWN) && 126062306a36Sopenharmony_ci system_state == SYSTEM_POWER_OFF) 126162306a36Sopenharmony_ci goto skip; 126262306a36Sopenharmony_ci 126362306a36Sopenharmony_ci if ((qc->ap->flags & ATA_FLAG_NO_HIBERNATE_SPINDOWN) && 126462306a36Sopenharmony_ci system_entering_hibernation()) 126562306a36Sopenharmony_ci goto skip; 126662306a36Sopenharmony_ci 126762306a36Sopenharmony_ci /* Issue ATA STANDBY IMMEDIATE command */ 126862306a36Sopenharmony_ci tf->command = ATA_CMD_STANDBYNOW1; 126962306a36Sopenharmony_ci } 127062306a36Sopenharmony_ci 127162306a36Sopenharmony_ci /* 127262306a36Sopenharmony_ci * Standby and Idle condition timers could be implemented but that 127362306a36Sopenharmony_ci * would require libata to implement the Power condition mode page 127462306a36Sopenharmony_ci * and allow the user to change it. Changing mode pages requires 127562306a36Sopenharmony_ci * MODE SELECT to be implemented. 127662306a36Sopenharmony_ci */ 127762306a36Sopenharmony_ci 127862306a36Sopenharmony_ci return 0; 127962306a36Sopenharmony_ci 128062306a36Sopenharmony_ci invalid_fld: 128162306a36Sopenharmony_ci ata_scsi_set_invalid_field(qc->dev, scmd, fp, bp); 128262306a36Sopenharmony_ci return 1; 128362306a36Sopenharmony_ci skip: 128462306a36Sopenharmony_ci scmd->result = SAM_STAT_GOOD; 128562306a36Sopenharmony_ci return 1; 128662306a36Sopenharmony_ci} 128762306a36Sopenharmony_ci 128862306a36Sopenharmony_ci 128962306a36Sopenharmony_ci/** 129062306a36Sopenharmony_ci * ata_scsi_flush_xlat - Translate SCSI SYNCHRONIZE CACHE command 129162306a36Sopenharmony_ci * @qc: Storage for translated ATA taskfile 129262306a36Sopenharmony_ci * 129362306a36Sopenharmony_ci * Sets up an ATA taskfile to issue FLUSH CACHE or 129462306a36Sopenharmony_ci * FLUSH CACHE EXT. 129562306a36Sopenharmony_ci * 129662306a36Sopenharmony_ci * LOCKING: 129762306a36Sopenharmony_ci * spin_lock_irqsave(host lock) 129862306a36Sopenharmony_ci * 129962306a36Sopenharmony_ci * RETURNS: 130062306a36Sopenharmony_ci * Zero on success, non-zero on error. 130162306a36Sopenharmony_ci */ 130262306a36Sopenharmony_cistatic unsigned int ata_scsi_flush_xlat(struct ata_queued_cmd *qc) 130362306a36Sopenharmony_ci{ 130462306a36Sopenharmony_ci struct ata_taskfile *tf = &qc->tf; 130562306a36Sopenharmony_ci 130662306a36Sopenharmony_ci tf->flags |= ATA_TFLAG_DEVICE; 130762306a36Sopenharmony_ci tf->protocol = ATA_PROT_NODATA; 130862306a36Sopenharmony_ci 130962306a36Sopenharmony_ci if (qc->dev->flags & ATA_DFLAG_FLUSH_EXT) 131062306a36Sopenharmony_ci tf->command = ATA_CMD_FLUSH_EXT; 131162306a36Sopenharmony_ci else 131262306a36Sopenharmony_ci tf->command = ATA_CMD_FLUSH; 131362306a36Sopenharmony_ci 131462306a36Sopenharmony_ci /* flush is critical for IO integrity, consider it an IO command */ 131562306a36Sopenharmony_ci qc->flags |= ATA_QCFLAG_IO; 131662306a36Sopenharmony_ci 131762306a36Sopenharmony_ci return 0; 131862306a36Sopenharmony_ci} 131962306a36Sopenharmony_ci 132062306a36Sopenharmony_ci/** 132162306a36Sopenharmony_ci * scsi_6_lba_len - Get LBA and transfer length 132262306a36Sopenharmony_ci * @cdb: SCSI command to translate 132362306a36Sopenharmony_ci * 132462306a36Sopenharmony_ci * Calculate LBA and transfer length for 6-byte commands. 132562306a36Sopenharmony_ci * 132662306a36Sopenharmony_ci * RETURNS: 132762306a36Sopenharmony_ci * @plba: the LBA 132862306a36Sopenharmony_ci * @plen: the transfer length 132962306a36Sopenharmony_ci */ 133062306a36Sopenharmony_cistatic void scsi_6_lba_len(const u8 *cdb, u64 *plba, u32 *plen) 133162306a36Sopenharmony_ci{ 133262306a36Sopenharmony_ci u64 lba = 0; 133362306a36Sopenharmony_ci u32 len; 133462306a36Sopenharmony_ci 133562306a36Sopenharmony_ci lba |= ((u64)(cdb[1] & 0x1f)) << 16; 133662306a36Sopenharmony_ci lba |= ((u64)cdb[2]) << 8; 133762306a36Sopenharmony_ci lba |= ((u64)cdb[3]); 133862306a36Sopenharmony_ci 133962306a36Sopenharmony_ci len = cdb[4]; 134062306a36Sopenharmony_ci 134162306a36Sopenharmony_ci *plba = lba; 134262306a36Sopenharmony_ci *plen = len; 134362306a36Sopenharmony_ci} 134462306a36Sopenharmony_ci 134562306a36Sopenharmony_ci/** 134662306a36Sopenharmony_ci * scsi_10_lba_len - Get LBA and transfer length 134762306a36Sopenharmony_ci * @cdb: SCSI command to translate 134862306a36Sopenharmony_ci * 134962306a36Sopenharmony_ci * Calculate LBA and transfer length for 10-byte commands. 135062306a36Sopenharmony_ci * 135162306a36Sopenharmony_ci * RETURNS: 135262306a36Sopenharmony_ci * @plba: the LBA 135362306a36Sopenharmony_ci * @plen: the transfer length 135462306a36Sopenharmony_ci */ 135562306a36Sopenharmony_cistatic inline void scsi_10_lba_len(const u8 *cdb, u64 *plba, u32 *plen) 135662306a36Sopenharmony_ci{ 135762306a36Sopenharmony_ci *plba = get_unaligned_be32(&cdb[2]); 135862306a36Sopenharmony_ci *plen = get_unaligned_be16(&cdb[7]); 135962306a36Sopenharmony_ci} 136062306a36Sopenharmony_ci 136162306a36Sopenharmony_ci/** 136262306a36Sopenharmony_ci * scsi_16_lba_len - Get LBA and transfer length 136362306a36Sopenharmony_ci * @cdb: SCSI command to translate 136462306a36Sopenharmony_ci * 136562306a36Sopenharmony_ci * Calculate LBA and transfer length for 16-byte commands. 136662306a36Sopenharmony_ci * 136762306a36Sopenharmony_ci * RETURNS: 136862306a36Sopenharmony_ci * @plba: the LBA 136962306a36Sopenharmony_ci * @plen: the transfer length 137062306a36Sopenharmony_ci */ 137162306a36Sopenharmony_cistatic inline void scsi_16_lba_len(const u8 *cdb, u64 *plba, u32 *plen) 137262306a36Sopenharmony_ci{ 137362306a36Sopenharmony_ci *plba = get_unaligned_be64(&cdb[2]); 137462306a36Sopenharmony_ci *plen = get_unaligned_be32(&cdb[10]); 137562306a36Sopenharmony_ci} 137662306a36Sopenharmony_ci 137762306a36Sopenharmony_ci/** 137862306a36Sopenharmony_ci * scsi_dld - Get duration limit descriptor index 137962306a36Sopenharmony_ci * @cdb: SCSI command to translate 138062306a36Sopenharmony_ci * 138162306a36Sopenharmony_ci * Returns the dld bits indicating the index of a command duration limit 138262306a36Sopenharmony_ci * descriptor. 138362306a36Sopenharmony_ci */ 138462306a36Sopenharmony_cistatic inline int scsi_dld(const u8 *cdb) 138562306a36Sopenharmony_ci{ 138662306a36Sopenharmony_ci return ((cdb[1] & 0x01) << 2) | ((cdb[14] >> 6) & 0x03); 138762306a36Sopenharmony_ci} 138862306a36Sopenharmony_ci 138962306a36Sopenharmony_ci/** 139062306a36Sopenharmony_ci * ata_scsi_verify_xlat - Translate SCSI VERIFY command into an ATA one 139162306a36Sopenharmony_ci * @qc: Storage for translated ATA taskfile 139262306a36Sopenharmony_ci * 139362306a36Sopenharmony_ci * Converts SCSI VERIFY command to an ATA READ VERIFY command. 139462306a36Sopenharmony_ci * 139562306a36Sopenharmony_ci * LOCKING: 139662306a36Sopenharmony_ci * spin_lock_irqsave(host lock) 139762306a36Sopenharmony_ci * 139862306a36Sopenharmony_ci * RETURNS: 139962306a36Sopenharmony_ci * Zero on success, non-zero on error. 140062306a36Sopenharmony_ci */ 140162306a36Sopenharmony_cistatic unsigned int ata_scsi_verify_xlat(struct ata_queued_cmd *qc) 140262306a36Sopenharmony_ci{ 140362306a36Sopenharmony_ci struct scsi_cmnd *scmd = qc->scsicmd; 140462306a36Sopenharmony_ci struct ata_taskfile *tf = &qc->tf; 140562306a36Sopenharmony_ci struct ata_device *dev = qc->dev; 140662306a36Sopenharmony_ci u64 dev_sectors = qc->dev->n_sectors; 140762306a36Sopenharmony_ci const u8 *cdb = scmd->cmnd; 140862306a36Sopenharmony_ci u64 block; 140962306a36Sopenharmony_ci u32 n_block; 141062306a36Sopenharmony_ci u16 fp; 141162306a36Sopenharmony_ci 141262306a36Sopenharmony_ci tf->flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE; 141362306a36Sopenharmony_ci tf->protocol = ATA_PROT_NODATA; 141462306a36Sopenharmony_ci 141562306a36Sopenharmony_ci switch (cdb[0]) { 141662306a36Sopenharmony_ci case VERIFY: 141762306a36Sopenharmony_ci if (scmd->cmd_len < 10) { 141862306a36Sopenharmony_ci fp = 9; 141962306a36Sopenharmony_ci goto invalid_fld; 142062306a36Sopenharmony_ci } 142162306a36Sopenharmony_ci scsi_10_lba_len(cdb, &block, &n_block); 142262306a36Sopenharmony_ci break; 142362306a36Sopenharmony_ci case VERIFY_16: 142462306a36Sopenharmony_ci if (scmd->cmd_len < 16) { 142562306a36Sopenharmony_ci fp = 15; 142662306a36Sopenharmony_ci goto invalid_fld; 142762306a36Sopenharmony_ci } 142862306a36Sopenharmony_ci scsi_16_lba_len(cdb, &block, &n_block); 142962306a36Sopenharmony_ci break; 143062306a36Sopenharmony_ci default: 143162306a36Sopenharmony_ci fp = 0; 143262306a36Sopenharmony_ci goto invalid_fld; 143362306a36Sopenharmony_ci } 143462306a36Sopenharmony_ci 143562306a36Sopenharmony_ci if (!n_block) 143662306a36Sopenharmony_ci goto nothing_to_do; 143762306a36Sopenharmony_ci if (block >= dev_sectors) 143862306a36Sopenharmony_ci goto out_of_range; 143962306a36Sopenharmony_ci if ((block + n_block) > dev_sectors) 144062306a36Sopenharmony_ci goto out_of_range; 144162306a36Sopenharmony_ci 144262306a36Sopenharmony_ci if (dev->flags & ATA_DFLAG_LBA) { 144362306a36Sopenharmony_ci tf->flags |= ATA_TFLAG_LBA; 144462306a36Sopenharmony_ci 144562306a36Sopenharmony_ci if (lba_28_ok(block, n_block)) { 144662306a36Sopenharmony_ci /* use LBA28 */ 144762306a36Sopenharmony_ci tf->command = ATA_CMD_VERIFY; 144862306a36Sopenharmony_ci tf->device |= (block >> 24) & 0xf; 144962306a36Sopenharmony_ci } else if (lba_48_ok(block, n_block)) { 145062306a36Sopenharmony_ci if (!(dev->flags & ATA_DFLAG_LBA48)) 145162306a36Sopenharmony_ci goto out_of_range; 145262306a36Sopenharmony_ci 145362306a36Sopenharmony_ci /* use LBA48 */ 145462306a36Sopenharmony_ci tf->flags |= ATA_TFLAG_LBA48; 145562306a36Sopenharmony_ci tf->command = ATA_CMD_VERIFY_EXT; 145662306a36Sopenharmony_ci 145762306a36Sopenharmony_ci tf->hob_nsect = (n_block >> 8) & 0xff; 145862306a36Sopenharmony_ci 145962306a36Sopenharmony_ci tf->hob_lbah = (block >> 40) & 0xff; 146062306a36Sopenharmony_ci tf->hob_lbam = (block >> 32) & 0xff; 146162306a36Sopenharmony_ci tf->hob_lbal = (block >> 24) & 0xff; 146262306a36Sopenharmony_ci } else 146362306a36Sopenharmony_ci /* request too large even for LBA48 */ 146462306a36Sopenharmony_ci goto out_of_range; 146562306a36Sopenharmony_ci 146662306a36Sopenharmony_ci tf->nsect = n_block & 0xff; 146762306a36Sopenharmony_ci 146862306a36Sopenharmony_ci tf->lbah = (block >> 16) & 0xff; 146962306a36Sopenharmony_ci tf->lbam = (block >> 8) & 0xff; 147062306a36Sopenharmony_ci tf->lbal = block & 0xff; 147162306a36Sopenharmony_ci 147262306a36Sopenharmony_ci tf->device |= ATA_LBA; 147362306a36Sopenharmony_ci } else { 147462306a36Sopenharmony_ci /* CHS */ 147562306a36Sopenharmony_ci u32 sect, head, cyl, track; 147662306a36Sopenharmony_ci 147762306a36Sopenharmony_ci if (!lba_28_ok(block, n_block)) 147862306a36Sopenharmony_ci goto out_of_range; 147962306a36Sopenharmony_ci 148062306a36Sopenharmony_ci /* Convert LBA to CHS */ 148162306a36Sopenharmony_ci track = (u32)block / dev->sectors; 148262306a36Sopenharmony_ci cyl = track / dev->heads; 148362306a36Sopenharmony_ci head = track % dev->heads; 148462306a36Sopenharmony_ci sect = (u32)block % dev->sectors + 1; 148562306a36Sopenharmony_ci 148662306a36Sopenharmony_ci /* Check whether the converted CHS can fit. 148762306a36Sopenharmony_ci Cylinder: 0-65535 148862306a36Sopenharmony_ci Head: 0-15 148962306a36Sopenharmony_ci Sector: 1-255*/ 149062306a36Sopenharmony_ci if ((cyl >> 16) || (head >> 4) || (sect >> 8) || (!sect)) 149162306a36Sopenharmony_ci goto out_of_range; 149262306a36Sopenharmony_ci 149362306a36Sopenharmony_ci tf->command = ATA_CMD_VERIFY; 149462306a36Sopenharmony_ci tf->nsect = n_block & 0xff; /* Sector count 0 means 256 sectors */ 149562306a36Sopenharmony_ci tf->lbal = sect; 149662306a36Sopenharmony_ci tf->lbam = cyl; 149762306a36Sopenharmony_ci tf->lbah = cyl >> 8; 149862306a36Sopenharmony_ci tf->device |= head; 149962306a36Sopenharmony_ci } 150062306a36Sopenharmony_ci 150162306a36Sopenharmony_ci return 0; 150262306a36Sopenharmony_ci 150362306a36Sopenharmony_ciinvalid_fld: 150462306a36Sopenharmony_ci ata_scsi_set_invalid_field(qc->dev, scmd, fp, 0xff); 150562306a36Sopenharmony_ci return 1; 150662306a36Sopenharmony_ci 150762306a36Sopenharmony_ciout_of_range: 150862306a36Sopenharmony_ci ata_scsi_set_sense(qc->dev, scmd, ILLEGAL_REQUEST, 0x21, 0x0); 150962306a36Sopenharmony_ci /* "Logical Block Address out of range" */ 151062306a36Sopenharmony_ci return 1; 151162306a36Sopenharmony_ci 151262306a36Sopenharmony_cinothing_to_do: 151362306a36Sopenharmony_ci scmd->result = SAM_STAT_GOOD; 151462306a36Sopenharmony_ci return 1; 151562306a36Sopenharmony_ci} 151662306a36Sopenharmony_ci 151762306a36Sopenharmony_cistatic bool ata_check_nblocks(struct scsi_cmnd *scmd, u32 n_blocks) 151862306a36Sopenharmony_ci{ 151962306a36Sopenharmony_ci struct request *rq = scsi_cmd_to_rq(scmd); 152062306a36Sopenharmony_ci u32 req_blocks; 152162306a36Sopenharmony_ci 152262306a36Sopenharmony_ci if (!blk_rq_is_passthrough(rq)) 152362306a36Sopenharmony_ci return true; 152462306a36Sopenharmony_ci 152562306a36Sopenharmony_ci req_blocks = blk_rq_bytes(rq) / scmd->device->sector_size; 152662306a36Sopenharmony_ci if (n_blocks > req_blocks) 152762306a36Sopenharmony_ci return false; 152862306a36Sopenharmony_ci 152962306a36Sopenharmony_ci return true; 153062306a36Sopenharmony_ci} 153162306a36Sopenharmony_ci 153262306a36Sopenharmony_ci/** 153362306a36Sopenharmony_ci * ata_scsi_rw_xlat - Translate SCSI r/w command into an ATA one 153462306a36Sopenharmony_ci * @qc: Storage for translated ATA taskfile 153562306a36Sopenharmony_ci * 153662306a36Sopenharmony_ci * Converts any of six SCSI read/write commands into the 153762306a36Sopenharmony_ci * ATA counterpart, including starting sector (LBA), 153862306a36Sopenharmony_ci * sector count, and taking into account the device's LBA48 153962306a36Sopenharmony_ci * support. 154062306a36Sopenharmony_ci * 154162306a36Sopenharmony_ci * Commands %READ_6, %READ_10, %READ_16, %WRITE_6, %WRITE_10, and 154262306a36Sopenharmony_ci * %WRITE_16 are currently supported. 154362306a36Sopenharmony_ci * 154462306a36Sopenharmony_ci * LOCKING: 154562306a36Sopenharmony_ci * spin_lock_irqsave(host lock) 154662306a36Sopenharmony_ci * 154762306a36Sopenharmony_ci * RETURNS: 154862306a36Sopenharmony_ci * Zero on success, non-zero on error. 154962306a36Sopenharmony_ci */ 155062306a36Sopenharmony_cistatic unsigned int ata_scsi_rw_xlat(struct ata_queued_cmd *qc) 155162306a36Sopenharmony_ci{ 155262306a36Sopenharmony_ci struct scsi_cmnd *scmd = qc->scsicmd; 155362306a36Sopenharmony_ci const u8 *cdb = scmd->cmnd; 155462306a36Sopenharmony_ci struct request *rq = scsi_cmd_to_rq(scmd); 155562306a36Sopenharmony_ci int class = IOPRIO_PRIO_CLASS(req_get_ioprio(rq)); 155662306a36Sopenharmony_ci unsigned int tf_flags = 0; 155762306a36Sopenharmony_ci int dld = 0; 155862306a36Sopenharmony_ci u64 block; 155962306a36Sopenharmony_ci u32 n_block; 156062306a36Sopenharmony_ci int rc; 156162306a36Sopenharmony_ci u16 fp = 0; 156262306a36Sopenharmony_ci 156362306a36Sopenharmony_ci switch (cdb[0]) { 156462306a36Sopenharmony_ci case WRITE_6: 156562306a36Sopenharmony_ci case WRITE_10: 156662306a36Sopenharmony_ci case WRITE_16: 156762306a36Sopenharmony_ci tf_flags |= ATA_TFLAG_WRITE; 156862306a36Sopenharmony_ci break; 156962306a36Sopenharmony_ci } 157062306a36Sopenharmony_ci 157162306a36Sopenharmony_ci /* Calculate the SCSI LBA, transfer length and FUA. */ 157262306a36Sopenharmony_ci switch (cdb[0]) { 157362306a36Sopenharmony_ci case READ_10: 157462306a36Sopenharmony_ci case WRITE_10: 157562306a36Sopenharmony_ci if (unlikely(scmd->cmd_len < 10)) { 157662306a36Sopenharmony_ci fp = 9; 157762306a36Sopenharmony_ci goto invalid_fld; 157862306a36Sopenharmony_ci } 157962306a36Sopenharmony_ci scsi_10_lba_len(cdb, &block, &n_block); 158062306a36Sopenharmony_ci if (cdb[1] & (1 << 3)) 158162306a36Sopenharmony_ci tf_flags |= ATA_TFLAG_FUA; 158262306a36Sopenharmony_ci if (!ata_check_nblocks(scmd, n_block)) 158362306a36Sopenharmony_ci goto invalid_fld; 158462306a36Sopenharmony_ci break; 158562306a36Sopenharmony_ci case READ_6: 158662306a36Sopenharmony_ci case WRITE_6: 158762306a36Sopenharmony_ci if (unlikely(scmd->cmd_len < 6)) { 158862306a36Sopenharmony_ci fp = 5; 158962306a36Sopenharmony_ci goto invalid_fld; 159062306a36Sopenharmony_ci } 159162306a36Sopenharmony_ci scsi_6_lba_len(cdb, &block, &n_block); 159262306a36Sopenharmony_ci 159362306a36Sopenharmony_ci /* for 6-byte r/w commands, transfer length 0 159462306a36Sopenharmony_ci * means 256 blocks of data, not 0 block. 159562306a36Sopenharmony_ci */ 159662306a36Sopenharmony_ci if (!n_block) 159762306a36Sopenharmony_ci n_block = 256; 159862306a36Sopenharmony_ci if (!ata_check_nblocks(scmd, n_block)) 159962306a36Sopenharmony_ci goto invalid_fld; 160062306a36Sopenharmony_ci break; 160162306a36Sopenharmony_ci case READ_16: 160262306a36Sopenharmony_ci case WRITE_16: 160362306a36Sopenharmony_ci if (unlikely(scmd->cmd_len < 16)) { 160462306a36Sopenharmony_ci fp = 15; 160562306a36Sopenharmony_ci goto invalid_fld; 160662306a36Sopenharmony_ci } 160762306a36Sopenharmony_ci scsi_16_lba_len(cdb, &block, &n_block); 160862306a36Sopenharmony_ci dld = scsi_dld(cdb); 160962306a36Sopenharmony_ci if (cdb[1] & (1 << 3)) 161062306a36Sopenharmony_ci tf_flags |= ATA_TFLAG_FUA; 161162306a36Sopenharmony_ci if (!ata_check_nblocks(scmd, n_block)) 161262306a36Sopenharmony_ci goto invalid_fld; 161362306a36Sopenharmony_ci break; 161462306a36Sopenharmony_ci default: 161562306a36Sopenharmony_ci fp = 0; 161662306a36Sopenharmony_ci goto invalid_fld; 161762306a36Sopenharmony_ci } 161862306a36Sopenharmony_ci 161962306a36Sopenharmony_ci /* Check and compose ATA command */ 162062306a36Sopenharmony_ci if (!n_block) 162162306a36Sopenharmony_ci /* For 10-byte and 16-byte SCSI R/W commands, transfer 162262306a36Sopenharmony_ci * length 0 means transfer 0 block of data. 162362306a36Sopenharmony_ci * However, for ATA R/W commands, sector count 0 means 162462306a36Sopenharmony_ci * 256 or 65536 sectors, not 0 sectors as in SCSI. 162562306a36Sopenharmony_ci * 162662306a36Sopenharmony_ci * WARNING: one or two older ATA drives treat 0 as 0... 162762306a36Sopenharmony_ci */ 162862306a36Sopenharmony_ci goto nothing_to_do; 162962306a36Sopenharmony_ci 163062306a36Sopenharmony_ci qc->flags |= ATA_QCFLAG_IO; 163162306a36Sopenharmony_ci qc->nbytes = n_block * scmd->device->sector_size; 163262306a36Sopenharmony_ci 163362306a36Sopenharmony_ci rc = ata_build_rw_tf(qc, block, n_block, tf_flags, dld, class); 163462306a36Sopenharmony_ci if (likely(rc == 0)) 163562306a36Sopenharmony_ci return 0; 163662306a36Sopenharmony_ci 163762306a36Sopenharmony_ci if (rc == -ERANGE) 163862306a36Sopenharmony_ci goto out_of_range; 163962306a36Sopenharmony_ci /* treat all other errors as -EINVAL, fall through */ 164062306a36Sopenharmony_ciinvalid_fld: 164162306a36Sopenharmony_ci ata_scsi_set_invalid_field(qc->dev, scmd, fp, 0xff); 164262306a36Sopenharmony_ci return 1; 164362306a36Sopenharmony_ci 164462306a36Sopenharmony_ciout_of_range: 164562306a36Sopenharmony_ci ata_scsi_set_sense(qc->dev, scmd, ILLEGAL_REQUEST, 0x21, 0x0); 164662306a36Sopenharmony_ci /* "Logical Block Address out of range" */ 164762306a36Sopenharmony_ci return 1; 164862306a36Sopenharmony_ci 164962306a36Sopenharmony_cinothing_to_do: 165062306a36Sopenharmony_ci scmd->result = SAM_STAT_GOOD; 165162306a36Sopenharmony_ci return 1; 165262306a36Sopenharmony_ci} 165362306a36Sopenharmony_ci 165462306a36Sopenharmony_cistatic void ata_qc_done(struct ata_queued_cmd *qc) 165562306a36Sopenharmony_ci{ 165662306a36Sopenharmony_ci struct scsi_cmnd *cmd = qc->scsicmd; 165762306a36Sopenharmony_ci void (*done)(struct scsi_cmnd *) = qc->scsidone; 165862306a36Sopenharmony_ci 165962306a36Sopenharmony_ci ata_qc_free(qc); 166062306a36Sopenharmony_ci done(cmd); 166162306a36Sopenharmony_ci} 166262306a36Sopenharmony_ci 166362306a36Sopenharmony_cistatic void ata_scsi_qc_complete(struct ata_queued_cmd *qc) 166462306a36Sopenharmony_ci{ 166562306a36Sopenharmony_ci struct scsi_cmnd *cmd = qc->scsicmd; 166662306a36Sopenharmony_ci u8 *cdb = cmd->cmnd; 166762306a36Sopenharmony_ci int need_sense = (qc->err_mask != 0) && 166862306a36Sopenharmony_ci !(qc->flags & ATA_QCFLAG_SENSE_VALID); 166962306a36Sopenharmony_ci 167062306a36Sopenharmony_ci /* For ATA pass thru (SAT) commands, generate a sense block if 167162306a36Sopenharmony_ci * user mandated it or if there's an error. Note that if we 167262306a36Sopenharmony_ci * generate because the user forced us to [CK_COND =1], a check 167362306a36Sopenharmony_ci * condition is generated and the ATA register values are returned 167462306a36Sopenharmony_ci * whether the command completed successfully or not. If there 167562306a36Sopenharmony_ci * was no error, we use the following sense data: 167662306a36Sopenharmony_ci * sk = RECOVERED ERROR 167762306a36Sopenharmony_ci * asc,ascq = ATA PASS-THROUGH INFORMATION AVAILABLE 167862306a36Sopenharmony_ci */ 167962306a36Sopenharmony_ci if (((cdb[0] == ATA_16) || (cdb[0] == ATA_12)) && 168062306a36Sopenharmony_ci ((cdb[2] & 0x20) || need_sense)) 168162306a36Sopenharmony_ci ata_gen_passthru_sense(qc); 168262306a36Sopenharmony_ci else if (need_sense) 168362306a36Sopenharmony_ci ata_gen_ata_sense(qc); 168462306a36Sopenharmony_ci else 168562306a36Sopenharmony_ci /* Keep the SCSI ML and status byte, clear host byte. */ 168662306a36Sopenharmony_ci cmd->result &= 0x0000ffff; 168762306a36Sopenharmony_ci 168862306a36Sopenharmony_ci ata_qc_done(qc); 168962306a36Sopenharmony_ci} 169062306a36Sopenharmony_ci 169162306a36Sopenharmony_ci/** 169262306a36Sopenharmony_ci * ata_scsi_translate - Translate then issue SCSI command to ATA device 169362306a36Sopenharmony_ci * @dev: ATA device to which the command is addressed 169462306a36Sopenharmony_ci * @cmd: SCSI command to execute 169562306a36Sopenharmony_ci * @xlat_func: Actor which translates @cmd to an ATA taskfile 169662306a36Sopenharmony_ci * 169762306a36Sopenharmony_ci * Our ->queuecommand() function has decided that the SCSI 169862306a36Sopenharmony_ci * command issued can be directly translated into an ATA 169962306a36Sopenharmony_ci * command, rather than handled internally. 170062306a36Sopenharmony_ci * 170162306a36Sopenharmony_ci * This function sets up an ata_queued_cmd structure for the 170262306a36Sopenharmony_ci * SCSI command, and sends that ata_queued_cmd to the hardware. 170362306a36Sopenharmony_ci * 170462306a36Sopenharmony_ci * The xlat_func argument (actor) returns 0 if ready to execute 170562306a36Sopenharmony_ci * ATA command, else 1 to finish translation. If 1 is returned 170662306a36Sopenharmony_ci * then cmd->result (and possibly cmd->sense_buffer) are assumed 170762306a36Sopenharmony_ci * to be set reflecting an error condition or clean (early) 170862306a36Sopenharmony_ci * termination. 170962306a36Sopenharmony_ci * 171062306a36Sopenharmony_ci * LOCKING: 171162306a36Sopenharmony_ci * spin_lock_irqsave(host lock) 171262306a36Sopenharmony_ci * 171362306a36Sopenharmony_ci * RETURNS: 171462306a36Sopenharmony_ci * 0 on success, SCSI_ML_QUEUE_DEVICE_BUSY if the command 171562306a36Sopenharmony_ci * needs to be deferred. 171662306a36Sopenharmony_ci */ 171762306a36Sopenharmony_cistatic int ata_scsi_translate(struct ata_device *dev, struct scsi_cmnd *cmd, 171862306a36Sopenharmony_ci ata_xlat_func_t xlat_func) 171962306a36Sopenharmony_ci{ 172062306a36Sopenharmony_ci struct ata_port *ap = dev->link->ap; 172162306a36Sopenharmony_ci struct ata_queued_cmd *qc; 172262306a36Sopenharmony_ci int rc; 172362306a36Sopenharmony_ci 172462306a36Sopenharmony_ci qc = ata_scsi_qc_new(dev, cmd); 172562306a36Sopenharmony_ci if (!qc) 172662306a36Sopenharmony_ci goto err_mem; 172762306a36Sopenharmony_ci 172862306a36Sopenharmony_ci /* data is present; dma-map it */ 172962306a36Sopenharmony_ci if (cmd->sc_data_direction == DMA_FROM_DEVICE || 173062306a36Sopenharmony_ci cmd->sc_data_direction == DMA_TO_DEVICE) { 173162306a36Sopenharmony_ci if (unlikely(scsi_bufflen(cmd) < 1)) { 173262306a36Sopenharmony_ci ata_dev_warn(dev, "WARNING: zero len r/w req\n"); 173362306a36Sopenharmony_ci goto err_did; 173462306a36Sopenharmony_ci } 173562306a36Sopenharmony_ci 173662306a36Sopenharmony_ci ata_sg_init(qc, scsi_sglist(cmd), scsi_sg_count(cmd)); 173762306a36Sopenharmony_ci 173862306a36Sopenharmony_ci qc->dma_dir = cmd->sc_data_direction; 173962306a36Sopenharmony_ci } 174062306a36Sopenharmony_ci 174162306a36Sopenharmony_ci qc->complete_fn = ata_scsi_qc_complete; 174262306a36Sopenharmony_ci 174362306a36Sopenharmony_ci if (xlat_func(qc)) 174462306a36Sopenharmony_ci goto early_finish; 174562306a36Sopenharmony_ci 174662306a36Sopenharmony_ci if (ap->ops->qc_defer) { 174762306a36Sopenharmony_ci if ((rc = ap->ops->qc_defer(qc))) 174862306a36Sopenharmony_ci goto defer; 174962306a36Sopenharmony_ci } 175062306a36Sopenharmony_ci 175162306a36Sopenharmony_ci /* select device, send command to hardware */ 175262306a36Sopenharmony_ci ata_qc_issue(qc); 175362306a36Sopenharmony_ci 175462306a36Sopenharmony_ci return 0; 175562306a36Sopenharmony_ci 175662306a36Sopenharmony_ciearly_finish: 175762306a36Sopenharmony_ci ata_qc_free(qc); 175862306a36Sopenharmony_ci scsi_done(cmd); 175962306a36Sopenharmony_ci return 0; 176062306a36Sopenharmony_ci 176162306a36Sopenharmony_cierr_did: 176262306a36Sopenharmony_ci ata_qc_free(qc); 176362306a36Sopenharmony_ci cmd->result = (DID_ERROR << 16); 176462306a36Sopenharmony_ci scsi_done(cmd); 176562306a36Sopenharmony_cierr_mem: 176662306a36Sopenharmony_ci return 0; 176762306a36Sopenharmony_ci 176862306a36Sopenharmony_cidefer: 176962306a36Sopenharmony_ci ata_qc_free(qc); 177062306a36Sopenharmony_ci if (rc == ATA_DEFER_LINK) 177162306a36Sopenharmony_ci return SCSI_MLQUEUE_DEVICE_BUSY; 177262306a36Sopenharmony_ci else 177362306a36Sopenharmony_ci return SCSI_MLQUEUE_HOST_BUSY; 177462306a36Sopenharmony_ci} 177562306a36Sopenharmony_ci 177662306a36Sopenharmony_cistruct ata_scsi_args { 177762306a36Sopenharmony_ci struct ata_device *dev; 177862306a36Sopenharmony_ci u16 *id; 177962306a36Sopenharmony_ci struct scsi_cmnd *cmd; 178062306a36Sopenharmony_ci}; 178162306a36Sopenharmony_ci 178262306a36Sopenharmony_ci/** 178362306a36Sopenharmony_ci * ata_scsi_rbuf_fill - wrapper for SCSI command simulators 178462306a36Sopenharmony_ci * @args: device IDENTIFY data / SCSI command of interest. 178562306a36Sopenharmony_ci * @actor: Callback hook for desired SCSI command simulator 178662306a36Sopenharmony_ci * 178762306a36Sopenharmony_ci * Takes care of the hard work of simulating a SCSI command... 178862306a36Sopenharmony_ci * Mapping the response buffer, calling the command's handler, 178962306a36Sopenharmony_ci * and handling the handler's return value. This return value 179062306a36Sopenharmony_ci * indicates whether the handler wishes the SCSI command to be 179162306a36Sopenharmony_ci * completed successfully (0), or not (in which case cmd->result 179262306a36Sopenharmony_ci * and sense buffer are assumed to be set). 179362306a36Sopenharmony_ci * 179462306a36Sopenharmony_ci * LOCKING: 179562306a36Sopenharmony_ci * spin_lock_irqsave(host lock) 179662306a36Sopenharmony_ci */ 179762306a36Sopenharmony_cistatic void ata_scsi_rbuf_fill(struct ata_scsi_args *args, 179862306a36Sopenharmony_ci unsigned int (*actor)(struct ata_scsi_args *args, u8 *rbuf)) 179962306a36Sopenharmony_ci{ 180062306a36Sopenharmony_ci unsigned int rc; 180162306a36Sopenharmony_ci struct scsi_cmnd *cmd = args->cmd; 180262306a36Sopenharmony_ci unsigned long flags; 180362306a36Sopenharmony_ci 180462306a36Sopenharmony_ci spin_lock_irqsave(&ata_scsi_rbuf_lock, flags); 180562306a36Sopenharmony_ci 180662306a36Sopenharmony_ci memset(ata_scsi_rbuf, 0, ATA_SCSI_RBUF_SIZE); 180762306a36Sopenharmony_ci rc = actor(args, ata_scsi_rbuf); 180862306a36Sopenharmony_ci if (rc == 0) 180962306a36Sopenharmony_ci sg_copy_from_buffer(scsi_sglist(cmd), scsi_sg_count(cmd), 181062306a36Sopenharmony_ci ata_scsi_rbuf, ATA_SCSI_RBUF_SIZE); 181162306a36Sopenharmony_ci 181262306a36Sopenharmony_ci spin_unlock_irqrestore(&ata_scsi_rbuf_lock, flags); 181362306a36Sopenharmony_ci 181462306a36Sopenharmony_ci if (rc == 0) 181562306a36Sopenharmony_ci cmd->result = SAM_STAT_GOOD; 181662306a36Sopenharmony_ci} 181762306a36Sopenharmony_ci 181862306a36Sopenharmony_ci/** 181962306a36Sopenharmony_ci * ata_scsiop_inq_std - Simulate INQUIRY command 182062306a36Sopenharmony_ci * @args: device IDENTIFY data / SCSI command of interest. 182162306a36Sopenharmony_ci * @rbuf: Response buffer, to which simulated SCSI cmd output is sent. 182262306a36Sopenharmony_ci * 182362306a36Sopenharmony_ci * Returns standard device identification data associated 182462306a36Sopenharmony_ci * with non-VPD INQUIRY command output. 182562306a36Sopenharmony_ci * 182662306a36Sopenharmony_ci * LOCKING: 182762306a36Sopenharmony_ci * spin_lock_irqsave(host lock) 182862306a36Sopenharmony_ci */ 182962306a36Sopenharmony_cistatic unsigned int ata_scsiop_inq_std(struct ata_scsi_args *args, u8 *rbuf) 183062306a36Sopenharmony_ci{ 183162306a36Sopenharmony_ci static const u8 versions[] = { 183262306a36Sopenharmony_ci 0x00, 183362306a36Sopenharmony_ci 0x60, /* SAM-3 (no version claimed) */ 183462306a36Sopenharmony_ci 183562306a36Sopenharmony_ci 0x03, 183662306a36Sopenharmony_ci 0x20, /* SBC-2 (no version claimed) */ 183762306a36Sopenharmony_ci 183862306a36Sopenharmony_ci 0x03, 183962306a36Sopenharmony_ci 0x00 /* SPC-3 (no version claimed) */ 184062306a36Sopenharmony_ci }; 184162306a36Sopenharmony_ci static const u8 versions_zbc[] = { 184262306a36Sopenharmony_ci 0x00, 184362306a36Sopenharmony_ci 0xA0, /* SAM-5 (no version claimed) */ 184462306a36Sopenharmony_ci 184562306a36Sopenharmony_ci 0x06, 184662306a36Sopenharmony_ci 0x00, /* SBC-4 (no version claimed) */ 184762306a36Sopenharmony_ci 184862306a36Sopenharmony_ci 0x05, 184962306a36Sopenharmony_ci 0xC0, /* SPC-5 (no version claimed) */ 185062306a36Sopenharmony_ci 185162306a36Sopenharmony_ci 0x60, 185262306a36Sopenharmony_ci 0x24, /* ZBC r05 */ 185362306a36Sopenharmony_ci }; 185462306a36Sopenharmony_ci 185562306a36Sopenharmony_ci u8 hdr[] = { 185662306a36Sopenharmony_ci TYPE_DISK, 185762306a36Sopenharmony_ci 0, 185862306a36Sopenharmony_ci 0x5, /* claim SPC-3 version compatibility */ 185962306a36Sopenharmony_ci 2, 186062306a36Sopenharmony_ci 95 - 4, 186162306a36Sopenharmony_ci 0, 186262306a36Sopenharmony_ci 0, 186362306a36Sopenharmony_ci 2 186462306a36Sopenharmony_ci }; 186562306a36Sopenharmony_ci 186662306a36Sopenharmony_ci /* set scsi removable (RMB) bit per ata bit, or if the 186762306a36Sopenharmony_ci * AHCI port says it's external (Hotplug-capable, eSATA). 186862306a36Sopenharmony_ci */ 186962306a36Sopenharmony_ci if (ata_id_removable(args->id) || 187062306a36Sopenharmony_ci (args->dev->link->ap->pflags & ATA_PFLAG_EXTERNAL)) 187162306a36Sopenharmony_ci hdr[1] |= (1 << 7); 187262306a36Sopenharmony_ci 187362306a36Sopenharmony_ci if (args->dev->class == ATA_DEV_ZAC) { 187462306a36Sopenharmony_ci hdr[0] = TYPE_ZBC; 187562306a36Sopenharmony_ci hdr[2] = 0x7; /* claim SPC-5 version compatibility */ 187662306a36Sopenharmony_ci } 187762306a36Sopenharmony_ci 187862306a36Sopenharmony_ci if (args->dev->flags & ATA_DFLAG_CDL) 187962306a36Sopenharmony_ci hdr[2] = 0xd; /* claim SPC-6 version compatibility */ 188062306a36Sopenharmony_ci 188162306a36Sopenharmony_ci memcpy(rbuf, hdr, sizeof(hdr)); 188262306a36Sopenharmony_ci memcpy(&rbuf[8], "ATA ", 8); 188362306a36Sopenharmony_ci ata_id_string(args->id, &rbuf[16], ATA_ID_PROD, 16); 188462306a36Sopenharmony_ci 188562306a36Sopenharmony_ci /* From SAT, use last 2 words from fw rev unless they are spaces */ 188662306a36Sopenharmony_ci ata_id_string(args->id, &rbuf[32], ATA_ID_FW_REV + 2, 4); 188762306a36Sopenharmony_ci if (strncmp(&rbuf[32], " ", 4) == 0) 188862306a36Sopenharmony_ci ata_id_string(args->id, &rbuf[32], ATA_ID_FW_REV, 4); 188962306a36Sopenharmony_ci 189062306a36Sopenharmony_ci if (rbuf[32] == 0 || rbuf[32] == ' ') 189162306a36Sopenharmony_ci memcpy(&rbuf[32], "n/a ", 4); 189262306a36Sopenharmony_ci 189362306a36Sopenharmony_ci if (ata_id_zoned_cap(args->id) || args->dev->class == ATA_DEV_ZAC) 189462306a36Sopenharmony_ci memcpy(rbuf + 58, versions_zbc, sizeof(versions_zbc)); 189562306a36Sopenharmony_ci else 189662306a36Sopenharmony_ci memcpy(rbuf + 58, versions, sizeof(versions)); 189762306a36Sopenharmony_ci 189862306a36Sopenharmony_ci return 0; 189962306a36Sopenharmony_ci} 190062306a36Sopenharmony_ci 190162306a36Sopenharmony_ci/** 190262306a36Sopenharmony_ci * ata_scsiop_inq_00 - Simulate INQUIRY VPD page 0, list of pages 190362306a36Sopenharmony_ci * @args: device IDENTIFY data / SCSI command of interest. 190462306a36Sopenharmony_ci * @rbuf: Response buffer, to which simulated SCSI cmd output is sent. 190562306a36Sopenharmony_ci * 190662306a36Sopenharmony_ci * Returns list of inquiry VPD pages available. 190762306a36Sopenharmony_ci * 190862306a36Sopenharmony_ci * LOCKING: 190962306a36Sopenharmony_ci * spin_lock_irqsave(host lock) 191062306a36Sopenharmony_ci */ 191162306a36Sopenharmony_cistatic unsigned int ata_scsiop_inq_00(struct ata_scsi_args *args, u8 *rbuf) 191262306a36Sopenharmony_ci{ 191362306a36Sopenharmony_ci int i, num_pages = 0; 191462306a36Sopenharmony_ci static const u8 pages[] = { 191562306a36Sopenharmony_ci 0x00, /* page 0x00, this page */ 191662306a36Sopenharmony_ci 0x80, /* page 0x80, unit serial no page */ 191762306a36Sopenharmony_ci 0x83, /* page 0x83, device ident page */ 191862306a36Sopenharmony_ci 0x89, /* page 0x89, ata info page */ 191962306a36Sopenharmony_ci 0xb0, /* page 0xb0, block limits page */ 192062306a36Sopenharmony_ci 0xb1, /* page 0xb1, block device characteristics page */ 192162306a36Sopenharmony_ci 0xb2, /* page 0xb2, thin provisioning page */ 192262306a36Sopenharmony_ci 0xb6, /* page 0xb6, zoned block device characteristics */ 192362306a36Sopenharmony_ci 0xb9, /* page 0xb9, concurrent positioning ranges */ 192462306a36Sopenharmony_ci }; 192562306a36Sopenharmony_ci 192662306a36Sopenharmony_ci for (i = 0; i < sizeof(pages); i++) { 192762306a36Sopenharmony_ci if (pages[i] == 0xb6 && 192862306a36Sopenharmony_ci !(args->dev->flags & ATA_DFLAG_ZAC)) 192962306a36Sopenharmony_ci continue; 193062306a36Sopenharmony_ci rbuf[num_pages + 4] = pages[i]; 193162306a36Sopenharmony_ci num_pages++; 193262306a36Sopenharmony_ci } 193362306a36Sopenharmony_ci rbuf[3] = num_pages; /* number of supported VPD pages */ 193462306a36Sopenharmony_ci return 0; 193562306a36Sopenharmony_ci} 193662306a36Sopenharmony_ci 193762306a36Sopenharmony_ci/** 193862306a36Sopenharmony_ci * ata_scsiop_inq_80 - Simulate INQUIRY VPD page 80, device serial number 193962306a36Sopenharmony_ci * @args: device IDENTIFY data / SCSI command of interest. 194062306a36Sopenharmony_ci * @rbuf: Response buffer, to which simulated SCSI cmd output is sent. 194162306a36Sopenharmony_ci * 194262306a36Sopenharmony_ci * Returns ATA device serial number. 194362306a36Sopenharmony_ci * 194462306a36Sopenharmony_ci * LOCKING: 194562306a36Sopenharmony_ci * spin_lock_irqsave(host lock) 194662306a36Sopenharmony_ci */ 194762306a36Sopenharmony_cistatic unsigned int ata_scsiop_inq_80(struct ata_scsi_args *args, u8 *rbuf) 194862306a36Sopenharmony_ci{ 194962306a36Sopenharmony_ci static const u8 hdr[] = { 195062306a36Sopenharmony_ci 0, 195162306a36Sopenharmony_ci 0x80, /* this page code */ 195262306a36Sopenharmony_ci 0, 195362306a36Sopenharmony_ci ATA_ID_SERNO_LEN, /* page len */ 195462306a36Sopenharmony_ci }; 195562306a36Sopenharmony_ci 195662306a36Sopenharmony_ci memcpy(rbuf, hdr, sizeof(hdr)); 195762306a36Sopenharmony_ci ata_id_string(args->id, (unsigned char *) &rbuf[4], 195862306a36Sopenharmony_ci ATA_ID_SERNO, ATA_ID_SERNO_LEN); 195962306a36Sopenharmony_ci return 0; 196062306a36Sopenharmony_ci} 196162306a36Sopenharmony_ci 196262306a36Sopenharmony_ci/** 196362306a36Sopenharmony_ci * ata_scsiop_inq_83 - Simulate INQUIRY VPD page 83, device identity 196462306a36Sopenharmony_ci * @args: device IDENTIFY data / SCSI command of interest. 196562306a36Sopenharmony_ci * @rbuf: Response buffer, to which simulated SCSI cmd output is sent. 196662306a36Sopenharmony_ci * 196762306a36Sopenharmony_ci * Yields two logical unit device identification designators: 196862306a36Sopenharmony_ci * - vendor specific ASCII containing the ATA serial number 196962306a36Sopenharmony_ci * - SAT defined "t10 vendor id based" containing ASCII vendor 197062306a36Sopenharmony_ci * name ("ATA "), model and serial numbers. 197162306a36Sopenharmony_ci * 197262306a36Sopenharmony_ci * LOCKING: 197362306a36Sopenharmony_ci * spin_lock_irqsave(host lock) 197462306a36Sopenharmony_ci */ 197562306a36Sopenharmony_cistatic unsigned int ata_scsiop_inq_83(struct ata_scsi_args *args, u8 *rbuf) 197662306a36Sopenharmony_ci{ 197762306a36Sopenharmony_ci const int sat_model_serial_desc_len = 68; 197862306a36Sopenharmony_ci int num; 197962306a36Sopenharmony_ci 198062306a36Sopenharmony_ci rbuf[1] = 0x83; /* this page code */ 198162306a36Sopenharmony_ci num = 4; 198262306a36Sopenharmony_ci 198362306a36Sopenharmony_ci /* piv=0, assoc=lu, code_set=ACSII, designator=vendor */ 198462306a36Sopenharmony_ci rbuf[num + 0] = 2; 198562306a36Sopenharmony_ci rbuf[num + 3] = ATA_ID_SERNO_LEN; 198662306a36Sopenharmony_ci num += 4; 198762306a36Sopenharmony_ci ata_id_string(args->id, (unsigned char *) rbuf + num, 198862306a36Sopenharmony_ci ATA_ID_SERNO, ATA_ID_SERNO_LEN); 198962306a36Sopenharmony_ci num += ATA_ID_SERNO_LEN; 199062306a36Sopenharmony_ci 199162306a36Sopenharmony_ci /* SAT defined lu model and serial numbers descriptor */ 199262306a36Sopenharmony_ci /* piv=0, assoc=lu, code_set=ACSII, designator=t10 vendor id */ 199362306a36Sopenharmony_ci rbuf[num + 0] = 2; 199462306a36Sopenharmony_ci rbuf[num + 1] = 1; 199562306a36Sopenharmony_ci rbuf[num + 3] = sat_model_serial_desc_len; 199662306a36Sopenharmony_ci num += 4; 199762306a36Sopenharmony_ci memcpy(rbuf + num, "ATA ", 8); 199862306a36Sopenharmony_ci num += 8; 199962306a36Sopenharmony_ci ata_id_string(args->id, (unsigned char *) rbuf + num, ATA_ID_PROD, 200062306a36Sopenharmony_ci ATA_ID_PROD_LEN); 200162306a36Sopenharmony_ci num += ATA_ID_PROD_LEN; 200262306a36Sopenharmony_ci ata_id_string(args->id, (unsigned char *) rbuf + num, ATA_ID_SERNO, 200362306a36Sopenharmony_ci ATA_ID_SERNO_LEN); 200462306a36Sopenharmony_ci num += ATA_ID_SERNO_LEN; 200562306a36Sopenharmony_ci 200662306a36Sopenharmony_ci if (ata_id_has_wwn(args->id)) { 200762306a36Sopenharmony_ci /* SAT defined lu world wide name */ 200862306a36Sopenharmony_ci /* piv=0, assoc=lu, code_set=binary, designator=NAA */ 200962306a36Sopenharmony_ci rbuf[num + 0] = 1; 201062306a36Sopenharmony_ci rbuf[num + 1] = 3; 201162306a36Sopenharmony_ci rbuf[num + 3] = ATA_ID_WWN_LEN; 201262306a36Sopenharmony_ci num += 4; 201362306a36Sopenharmony_ci ata_id_string(args->id, (unsigned char *) rbuf + num, 201462306a36Sopenharmony_ci ATA_ID_WWN, ATA_ID_WWN_LEN); 201562306a36Sopenharmony_ci num += ATA_ID_WWN_LEN; 201662306a36Sopenharmony_ci } 201762306a36Sopenharmony_ci rbuf[3] = num - 4; /* page len (assume less than 256 bytes) */ 201862306a36Sopenharmony_ci return 0; 201962306a36Sopenharmony_ci} 202062306a36Sopenharmony_ci 202162306a36Sopenharmony_ci/** 202262306a36Sopenharmony_ci * ata_scsiop_inq_89 - Simulate INQUIRY VPD page 89, ATA info 202362306a36Sopenharmony_ci * @args: device IDENTIFY data / SCSI command of interest. 202462306a36Sopenharmony_ci * @rbuf: Response buffer, to which simulated SCSI cmd output is sent. 202562306a36Sopenharmony_ci * 202662306a36Sopenharmony_ci * Yields SAT-specified ATA VPD page. 202762306a36Sopenharmony_ci * 202862306a36Sopenharmony_ci * LOCKING: 202962306a36Sopenharmony_ci * spin_lock_irqsave(host lock) 203062306a36Sopenharmony_ci */ 203162306a36Sopenharmony_cistatic unsigned int ata_scsiop_inq_89(struct ata_scsi_args *args, u8 *rbuf) 203262306a36Sopenharmony_ci{ 203362306a36Sopenharmony_ci rbuf[1] = 0x89; /* our page code */ 203462306a36Sopenharmony_ci rbuf[2] = (0x238 >> 8); /* page size fixed at 238h */ 203562306a36Sopenharmony_ci rbuf[3] = (0x238 & 0xff); 203662306a36Sopenharmony_ci 203762306a36Sopenharmony_ci memcpy(&rbuf[8], "linux ", 8); 203862306a36Sopenharmony_ci memcpy(&rbuf[16], "libata ", 16); 203962306a36Sopenharmony_ci memcpy(&rbuf[32], DRV_VERSION, 4); 204062306a36Sopenharmony_ci 204162306a36Sopenharmony_ci rbuf[36] = 0x34; /* force D2H Reg FIS (34h) */ 204262306a36Sopenharmony_ci rbuf[37] = (1 << 7); /* bit 7 indicates Command FIS */ 204362306a36Sopenharmony_ci /* TODO: PMP? */ 204462306a36Sopenharmony_ci 204562306a36Sopenharmony_ci /* we don't store the ATA device signature, so we fake it */ 204662306a36Sopenharmony_ci rbuf[38] = ATA_DRDY; /* really, this is Status reg */ 204762306a36Sopenharmony_ci rbuf[40] = 0x1; 204862306a36Sopenharmony_ci rbuf[48] = 0x1; 204962306a36Sopenharmony_ci 205062306a36Sopenharmony_ci rbuf[56] = ATA_CMD_ID_ATA; 205162306a36Sopenharmony_ci 205262306a36Sopenharmony_ci memcpy(&rbuf[60], &args->id[0], 512); 205362306a36Sopenharmony_ci return 0; 205462306a36Sopenharmony_ci} 205562306a36Sopenharmony_ci 205662306a36Sopenharmony_cistatic unsigned int ata_scsiop_inq_b0(struct ata_scsi_args *args, u8 *rbuf) 205762306a36Sopenharmony_ci{ 205862306a36Sopenharmony_ci struct ata_device *dev = args->dev; 205962306a36Sopenharmony_ci u16 min_io_sectors; 206062306a36Sopenharmony_ci 206162306a36Sopenharmony_ci rbuf[1] = 0xb0; 206262306a36Sopenharmony_ci rbuf[3] = 0x3c; /* required VPD size with unmap support */ 206362306a36Sopenharmony_ci 206462306a36Sopenharmony_ci /* 206562306a36Sopenharmony_ci * Optimal transfer length granularity. 206662306a36Sopenharmony_ci * 206762306a36Sopenharmony_ci * This is always one physical block, but for disks with a smaller 206862306a36Sopenharmony_ci * logical than physical sector size we need to figure out what the 206962306a36Sopenharmony_ci * latter is. 207062306a36Sopenharmony_ci */ 207162306a36Sopenharmony_ci min_io_sectors = 1 << ata_id_log2_per_physical_sector(args->id); 207262306a36Sopenharmony_ci put_unaligned_be16(min_io_sectors, &rbuf[6]); 207362306a36Sopenharmony_ci 207462306a36Sopenharmony_ci /* 207562306a36Sopenharmony_ci * Optimal unmap granularity. 207662306a36Sopenharmony_ci * 207762306a36Sopenharmony_ci * The ATA spec doesn't even know about a granularity or alignment 207862306a36Sopenharmony_ci * for the TRIM command. We can leave away most of the unmap related 207962306a36Sopenharmony_ci * VPD page entries, but we have specifify a granularity to signal 208062306a36Sopenharmony_ci * that we support some form of unmap - in thise case via WRITE SAME 208162306a36Sopenharmony_ci * with the unmap bit set. 208262306a36Sopenharmony_ci */ 208362306a36Sopenharmony_ci if (ata_id_has_trim(args->id)) { 208462306a36Sopenharmony_ci u64 max_blocks = 65535 * ATA_MAX_TRIM_RNUM; 208562306a36Sopenharmony_ci 208662306a36Sopenharmony_ci if (dev->horkage & ATA_HORKAGE_MAX_TRIM_128M) 208762306a36Sopenharmony_ci max_blocks = 128 << (20 - SECTOR_SHIFT); 208862306a36Sopenharmony_ci 208962306a36Sopenharmony_ci put_unaligned_be64(max_blocks, &rbuf[36]); 209062306a36Sopenharmony_ci put_unaligned_be32(1, &rbuf[28]); 209162306a36Sopenharmony_ci } 209262306a36Sopenharmony_ci 209362306a36Sopenharmony_ci return 0; 209462306a36Sopenharmony_ci} 209562306a36Sopenharmony_ci 209662306a36Sopenharmony_cistatic unsigned int ata_scsiop_inq_b1(struct ata_scsi_args *args, u8 *rbuf) 209762306a36Sopenharmony_ci{ 209862306a36Sopenharmony_ci int form_factor = ata_id_form_factor(args->id); 209962306a36Sopenharmony_ci int media_rotation_rate = ata_id_rotation_rate(args->id); 210062306a36Sopenharmony_ci u8 zoned = ata_id_zoned_cap(args->id); 210162306a36Sopenharmony_ci 210262306a36Sopenharmony_ci rbuf[1] = 0xb1; 210362306a36Sopenharmony_ci rbuf[3] = 0x3c; 210462306a36Sopenharmony_ci rbuf[4] = media_rotation_rate >> 8; 210562306a36Sopenharmony_ci rbuf[5] = media_rotation_rate; 210662306a36Sopenharmony_ci rbuf[7] = form_factor; 210762306a36Sopenharmony_ci if (zoned) 210862306a36Sopenharmony_ci rbuf[8] = (zoned << 4); 210962306a36Sopenharmony_ci 211062306a36Sopenharmony_ci return 0; 211162306a36Sopenharmony_ci} 211262306a36Sopenharmony_ci 211362306a36Sopenharmony_cistatic unsigned int ata_scsiop_inq_b2(struct ata_scsi_args *args, u8 *rbuf) 211462306a36Sopenharmony_ci{ 211562306a36Sopenharmony_ci /* SCSI Thin Provisioning VPD page: SBC-3 rev 22 or later */ 211662306a36Sopenharmony_ci rbuf[1] = 0xb2; 211762306a36Sopenharmony_ci rbuf[3] = 0x4; 211862306a36Sopenharmony_ci rbuf[5] = 1 << 6; /* TPWS */ 211962306a36Sopenharmony_ci 212062306a36Sopenharmony_ci return 0; 212162306a36Sopenharmony_ci} 212262306a36Sopenharmony_ci 212362306a36Sopenharmony_cistatic unsigned int ata_scsiop_inq_b6(struct ata_scsi_args *args, u8 *rbuf) 212462306a36Sopenharmony_ci{ 212562306a36Sopenharmony_ci /* 212662306a36Sopenharmony_ci * zbc-r05 SCSI Zoned Block device characteristics VPD page 212762306a36Sopenharmony_ci */ 212862306a36Sopenharmony_ci rbuf[1] = 0xb6; 212962306a36Sopenharmony_ci rbuf[3] = 0x3C; 213062306a36Sopenharmony_ci 213162306a36Sopenharmony_ci /* 213262306a36Sopenharmony_ci * URSWRZ bit is only meaningful for host-managed ZAC drives 213362306a36Sopenharmony_ci */ 213462306a36Sopenharmony_ci if (args->dev->zac_zoned_cap & 1) 213562306a36Sopenharmony_ci rbuf[4] |= 1; 213662306a36Sopenharmony_ci put_unaligned_be32(args->dev->zac_zones_optimal_open, &rbuf[8]); 213762306a36Sopenharmony_ci put_unaligned_be32(args->dev->zac_zones_optimal_nonseq, &rbuf[12]); 213862306a36Sopenharmony_ci put_unaligned_be32(args->dev->zac_zones_max_open, &rbuf[16]); 213962306a36Sopenharmony_ci 214062306a36Sopenharmony_ci return 0; 214162306a36Sopenharmony_ci} 214262306a36Sopenharmony_ci 214362306a36Sopenharmony_cistatic unsigned int ata_scsiop_inq_b9(struct ata_scsi_args *args, u8 *rbuf) 214462306a36Sopenharmony_ci{ 214562306a36Sopenharmony_ci struct ata_cpr_log *cpr_log = args->dev->cpr_log; 214662306a36Sopenharmony_ci u8 *desc = &rbuf[64]; 214762306a36Sopenharmony_ci int i; 214862306a36Sopenharmony_ci 214962306a36Sopenharmony_ci /* SCSI Concurrent Positioning Ranges VPD page: SBC-5 rev 1 or later */ 215062306a36Sopenharmony_ci rbuf[1] = 0xb9; 215162306a36Sopenharmony_ci put_unaligned_be16(64 + (int)cpr_log->nr_cpr * 32 - 4, &rbuf[2]); 215262306a36Sopenharmony_ci 215362306a36Sopenharmony_ci for (i = 0; i < cpr_log->nr_cpr; i++, desc += 32) { 215462306a36Sopenharmony_ci desc[0] = cpr_log->cpr[i].num; 215562306a36Sopenharmony_ci desc[1] = cpr_log->cpr[i].num_storage_elements; 215662306a36Sopenharmony_ci put_unaligned_be64(cpr_log->cpr[i].start_lba, &desc[8]); 215762306a36Sopenharmony_ci put_unaligned_be64(cpr_log->cpr[i].num_lbas, &desc[16]); 215862306a36Sopenharmony_ci } 215962306a36Sopenharmony_ci 216062306a36Sopenharmony_ci return 0; 216162306a36Sopenharmony_ci} 216262306a36Sopenharmony_ci 216362306a36Sopenharmony_ci/** 216462306a36Sopenharmony_ci * modecpy - Prepare response for MODE SENSE 216562306a36Sopenharmony_ci * @dest: output buffer 216662306a36Sopenharmony_ci * @src: data being copied 216762306a36Sopenharmony_ci * @n: length of mode page 216862306a36Sopenharmony_ci * @changeable: whether changeable parameters are requested 216962306a36Sopenharmony_ci * 217062306a36Sopenharmony_ci * Generate a generic MODE SENSE page for either current or changeable 217162306a36Sopenharmony_ci * parameters. 217262306a36Sopenharmony_ci * 217362306a36Sopenharmony_ci * LOCKING: 217462306a36Sopenharmony_ci * None. 217562306a36Sopenharmony_ci */ 217662306a36Sopenharmony_cistatic void modecpy(u8 *dest, const u8 *src, int n, bool changeable) 217762306a36Sopenharmony_ci{ 217862306a36Sopenharmony_ci if (changeable) { 217962306a36Sopenharmony_ci memcpy(dest, src, 2); 218062306a36Sopenharmony_ci memset(dest + 2, 0, n - 2); 218162306a36Sopenharmony_ci } else { 218262306a36Sopenharmony_ci memcpy(dest, src, n); 218362306a36Sopenharmony_ci } 218462306a36Sopenharmony_ci} 218562306a36Sopenharmony_ci 218662306a36Sopenharmony_ci/** 218762306a36Sopenharmony_ci * ata_msense_caching - Simulate MODE SENSE caching info page 218862306a36Sopenharmony_ci * @id: device IDENTIFY data 218962306a36Sopenharmony_ci * @buf: output buffer 219062306a36Sopenharmony_ci * @changeable: whether changeable parameters are requested 219162306a36Sopenharmony_ci * 219262306a36Sopenharmony_ci * Generate a caching info page, which conditionally indicates 219362306a36Sopenharmony_ci * write caching to the SCSI layer, depending on device 219462306a36Sopenharmony_ci * capabilities. 219562306a36Sopenharmony_ci * 219662306a36Sopenharmony_ci * LOCKING: 219762306a36Sopenharmony_ci * None. 219862306a36Sopenharmony_ci */ 219962306a36Sopenharmony_cistatic unsigned int ata_msense_caching(u16 *id, u8 *buf, bool changeable) 220062306a36Sopenharmony_ci{ 220162306a36Sopenharmony_ci modecpy(buf, def_cache_mpage, sizeof(def_cache_mpage), changeable); 220262306a36Sopenharmony_ci if (changeable) { 220362306a36Sopenharmony_ci buf[2] |= (1 << 2); /* ata_mselect_caching() */ 220462306a36Sopenharmony_ci } else { 220562306a36Sopenharmony_ci buf[2] |= (ata_id_wcache_enabled(id) << 2); /* write cache enable */ 220662306a36Sopenharmony_ci buf[12] |= (!ata_id_rahead_enabled(id) << 5); /* disable read ahead */ 220762306a36Sopenharmony_ci } 220862306a36Sopenharmony_ci return sizeof(def_cache_mpage); 220962306a36Sopenharmony_ci} 221062306a36Sopenharmony_ci 221162306a36Sopenharmony_ci/* 221262306a36Sopenharmony_ci * Simulate MODE SENSE control mode page, sub-page 0. 221362306a36Sopenharmony_ci */ 221462306a36Sopenharmony_cistatic unsigned int ata_msense_control_spg0(struct ata_device *dev, u8 *buf, 221562306a36Sopenharmony_ci bool changeable) 221662306a36Sopenharmony_ci{ 221762306a36Sopenharmony_ci modecpy(buf, def_control_mpage, 221862306a36Sopenharmony_ci sizeof(def_control_mpage), changeable); 221962306a36Sopenharmony_ci if (changeable) { 222062306a36Sopenharmony_ci /* ata_mselect_control() */ 222162306a36Sopenharmony_ci buf[2] |= (1 << 2); 222262306a36Sopenharmony_ci } else { 222362306a36Sopenharmony_ci bool d_sense = (dev->flags & ATA_DFLAG_D_SENSE); 222462306a36Sopenharmony_ci 222562306a36Sopenharmony_ci /* descriptor format sense data */ 222662306a36Sopenharmony_ci buf[2] |= (d_sense << 2); 222762306a36Sopenharmony_ci } 222862306a36Sopenharmony_ci 222962306a36Sopenharmony_ci return sizeof(def_control_mpage); 223062306a36Sopenharmony_ci} 223162306a36Sopenharmony_ci 223262306a36Sopenharmony_ci/* 223362306a36Sopenharmony_ci * Translate an ATA duration limit in microseconds to a SCSI duration limit 223462306a36Sopenharmony_ci * using the t2cdlunits 0xa (10ms). Since the SCSI duration limits are 2-bytes 223562306a36Sopenharmony_ci * only, take care of overflows. 223662306a36Sopenharmony_ci */ 223762306a36Sopenharmony_cistatic inline u16 ata_xlat_cdl_limit(u8 *buf) 223862306a36Sopenharmony_ci{ 223962306a36Sopenharmony_ci u32 limit = get_unaligned_le32(buf); 224062306a36Sopenharmony_ci 224162306a36Sopenharmony_ci return min_t(u32, limit / 10000, 65535); 224262306a36Sopenharmony_ci} 224362306a36Sopenharmony_ci 224462306a36Sopenharmony_ci/* 224562306a36Sopenharmony_ci * Simulate MODE SENSE control mode page, sub-pages 07h and 08h 224662306a36Sopenharmony_ci * (command duration limits T2A and T2B mode pages). 224762306a36Sopenharmony_ci */ 224862306a36Sopenharmony_cistatic unsigned int ata_msense_control_spgt2(struct ata_device *dev, u8 *buf, 224962306a36Sopenharmony_ci u8 spg) 225062306a36Sopenharmony_ci{ 225162306a36Sopenharmony_ci u8 *b, *cdl = dev->cdl, *desc; 225262306a36Sopenharmony_ci u32 policy; 225362306a36Sopenharmony_ci int i; 225462306a36Sopenharmony_ci 225562306a36Sopenharmony_ci /* 225662306a36Sopenharmony_ci * Fill the subpage. The first four bytes of the T2A/T2B mode pages 225762306a36Sopenharmony_ci * are a header. The PAGE LENGTH field is the size of the page 225862306a36Sopenharmony_ci * excluding the header. 225962306a36Sopenharmony_ci */ 226062306a36Sopenharmony_ci buf[0] = CONTROL_MPAGE; 226162306a36Sopenharmony_ci buf[1] = spg; 226262306a36Sopenharmony_ci put_unaligned_be16(CDL_T2_SUB_MPAGE_LEN - 4, &buf[2]); 226362306a36Sopenharmony_ci if (spg == CDL_T2A_SUB_MPAGE) { 226462306a36Sopenharmony_ci /* 226562306a36Sopenharmony_ci * Read descriptors map to the T2A page: 226662306a36Sopenharmony_ci * set perf_vs_duration_guidleine. 226762306a36Sopenharmony_ci */ 226862306a36Sopenharmony_ci buf[7] = (cdl[0] & 0x03) << 4; 226962306a36Sopenharmony_ci desc = cdl + 64; 227062306a36Sopenharmony_ci } else { 227162306a36Sopenharmony_ci /* Write descriptors map to the T2B page */ 227262306a36Sopenharmony_ci desc = cdl + 288; 227362306a36Sopenharmony_ci } 227462306a36Sopenharmony_ci 227562306a36Sopenharmony_ci /* Fill the T2 page descriptors */ 227662306a36Sopenharmony_ci b = &buf[8]; 227762306a36Sopenharmony_ci policy = get_unaligned_le32(&cdl[0]); 227862306a36Sopenharmony_ci for (i = 0; i < 7; i++, b += 32, desc += 32) { 227962306a36Sopenharmony_ci /* t2cdlunits: fixed to 10ms */ 228062306a36Sopenharmony_ci b[0] = 0x0a; 228162306a36Sopenharmony_ci 228262306a36Sopenharmony_ci /* Max inactive time and its policy */ 228362306a36Sopenharmony_ci put_unaligned_be16(ata_xlat_cdl_limit(&desc[8]), &b[2]); 228462306a36Sopenharmony_ci b[6] = ((policy >> 8) & 0x0f) << 4; 228562306a36Sopenharmony_ci 228662306a36Sopenharmony_ci /* Max active time and its policy */ 228762306a36Sopenharmony_ci put_unaligned_be16(ata_xlat_cdl_limit(&desc[4]), &b[4]); 228862306a36Sopenharmony_ci b[6] |= (policy >> 4) & 0x0f; 228962306a36Sopenharmony_ci 229062306a36Sopenharmony_ci /* Command duration guideline and its policy */ 229162306a36Sopenharmony_ci put_unaligned_be16(ata_xlat_cdl_limit(&desc[16]), &b[10]); 229262306a36Sopenharmony_ci b[14] = policy & 0x0f; 229362306a36Sopenharmony_ci } 229462306a36Sopenharmony_ci 229562306a36Sopenharmony_ci return CDL_T2_SUB_MPAGE_LEN; 229662306a36Sopenharmony_ci} 229762306a36Sopenharmony_ci 229862306a36Sopenharmony_ci/* 229962306a36Sopenharmony_ci * Simulate MODE SENSE control mode page, sub-page f2h 230062306a36Sopenharmony_ci * (ATA feature control mode page). 230162306a36Sopenharmony_ci */ 230262306a36Sopenharmony_cistatic unsigned int ata_msense_control_ata_feature(struct ata_device *dev, 230362306a36Sopenharmony_ci u8 *buf) 230462306a36Sopenharmony_ci{ 230562306a36Sopenharmony_ci /* PS=0, SPF=1 */ 230662306a36Sopenharmony_ci buf[0] = CONTROL_MPAGE | (1 << 6); 230762306a36Sopenharmony_ci buf[1] = ATA_FEATURE_SUB_MPAGE; 230862306a36Sopenharmony_ci 230962306a36Sopenharmony_ci /* 231062306a36Sopenharmony_ci * The first four bytes of ATA Feature Control mode page are a header. 231162306a36Sopenharmony_ci * The PAGE LENGTH field is the size of the page excluding the header. 231262306a36Sopenharmony_ci */ 231362306a36Sopenharmony_ci put_unaligned_be16(ATA_FEATURE_SUB_MPAGE_LEN - 4, &buf[2]); 231462306a36Sopenharmony_ci 231562306a36Sopenharmony_ci if (dev->flags & ATA_DFLAG_CDL) 231662306a36Sopenharmony_ci buf[4] = 0x02; /* Support T2A and T2B pages */ 231762306a36Sopenharmony_ci else 231862306a36Sopenharmony_ci buf[4] = 0; 231962306a36Sopenharmony_ci 232062306a36Sopenharmony_ci return ATA_FEATURE_SUB_MPAGE_LEN; 232162306a36Sopenharmony_ci} 232262306a36Sopenharmony_ci 232362306a36Sopenharmony_ci/** 232462306a36Sopenharmony_ci * ata_msense_control - Simulate MODE SENSE control mode page 232562306a36Sopenharmony_ci * @dev: ATA device of interest 232662306a36Sopenharmony_ci * @buf: output buffer 232762306a36Sopenharmony_ci * @spg: sub-page code 232862306a36Sopenharmony_ci * @changeable: whether changeable parameters are requested 232962306a36Sopenharmony_ci * 233062306a36Sopenharmony_ci * Generate a generic MODE SENSE control mode page. 233162306a36Sopenharmony_ci * 233262306a36Sopenharmony_ci * LOCKING: 233362306a36Sopenharmony_ci * None. 233462306a36Sopenharmony_ci */ 233562306a36Sopenharmony_cistatic unsigned int ata_msense_control(struct ata_device *dev, u8 *buf, 233662306a36Sopenharmony_ci u8 spg, bool changeable) 233762306a36Sopenharmony_ci{ 233862306a36Sopenharmony_ci unsigned int n; 233962306a36Sopenharmony_ci 234062306a36Sopenharmony_ci switch (spg) { 234162306a36Sopenharmony_ci case 0: 234262306a36Sopenharmony_ci return ata_msense_control_spg0(dev, buf, changeable); 234362306a36Sopenharmony_ci case CDL_T2A_SUB_MPAGE: 234462306a36Sopenharmony_ci case CDL_T2B_SUB_MPAGE: 234562306a36Sopenharmony_ci return ata_msense_control_spgt2(dev, buf, spg); 234662306a36Sopenharmony_ci case ATA_FEATURE_SUB_MPAGE: 234762306a36Sopenharmony_ci return ata_msense_control_ata_feature(dev, buf); 234862306a36Sopenharmony_ci case ALL_SUB_MPAGES: 234962306a36Sopenharmony_ci n = ata_msense_control_spg0(dev, buf, changeable); 235062306a36Sopenharmony_ci n += ata_msense_control_spgt2(dev, buf + n, CDL_T2A_SUB_MPAGE); 235162306a36Sopenharmony_ci n += ata_msense_control_spgt2(dev, buf + n, CDL_T2A_SUB_MPAGE); 235262306a36Sopenharmony_ci n += ata_msense_control_ata_feature(dev, buf + n); 235362306a36Sopenharmony_ci return n; 235462306a36Sopenharmony_ci default: 235562306a36Sopenharmony_ci return 0; 235662306a36Sopenharmony_ci } 235762306a36Sopenharmony_ci} 235862306a36Sopenharmony_ci 235962306a36Sopenharmony_ci/** 236062306a36Sopenharmony_ci * ata_msense_rw_recovery - Simulate MODE SENSE r/w error recovery page 236162306a36Sopenharmony_ci * @buf: output buffer 236262306a36Sopenharmony_ci * @changeable: whether changeable parameters are requested 236362306a36Sopenharmony_ci * 236462306a36Sopenharmony_ci * Generate a generic MODE SENSE r/w error recovery page. 236562306a36Sopenharmony_ci * 236662306a36Sopenharmony_ci * LOCKING: 236762306a36Sopenharmony_ci * None. 236862306a36Sopenharmony_ci */ 236962306a36Sopenharmony_cistatic unsigned int ata_msense_rw_recovery(u8 *buf, bool changeable) 237062306a36Sopenharmony_ci{ 237162306a36Sopenharmony_ci modecpy(buf, def_rw_recovery_mpage, sizeof(def_rw_recovery_mpage), 237262306a36Sopenharmony_ci changeable); 237362306a36Sopenharmony_ci return sizeof(def_rw_recovery_mpage); 237462306a36Sopenharmony_ci} 237562306a36Sopenharmony_ci 237662306a36Sopenharmony_ci/** 237762306a36Sopenharmony_ci * ata_scsiop_mode_sense - Simulate MODE SENSE 6, 10 commands 237862306a36Sopenharmony_ci * @args: device IDENTIFY data / SCSI command of interest. 237962306a36Sopenharmony_ci * @rbuf: Response buffer, to which simulated SCSI cmd output is sent. 238062306a36Sopenharmony_ci * 238162306a36Sopenharmony_ci * Simulate MODE SENSE commands. Assume this is invoked for direct 238262306a36Sopenharmony_ci * access devices (e.g. disks) only. There should be no block 238362306a36Sopenharmony_ci * descriptor for other device types. 238462306a36Sopenharmony_ci * 238562306a36Sopenharmony_ci * LOCKING: 238662306a36Sopenharmony_ci * spin_lock_irqsave(host lock) 238762306a36Sopenharmony_ci */ 238862306a36Sopenharmony_cistatic unsigned int ata_scsiop_mode_sense(struct ata_scsi_args *args, u8 *rbuf) 238962306a36Sopenharmony_ci{ 239062306a36Sopenharmony_ci struct ata_device *dev = args->dev; 239162306a36Sopenharmony_ci u8 *scsicmd = args->cmd->cmnd, *p = rbuf; 239262306a36Sopenharmony_ci static const u8 sat_blk_desc[] = { 239362306a36Sopenharmony_ci 0, 0, 0, 0, /* number of blocks: sat unspecified */ 239462306a36Sopenharmony_ci 0, 239562306a36Sopenharmony_ci 0, 0x2, 0x0 /* block length: 512 bytes */ 239662306a36Sopenharmony_ci }; 239762306a36Sopenharmony_ci u8 pg, spg; 239862306a36Sopenharmony_ci unsigned int ebd, page_control, six_byte; 239962306a36Sopenharmony_ci u8 dpofua = 0, bp = 0xff; 240062306a36Sopenharmony_ci u16 fp; 240162306a36Sopenharmony_ci 240262306a36Sopenharmony_ci six_byte = (scsicmd[0] == MODE_SENSE); 240362306a36Sopenharmony_ci ebd = !(scsicmd[1] & 0x8); /* dbd bit inverted == edb */ 240462306a36Sopenharmony_ci /* 240562306a36Sopenharmony_ci * LLBA bit in msense(10) ignored (compliant) 240662306a36Sopenharmony_ci */ 240762306a36Sopenharmony_ci 240862306a36Sopenharmony_ci page_control = scsicmd[2] >> 6; 240962306a36Sopenharmony_ci switch (page_control) { 241062306a36Sopenharmony_ci case 0: /* current */ 241162306a36Sopenharmony_ci case 1: /* changeable */ 241262306a36Sopenharmony_ci case 2: /* defaults */ 241362306a36Sopenharmony_ci break; /* supported */ 241462306a36Sopenharmony_ci case 3: /* saved */ 241562306a36Sopenharmony_ci goto saving_not_supp; 241662306a36Sopenharmony_ci default: 241762306a36Sopenharmony_ci fp = 2; 241862306a36Sopenharmony_ci bp = 6; 241962306a36Sopenharmony_ci goto invalid_fld; 242062306a36Sopenharmony_ci } 242162306a36Sopenharmony_ci 242262306a36Sopenharmony_ci if (six_byte) 242362306a36Sopenharmony_ci p += 4 + (ebd ? 8 : 0); 242462306a36Sopenharmony_ci else 242562306a36Sopenharmony_ci p += 8 + (ebd ? 8 : 0); 242662306a36Sopenharmony_ci 242762306a36Sopenharmony_ci pg = scsicmd[2] & 0x3f; 242862306a36Sopenharmony_ci spg = scsicmd[3]; 242962306a36Sopenharmony_ci 243062306a36Sopenharmony_ci /* 243162306a36Sopenharmony_ci * Supported subpages: all subpages and sub-pages 07h, 08h and f2h of 243262306a36Sopenharmony_ci * the control page. 243362306a36Sopenharmony_ci */ 243462306a36Sopenharmony_ci if (spg) { 243562306a36Sopenharmony_ci switch (spg) { 243662306a36Sopenharmony_ci case ALL_SUB_MPAGES: 243762306a36Sopenharmony_ci break; 243862306a36Sopenharmony_ci case CDL_T2A_SUB_MPAGE: 243962306a36Sopenharmony_ci case CDL_T2B_SUB_MPAGE: 244062306a36Sopenharmony_ci case ATA_FEATURE_SUB_MPAGE: 244162306a36Sopenharmony_ci if (dev->flags & ATA_DFLAG_CDL && pg == CONTROL_MPAGE) 244262306a36Sopenharmony_ci break; 244362306a36Sopenharmony_ci fallthrough; 244462306a36Sopenharmony_ci default: 244562306a36Sopenharmony_ci fp = 3; 244662306a36Sopenharmony_ci goto invalid_fld; 244762306a36Sopenharmony_ci } 244862306a36Sopenharmony_ci } 244962306a36Sopenharmony_ci 245062306a36Sopenharmony_ci switch(pg) { 245162306a36Sopenharmony_ci case RW_RECOVERY_MPAGE: 245262306a36Sopenharmony_ci p += ata_msense_rw_recovery(p, page_control == 1); 245362306a36Sopenharmony_ci break; 245462306a36Sopenharmony_ci 245562306a36Sopenharmony_ci case CACHE_MPAGE: 245662306a36Sopenharmony_ci p += ata_msense_caching(args->id, p, page_control == 1); 245762306a36Sopenharmony_ci break; 245862306a36Sopenharmony_ci 245962306a36Sopenharmony_ci case CONTROL_MPAGE: 246062306a36Sopenharmony_ci p += ata_msense_control(args->dev, p, spg, page_control == 1); 246162306a36Sopenharmony_ci break; 246262306a36Sopenharmony_ci 246362306a36Sopenharmony_ci case ALL_MPAGES: 246462306a36Sopenharmony_ci p += ata_msense_rw_recovery(p, page_control == 1); 246562306a36Sopenharmony_ci p += ata_msense_caching(args->id, p, page_control == 1); 246662306a36Sopenharmony_ci p += ata_msense_control(args->dev, p, spg, page_control == 1); 246762306a36Sopenharmony_ci break; 246862306a36Sopenharmony_ci 246962306a36Sopenharmony_ci default: /* invalid page code */ 247062306a36Sopenharmony_ci fp = 2; 247162306a36Sopenharmony_ci goto invalid_fld; 247262306a36Sopenharmony_ci } 247362306a36Sopenharmony_ci 247462306a36Sopenharmony_ci if (dev->flags & ATA_DFLAG_FUA) 247562306a36Sopenharmony_ci dpofua = 1 << 4; 247662306a36Sopenharmony_ci 247762306a36Sopenharmony_ci if (six_byte) { 247862306a36Sopenharmony_ci rbuf[0] = p - rbuf - 1; 247962306a36Sopenharmony_ci rbuf[2] |= dpofua; 248062306a36Sopenharmony_ci if (ebd) { 248162306a36Sopenharmony_ci rbuf[3] = sizeof(sat_blk_desc); 248262306a36Sopenharmony_ci memcpy(rbuf + 4, sat_blk_desc, sizeof(sat_blk_desc)); 248362306a36Sopenharmony_ci } 248462306a36Sopenharmony_ci } else { 248562306a36Sopenharmony_ci put_unaligned_be16(p - rbuf - 2, &rbuf[0]); 248662306a36Sopenharmony_ci rbuf[3] |= dpofua; 248762306a36Sopenharmony_ci if (ebd) { 248862306a36Sopenharmony_ci rbuf[7] = sizeof(sat_blk_desc); 248962306a36Sopenharmony_ci memcpy(rbuf + 8, sat_blk_desc, sizeof(sat_blk_desc)); 249062306a36Sopenharmony_ci } 249162306a36Sopenharmony_ci } 249262306a36Sopenharmony_ci return 0; 249362306a36Sopenharmony_ci 249462306a36Sopenharmony_ciinvalid_fld: 249562306a36Sopenharmony_ci ata_scsi_set_invalid_field(dev, args->cmd, fp, bp); 249662306a36Sopenharmony_ci return 1; 249762306a36Sopenharmony_ci 249862306a36Sopenharmony_cisaving_not_supp: 249962306a36Sopenharmony_ci ata_scsi_set_sense(dev, args->cmd, ILLEGAL_REQUEST, 0x39, 0x0); 250062306a36Sopenharmony_ci /* "Saving parameters not supported" */ 250162306a36Sopenharmony_ci return 1; 250262306a36Sopenharmony_ci} 250362306a36Sopenharmony_ci 250462306a36Sopenharmony_ci/** 250562306a36Sopenharmony_ci * ata_scsiop_read_cap - Simulate READ CAPACITY[ 16] commands 250662306a36Sopenharmony_ci * @args: device IDENTIFY data / SCSI command of interest. 250762306a36Sopenharmony_ci * @rbuf: Response buffer, to which simulated SCSI cmd output is sent. 250862306a36Sopenharmony_ci * 250962306a36Sopenharmony_ci * Simulate READ CAPACITY commands. 251062306a36Sopenharmony_ci * 251162306a36Sopenharmony_ci * LOCKING: 251262306a36Sopenharmony_ci * None. 251362306a36Sopenharmony_ci */ 251462306a36Sopenharmony_cistatic unsigned int ata_scsiop_read_cap(struct ata_scsi_args *args, u8 *rbuf) 251562306a36Sopenharmony_ci{ 251662306a36Sopenharmony_ci struct ata_device *dev = args->dev; 251762306a36Sopenharmony_ci u64 last_lba = dev->n_sectors - 1; /* LBA of the last block */ 251862306a36Sopenharmony_ci u32 sector_size; /* physical sector size in bytes */ 251962306a36Sopenharmony_ci u8 log2_per_phys; 252062306a36Sopenharmony_ci u16 lowest_aligned; 252162306a36Sopenharmony_ci 252262306a36Sopenharmony_ci sector_size = ata_id_logical_sector_size(dev->id); 252362306a36Sopenharmony_ci log2_per_phys = ata_id_log2_per_physical_sector(dev->id); 252462306a36Sopenharmony_ci lowest_aligned = ata_id_logical_sector_offset(dev->id, log2_per_phys); 252562306a36Sopenharmony_ci 252662306a36Sopenharmony_ci if (args->cmd->cmnd[0] == READ_CAPACITY) { 252762306a36Sopenharmony_ci if (last_lba >= 0xffffffffULL) 252862306a36Sopenharmony_ci last_lba = 0xffffffff; 252962306a36Sopenharmony_ci 253062306a36Sopenharmony_ci /* sector count, 32-bit */ 253162306a36Sopenharmony_ci rbuf[0] = last_lba >> (8 * 3); 253262306a36Sopenharmony_ci rbuf[1] = last_lba >> (8 * 2); 253362306a36Sopenharmony_ci rbuf[2] = last_lba >> (8 * 1); 253462306a36Sopenharmony_ci rbuf[3] = last_lba; 253562306a36Sopenharmony_ci 253662306a36Sopenharmony_ci /* sector size */ 253762306a36Sopenharmony_ci rbuf[4] = sector_size >> (8 * 3); 253862306a36Sopenharmony_ci rbuf[5] = sector_size >> (8 * 2); 253962306a36Sopenharmony_ci rbuf[6] = sector_size >> (8 * 1); 254062306a36Sopenharmony_ci rbuf[7] = sector_size; 254162306a36Sopenharmony_ci } else { 254262306a36Sopenharmony_ci /* sector count, 64-bit */ 254362306a36Sopenharmony_ci rbuf[0] = last_lba >> (8 * 7); 254462306a36Sopenharmony_ci rbuf[1] = last_lba >> (8 * 6); 254562306a36Sopenharmony_ci rbuf[2] = last_lba >> (8 * 5); 254662306a36Sopenharmony_ci rbuf[3] = last_lba >> (8 * 4); 254762306a36Sopenharmony_ci rbuf[4] = last_lba >> (8 * 3); 254862306a36Sopenharmony_ci rbuf[5] = last_lba >> (8 * 2); 254962306a36Sopenharmony_ci rbuf[6] = last_lba >> (8 * 1); 255062306a36Sopenharmony_ci rbuf[7] = last_lba; 255162306a36Sopenharmony_ci 255262306a36Sopenharmony_ci /* sector size */ 255362306a36Sopenharmony_ci rbuf[ 8] = sector_size >> (8 * 3); 255462306a36Sopenharmony_ci rbuf[ 9] = sector_size >> (8 * 2); 255562306a36Sopenharmony_ci rbuf[10] = sector_size >> (8 * 1); 255662306a36Sopenharmony_ci rbuf[11] = sector_size; 255762306a36Sopenharmony_ci 255862306a36Sopenharmony_ci rbuf[12] = 0; 255962306a36Sopenharmony_ci rbuf[13] = log2_per_phys; 256062306a36Sopenharmony_ci rbuf[14] = (lowest_aligned >> 8) & 0x3f; 256162306a36Sopenharmony_ci rbuf[15] = lowest_aligned; 256262306a36Sopenharmony_ci 256362306a36Sopenharmony_ci if (ata_id_has_trim(args->id) && 256462306a36Sopenharmony_ci !(dev->horkage & ATA_HORKAGE_NOTRIM)) { 256562306a36Sopenharmony_ci rbuf[14] |= 0x80; /* LBPME */ 256662306a36Sopenharmony_ci 256762306a36Sopenharmony_ci if (ata_id_has_zero_after_trim(args->id) && 256862306a36Sopenharmony_ci dev->horkage & ATA_HORKAGE_ZERO_AFTER_TRIM) { 256962306a36Sopenharmony_ci ata_dev_info(dev, "Enabling discard_zeroes_data\n"); 257062306a36Sopenharmony_ci rbuf[14] |= 0x40; /* LBPRZ */ 257162306a36Sopenharmony_ci } 257262306a36Sopenharmony_ci } 257362306a36Sopenharmony_ci if (ata_id_zoned_cap(args->id) || 257462306a36Sopenharmony_ci args->dev->class == ATA_DEV_ZAC) 257562306a36Sopenharmony_ci rbuf[12] = (1 << 4); /* RC_BASIS */ 257662306a36Sopenharmony_ci } 257762306a36Sopenharmony_ci return 0; 257862306a36Sopenharmony_ci} 257962306a36Sopenharmony_ci 258062306a36Sopenharmony_ci/** 258162306a36Sopenharmony_ci * ata_scsiop_report_luns - Simulate REPORT LUNS command 258262306a36Sopenharmony_ci * @args: device IDENTIFY data / SCSI command of interest. 258362306a36Sopenharmony_ci * @rbuf: Response buffer, to which simulated SCSI cmd output is sent. 258462306a36Sopenharmony_ci * 258562306a36Sopenharmony_ci * Simulate REPORT LUNS command. 258662306a36Sopenharmony_ci * 258762306a36Sopenharmony_ci * LOCKING: 258862306a36Sopenharmony_ci * spin_lock_irqsave(host lock) 258962306a36Sopenharmony_ci */ 259062306a36Sopenharmony_cistatic unsigned int ata_scsiop_report_luns(struct ata_scsi_args *args, u8 *rbuf) 259162306a36Sopenharmony_ci{ 259262306a36Sopenharmony_ci rbuf[3] = 8; /* just one lun, LUN 0, size 8 bytes */ 259362306a36Sopenharmony_ci 259462306a36Sopenharmony_ci return 0; 259562306a36Sopenharmony_ci} 259662306a36Sopenharmony_ci 259762306a36Sopenharmony_ci/* 259862306a36Sopenharmony_ci * ATAPI devices typically report zero for their SCSI version, and sometimes 259962306a36Sopenharmony_ci * deviate from the spec WRT response data format. If SCSI version is 260062306a36Sopenharmony_ci * reported as zero like normal, then we make the following fixups: 260162306a36Sopenharmony_ci * 1) Fake MMC-5 version, to indicate to the Linux scsi midlayer this is a 260262306a36Sopenharmony_ci * modern device. 260362306a36Sopenharmony_ci * 2) Ensure response data format / ATAPI information are always correct. 260462306a36Sopenharmony_ci */ 260562306a36Sopenharmony_cistatic void atapi_fixup_inquiry(struct scsi_cmnd *cmd) 260662306a36Sopenharmony_ci{ 260762306a36Sopenharmony_ci u8 buf[4]; 260862306a36Sopenharmony_ci 260962306a36Sopenharmony_ci sg_copy_to_buffer(scsi_sglist(cmd), scsi_sg_count(cmd), buf, 4); 261062306a36Sopenharmony_ci if (buf[2] == 0) { 261162306a36Sopenharmony_ci buf[2] = 0x5; 261262306a36Sopenharmony_ci buf[3] = 0x32; 261362306a36Sopenharmony_ci } 261462306a36Sopenharmony_ci sg_copy_from_buffer(scsi_sglist(cmd), scsi_sg_count(cmd), buf, 4); 261562306a36Sopenharmony_ci} 261662306a36Sopenharmony_ci 261762306a36Sopenharmony_cistatic void atapi_qc_complete(struct ata_queued_cmd *qc) 261862306a36Sopenharmony_ci{ 261962306a36Sopenharmony_ci struct scsi_cmnd *cmd = qc->scsicmd; 262062306a36Sopenharmony_ci unsigned int err_mask = qc->err_mask; 262162306a36Sopenharmony_ci 262262306a36Sopenharmony_ci /* handle completion from EH */ 262362306a36Sopenharmony_ci if (unlikely(err_mask || qc->flags & ATA_QCFLAG_SENSE_VALID)) { 262462306a36Sopenharmony_ci 262562306a36Sopenharmony_ci if (!(qc->flags & ATA_QCFLAG_SENSE_VALID)) { 262662306a36Sopenharmony_ci /* FIXME: not quite right; we don't want the 262762306a36Sopenharmony_ci * translation of taskfile registers into a 262862306a36Sopenharmony_ci * sense descriptors, since that's only 262962306a36Sopenharmony_ci * correct for ATA, not ATAPI 263062306a36Sopenharmony_ci */ 263162306a36Sopenharmony_ci ata_gen_passthru_sense(qc); 263262306a36Sopenharmony_ci } 263362306a36Sopenharmony_ci 263462306a36Sopenharmony_ci /* SCSI EH automatically locks door if sdev->locked is 263562306a36Sopenharmony_ci * set. Sometimes door lock request continues to 263662306a36Sopenharmony_ci * fail, for example, when no media is present. This 263762306a36Sopenharmony_ci * creates a loop - SCSI EH issues door lock which 263862306a36Sopenharmony_ci * fails and gets invoked again to acquire sense data 263962306a36Sopenharmony_ci * for the failed command. 264062306a36Sopenharmony_ci * 264162306a36Sopenharmony_ci * If door lock fails, always clear sdev->locked to 264262306a36Sopenharmony_ci * avoid this infinite loop. 264362306a36Sopenharmony_ci * 264462306a36Sopenharmony_ci * This may happen before SCSI scan is complete. Make 264562306a36Sopenharmony_ci * sure qc->dev->sdev isn't NULL before dereferencing. 264662306a36Sopenharmony_ci */ 264762306a36Sopenharmony_ci if (qc->cdb[0] == ALLOW_MEDIUM_REMOVAL && qc->dev->sdev) 264862306a36Sopenharmony_ci qc->dev->sdev->locked = 0; 264962306a36Sopenharmony_ci 265062306a36Sopenharmony_ci qc->scsicmd->result = SAM_STAT_CHECK_CONDITION; 265162306a36Sopenharmony_ci ata_qc_done(qc); 265262306a36Sopenharmony_ci return; 265362306a36Sopenharmony_ci } 265462306a36Sopenharmony_ci 265562306a36Sopenharmony_ci /* successful completion path */ 265662306a36Sopenharmony_ci if (cmd->cmnd[0] == INQUIRY && (cmd->cmnd[1] & 0x03) == 0) 265762306a36Sopenharmony_ci atapi_fixup_inquiry(cmd); 265862306a36Sopenharmony_ci cmd->result = SAM_STAT_GOOD; 265962306a36Sopenharmony_ci 266062306a36Sopenharmony_ci ata_qc_done(qc); 266162306a36Sopenharmony_ci} 266262306a36Sopenharmony_ci/** 266362306a36Sopenharmony_ci * atapi_xlat - Initialize PACKET taskfile 266462306a36Sopenharmony_ci * @qc: command structure to be initialized 266562306a36Sopenharmony_ci * 266662306a36Sopenharmony_ci * LOCKING: 266762306a36Sopenharmony_ci * spin_lock_irqsave(host lock) 266862306a36Sopenharmony_ci * 266962306a36Sopenharmony_ci * RETURNS: 267062306a36Sopenharmony_ci * Zero on success, non-zero on failure. 267162306a36Sopenharmony_ci */ 267262306a36Sopenharmony_cistatic unsigned int atapi_xlat(struct ata_queued_cmd *qc) 267362306a36Sopenharmony_ci{ 267462306a36Sopenharmony_ci struct scsi_cmnd *scmd = qc->scsicmd; 267562306a36Sopenharmony_ci struct ata_device *dev = qc->dev; 267662306a36Sopenharmony_ci int nodata = (scmd->sc_data_direction == DMA_NONE); 267762306a36Sopenharmony_ci int using_pio = !nodata && (dev->flags & ATA_DFLAG_PIO); 267862306a36Sopenharmony_ci unsigned int nbytes; 267962306a36Sopenharmony_ci 268062306a36Sopenharmony_ci memset(qc->cdb, 0, dev->cdb_len); 268162306a36Sopenharmony_ci memcpy(qc->cdb, scmd->cmnd, scmd->cmd_len); 268262306a36Sopenharmony_ci 268362306a36Sopenharmony_ci qc->complete_fn = atapi_qc_complete; 268462306a36Sopenharmony_ci 268562306a36Sopenharmony_ci qc->tf.flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE; 268662306a36Sopenharmony_ci if (scmd->sc_data_direction == DMA_TO_DEVICE) { 268762306a36Sopenharmony_ci qc->tf.flags |= ATA_TFLAG_WRITE; 268862306a36Sopenharmony_ci } 268962306a36Sopenharmony_ci 269062306a36Sopenharmony_ci qc->tf.command = ATA_CMD_PACKET; 269162306a36Sopenharmony_ci ata_qc_set_pc_nbytes(qc); 269262306a36Sopenharmony_ci 269362306a36Sopenharmony_ci /* check whether ATAPI DMA is safe */ 269462306a36Sopenharmony_ci if (!nodata && !using_pio && atapi_check_dma(qc)) 269562306a36Sopenharmony_ci using_pio = 1; 269662306a36Sopenharmony_ci 269762306a36Sopenharmony_ci /* Some controller variants snoop this value for Packet 269862306a36Sopenharmony_ci * transfers to do state machine and FIFO management. Thus we 269962306a36Sopenharmony_ci * want to set it properly, and for DMA where it is 270062306a36Sopenharmony_ci * effectively meaningless. 270162306a36Sopenharmony_ci */ 270262306a36Sopenharmony_ci nbytes = min(ata_qc_raw_nbytes(qc), (unsigned int)63 * 1024); 270362306a36Sopenharmony_ci 270462306a36Sopenharmony_ci /* Most ATAPI devices which honor transfer chunk size don't 270562306a36Sopenharmony_ci * behave according to the spec when odd chunk size which 270662306a36Sopenharmony_ci * matches the transfer length is specified. If the number of 270762306a36Sopenharmony_ci * bytes to transfer is 2n+1. According to the spec, what 270862306a36Sopenharmony_ci * should happen is to indicate that 2n+1 is going to be 270962306a36Sopenharmony_ci * transferred and transfer 2n+2 bytes where the last byte is 271062306a36Sopenharmony_ci * padding. 271162306a36Sopenharmony_ci * 271262306a36Sopenharmony_ci * In practice, this doesn't happen. ATAPI devices first 271362306a36Sopenharmony_ci * indicate and transfer 2n bytes and then indicate and 271462306a36Sopenharmony_ci * transfer 2 bytes where the last byte is padding. 271562306a36Sopenharmony_ci * 271662306a36Sopenharmony_ci * This inconsistency confuses several controllers which 271762306a36Sopenharmony_ci * perform PIO using DMA such as Intel AHCIs and sil3124/32. 271862306a36Sopenharmony_ci * These controllers use actual number of transferred bytes to 271962306a36Sopenharmony_ci * update DMA pointer and transfer of 4n+2 bytes make those 272062306a36Sopenharmony_ci * controller push DMA pointer by 4n+4 bytes because SATA data 272162306a36Sopenharmony_ci * FISes are aligned to 4 bytes. This causes data corruption 272262306a36Sopenharmony_ci * and buffer overrun. 272362306a36Sopenharmony_ci * 272462306a36Sopenharmony_ci * Always setting nbytes to even number solves this problem 272562306a36Sopenharmony_ci * because then ATAPI devices don't have to split data at 2n 272662306a36Sopenharmony_ci * boundaries. 272762306a36Sopenharmony_ci */ 272862306a36Sopenharmony_ci if (nbytes & 0x1) 272962306a36Sopenharmony_ci nbytes++; 273062306a36Sopenharmony_ci 273162306a36Sopenharmony_ci qc->tf.lbam = (nbytes & 0xFF); 273262306a36Sopenharmony_ci qc->tf.lbah = (nbytes >> 8); 273362306a36Sopenharmony_ci 273462306a36Sopenharmony_ci if (nodata) 273562306a36Sopenharmony_ci qc->tf.protocol = ATAPI_PROT_NODATA; 273662306a36Sopenharmony_ci else if (using_pio) 273762306a36Sopenharmony_ci qc->tf.protocol = ATAPI_PROT_PIO; 273862306a36Sopenharmony_ci else { 273962306a36Sopenharmony_ci /* DMA data xfer */ 274062306a36Sopenharmony_ci qc->tf.protocol = ATAPI_PROT_DMA; 274162306a36Sopenharmony_ci qc->tf.feature |= ATAPI_PKT_DMA; 274262306a36Sopenharmony_ci 274362306a36Sopenharmony_ci if ((dev->flags & ATA_DFLAG_DMADIR) && 274462306a36Sopenharmony_ci (scmd->sc_data_direction != DMA_TO_DEVICE)) 274562306a36Sopenharmony_ci /* some SATA bridges need us to indicate data xfer direction */ 274662306a36Sopenharmony_ci qc->tf.feature |= ATAPI_DMADIR; 274762306a36Sopenharmony_ci } 274862306a36Sopenharmony_ci 274962306a36Sopenharmony_ci 275062306a36Sopenharmony_ci /* FIXME: We need to translate 0x05 READ_BLOCK_LIMITS to a MODE_SENSE 275162306a36Sopenharmony_ci as ATAPI tape drives don't get this right otherwise */ 275262306a36Sopenharmony_ci return 0; 275362306a36Sopenharmony_ci} 275462306a36Sopenharmony_ci 275562306a36Sopenharmony_cistatic struct ata_device *ata_find_dev(struct ata_port *ap, unsigned int devno) 275662306a36Sopenharmony_ci{ 275762306a36Sopenharmony_ci /* 275862306a36Sopenharmony_ci * For the non-PMP case, ata_link_max_devices() returns 1 (SATA case), 275962306a36Sopenharmony_ci * or 2 (IDE master + slave case). However, the former case includes 276062306a36Sopenharmony_ci * libsas hosted devices which are numbered per scsi host, leading 276162306a36Sopenharmony_ci * to devno potentially being larger than 0 but with each struct 276262306a36Sopenharmony_ci * ata_device having its own struct ata_port and struct ata_link. 276362306a36Sopenharmony_ci * To accommodate these, ignore devno and always use device number 0. 276462306a36Sopenharmony_ci */ 276562306a36Sopenharmony_ci if (likely(!sata_pmp_attached(ap))) { 276662306a36Sopenharmony_ci int link_max_devices = ata_link_max_devices(&ap->link); 276762306a36Sopenharmony_ci 276862306a36Sopenharmony_ci if (link_max_devices == 1) 276962306a36Sopenharmony_ci return &ap->link.device[0]; 277062306a36Sopenharmony_ci 277162306a36Sopenharmony_ci if (devno < link_max_devices) 277262306a36Sopenharmony_ci return &ap->link.device[devno]; 277362306a36Sopenharmony_ci 277462306a36Sopenharmony_ci return NULL; 277562306a36Sopenharmony_ci } 277662306a36Sopenharmony_ci 277762306a36Sopenharmony_ci /* 277862306a36Sopenharmony_ci * For PMP-attached devices, the device number corresponds to C 277962306a36Sopenharmony_ci * (channel) of SCSI [H:C:I:L], indicating the port pmp link 278062306a36Sopenharmony_ci * for the device. 278162306a36Sopenharmony_ci */ 278262306a36Sopenharmony_ci if (devno < ap->nr_pmp_links) 278362306a36Sopenharmony_ci return &ap->pmp_link[devno].device[0]; 278462306a36Sopenharmony_ci 278562306a36Sopenharmony_ci return NULL; 278662306a36Sopenharmony_ci} 278762306a36Sopenharmony_ci 278862306a36Sopenharmony_cistatic struct ata_device *__ata_scsi_find_dev(struct ata_port *ap, 278962306a36Sopenharmony_ci const struct scsi_device *scsidev) 279062306a36Sopenharmony_ci{ 279162306a36Sopenharmony_ci int devno; 279262306a36Sopenharmony_ci 279362306a36Sopenharmony_ci /* skip commands not addressed to targets we simulate */ 279462306a36Sopenharmony_ci if (!sata_pmp_attached(ap)) { 279562306a36Sopenharmony_ci if (unlikely(scsidev->channel || scsidev->lun)) 279662306a36Sopenharmony_ci return NULL; 279762306a36Sopenharmony_ci devno = scsidev->id; 279862306a36Sopenharmony_ci } else { 279962306a36Sopenharmony_ci if (unlikely(scsidev->id || scsidev->lun)) 280062306a36Sopenharmony_ci return NULL; 280162306a36Sopenharmony_ci devno = scsidev->channel; 280262306a36Sopenharmony_ci } 280362306a36Sopenharmony_ci 280462306a36Sopenharmony_ci return ata_find_dev(ap, devno); 280562306a36Sopenharmony_ci} 280662306a36Sopenharmony_ci 280762306a36Sopenharmony_ci/** 280862306a36Sopenharmony_ci * ata_scsi_find_dev - lookup ata_device from scsi_cmnd 280962306a36Sopenharmony_ci * @ap: ATA port to which the device is attached 281062306a36Sopenharmony_ci * @scsidev: SCSI device from which we derive the ATA device 281162306a36Sopenharmony_ci * 281262306a36Sopenharmony_ci * Given various information provided in struct scsi_cmnd, 281362306a36Sopenharmony_ci * map that onto an ATA bus, and using that mapping 281462306a36Sopenharmony_ci * determine which ata_device is associated with the 281562306a36Sopenharmony_ci * SCSI command to be sent. 281662306a36Sopenharmony_ci * 281762306a36Sopenharmony_ci * LOCKING: 281862306a36Sopenharmony_ci * spin_lock_irqsave(host lock) 281962306a36Sopenharmony_ci * 282062306a36Sopenharmony_ci * RETURNS: 282162306a36Sopenharmony_ci * Associated ATA device, or %NULL if not found. 282262306a36Sopenharmony_ci */ 282362306a36Sopenharmony_cistruct ata_device * 282462306a36Sopenharmony_ciata_scsi_find_dev(struct ata_port *ap, const struct scsi_device *scsidev) 282562306a36Sopenharmony_ci{ 282662306a36Sopenharmony_ci struct ata_device *dev = __ata_scsi_find_dev(ap, scsidev); 282762306a36Sopenharmony_ci 282862306a36Sopenharmony_ci if (unlikely(!dev || !ata_dev_enabled(dev))) 282962306a36Sopenharmony_ci return NULL; 283062306a36Sopenharmony_ci 283162306a36Sopenharmony_ci return dev; 283262306a36Sopenharmony_ci} 283362306a36Sopenharmony_ci 283462306a36Sopenharmony_ci/* 283562306a36Sopenharmony_ci * ata_scsi_map_proto - Map pass-thru protocol value to taskfile value. 283662306a36Sopenharmony_ci * @byte1: Byte 1 from pass-thru CDB. 283762306a36Sopenharmony_ci * 283862306a36Sopenharmony_ci * RETURNS: 283962306a36Sopenharmony_ci * ATA_PROT_UNKNOWN if mapping failed/unimplemented, protocol otherwise. 284062306a36Sopenharmony_ci */ 284162306a36Sopenharmony_cistatic u8 284262306a36Sopenharmony_ciata_scsi_map_proto(u8 byte1) 284362306a36Sopenharmony_ci{ 284462306a36Sopenharmony_ci switch((byte1 & 0x1e) >> 1) { 284562306a36Sopenharmony_ci case 3: /* Non-data */ 284662306a36Sopenharmony_ci return ATA_PROT_NODATA; 284762306a36Sopenharmony_ci 284862306a36Sopenharmony_ci case 6: /* DMA */ 284962306a36Sopenharmony_ci case 10: /* UDMA Data-in */ 285062306a36Sopenharmony_ci case 11: /* UDMA Data-Out */ 285162306a36Sopenharmony_ci return ATA_PROT_DMA; 285262306a36Sopenharmony_ci 285362306a36Sopenharmony_ci case 4: /* PIO Data-in */ 285462306a36Sopenharmony_ci case 5: /* PIO Data-out */ 285562306a36Sopenharmony_ci return ATA_PROT_PIO; 285662306a36Sopenharmony_ci 285762306a36Sopenharmony_ci case 12: /* FPDMA */ 285862306a36Sopenharmony_ci return ATA_PROT_NCQ; 285962306a36Sopenharmony_ci 286062306a36Sopenharmony_ci case 0: /* Hard Reset */ 286162306a36Sopenharmony_ci case 1: /* SRST */ 286262306a36Sopenharmony_ci case 8: /* Device Diagnostic */ 286362306a36Sopenharmony_ci case 9: /* Device Reset */ 286462306a36Sopenharmony_ci case 7: /* DMA Queued */ 286562306a36Sopenharmony_ci case 15: /* Return Response Info */ 286662306a36Sopenharmony_ci default: /* Reserved */ 286762306a36Sopenharmony_ci break; 286862306a36Sopenharmony_ci } 286962306a36Sopenharmony_ci 287062306a36Sopenharmony_ci return ATA_PROT_UNKNOWN; 287162306a36Sopenharmony_ci} 287262306a36Sopenharmony_ci 287362306a36Sopenharmony_ci/** 287462306a36Sopenharmony_ci * ata_scsi_pass_thru - convert ATA pass-thru CDB to taskfile 287562306a36Sopenharmony_ci * @qc: command structure to be initialized 287662306a36Sopenharmony_ci * 287762306a36Sopenharmony_ci * Handles either 12, 16, or 32-byte versions of the CDB. 287862306a36Sopenharmony_ci * 287962306a36Sopenharmony_ci * RETURNS: 288062306a36Sopenharmony_ci * Zero on success, non-zero on failure. 288162306a36Sopenharmony_ci */ 288262306a36Sopenharmony_cistatic unsigned int ata_scsi_pass_thru(struct ata_queued_cmd *qc) 288362306a36Sopenharmony_ci{ 288462306a36Sopenharmony_ci struct ata_taskfile *tf = &(qc->tf); 288562306a36Sopenharmony_ci struct scsi_cmnd *scmd = qc->scsicmd; 288662306a36Sopenharmony_ci struct ata_device *dev = qc->dev; 288762306a36Sopenharmony_ci const u8 *cdb = scmd->cmnd; 288862306a36Sopenharmony_ci u16 fp; 288962306a36Sopenharmony_ci u16 cdb_offset = 0; 289062306a36Sopenharmony_ci 289162306a36Sopenharmony_ci /* 7Fh variable length cmd means a ata pass-thru(32) */ 289262306a36Sopenharmony_ci if (cdb[0] == VARIABLE_LENGTH_CMD) 289362306a36Sopenharmony_ci cdb_offset = 9; 289462306a36Sopenharmony_ci 289562306a36Sopenharmony_ci tf->protocol = ata_scsi_map_proto(cdb[1 + cdb_offset]); 289662306a36Sopenharmony_ci if (tf->protocol == ATA_PROT_UNKNOWN) { 289762306a36Sopenharmony_ci fp = 1; 289862306a36Sopenharmony_ci goto invalid_fld; 289962306a36Sopenharmony_ci } 290062306a36Sopenharmony_ci 290162306a36Sopenharmony_ci if ((cdb[2 + cdb_offset] & 0x3) == 0) { 290262306a36Sopenharmony_ci /* 290362306a36Sopenharmony_ci * When T_LENGTH is zero (No data is transferred), dir should 290462306a36Sopenharmony_ci * be DMA_NONE. 290562306a36Sopenharmony_ci */ 290662306a36Sopenharmony_ci if (scmd->sc_data_direction != DMA_NONE) { 290762306a36Sopenharmony_ci fp = 2 + cdb_offset; 290862306a36Sopenharmony_ci goto invalid_fld; 290962306a36Sopenharmony_ci } 291062306a36Sopenharmony_ci 291162306a36Sopenharmony_ci if (ata_is_ncq(tf->protocol)) 291262306a36Sopenharmony_ci tf->protocol = ATA_PROT_NCQ_NODATA; 291362306a36Sopenharmony_ci } 291462306a36Sopenharmony_ci 291562306a36Sopenharmony_ci /* enable LBA */ 291662306a36Sopenharmony_ci tf->flags |= ATA_TFLAG_LBA; 291762306a36Sopenharmony_ci 291862306a36Sopenharmony_ci /* 291962306a36Sopenharmony_ci * 12 and 16 byte CDBs use different offsets to 292062306a36Sopenharmony_ci * provide the various register values. 292162306a36Sopenharmony_ci */ 292262306a36Sopenharmony_ci switch (cdb[0]) { 292362306a36Sopenharmony_ci case ATA_16: 292462306a36Sopenharmony_ci /* 292562306a36Sopenharmony_ci * 16-byte CDB - may contain extended commands. 292662306a36Sopenharmony_ci * 292762306a36Sopenharmony_ci * If that is the case, copy the upper byte register values. 292862306a36Sopenharmony_ci */ 292962306a36Sopenharmony_ci if (cdb[1] & 0x01) { 293062306a36Sopenharmony_ci tf->hob_feature = cdb[3]; 293162306a36Sopenharmony_ci tf->hob_nsect = cdb[5]; 293262306a36Sopenharmony_ci tf->hob_lbal = cdb[7]; 293362306a36Sopenharmony_ci tf->hob_lbam = cdb[9]; 293462306a36Sopenharmony_ci tf->hob_lbah = cdb[11]; 293562306a36Sopenharmony_ci tf->flags |= ATA_TFLAG_LBA48; 293662306a36Sopenharmony_ci } else 293762306a36Sopenharmony_ci tf->flags &= ~ATA_TFLAG_LBA48; 293862306a36Sopenharmony_ci 293962306a36Sopenharmony_ci /* 294062306a36Sopenharmony_ci * Always copy low byte, device and command registers. 294162306a36Sopenharmony_ci */ 294262306a36Sopenharmony_ci tf->feature = cdb[4]; 294362306a36Sopenharmony_ci tf->nsect = cdb[6]; 294462306a36Sopenharmony_ci tf->lbal = cdb[8]; 294562306a36Sopenharmony_ci tf->lbam = cdb[10]; 294662306a36Sopenharmony_ci tf->lbah = cdb[12]; 294762306a36Sopenharmony_ci tf->device = cdb[13]; 294862306a36Sopenharmony_ci tf->command = cdb[14]; 294962306a36Sopenharmony_ci break; 295062306a36Sopenharmony_ci case ATA_12: 295162306a36Sopenharmony_ci /* 295262306a36Sopenharmony_ci * 12-byte CDB - incapable of extended commands. 295362306a36Sopenharmony_ci */ 295462306a36Sopenharmony_ci tf->flags &= ~ATA_TFLAG_LBA48; 295562306a36Sopenharmony_ci 295662306a36Sopenharmony_ci tf->feature = cdb[3]; 295762306a36Sopenharmony_ci tf->nsect = cdb[4]; 295862306a36Sopenharmony_ci tf->lbal = cdb[5]; 295962306a36Sopenharmony_ci tf->lbam = cdb[6]; 296062306a36Sopenharmony_ci tf->lbah = cdb[7]; 296162306a36Sopenharmony_ci tf->device = cdb[8]; 296262306a36Sopenharmony_ci tf->command = cdb[9]; 296362306a36Sopenharmony_ci break; 296462306a36Sopenharmony_ci default: 296562306a36Sopenharmony_ci /* 296662306a36Sopenharmony_ci * 32-byte CDB - may contain extended command fields. 296762306a36Sopenharmony_ci * 296862306a36Sopenharmony_ci * If that is the case, copy the upper byte register values. 296962306a36Sopenharmony_ci */ 297062306a36Sopenharmony_ci if (cdb[10] & 0x01) { 297162306a36Sopenharmony_ci tf->hob_feature = cdb[20]; 297262306a36Sopenharmony_ci tf->hob_nsect = cdb[22]; 297362306a36Sopenharmony_ci tf->hob_lbal = cdb[16]; 297462306a36Sopenharmony_ci tf->hob_lbam = cdb[15]; 297562306a36Sopenharmony_ci tf->hob_lbah = cdb[14]; 297662306a36Sopenharmony_ci tf->flags |= ATA_TFLAG_LBA48; 297762306a36Sopenharmony_ci } else 297862306a36Sopenharmony_ci tf->flags &= ~ATA_TFLAG_LBA48; 297962306a36Sopenharmony_ci 298062306a36Sopenharmony_ci tf->feature = cdb[21]; 298162306a36Sopenharmony_ci tf->nsect = cdb[23]; 298262306a36Sopenharmony_ci tf->lbal = cdb[19]; 298362306a36Sopenharmony_ci tf->lbam = cdb[18]; 298462306a36Sopenharmony_ci tf->lbah = cdb[17]; 298562306a36Sopenharmony_ci tf->device = cdb[24]; 298662306a36Sopenharmony_ci tf->command = cdb[25]; 298762306a36Sopenharmony_ci tf->auxiliary = get_unaligned_be32(&cdb[28]); 298862306a36Sopenharmony_ci break; 298962306a36Sopenharmony_ci } 299062306a36Sopenharmony_ci 299162306a36Sopenharmony_ci /* For NCQ commands copy the tag value */ 299262306a36Sopenharmony_ci if (ata_is_ncq(tf->protocol)) 299362306a36Sopenharmony_ci tf->nsect = qc->hw_tag << 3; 299462306a36Sopenharmony_ci 299562306a36Sopenharmony_ci /* enforce correct master/slave bit */ 299662306a36Sopenharmony_ci tf->device = dev->devno ? 299762306a36Sopenharmony_ci tf->device | ATA_DEV1 : tf->device & ~ATA_DEV1; 299862306a36Sopenharmony_ci 299962306a36Sopenharmony_ci switch (tf->command) { 300062306a36Sopenharmony_ci /* READ/WRITE LONG use a non-standard sect_size */ 300162306a36Sopenharmony_ci case ATA_CMD_READ_LONG: 300262306a36Sopenharmony_ci case ATA_CMD_READ_LONG_ONCE: 300362306a36Sopenharmony_ci case ATA_CMD_WRITE_LONG: 300462306a36Sopenharmony_ci case ATA_CMD_WRITE_LONG_ONCE: 300562306a36Sopenharmony_ci if (tf->protocol != ATA_PROT_PIO || tf->nsect != 1) { 300662306a36Sopenharmony_ci fp = 1; 300762306a36Sopenharmony_ci goto invalid_fld; 300862306a36Sopenharmony_ci } 300962306a36Sopenharmony_ci qc->sect_size = scsi_bufflen(scmd); 301062306a36Sopenharmony_ci break; 301162306a36Sopenharmony_ci 301262306a36Sopenharmony_ci /* commands using reported Logical Block size (e.g. 512 or 4K) */ 301362306a36Sopenharmony_ci case ATA_CMD_CFA_WRITE_NE: 301462306a36Sopenharmony_ci case ATA_CMD_CFA_TRANS_SECT: 301562306a36Sopenharmony_ci case ATA_CMD_CFA_WRITE_MULT_NE: 301662306a36Sopenharmony_ci /* XXX: case ATA_CMD_CFA_WRITE_SECTORS_WITHOUT_ERASE: */ 301762306a36Sopenharmony_ci case ATA_CMD_READ: 301862306a36Sopenharmony_ci case ATA_CMD_READ_EXT: 301962306a36Sopenharmony_ci case ATA_CMD_READ_QUEUED: 302062306a36Sopenharmony_ci /* XXX: case ATA_CMD_READ_QUEUED_EXT: */ 302162306a36Sopenharmony_ci case ATA_CMD_FPDMA_READ: 302262306a36Sopenharmony_ci case ATA_CMD_READ_MULTI: 302362306a36Sopenharmony_ci case ATA_CMD_READ_MULTI_EXT: 302462306a36Sopenharmony_ci case ATA_CMD_PIO_READ: 302562306a36Sopenharmony_ci case ATA_CMD_PIO_READ_EXT: 302662306a36Sopenharmony_ci case ATA_CMD_READ_STREAM_DMA_EXT: 302762306a36Sopenharmony_ci case ATA_CMD_READ_STREAM_EXT: 302862306a36Sopenharmony_ci case ATA_CMD_VERIFY: 302962306a36Sopenharmony_ci case ATA_CMD_VERIFY_EXT: 303062306a36Sopenharmony_ci case ATA_CMD_WRITE: 303162306a36Sopenharmony_ci case ATA_CMD_WRITE_EXT: 303262306a36Sopenharmony_ci case ATA_CMD_WRITE_FUA_EXT: 303362306a36Sopenharmony_ci case ATA_CMD_WRITE_QUEUED: 303462306a36Sopenharmony_ci case ATA_CMD_WRITE_QUEUED_FUA_EXT: 303562306a36Sopenharmony_ci case ATA_CMD_FPDMA_WRITE: 303662306a36Sopenharmony_ci case ATA_CMD_WRITE_MULTI: 303762306a36Sopenharmony_ci case ATA_CMD_WRITE_MULTI_EXT: 303862306a36Sopenharmony_ci case ATA_CMD_WRITE_MULTI_FUA_EXT: 303962306a36Sopenharmony_ci case ATA_CMD_PIO_WRITE: 304062306a36Sopenharmony_ci case ATA_CMD_PIO_WRITE_EXT: 304162306a36Sopenharmony_ci case ATA_CMD_WRITE_STREAM_DMA_EXT: 304262306a36Sopenharmony_ci case ATA_CMD_WRITE_STREAM_EXT: 304362306a36Sopenharmony_ci qc->sect_size = scmd->device->sector_size; 304462306a36Sopenharmony_ci break; 304562306a36Sopenharmony_ci 304662306a36Sopenharmony_ci /* Everything else uses 512 byte "sectors" */ 304762306a36Sopenharmony_ci default: 304862306a36Sopenharmony_ci qc->sect_size = ATA_SECT_SIZE; 304962306a36Sopenharmony_ci } 305062306a36Sopenharmony_ci 305162306a36Sopenharmony_ci /* 305262306a36Sopenharmony_ci * Set flags so that all registers will be written, pass on 305362306a36Sopenharmony_ci * write indication (used for PIO/DMA setup), result TF is 305462306a36Sopenharmony_ci * copied back and we don't whine too much about its failure. 305562306a36Sopenharmony_ci */ 305662306a36Sopenharmony_ci tf->flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE; 305762306a36Sopenharmony_ci if (scmd->sc_data_direction == DMA_TO_DEVICE) 305862306a36Sopenharmony_ci tf->flags |= ATA_TFLAG_WRITE; 305962306a36Sopenharmony_ci 306062306a36Sopenharmony_ci qc->flags |= ATA_QCFLAG_RESULT_TF | ATA_QCFLAG_QUIET; 306162306a36Sopenharmony_ci 306262306a36Sopenharmony_ci /* 306362306a36Sopenharmony_ci * Set transfer length. 306462306a36Sopenharmony_ci * 306562306a36Sopenharmony_ci * TODO: find out if we need to do more here to 306662306a36Sopenharmony_ci * cover scatter/gather case. 306762306a36Sopenharmony_ci */ 306862306a36Sopenharmony_ci ata_qc_set_pc_nbytes(qc); 306962306a36Sopenharmony_ci 307062306a36Sopenharmony_ci /* We may not issue DMA commands if no DMA mode is set */ 307162306a36Sopenharmony_ci if (tf->protocol == ATA_PROT_DMA && !ata_dma_enabled(dev)) { 307262306a36Sopenharmony_ci fp = 1; 307362306a36Sopenharmony_ci goto invalid_fld; 307462306a36Sopenharmony_ci } 307562306a36Sopenharmony_ci 307662306a36Sopenharmony_ci /* We may not issue NCQ commands to devices not supporting NCQ */ 307762306a36Sopenharmony_ci if (ata_is_ncq(tf->protocol) && !ata_ncq_enabled(dev)) { 307862306a36Sopenharmony_ci fp = 1; 307962306a36Sopenharmony_ci goto invalid_fld; 308062306a36Sopenharmony_ci } 308162306a36Sopenharmony_ci 308262306a36Sopenharmony_ci /* sanity check for pio multi commands */ 308362306a36Sopenharmony_ci if ((cdb[1] & 0xe0) && !is_multi_taskfile(tf)) { 308462306a36Sopenharmony_ci fp = 1; 308562306a36Sopenharmony_ci goto invalid_fld; 308662306a36Sopenharmony_ci } 308762306a36Sopenharmony_ci 308862306a36Sopenharmony_ci if (is_multi_taskfile(tf)) { 308962306a36Sopenharmony_ci unsigned int multi_count = 1 << (cdb[1] >> 5); 309062306a36Sopenharmony_ci 309162306a36Sopenharmony_ci /* compare the passed through multi_count 309262306a36Sopenharmony_ci * with the cached multi_count of libata 309362306a36Sopenharmony_ci */ 309462306a36Sopenharmony_ci if (multi_count != dev->multi_count) 309562306a36Sopenharmony_ci ata_dev_warn(dev, "invalid multi_count %u ignored\n", 309662306a36Sopenharmony_ci multi_count); 309762306a36Sopenharmony_ci } 309862306a36Sopenharmony_ci 309962306a36Sopenharmony_ci /* 310062306a36Sopenharmony_ci * Filter SET_FEATURES - XFER MODE command -- otherwise, 310162306a36Sopenharmony_ci * SET_FEATURES - XFER MODE must be preceded/succeeded 310262306a36Sopenharmony_ci * by an update to hardware-specific registers for each 310362306a36Sopenharmony_ci * controller (i.e. the reason for ->set_piomode(), 310462306a36Sopenharmony_ci * ->set_dmamode(), and ->post_set_mode() hooks). 310562306a36Sopenharmony_ci */ 310662306a36Sopenharmony_ci if (tf->command == ATA_CMD_SET_FEATURES && 310762306a36Sopenharmony_ci tf->feature == SETFEATURES_XFER) { 310862306a36Sopenharmony_ci fp = (cdb[0] == ATA_16) ? 4 : 3; 310962306a36Sopenharmony_ci goto invalid_fld; 311062306a36Sopenharmony_ci } 311162306a36Sopenharmony_ci 311262306a36Sopenharmony_ci /* 311362306a36Sopenharmony_ci * Filter TPM commands by default. These provide an 311462306a36Sopenharmony_ci * essentially uncontrolled encrypted "back door" between 311562306a36Sopenharmony_ci * applications and the disk. Set libata.allow_tpm=1 if you 311662306a36Sopenharmony_ci * have a real reason for wanting to use them. This ensures 311762306a36Sopenharmony_ci * that installed software cannot easily mess stuff up without 311862306a36Sopenharmony_ci * user intent. DVR type users will probably ship with this enabled 311962306a36Sopenharmony_ci * for movie content management. 312062306a36Sopenharmony_ci * 312162306a36Sopenharmony_ci * Note that for ATA8 we can issue a DCS change and DCS freeze lock 312262306a36Sopenharmony_ci * for this and should do in future but that it is not sufficient as 312362306a36Sopenharmony_ci * DCS is an optional feature set. Thus we also do the software filter 312462306a36Sopenharmony_ci * so that we comply with the TC consortium stated goal that the user 312562306a36Sopenharmony_ci * can turn off TC features of their system. 312662306a36Sopenharmony_ci */ 312762306a36Sopenharmony_ci if (tf->command >= 0x5C && tf->command <= 0x5F && !libata_allow_tpm) { 312862306a36Sopenharmony_ci fp = (cdb[0] == ATA_16) ? 14 : 9; 312962306a36Sopenharmony_ci goto invalid_fld; 313062306a36Sopenharmony_ci } 313162306a36Sopenharmony_ci 313262306a36Sopenharmony_ci return 0; 313362306a36Sopenharmony_ci 313462306a36Sopenharmony_ci invalid_fld: 313562306a36Sopenharmony_ci ata_scsi_set_invalid_field(dev, scmd, fp, 0xff); 313662306a36Sopenharmony_ci return 1; 313762306a36Sopenharmony_ci} 313862306a36Sopenharmony_ci 313962306a36Sopenharmony_ci/** 314062306a36Sopenharmony_ci * ata_format_dsm_trim_descr() - SATL Write Same to DSM Trim 314162306a36Sopenharmony_ci * @cmd: SCSI command being translated 314262306a36Sopenharmony_ci * @trmax: Maximum number of entries that will fit in sector_size bytes. 314362306a36Sopenharmony_ci * @sector: Starting sector 314462306a36Sopenharmony_ci * @count: Total Range of request in logical sectors 314562306a36Sopenharmony_ci * 314662306a36Sopenharmony_ci * Rewrite the WRITE SAME descriptor to be a DSM TRIM little-endian formatted 314762306a36Sopenharmony_ci * descriptor. 314862306a36Sopenharmony_ci * 314962306a36Sopenharmony_ci * Upto 64 entries of the format: 315062306a36Sopenharmony_ci * 63:48 Range Length 315162306a36Sopenharmony_ci * 47:0 LBA 315262306a36Sopenharmony_ci * 315362306a36Sopenharmony_ci * Range Length of 0 is ignored. 315462306a36Sopenharmony_ci * LBA's should be sorted order and not overlap. 315562306a36Sopenharmony_ci * 315662306a36Sopenharmony_ci * NOTE: this is the same format as ADD LBA(S) TO NV CACHE PINNED SET 315762306a36Sopenharmony_ci * 315862306a36Sopenharmony_ci * Return: Number of bytes copied into sglist. 315962306a36Sopenharmony_ci */ 316062306a36Sopenharmony_cistatic size_t ata_format_dsm_trim_descr(struct scsi_cmnd *cmd, u32 trmax, 316162306a36Sopenharmony_ci u64 sector, u32 count) 316262306a36Sopenharmony_ci{ 316362306a36Sopenharmony_ci struct scsi_device *sdp = cmd->device; 316462306a36Sopenharmony_ci size_t len = sdp->sector_size; 316562306a36Sopenharmony_ci size_t r; 316662306a36Sopenharmony_ci __le64 *buf; 316762306a36Sopenharmony_ci u32 i = 0; 316862306a36Sopenharmony_ci unsigned long flags; 316962306a36Sopenharmony_ci 317062306a36Sopenharmony_ci WARN_ON(len > ATA_SCSI_RBUF_SIZE); 317162306a36Sopenharmony_ci 317262306a36Sopenharmony_ci if (len > ATA_SCSI_RBUF_SIZE) 317362306a36Sopenharmony_ci len = ATA_SCSI_RBUF_SIZE; 317462306a36Sopenharmony_ci 317562306a36Sopenharmony_ci spin_lock_irqsave(&ata_scsi_rbuf_lock, flags); 317662306a36Sopenharmony_ci buf = ((void *)ata_scsi_rbuf); 317762306a36Sopenharmony_ci memset(buf, 0, len); 317862306a36Sopenharmony_ci while (i < trmax) { 317962306a36Sopenharmony_ci u64 entry = sector | 318062306a36Sopenharmony_ci ((u64)(count > 0xffff ? 0xffff : count) << 48); 318162306a36Sopenharmony_ci buf[i++] = __cpu_to_le64(entry); 318262306a36Sopenharmony_ci if (count <= 0xffff) 318362306a36Sopenharmony_ci break; 318462306a36Sopenharmony_ci count -= 0xffff; 318562306a36Sopenharmony_ci sector += 0xffff; 318662306a36Sopenharmony_ci } 318762306a36Sopenharmony_ci r = sg_copy_from_buffer(scsi_sglist(cmd), scsi_sg_count(cmd), buf, len); 318862306a36Sopenharmony_ci spin_unlock_irqrestore(&ata_scsi_rbuf_lock, flags); 318962306a36Sopenharmony_ci 319062306a36Sopenharmony_ci return r; 319162306a36Sopenharmony_ci} 319262306a36Sopenharmony_ci 319362306a36Sopenharmony_ci/** 319462306a36Sopenharmony_ci * ata_scsi_write_same_xlat() - SATL Write Same to ATA SCT Write Same 319562306a36Sopenharmony_ci * @qc: Command to be translated 319662306a36Sopenharmony_ci * 319762306a36Sopenharmony_ci * Translate a SCSI WRITE SAME command to be either a DSM TRIM command or 319862306a36Sopenharmony_ci * an SCT Write Same command. 319962306a36Sopenharmony_ci * Based on WRITE SAME has the UNMAP flag: 320062306a36Sopenharmony_ci * 320162306a36Sopenharmony_ci * - When set translate to DSM TRIM 320262306a36Sopenharmony_ci * - When clear translate to SCT Write Same 320362306a36Sopenharmony_ci */ 320462306a36Sopenharmony_cistatic unsigned int ata_scsi_write_same_xlat(struct ata_queued_cmd *qc) 320562306a36Sopenharmony_ci{ 320662306a36Sopenharmony_ci struct ata_taskfile *tf = &qc->tf; 320762306a36Sopenharmony_ci struct scsi_cmnd *scmd = qc->scsicmd; 320862306a36Sopenharmony_ci struct scsi_device *sdp = scmd->device; 320962306a36Sopenharmony_ci size_t len = sdp->sector_size; 321062306a36Sopenharmony_ci struct ata_device *dev = qc->dev; 321162306a36Sopenharmony_ci const u8 *cdb = scmd->cmnd; 321262306a36Sopenharmony_ci u64 block; 321362306a36Sopenharmony_ci u32 n_block; 321462306a36Sopenharmony_ci const u32 trmax = len >> 3; 321562306a36Sopenharmony_ci u32 size; 321662306a36Sopenharmony_ci u16 fp; 321762306a36Sopenharmony_ci u8 bp = 0xff; 321862306a36Sopenharmony_ci u8 unmap = cdb[1] & 0x8; 321962306a36Sopenharmony_ci 322062306a36Sopenharmony_ci /* we may not issue DMA commands if no DMA mode is set */ 322162306a36Sopenharmony_ci if (unlikely(!ata_dma_enabled(dev))) 322262306a36Sopenharmony_ci goto invalid_opcode; 322362306a36Sopenharmony_ci 322462306a36Sopenharmony_ci /* 322562306a36Sopenharmony_ci * We only allow sending this command through the block layer, 322662306a36Sopenharmony_ci * as it modifies the DATA OUT buffer, which would corrupt user 322762306a36Sopenharmony_ci * memory for SG_IO commands. 322862306a36Sopenharmony_ci */ 322962306a36Sopenharmony_ci if (unlikely(blk_rq_is_passthrough(scsi_cmd_to_rq(scmd)))) 323062306a36Sopenharmony_ci goto invalid_opcode; 323162306a36Sopenharmony_ci 323262306a36Sopenharmony_ci if (unlikely(scmd->cmd_len < 16)) { 323362306a36Sopenharmony_ci fp = 15; 323462306a36Sopenharmony_ci goto invalid_fld; 323562306a36Sopenharmony_ci } 323662306a36Sopenharmony_ci scsi_16_lba_len(cdb, &block, &n_block); 323762306a36Sopenharmony_ci 323862306a36Sopenharmony_ci if (!unmap || 323962306a36Sopenharmony_ci (dev->horkage & ATA_HORKAGE_NOTRIM) || 324062306a36Sopenharmony_ci !ata_id_has_trim(dev->id)) { 324162306a36Sopenharmony_ci fp = 1; 324262306a36Sopenharmony_ci bp = 3; 324362306a36Sopenharmony_ci goto invalid_fld; 324462306a36Sopenharmony_ci } 324562306a36Sopenharmony_ci /* If the request is too large the cmd is invalid */ 324662306a36Sopenharmony_ci if (n_block > 0xffff * trmax) { 324762306a36Sopenharmony_ci fp = 2; 324862306a36Sopenharmony_ci goto invalid_fld; 324962306a36Sopenharmony_ci } 325062306a36Sopenharmony_ci 325162306a36Sopenharmony_ci /* 325262306a36Sopenharmony_ci * WRITE SAME always has a sector sized buffer as payload, this 325362306a36Sopenharmony_ci * should never be a multiple entry S/G list. 325462306a36Sopenharmony_ci */ 325562306a36Sopenharmony_ci if (!scsi_sg_count(scmd)) 325662306a36Sopenharmony_ci goto invalid_param_len; 325762306a36Sopenharmony_ci 325862306a36Sopenharmony_ci /* 325962306a36Sopenharmony_ci * size must match sector size in bytes 326062306a36Sopenharmony_ci * For DATA SET MANAGEMENT TRIM in ACS-2 nsect (aka count) 326162306a36Sopenharmony_ci * is defined as number of 512 byte blocks to be transferred. 326262306a36Sopenharmony_ci */ 326362306a36Sopenharmony_ci 326462306a36Sopenharmony_ci size = ata_format_dsm_trim_descr(scmd, trmax, block, n_block); 326562306a36Sopenharmony_ci if (size != len) 326662306a36Sopenharmony_ci goto invalid_param_len; 326762306a36Sopenharmony_ci 326862306a36Sopenharmony_ci if (ata_ncq_enabled(dev) && ata_fpdma_dsm_supported(dev)) { 326962306a36Sopenharmony_ci /* Newer devices support queued TRIM commands */ 327062306a36Sopenharmony_ci tf->protocol = ATA_PROT_NCQ; 327162306a36Sopenharmony_ci tf->command = ATA_CMD_FPDMA_SEND; 327262306a36Sopenharmony_ci tf->hob_nsect = ATA_SUBCMD_FPDMA_SEND_DSM & 0x1f; 327362306a36Sopenharmony_ci tf->nsect = qc->hw_tag << 3; 327462306a36Sopenharmony_ci tf->hob_feature = (size / 512) >> 8; 327562306a36Sopenharmony_ci tf->feature = size / 512; 327662306a36Sopenharmony_ci 327762306a36Sopenharmony_ci tf->auxiliary = 1; 327862306a36Sopenharmony_ci } else { 327962306a36Sopenharmony_ci tf->protocol = ATA_PROT_DMA; 328062306a36Sopenharmony_ci tf->hob_feature = 0; 328162306a36Sopenharmony_ci tf->feature = ATA_DSM_TRIM; 328262306a36Sopenharmony_ci tf->hob_nsect = (size / 512) >> 8; 328362306a36Sopenharmony_ci tf->nsect = size / 512; 328462306a36Sopenharmony_ci tf->command = ATA_CMD_DSM; 328562306a36Sopenharmony_ci } 328662306a36Sopenharmony_ci 328762306a36Sopenharmony_ci tf->flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE | ATA_TFLAG_LBA48 | 328862306a36Sopenharmony_ci ATA_TFLAG_WRITE; 328962306a36Sopenharmony_ci 329062306a36Sopenharmony_ci ata_qc_set_pc_nbytes(qc); 329162306a36Sopenharmony_ci 329262306a36Sopenharmony_ci return 0; 329362306a36Sopenharmony_ci 329462306a36Sopenharmony_ciinvalid_fld: 329562306a36Sopenharmony_ci ata_scsi_set_invalid_field(dev, scmd, fp, bp); 329662306a36Sopenharmony_ci return 1; 329762306a36Sopenharmony_ciinvalid_param_len: 329862306a36Sopenharmony_ci /* "Parameter list length error" */ 329962306a36Sopenharmony_ci ata_scsi_set_sense(dev, scmd, ILLEGAL_REQUEST, 0x1a, 0x0); 330062306a36Sopenharmony_ci return 1; 330162306a36Sopenharmony_ciinvalid_opcode: 330262306a36Sopenharmony_ci /* "Invalid command operation code" */ 330362306a36Sopenharmony_ci ata_scsi_set_sense(dev, scmd, ILLEGAL_REQUEST, 0x20, 0x0); 330462306a36Sopenharmony_ci return 1; 330562306a36Sopenharmony_ci} 330662306a36Sopenharmony_ci 330762306a36Sopenharmony_ci/** 330862306a36Sopenharmony_ci * ata_scsiop_maint_in - Simulate a subset of MAINTENANCE_IN 330962306a36Sopenharmony_ci * @args: device MAINTENANCE_IN data / SCSI command of interest. 331062306a36Sopenharmony_ci * @rbuf: Response buffer, to which simulated SCSI cmd output is sent. 331162306a36Sopenharmony_ci * 331262306a36Sopenharmony_ci * Yields a subset to satisfy scsi_report_opcode() 331362306a36Sopenharmony_ci * 331462306a36Sopenharmony_ci * LOCKING: 331562306a36Sopenharmony_ci * spin_lock_irqsave(host lock) 331662306a36Sopenharmony_ci */ 331762306a36Sopenharmony_cistatic unsigned int ata_scsiop_maint_in(struct ata_scsi_args *args, u8 *rbuf) 331862306a36Sopenharmony_ci{ 331962306a36Sopenharmony_ci struct ata_device *dev = args->dev; 332062306a36Sopenharmony_ci u8 *cdb = args->cmd->cmnd; 332162306a36Sopenharmony_ci u8 supported = 0, cdlp = 0, rwcdlp = 0; 332262306a36Sopenharmony_ci unsigned int err = 0; 332362306a36Sopenharmony_ci 332462306a36Sopenharmony_ci if (cdb[2] != 1 && cdb[2] != 3) { 332562306a36Sopenharmony_ci ata_dev_warn(dev, "invalid command format %d\n", cdb[2]); 332662306a36Sopenharmony_ci err = 2; 332762306a36Sopenharmony_ci goto out; 332862306a36Sopenharmony_ci } 332962306a36Sopenharmony_ci 333062306a36Sopenharmony_ci switch (cdb[3]) { 333162306a36Sopenharmony_ci case INQUIRY: 333262306a36Sopenharmony_ci case MODE_SENSE: 333362306a36Sopenharmony_ci case MODE_SENSE_10: 333462306a36Sopenharmony_ci case READ_CAPACITY: 333562306a36Sopenharmony_ci case SERVICE_ACTION_IN_16: 333662306a36Sopenharmony_ci case REPORT_LUNS: 333762306a36Sopenharmony_ci case REQUEST_SENSE: 333862306a36Sopenharmony_ci case SYNCHRONIZE_CACHE: 333962306a36Sopenharmony_ci case SYNCHRONIZE_CACHE_16: 334062306a36Sopenharmony_ci case REZERO_UNIT: 334162306a36Sopenharmony_ci case SEEK_6: 334262306a36Sopenharmony_ci case SEEK_10: 334362306a36Sopenharmony_ci case TEST_UNIT_READY: 334462306a36Sopenharmony_ci case SEND_DIAGNOSTIC: 334562306a36Sopenharmony_ci case MAINTENANCE_IN: 334662306a36Sopenharmony_ci case READ_6: 334762306a36Sopenharmony_ci case READ_10: 334862306a36Sopenharmony_ci case WRITE_6: 334962306a36Sopenharmony_ci case WRITE_10: 335062306a36Sopenharmony_ci case ATA_12: 335162306a36Sopenharmony_ci case ATA_16: 335262306a36Sopenharmony_ci case VERIFY: 335362306a36Sopenharmony_ci case VERIFY_16: 335462306a36Sopenharmony_ci case MODE_SELECT: 335562306a36Sopenharmony_ci case MODE_SELECT_10: 335662306a36Sopenharmony_ci case START_STOP: 335762306a36Sopenharmony_ci supported = 3; 335862306a36Sopenharmony_ci break; 335962306a36Sopenharmony_ci case READ_16: 336062306a36Sopenharmony_ci supported = 3; 336162306a36Sopenharmony_ci if (dev->flags & ATA_DFLAG_CDL) { 336262306a36Sopenharmony_ci /* 336362306a36Sopenharmony_ci * CDL read descriptors map to the T2A page, that is, 336462306a36Sopenharmony_ci * rwcdlp = 0x01 and cdlp = 0x01 336562306a36Sopenharmony_ci */ 336662306a36Sopenharmony_ci rwcdlp = 0x01; 336762306a36Sopenharmony_ci cdlp = 0x01 << 3; 336862306a36Sopenharmony_ci } 336962306a36Sopenharmony_ci break; 337062306a36Sopenharmony_ci case WRITE_16: 337162306a36Sopenharmony_ci supported = 3; 337262306a36Sopenharmony_ci if (dev->flags & ATA_DFLAG_CDL) { 337362306a36Sopenharmony_ci /* 337462306a36Sopenharmony_ci * CDL write descriptors map to the T2B page, that is, 337562306a36Sopenharmony_ci * rwcdlp = 0x01 and cdlp = 0x02 337662306a36Sopenharmony_ci */ 337762306a36Sopenharmony_ci rwcdlp = 0x01; 337862306a36Sopenharmony_ci cdlp = 0x02 << 3; 337962306a36Sopenharmony_ci } 338062306a36Sopenharmony_ci break; 338162306a36Sopenharmony_ci case ZBC_IN: 338262306a36Sopenharmony_ci case ZBC_OUT: 338362306a36Sopenharmony_ci if (ata_id_zoned_cap(dev->id) || 338462306a36Sopenharmony_ci dev->class == ATA_DEV_ZAC) 338562306a36Sopenharmony_ci supported = 3; 338662306a36Sopenharmony_ci break; 338762306a36Sopenharmony_ci case SECURITY_PROTOCOL_IN: 338862306a36Sopenharmony_ci case SECURITY_PROTOCOL_OUT: 338962306a36Sopenharmony_ci if (dev->flags & ATA_DFLAG_TRUSTED) 339062306a36Sopenharmony_ci supported = 3; 339162306a36Sopenharmony_ci break; 339262306a36Sopenharmony_ci default: 339362306a36Sopenharmony_ci break; 339462306a36Sopenharmony_ci } 339562306a36Sopenharmony_ciout: 339662306a36Sopenharmony_ci /* One command format */ 339762306a36Sopenharmony_ci rbuf[0] = rwcdlp; 339862306a36Sopenharmony_ci rbuf[1] = cdlp | supported; 339962306a36Sopenharmony_ci return err; 340062306a36Sopenharmony_ci} 340162306a36Sopenharmony_ci 340262306a36Sopenharmony_ci/** 340362306a36Sopenharmony_ci * ata_scsi_report_zones_complete - convert ATA output 340462306a36Sopenharmony_ci * @qc: command structure returning the data 340562306a36Sopenharmony_ci * 340662306a36Sopenharmony_ci * Convert T-13 little-endian field representation into 340762306a36Sopenharmony_ci * T-10 big-endian field representation. 340862306a36Sopenharmony_ci * What a mess. 340962306a36Sopenharmony_ci */ 341062306a36Sopenharmony_cistatic void ata_scsi_report_zones_complete(struct ata_queued_cmd *qc) 341162306a36Sopenharmony_ci{ 341262306a36Sopenharmony_ci struct scsi_cmnd *scmd = qc->scsicmd; 341362306a36Sopenharmony_ci struct sg_mapping_iter miter; 341462306a36Sopenharmony_ci unsigned long flags; 341562306a36Sopenharmony_ci unsigned int bytes = 0; 341662306a36Sopenharmony_ci 341762306a36Sopenharmony_ci sg_miter_start(&miter, scsi_sglist(scmd), scsi_sg_count(scmd), 341862306a36Sopenharmony_ci SG_MITER_TO_SG | SG_MITER_ATOMIC); 341962306a36Sopenharmony_ci 342062306a36Sopenharmony_ci local_irq_save(flags); 342162306a36Sopenharmony_ci while (sg_miter_next(&miter)) { 342262306a36Sopenharmony_ci unsigned int offset = 0; 342362306a36Sopenharmony_ci 342462306a36Sopenharmony_ci if (bytes == 0) { 342562306a36Sopenharmony_ci char *hdr; 342662306a36Sopenharmony_ci u32 list_length; 342762306a36Sopenharmony_ci u64 max_lba, opt_lba; 342862306a36Sopenharmony_ci u16 same; 342962306a36Sopenharmony_ci 343062306a36Sopenharmony_ci /* Swizzle header */ 343162306a36Sopenharmony_ci hdr = miter.addr; 343262306a36Sopenharmony_ci list_length = get_unaligned_le32(&hdr[0]); 343362306a36Sopenharmony_ci same = get_unaligned_le16(&hdr[4]); 343462306a36Sopenharmony_ci max_lba = get_unaligned_le64(&hdr[8]); 343562306a36Sopenharmony_ci opt_lba = get_unaligned_le64(&hdr[16]); 343662306a36Sopenharmony_ci put_unaligned_be32(list_length, &hdr[0]); 343762306a36Sopenharmony_ci hdr[4] = same & 0xf; 343862306a36Sopenharmony_ci put_unaligned_be64(max_lba, &hdr[8]); 343962306a36Sopenharmony_ci put_unaligned_be64(opt_lba, &hdr[16]); 344062306a36Sopenharmony_ci offset += 64; 344162306a36Sopenharmony_ci bytes += 64; 344262306a36Sopenharmony_ci } 344362306a36Sopenharmony_ci while (offset < miter.length) { 344462306a36Sopenharmony_ci char *rec; 344562306a36Sopenharmony_ci u8 cond, type, non_seq, reset; 344662306a36Sopenharmony_ci u64 size, start, wp; 344762306a36Sopenharmony_ci 344862306a36Sopenharmony_ci /* Swizzle zone descriptor */ 344962306a36Sopenharmony_ci rec = miter.addr + offset; 345062306a36Sopenharmony_ci type = rec[0] & 0xf; 345162306a36Sopenharmony_ci cond = (rec[1] >> 4) & 0xf; 345262306a36Sopenharmony_ci non_seq = (rec[1] & 2); 345362306a36Sopenharmony_ci reset = (rec[1] & 1); 345462306a36Sopenharmony_ci size = get_unaligned_le64(&rec[8]); 345562306a36Sopenharmony_ci start = get_unaligned_le64(&rec[16]); 345662306a36Sopenharmony_ci wp = get_unaligned_le64(&rec[24]); 345762306a36Sopenharmony_ci rec[0] = type; 345862306a36Sopenharmony_ci rec[1] = (cond << 4) | non_seq | reset; 345962306a36Sopenharmony_ci put_unaligned_be64(size, &rec[8]); 346062306a36Sopenharmony_ci put_unaligned_be64(start, &rec[16]); 346162306a36Sopenharmony_ci put_unaligned_be64(wp, &rec[24]); 346262306a36Sopenharmony_ci WARN_ON(offset + 64 > miter.length); 346362306a36Sopenharmony_ci offset += 64; 346462306a36Sopenharmony_ci bytes += 64; 346562306a36Sopenharmony_ci } 346662306a36Sopenharmony_ci } 346762306a36Sopenharmony_ci sg_miter_stop(&miter); 346862306a36Sopenharmony_ci local_irq_restore(flags); 346962306a36Sopenharmony_ci 347062306a36Sopenharmony_ci ata_scsi_qc_complete(qc); 347162306a36Sopenharmony_ci} 347262306a36Sopenharmony_ci 347362306a36Sopenharmony_cistatic unsigned int ata_scsi_zbc_in_xlat(struct ata_queued_cmd *qc) 347462306a36Sopenharmony_ci{ 347562306a36Sopenharmony_ci struct ata_taskfile *tf = &qc->tf; 347662306a36Sopenharmony_ci struct scsi_cmnd *scmd = qc->scsicmd; 347762306a36Sopenharmony_ci const u8 *cdb = scmd->cmnd; 347862306a36Sopenharmony_ci u16 sect, fp = (u16)-1; 347962306a36Sopenharmony_ci u8 sa, options, bp = 0xff; 348062306a36Sopenharmony_ci u64 block; 348162306a36Sopenharmony_ci u32 n_block; 348262306a36Sopenharmony_ci 348362306a36Sopenharmony_ci if (unlikely(scmd->cmd_len < 16)) { 348462306a36Sopenharmony_ci ata_dev_warn(qc->dev, "invalid cdb length %d\n", 348562306a36Sopenharmony_ci scmd->cmd_len); 348662306a36Sopenharmony_ci fp = 15; 348762306a36Sopenharmony_ci goto invalid_fld; 348862306a36Sopenharmony_ci } 348962306a36Sopenharmony_ci scsi_16_lba_len(cdb, &block, &n_block); 349062306a36Sopenharmony_ci if (n_block != scsi_bufflen(scmd)) { 349162306a36Sopenharmony_ci ata_dev_warn(qc->dev, "non-matching transfer count (%d/%d)\n", 349262306a36Sopenharmony_ci n_block, scsi_bufflen(scmd)); 349362306a36Sopenharmony_ci goto invalid_param_len; 349462306a36Sopenharmony_ci } 349562306a36Sopenharmony_ci sa = cdb[1] & 0x1f; 349662306a36Sopenharmony_ci if (sa != ZI_REPORT_ZONES) { 349762306a36Sopenharmony_ci ata_dev_warn(qc->dev, "invalid service action %d\n", sa); 349862306a36Sopenharmony_ci fp = 1; 349962306a36Sopenharmony_ci goto invalid_fld; 350062306a36Sopenharmony_ci } 350162306a36Sopenharmony_ci /* 350262306a36Sopenharmony_ci * ZAC allows only for transfers in 512 byte blocks, 350362306a36Sopenharmony_ci * and uses a 16 bit value for the transfer count. 350462306a36Sopenharmony_ci */ 350562306a36Sopenharmony_ci if ((n_block / 512) > 0xffff || n_block < 512 || (n_block % 512)) { 350662306a36Sopenharmony_ci ata_dev_warn(qc->dev, "invalid transfer count %d\n", n_block); 350762306a36Sopenharmony_ci goto invalid_param_len; 350862306a36Sopenharmony_ci } 350962306a36Sopenharmony_ci sect = n_block / 512; 351062306a36Sopenharmony_ci options = cdb[14] & 0xbf; 351162306a36Sopenharmony_ci 351262306a36Sopenharmony_ci if (ata_ncq_enabled(qc->dev) && 351362306a36Sopenharmony_ci ata_fpdma_zac_mgmt_in_supported(qc->dev)) { 351462306a36Sopenharmony_ci tf->protocol = ATA_PROT_NCQ; 351562306a36Sopenharmony_ci tf->command = ATA_CMD_FPDMA_RECV; 351662306a36Sopenharmony_ci tf->hob_nsect = ATA_SUBCMD_FPDMA_RECV_ZAC_MGMT_IN & 0x1f; 351762306a36Sopenharmony_ci tf->nsect = qc->hw_tag << 3; 351862306a36Sopenharmony_ci tf->feature = sect & 0xff; 351962306a36Sopenharmony_ci tf->hob_feature = (sect >> 8) & 0xff; 352062306a36Sopenharmony_ci tf->auxiliary = ATA_SUBCMD_ZAC_MGMT_IN_REPORT_ZONES | (options << 8); 352162306a36Sopenharmony_ci } else { 352262306a36Sopenharmony_ci tf->command = ATA_CMD_ZAC_MGMT_IN; 352362306a36Sopenharmony_ci tf->feature = ATA_SUBCMD_ZAC_MGMT_IN_REPORT_ZONES; 352462306a36Sopenharmony_ci tf->protocol = ATA_PROT_DMA; 352562306a36Sopenharmony_ci tf->hob_feature = options; 352662306a36Sopenharmony_ci tf->hob_nsect = (sect >> 8) & 0xff; 352762306a36Sopenharmony_ci tf->nsect = sect & 0xff; 352862306a36Sopenharmony_ci } 352962306a36Sopenharmony_ci tf->device = ATA_LBA; 353062306a36Sopenharmony_ci tf->lbah = (block >> 16) & 0xff; 353162306a36Sopenharmony_ci tf->lbam = (block >> 8) & 0xff; 353262306a36Sopenharmony_ci tf->lbal = block & 0xff; 353362306a36Sopenharmony_ci tf->hob_lbah = (block >> 40) & 0xff; 353462306a36Sopenharmony_ci tf->hob_lbam = (block >> 32) & 0xff; 353562306a36Sopenharmony_ci tf->hob_lbal = (block >> 24) & 0xff; 353662306a36Sopenharmony_ci 353762306a36Sopenharmony_ci tf->flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE | ATA_TFLAG_LBA48; 353862306a36Sopenharmony_ci qc->flags |= ATA_QCFLAG_RESULT_TF; 353962306a36Sopenharmony_ci 354062306a36Sopenharmony_ci ata_qc_set_pc_nbytes(qc); 354162306a36Sopenharmony_ci 354262306a36Sopenharmony_ci qc->complete_fn = ata_scsi_report_zones_complete; 354362306a36Sopenharmony_ci 354462306a36Sopenharmony_ci return 0; 354562306a36Sopenharmony_ci 354662306a36Sopenharmony_ciinvalid_fld: 354762306a36Sopenharmony_ci ata_scsi_set_invalid_field(qc->dev, scmd, fp, bp); 354862306a36Sopenharmony_ci return 1; 354962306a36Sopenharmony_ci 355062306a36Sopenharmony_ciinvalid_param_len: 355162306a36Sopenharmony_ci /* "Parameter list length error" */ 355262306a36Sopenharmony_ci ata_scsi_set_sense(qc->dev, scmd, ILLEGAL_REQUEST, 0x1a, 0x0); 355362306a36Sopenharmony_ci return 1; 355462306a36Sopenharmony_ci} 355562306a36Sopenharmony_ci 355662306a36Sopenharmony_cistatic unsigned int ata_scsi_zbc_out_xlat(struct ata_queued_cmd *qc) 355762306a36Sopenharmony_ci{ 355862306a36Sopenharmony_ci struct ata_taskfile *tf = &qc->tf; 355962306a36Sopenharmony_ci struct scsi_cmnd *scmd = qc->scsicmd; 356062306a36Sopenharmony_ci struct ata_device *dev = qc->dev; 356162306a36Sopenharmony_ci const u8 *cdb = scmd->cmnd; 356262306a36Sopenharmony_ci u8 all, sa; 356362306a36Sopenharmony_ci u64 block; 356462306a36Sopenharmony_ci u32 n_block; 356562306a36Sopenharmony_ci u16 fp = (u16)-1; 356662306a36Sopenharmony_ci 356762306a36Sopenharmony_ci if (unlikely(scmd->cmd_len < 16)) { 356862306a36Sopenharmony_ci fp = 15; 356962306a36Sopenharmony_ci goto invalid_fld; 357062306a36Sopenharmony_ci } 357162306a36Sopenharmony_ci 357262306a36Sopenharmony_ci sa = cdb[1] & 0x1f; 357362306a36Sopenharmony_ci if ((sa != ZO_CLOSE_ZONE) && (sa != ZO_FINISH_ZONE) && 357462306a36Sopenharmony_ci (sa != ZO_OPEN_ZONE) && (sa != ZO_RESET_WRITE_POINTER)) { 357562306a36Sopenharmony_ci fp = 1; 357662306a36Sopenharmony_ci goto invalid_fld; 357762306a36Sopenharmony_ci } 357862306a36Sopenharmony_ci 357962306a36Sopenharmony_ci scsi_16_lba_len(cdb, &block, &n_block); 358062306a36Sopenharmony_ci if (n_block) { 358162306a36Sopenharmony_ci /* 358262306a36Sopenharmony_ci * ZAC MANAGEMENT OUT doesn't define any length 358362306a36Sopenharmony_ci */ 358462306a36Sopenharmony_ci goto invalid_param_len; 358562306a36Sopenharmony_ci } 358662306a36Sopenharmony_ci 358762306a36Sopenharmony_ci all = cdb[14] & 0x1; 358862306a36Sopenharmony_ci if (all) { 358962306a36Sopenharmony_ci /* 359062306a36Sopenharmony_ci * Ignore the block address (zone ID) as defined by ZBC. 359162306a36Sopenharmony_ci */ 359262306a36Sopenharmony_ci block = 0; 359362306a36Sopenharmony_ci } else if (block >= dev->n_sectors) { 359462306a36Sopenharmony_ci /* 359562306a36Sopenharmony_ci * Block must be a valid zone ID (a zone start LBA). 359662306a36Sopenharmony_ci */ 359762306a36Sopenharmony_ci fp = 2; 359862306a36Sopenharmony_ci goto invalid_fld; 359962306a36Sopenharmony_ci } 360062306a36Sopenharmony_ci 360162306a36Sopenharmony_ci if (ata_ncq_enabled(qc->dev) && 360262306a36Sopenharmony_ci ata_fpdma_zac_mgmt_out_supported(qc->dev)) { 360362306a36Sopenharmony_ci tf->protocol = ATA_PROT_NCQ_NODATA; 360462306a36Sopenharmony_ci tf->command = ATA_CMD_NCQ_NON_DATA; 360562306a36Sopenharmony_ci tf->feature = ATA_SUBCMD_NCQ_NON_DATA_ZAC_MGMT_OUT; 360662306a36Sopenharmony_ci tf->nsect = qc->hw_tag << 3; 360762306a36Sopenharmony_ci tf->auxiliary = sa | ((u16)all << 8); 360862306a36Sopenharmony_ci } else { 360962306a36Sopenharmony_ci tf->protocol = ATA_PROT_NODATA; 361062306a36Sopenharmony_ci tf->command = ATA_CMD_ZAC_MGMT_OUT; 361162306a36Sopenharmony_ci tf->feature = sa; 361262306a36Sopenharmony_ci tf->hob_feature = all; 361362306a36Sopenharmony_ci } 361462306a36Sopenharmony_ci tf->lbah = (block >> 16) & 0xff; 361562306a36Sopenharmony_ci tf->lbam = (block >> 8) & 0xff; 361662306a36Sopenharmony_ci tf->lbal = block & 0xff; 361762306a36Sopenharmony_ci tf->hob_lbah = (block >> 40) & 0xff; 361862306a36Sopenharmony_ci tf->hob_lbam = (block >> 32) & 0xff; 361962306a36Sopenharmony_ci tf->hob_lbal = (block >> 24) & 0xff; 362062306a36Sopenharmony_ci tf->device = ATA_LBA; 362162306a36Sopenharmony_ci tf->flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE | ATA_TFLAG_LBA48; 362262306a36Sopenharmony_ci 362362306a36Sopenharmony_ci return 0; 362462306a36Sopenharmony_ci 362562306a36Sopenharmony_ci invalid_fld: 362662306a36Sopenharmony_ci ata_scsi_set_invalid_field(qc->dev, scmd, fp, 0xff); 362762306a36Sopenharmony_ci return 1; 362862306a36Sopenharmony_ciinvalid_param_len: 362962306a36Sopenharmony_ci /* "Parameter list length error" */ 363062306a36Sopenharmony_ci ata_scsi_set_sense(qc->dev, scmd, ILLEGAL_REQUEST, 0x1a, 0x0); 363162306a36Sopenharmony_ci return 1; 363262306a36Sopenharmony_ci} 363362306a36Sopenharmony_ci 363462306a36Sopenharmony_ci/** 363562306a36Sopenharmony_ci * ata_mselect_caching - Simulate MODE SELECT for caching info page 363662306a36Sopenharmony_ci * @qc: Storage for translated ATA taskfile 363762306a36Sopenharmony_ci * @buf: input buffer 363862306a36Sopenharmony_ci * @len: number of valid bytes in the input buffer 363962306a36Sopenharmony_ci * @fp: out parameter for the failed field on error 364062306a36Sopenharmony_ci * 364162306a36Sopenharmony_ci * Prepare a taskfile to modify caching information for the device. 364262306a36Sopenharmony_ci * 364362306a36Sopenharmony_ci * LOCKING: 364462306a36Sopenharmony_ci * None. 364562306a36Sopenharmony_ci */ 364662306a36Sopenharmony_cistatic int ata_mselect_caching(struct ata_queued_cmd *qc, 364762306a36Sopenharmony_ci const u8 *buf, int len, u16 *fp) 364862306a36Sopenharmony_ci{ 364962306a36Sopenharmony_ci struct ata_taskfile *tf = &qc->tf; 365062306a36Sopenharmony_ci struct ata_device *dev = qc->dev; 365162306a36Sopenharmony_ci u8 mpage[CACHE_MPAGE_LEN]; 365262306a36Sopenharmony_ci u8 wce; 365362306a36Sopenharmony_ci int i; 365462306a36Sopenharmony_ci 365562306a36Sopenharmony_ci /* 365662306a36Sopenharmony_ci * The first two bytes of def_cache_mpage are a header, so offsets 365762306a36Sopenharmony_ci * in mpage are off by 2 compared to buf. Same for len. 365862306a36Sopenharmony_ci */ 365962306a36Sopenharmony_ci 366062306a36Sopenharmony_ci if (len != CACHE_MPAGE_LEN - 2) { 366162306a36Sopenharmony_ci *fp = min(len, CACHE_MPAGE_LEN - 2); 366262306a36Sopenharmony_ci return -EINVAL; 366362306a36Sopenharmony_ci } 366462306a36Sopenharmony_ci 366562306a36Sopenharmony_ci wce = buf[0] & (1 << 2); 366662306a36Sopenharmony_ci 366762306a36Sopenharmony_ci /* 366862306a36Sopenharmony_ci * Check that read-only bits are not modified. 366962306a36Sopenharmony_ci */ 367062306a36Sopenharmony_ci ata_msense_caching(dev->id, mpage, false); 367162306a36Sopenharmony_ci for (i = 0; i < CACHE_MPAGE_LEN - 2; i++) { 367262306a36Sopenharmony_ci if (i == 0) 367362306a36Sopenharmony_ci continue; 367462306a36Sopenharmony_ci if (mpage[i + 2] != buf[i]) { 367562306a36Sopenharmony_ci *fp = i; 367662306a36Sopenharmony_ci return -EINVAL; 367762306a36Sopenharmony_ci } 367862306a36Sopenharmony_ci } 367962306a36Sopenharmony_ci 368062306a36Sopenharmony_ci tf->flags |= ATA_TFLAG_DEVICE | ATA_TFLAG_ISADDR; 368162306a36Sopenharmony_ci tf->protocol = ATA_PROT_NODATA; 368262306a36Sopenharmony_ci tf->nsect = 0; 368362306a36Sopenharmony_ci tf->command = ATA_CMD_SET_FEATURES; 368462306a36Sopenharmony_ci tf->feature = wce ? SETFEATURES_WC_ON : SETFEATURES_WC_OFF; 368562306a36Sopenharmony_ci return 0; 368662306a36Sopenharmony_ci} 368762306a36Sopenharmony_ci 368862306a36Sopenharmony_ci/* 368962306a36Sopenharmony_ci * Simulate MODE SELECT control mode page, sub-page 0. 369062306a36Sopenharmony_ci */ 369162306a36Sopenharmony_cistatic int ata_mselect_control_spg0(struct ata_queued_cmd *qc, 369262306a36Sopenharmony_ci const u8 *buf, int len, u16 *fp) 369362306a36Sopenharmony_ci{ 369462306a36Sopenharmony_ci struct ata_device *dev = qc->dev; 369562306a36Sopenharmony_ci u8 mpage[CONTROL_MPAGE_LEN]; 369662306a36Sopenharmony_ci u8 d_sense; 369762306a36Sopenharmony_ci int i; 369862306a36Sopenharmony_ci 369962306a36Sopenharmony_ci /* 370062306a36Sopenharmony_ci * The first two bytes of def_control_mpage are a header, so offsets 370162306a36Sopenharmony_ci * in mpage are off by 2 compared to buf. Same for len. 370262306a36Sopenharmony_ci */ 370362306a36Sopenharmony_ci 370462306a36Sopenharmony_ci if (len != CONTROL_MPAGE_LEN - 2) { 370562306a36Sopenharmony_ci *fp = min(len, CONTROL_MPAGE_LEN - 2); 370662306a36Sopenharmony_ci return -EINVAL; 370762306a36Sopenharmony_ci } 370862306a36Sopenharmony_ci 370962306a36Sopenharmony_ci d_sense = buf[0] & (1 << 2); 371062306a36Sopenharmony_ci 371162306a36Sopenharmony_ci /* 371262306a36Sopenharmony_ci * Check that read-only bits are not modified. 371362306a36Sopenharmony_ci */ 371462306a36Sopenharmony_ci ata_msense_control_spg0(dev, mpage, false); 371562306a36Sopenharmony_ci for (i = 0; i < CONTROL_MPAGE_LEN - 2; i++) { 371662306a36Sopenharmony_ci if (i == 0) 371762306a36Sopenharmony_ci continue; 371862306a36Sopenharmony_ci if (mpage[2 + i] != buf[i]) { 371962306a36Sopenharmony_ci *fp = i; 372062306a36Sopenharmony_ci return -EINVAL; 372162306a36Sopenharmony_ci } 372262306a36Sopenharmony_ci } 372362306a36Sopenharmony_ci if (d_sense & (1 << 2)) 372462306a36Sopenharmony_ci dev->flags |= ATA_DFLAG_D_SENSE; 372562306a36Sopenharmony_ci else 372662306a36Sopenharmony_ci dev->flags &= ~ATA_DFLAG_D_SENSE; 372762306a36Sopenharmony_ci return 0; 372862306a36Sopenharmony_ci} 372962306a36Sopenharmony_ci 373062306a36Sopenharmony_ci/* 373162306a36Sopenharmony_ci * Translate MODE SELECT control mode page, sub-pages f2h (ATA feature mode 373262306a36Sopenharmony_ci * page) into a SET FEATURES command. 373362306a36Sopenharmony_ci */ 373462306a36Sopenharmony_cistatic unsigned int ata_mselect_control_ata_feature(struct ata_queued_cmd *qc, 373562306a36Sopenharmony_ci const u8 *buf, int len, 373662306a36Sopenharmony_ci u16 *fp) 373762306a36Sopenharmony_ci{ 373862306a36Sopenharmony_ci struct ata_device *dev = qc->dev; 373962306a36Sopenharmony_ci struct ata_taskfile *tf = &qc->tf; 374062306a36Sopenharmony_ci u8 cdl_action; 374162306a36Sopenharmony_ci 374262306a36Sopenharmony_ci /* 374362306a36Sopenharmony_ci * The first four bytes of ATA Feature Control mode page are a header, 374462306a36Sopenharmony_ci * so offsets in mpage are off by 4 compared to buf. Same for len. 374562306a36Sopenharmony_ci */ 374662306a36Sopenharmony_ci if (len != ATA_FEATURE_SUB_MPAGE_LEN - 4) { 374762306a36Sopenharmony_ci *fp = min(len, ATA_FEATURE_SUB_MPAGE_LEN - 4); 374862306a36Sopenharmony_ci return -EINVAL; 374962306a36Sopenharmony_ci } 375062306a36Sopenharmony_ci 375162306a36Sopenharmony_ci /* Check cdl_ctrl */ 375262306a36Sopenharmony_ci switch (buf[0] & 0x03) { 375362306a36Sopenharmony_ci case 0: 375462306a36Sopenharmony_ci /* Disable CDL */ 375562306a36Sopenharmony_ci cdl_action = 0; 375662306a36Sopenharmony_ci dev->flags &= ~ATA_DFLAG_CDL_ENABLED; 375762306a36Sopenharmony_ci break; 375862306a36Sopenharmony_ci case 0x02: 375962306a36Sopenharmony_ci /* Enable CDL T2A/T2B: NCQ priority must be disabled */ 376062306a36Sopenharmony_ci if (dev->flags & ATA_DFLAG_NCQ_PRIO_ENABLED) { 376162306a36Sopenharmony_ci ata_dev_err(dev, 376262306a36Sopenharmony_ci "NCQ priority must be disabled to enable CDL\n"); 376362306a36Sopenharmony_ci return -EINVAL; 376462306a36Sopenharmony_ci } 376562306a36Sopenharmony_ci cdl_action = 1; 376662306a36Sopenharmony_ci dev->flags |= ATA_DFLAG_CDL_ENABLED; 376762306a36Sopenharmony_ci break; 376862306a36Sopenharmony_ci default: 376962306a36Sopenharmony_ci *fp = 0; 377062306a36Sopenharmony_ci return -EINVAL; 377162306a36Sopenharmony_ci } 377262306a36Sopenharmony_ci 377362306a36Sopenharmony_ci tf->flags |= ATA_TFLAG_DEVICE | ATA_TFLAG_ISADDR; 377462306a36Sopenharmony_ci tf->protocol = ATA_PROT_NODATA; 377562306a36Sopenharmony_ci tf->command = ATA_CMD_SET_FEATURES; 377662306a36Sopenharmony_ci tf->feature = SETFEATURES_CDL; 377762306a36Sopenharmony_ci tf->nsect = cdl_action; 377862306a36Sopenharmony_ci 377962306a36Sopenharmony_ci return 1; 378062306a36Sopenharmony_ci} 378162306a36Sopenharmony_ci 378262306a36Sopenharmony_ci/** 378362306a36Sopenharmony_ci * ata_mselect_control - Simulate MODE SELECT for control page 378462306a36Sopenharmony_ci * @qc: Storage for translated ATA taskfile 378562306a36Sopenharmony_ci * @spg: target sub-page of the control page 378662306a36Sopenharmony_ci * @buf: input buffer 378762306a36Sopenharmony_ci * @len: number of valid bytes in the input buffer 378862306a36Sopenharmony_ci * @fp: out parameter for the failed field on error 378962306a36Sopenharmony_ci * 379062306a36Sopenharmony_ci * Prepare a taskfile to modify caching information for the device. 379162306a36Sopenharmony_ci * 379262306a36Sopenharmony_ci * LOCKING: 379362306a36Sopenharmony_ci * None. 379462306a36Sopenharmony_ci */ 379562306a36Sopenharmony_cistatic int ata_mselect_control(struct ata_queued_cmd *qc, u8 spg, 379662306a36Sopenharmony_ci const u8 *buf, int len, u16 *fp) 379762306a36Sopenharmony_ci{ 379862306a36Sopenharmony_ci switch (spg) { 379962306a36Sopenharmony_ci case 0: 380062306a36Sopenharmony_ci return ata_mselect_control_spg0(qc, buf, len, fp); 380162306a36Sopenharmony_ci case ATA_FEATURE_SUB_MPAGE: 380262306a36Sopenharmony_ci return ata_mselect_control_ata_feature(qc, buf, len, fp); 380362306a36Sopenharmony_ci default: 380462306a36Sopenharmony_ci return -EINVAL; 380562306a36Sopenharmony_ci } 380662306a36Sopenharmony_ci} 380762306a36Sopenharmony_ci 380862306a36Sopenharmony_ci/** 380962306a36Sopenharmony_ci * ata_scsi_mode_select_xlat - Simulate MODE SELECT 6, 10 commands 381062306a36Sopenharmony_ci * @qc: Storage for translated ATA taskfile 381162306a36Sopenharmony_ci * 381262306a36Sopenharmony_ci * Converts a MODE SELECT command to an ATA SET FEATURES taskfile. 381362306a36Sopenharmony_ci * Assume this is invoked for direct access devices (e.g. disks) only. 381462306a36Sopenharmony_ci * There should be no block descriptor for other device types. 381562306a36Sopenharmony_ci * 381662306a36Sopenharmony_ci * LOCKING: 381762306a36Sopenharmony_ci * spin_lock_irqsave(host lock) 381862306a36Sopenharmony_ci */ 381962306a36Sopenharmony_cistatic unsigned int ata_scsi_mode_select_xlat(struct ata_queued_cmd *qc) 382062306a36Sopenharmony_ci{ 382162306a36Sopenharmony_ci struct scsi_cmnd *scmd = qc->scsicmd; 382262306a36Sopenharmony_ci const u8 *cdb = scmd->cmnd; 382362306a36Sopenharmony_ci u8 pg, spg; 382462306a36Sopenharmony_ci unsigned six_byte, pg_len, hdr_len, bd_len; 382562306a36Sopenharmony_ci int len, ret; 382662306a36Sopenharmony_ci u16 fp = (u16)-1; 382762306a36Sopenharmony_ci u8 bp = 0xff; 382862306a36Sopenharmony_ci u8 buffer[64]; 382962306a36Sopenharmony_ci const u8 *p = buffer; 383062306a36Sopenharmony_ci 383162306a36Sopenharmony_ci six_byte = (cdb[0] == MODE_SELECT); 383262306a36Sopenharmony_ci if (six_byte) { 383362306a36Sopenharmony_ci if (scmd->cmd_len < 5) { 383462306a36Sopenharmony_ci fp = 4; 383562306a36Sopenharmony_ci goto invalid_fld; 383662306a36Sopenharmony_ci } 383762306a36Sopenharmony_ci 383862306a36Sopenharmony_ci len = cdb[4]; 383962306a36Sopenharmony_ci hdr_len = 4; 384062306a36Sopenharmony_ci } else { 384162306a36Sopenharmony_ci if (scmd->cmd_len < 9) { 384262306a36Sopenharmony_ci fp = 8; 384362306a36Sopenharmony_ci goto invalid_fld; 384462306a36Sopenharmony_ci } 384562306a36Sopenharmony_ci 384662306a36Sopenharmony_ci len = get_unaligned_be16(&cdb[7]); 384762306a36Sopenharmony_ci hdr_len = 8; 384862306a36Sopenharmony_ci } 384962306a36Sopenharmony_ci 385062306a36Sopenharmony_ci /* We only support PF=1, SP=0. */ 385162306a36Sopenharmony_ci if ((cdb[1] & 0x11) != 0x10) { 385262306a36Sopenharmony_ci fp = 1; 385362306a36Sopenharmony_ci bp = (cdb[1] & 0x01) ? 1 : 5; 385462306a36Sopenharmony_ci goto invalid_fld; 385562306a36Sopenharmony_ci } 385662306a36Sopenharmony_ci 385762306a36Sopenharmony_ci /* Test early for possible overrun. */ 385862306a36Sopenharmony_ci if (!scsi_sg_count(scmd) || scsi_sglist(scmd)->length < len) 385962306a36Sopenharmony_ci goto invalid_param_len; 386062306a36Sopenharmony_ci 386162306a36Sopenharmony_ci /* Move past header and block descriptors. */ 386262306a36Sopenharmony_ci if (len < hdr_len) 386362306a36Sopenharmony_ci goto invalid_param_len; 386462306a36Sopenharmony_ci 386562306a36Sopenharmony_ci if (!sg_copy_to_buffer(scsi_sglist(scmd), scsi_sg_count(scmd), 386662306a36Sopenharmony_ci buffer, sizeof(buffer))) 386762306a36Sopenharmony_ci goto invalid_param_len; 386862306a36Sopenharmony_ci 386962306a36Sopenharmony_ci if (six_byte) 387062306a36Sopenharmony_ci bd_len = p[3]; 387162306a36Sopenharmony_ci else 387262306a36Sopenharmony_ci bd_len = get_unaligned_be16(&p[6]); 387362306a36Sopenharmony_ci 387462306a36Sopenharmony_ci len -= hdr_len; 387562306a36Sopenharmony_ci p += hdr_len; 387662306a36Sopenharmony_ci if (len < bd_len) 387762306a36Sopenharmony_ci goto invalid_param_len; 387862306a36Sopenharmony_ci if (bd_len != 0 && bd_len != 8) { 387962306a36Sopenharmony_ci fp = (six_byte) ? 3 : 6; 388062306a36Sopenharmony_ci fp += bd_len + hdr_len; 388162306a36Sopenharmony_ci goto invalid_param; 388262306a36Sopenharmony_ci } 388362306a36Sopenharmony_ci 388462306a36Sopenharmony_ci len -= bd_len; 388562306a36Sopenharmony_ci p += bd_len; 388662306a36Sopenharmony_ci if (len == 0) 388762306a36Sopenharmony_ci goto skip; 388862306a36Sopenharmony_ci 388962306a36Sopenharmony_ci /* Parse both possible formats for the mode page headers. */ 389062306a36Sopenharmony_ci pg = p[0] & 0x3f; 389162306a36Sopenharmony_ci if (p[0] & 0x40) { 389262306a36Sopenharmony_ci if (len < 4) 389362306a36Sopenharmony_ci goto invalid_param_len; 389462306a36Sopenharmony_ci 389562306a36Sopenharmony_ci spg = p[1]; 389662306a36Sopenharmony_ci pg_len = get_unaligned_be16(&p[2]); 389762306a36Sopenharmony_ci p += 4; 389862306a36Sopenharmony_ci len -= 4; 389962306a36Sopenharmony_ci } else { 390062306a36Sopenharmony_ci if (len < 2) 390162306a36Sopenharmony_ci goto invalid_param_len; 390262306a36Sopenharmony_ci 390362306a36Sopenharmony_ci spg = 0; 390462306a36Sopenharmony_ci pg_len = p[1]; 390562306a36Sopenharmony_ci p += 2; 390662306a36Sopenharmony_ci len -= 2; 390762306a36Sopenharmony_ci } 390862306a36Sopenharmony_ci 390962306a36Sopenharmony_ci /* 391062306a36Sopenharmony_ci * Supported subpages: all subpages and ATA feature sub-page f2h of 391162306a36Sopenharmony_ci * the control page. 391262306a36Sopenharmony_ci */ 391362306a36Sopenharmony_ci if (spg) { 391462306a36Sopenharmony_ci switch (spg) { 391562306a36Sopenharmony_ci case ALL_SUB_MPAGES: 391662306a36Sopenharmony_ci /* All subpages is not supported for the control page */ 391762306a36Sopenharmony_ci if (pg == CONTROL_MPAGE) { 391862306a36Sopenharmony_ci fp = (p[0] & 0x40) ? 1 : 0; 391962306a36Sopenharmony_ci fp += hdr_len + bd_len; 392062306a36Sopenharmony_ci goto invalid_param; 392162306a36Sopenharmony_ci } 392262306a36Sopenharmony_ci break; 392362306a36Sopenharmony_ci case ATA_FEATURE_SUB_MPAGE: 392462306a36Sopenharmony_ci if (qc->dev->flags & ATA_DFLAG_CDL && 392562306a36Sopenharmony_ci pg == CONTROL_MPAGE) 392662306a36Sopenharmony_ci break; 392762306a36Sopenharmony_ci fallthrough; 392862306a36Sopenharmony_ci default: 392962306a36Sopenharmony_ci fp = (p[0] & 0x40) ? 1 : 0; 393062306a36Sopenharmony_ci fp += hdr_len + bd_len; 393162306a36Sopenharmony_ci goto invalid_param; 393262306a36Sopenharmony_ci } 393362306a36Sopenharmony_ci } 393462306a36Sopenharmony_ci if (pg_len > len) 393562306a36Sopenharmony_ci goto invalid_param_len; 393662306a36Sopenharmony_ci 393762306a36Sopenharmony_ci switch (pg) { 393862306a36Sopenharmony_ci case CACHE_MPAGE: 393962306a36Sopenharmony_ci if (ata_mselect_caching(qc, p, pg_len, &fp) < 0) { 394062306a36Sopenharmony_ci fp += hdr_len + bd_len; 394162306a36Sopenharmony_ci goto invalid_param; 394262306a36Sopenharmony_ci } 394362306a36Sopenharmony_ci break; 394462306a36Sopenharmony_ci case CONTROL_MPAGE: 394562306a36Sopenharmony_ci ret = ata_mselect_control(qc, spg, p, pg_len, &fp); 394662306a36Sopenharmony_ci if (ret < 0) { 394762306a36Sopenharmony_ci fp += hdr_len + bd_len; 394862306a36Sopenharmony_ci goto invalid_param; 394962306a36Sopenharmony_ci } 395062306a36Sopenharmony_ci if (!ret) 395162306a36Sopenharmony_ci goto skip; /* No ATA command to send */ 395262306a36Sopenharmony_ci break; 395362306a36Sopenharmony_ci default: 395462306a36Sopenharmony_ci /* Invalid page code */ 395562306a36Sopenharmony_ci fp = bd_len + hdr_len; 395662306a36Sopenharmony_ci goto invalid_param; 395762306a36Sopenharmony_ci } 395862306a36Sopenharmony_ci 395962306a36Sopenharmony_ci /* 396062306a36Sopenharmony_ci * Only one page has changeable data, so we only support setting one 396162306a36Sopenharmony_ci * page at a time. 396262306a36Sopenharmony_ci */ 396362306a36Sopenharmony_ci if (len > pg_len) 396462306a36Sopenharmony_ci goto invalid_param; 396562306a36Sopenharmony_ci 396662306a36Sopenharmony_ci return 0; 396762306a36Sopenharmony_ci 396862306a36Sopenharmony_ci invalid_fld: 396962306a36Sopenharmony_ci ata_scsi_set_invalid_field(qc->dev, scmd, fp, bp); 397062306a36Sopenharmony_ci return 1; 397162306a36Sopenharmony_ci 397262306a36Sopenharmony_ci invalid_param: 397362306a36Sopenharmony_ci ata_scsi_set_invalid_parameter(qc->dev, scmd, fp); 397462306a36Sopenharmony_ci return 1; 397562306a36Sopenharmony_ci 397662306a36Sopenharmony_ci invalid_param_len: 397762306a36Sopenharmony_ci /* "Parameter list length error" */ 397862306a36Sopenharmony_ci ata_scsi_set_sense(qc->dev, scmd, ILLEGAL_REQUEST, 0x1a, 0x0); 397962306a36Sopenharmony_ci return 1; 398062306a36Sopenharmony_ci 398162306a36Sopenharmony_ci skip: 398262306a36Sopenharmony_ci scmd->result = SAM_STAT_GOOD; 398362306a36Sopenharmony_ci return 1; 398462306a36Sopenharmony_ci} 398562306a36Sopenharmony_ci 398662306a36Sopenharmony_cistatic u8 ata_scsi_trusted_op(u32 len, bool send, bool dma) 398762306a36Sopenharmony_ci{ 398862306a36Sopenharmony_ci if (len == 0) 398962306a36Sopenharmony_ci return ATA_CMD_TRUSTED_NONDATA; 399062306a36Sopenharmony_ci else if (send) 399162306a36Sopenharmony_ci return dma ? ATA_CMD_TRUSTED_SND_DMA : ATA_CMD_TRUSTED_SND; 399262306a36Sopenharmony_ci else 399362306a36Sopenharmony_ci return dma ? ATA_CMD_TRUSTED_RCV_DMA : ATA_CMD_TRUSTED_RCV; 399462306a36Sopenharmony_ci} 399562306a36Sopenharmony_ci 399662306a36Sopenharmony_cistatic unsigned int ata_scsi_security_inout_xlat(struct ata_queued_cmd *qc) 399762306a36Sopenharmony_ci{ 399862306a36Sopenharmony_ci struct scsi_cmnd *scmd = qc->scsicmd; 399962306a36Sopenharmony_ci const u8 *cdb = scmd->cmnd; 400062306a36Sopenharmony_ci struct ata_taskfile *tf = &qc->tf; 400162306a36Sopenharmony_ci u8 secp = cdb[1]; 400262306a36Sopenharmony_ci bool send = (cdb[0] == SECURITY_PROTOCOL_OUT); 400362306a36Sopenharmony_ci u16 spsp = get_unaligned_be16(&cdb[2]); 400462306a36Sopenharmony_ci u32 len = get_unaligned_be32(&cdb[6]); 400562306a36Sopenharmony_ci bool dma = !(qc->dev->flags & ATA_DFLAG_PIO); 400662306a36Sopenharmony_ci 400762306a36Sopenharmony_ci /* 400862306a36Sopenharmony_ci * We don't support the ATA "security" protocol. 400962306a36Sopenharmony_ci */ 401062306a36Sopenharmony_ci if (secp == 0xef) { 401162306a36Sopenharmony_ci ata_scsi_set_invalid_field(qc->dev, scmd, 1, 0); 401262306a36Sopenharmony_ci return 1; 401362306a36Sopenharmony_ci } 401462306a36Sopenharmony_ci 401562306a36Sopenharmony_ci if (cdb[4] & 7) { /* INC_512 */ 401662306a36Sopenharmony_ci if (len > 0xffff) { 401762306a36Sopenharmony_ci ata_scsi_set_invalid_field(qc->dev, scmd, 6, 0); 401862306a36Sopenharmony_ci return 1; 401962306a36Sopenharmony_ci } 402062306a36Sopenharmony_ci } else { 402162306a36Sopenharmony_ci if (len > 0x01fffe00) { 402262306a36Sopenharmony_ci ata_scsi_set_invalid_field(qc->dev, scmd, 6, 0); 402362306a36Sopenharmony_ci return 1; 402462306a36Sopenharmony_ci } 402562306a36Sopenharmony_ci 402662306a36Sopenharmony_ci /* convert to the sector-based ATA addressing */ 402762306a36Sopenharmony_ci len = (len + 511) / 512; 402862306a36Sopenharmony_ci } 402962306a36Sopenharmony_ci 403062306a36Sopenharmony_ci tf->protocol = dma ? ATA_PROT_DMA : ATA_PROT_PIO; 403162306a36Sopenharmony_ci tf->flags |= ATA_TFLAG_DEVICE | ATA_TFLAG_ISADDR | ATA_TFLAG_LBA; 403262306a36Sopenharmony_ci if (send) 403362306a36Sopenharmony_ci tf->flags |= ATA_TFLAG_WRITE; 403462306a36Sopenharmony_ci tf->command = ata_scsi_trusted_op(len, send, dma); 403562306a36Sopenharmony_ci tf->feature = secp; 403662306a36Sopenharmony_ci tf->lbam = spsp & 0xff; 403762306a36Sopenharmony_ci tf->lbah = spsp >> 8; 403862306a36Sopenharmony_ci 403962306a36Sopenharmony_ci if (len) { 404062306a36Sopenharmony_ci tf->nsect = len & 0xff; 404162306a36Sopenharmony_ci tf->lbal = len >> 8; 404262306a36Sopenharmony_ci } else { 404362306a36Sopenharmony_ci if (!send) 404462306a36Sopenharmony_ci tf->lbah = (1 << 7); 404562306a36Sopenharmony_ci } 404662306a36Sopenharmony_ci 404762306a36Sopenharmony_ci ata_qc_set_pc_nbytes(qc); 404862306a36Sopenharmony_ci return 0; 404962306a36Sopenharmony_ci} 405062306a36Sopenharmony_ci 405162306a36Sopenharmony_ci/** 405262306a36Sopenharmony_ci * ata_scsi_var_len_cdb_xlat - SATL variable length CDB to Handler 405362306a36Sopenharmony_ci * @qc: Command to be translated 405462306a36Sopenharmony_ci * 405562306a36Sopenharmony_ci * Translate a SCSI variable length CDB to specified commands. 405662306a36Sopenharmony_ci * It checks a service action value in CDB to call corresponding handler. 405762306a36Sopenharmony_ci * 405862306a36Sopenharmony_ci * RETURNS: 405962306a36Sopenharmony_ci * Zero on success, non-zero on failure 406062306a36Sopenharmony_ci * 406162306a36Sopenharmony_ci */ 406262306a36Sopenharmony_cistatic unsigned int ata_scsi_var_len_cdb_xlat(struct ata_queued_cmd *qc) 406362306a36Sopenharmony_ci{ 406462306a36Sopenharmony_ci struct scsi_cmnd *scmd = qc->scsicmd; 406562306a36Sopenharmony_ci const u8 *cdb = scmd->cmnd; 406662306a36Sopenharmony_ci const u16 sa = get_unaligned_be16(&cdb[8]); 406762306a36Sopenharmony_ci 406862306a36Sopenharmony_ci /* 406962306a36Sopenharmony_ci * if service action represents a ata pass-thru(32) command, 407062306a36Sopenharmony_ci * then pass it to ata_scsi_pass_thru handler. 407162306a36Sopenharmony_ci */ 407262306a36Sopenharmony_ci if (sa == ATA_32) 407362306a36Sopenharmony_ci return ata_scsi_pass_thru(qc); 407462306a36Sopenharmony_ci 407562306a36Sopenharmony_ci /* unsupported service action */ 407662306a36Sopenharmony_ci return 1; 407762306a36Sopenharmony_ci} 407862306a36Sopenharmony_ci 407962306a36Sopenharmony_ci/** 408062306a36Sopenharmony_ci * ata_get_xlat_func - check if SCSI to ATA translation is possible 408162306a36Sopenharmony_ci * @dev: ATA device 408262306a36Sopenharmony_ci * @cmd: SCSI command opcode to consider 408362306a36Sopenharmony_ci * 408462306a36Sopenharmony_ci * Look up the SCSI command given, and determine whether the 408562306a36Sopenharmony_ci * SCSI command is to be translated or simulated. 408662306a36Sopenharmony_ci * 408762306a36Sopenharmony_ci * RETURNS: 408862306a36Sopenharmony_ci * Pointer to translation function if possible, %NULL if not. 408962306a36Sopenharmony_ci */ 409062306a36Sopenharmony_ci 409162306a36Sopenharmony_cistatic inline ata_xlat_func_t ata_get_xlat_func(struct ata_device *dev, u8 cmd) 409262306a36Sopenharmony_ci{ 409362306a36Sopenharmony_ci switch (cmd) { 409462306a36Sopenharmony_ci case READ_6: 409562306a36Sopenharmony_ci case READ_10: 409662306a36Sopenharmony_ci case READ_16: 409762306a36Sopenharmony_ci 409862306a36Sopenharmony_ci case WRITE_6: 409962306a36Sopenharmony_ci case WRITE_10: 410062306a36Sopenharmony_ci case WRITE_16: 410162306a36Sopenharmony_ci return ata_scsi_rw_xlat; 410262306a36Sopenharmony_ci 410362306a36Sopenharmony_ci case WRITE_SAME_16: 410462306a36Sopenharmony_ci return ata_scsi_write_same_xlat; 410562306a36Sopenharmony_ci 410662306a36Sopenharmony_ci case SYNCHRONIZE_CACHE: 410762306a36Sopenharmony_ci case SYNCHRONIZE_CACHE_16: 410862306a36Sopenharmony_ci if (ata_try_flush_cache(dev)) 410962306a36Sopenharmony_ci return ata_scsi_flush_xlat; 411062306a36Sopenharmony_ci break; 411162306a36Sopenharmony_ci 411262306a36Sopenharmony_ci case VERIFY: 411362306a36Sopenharmony_ci case VERIFY_16: 411462306a36Sopenharmony_ci return ata_scsi_verify_xlat; 411562306a36Sopenharmony_ci 411662306a36Sopenharmony_ci case ATA_12: 411762306a36Sopenharmony_ci case ATA_16: 411862306a36Sopenharmony_ci return ata_scsi_pass_thru; 411962306a36Sopenharmony_ci 412062306a36Sopenharmony_ci case VARIABLE_LENGTH_CMD: 412162306a36Sopenharmony_ci return ata_scsi_var_len_cdb_xlat; 412262306a36Sopenharmony_ci 412362306a36Sopenharmony_ci case MODE_SELECT: 412462306a36Sopenharmony_ci case MODE_SELECT_10: 412562306a36Sopenharmony_ci return ata_scsi_mode_select_xlat; 412662306a36Sopenharmony_ci 412762306a36Sopenharmony_ci case ZBC_IN: 412862306a36Sopenharmony_ci return ata_scsi_zbc_in_xlat; 412962306a36Sopenharmony_ci 413062306a36Sopenharmony_ci case ZBC_OUT: 413162306a36Sopenharmony_ci return ata_scsi_zbc_out_xlat; 413262306a36Sopenharmony_ci 413362306a36Sopenharmony_ci case SECURITY_PROTOCOL_IN: 413462306a36Sopenharmony_ci case SECURITY_PROTOCOL_OUT: 413562306a36Sopenharmony_ci if (!(dev->flags & ATA_DFLAG_TRUSTED)) 413662306a36Sopenharmony_ci break; 413762306a36Sopenharmony_ci return ata_scsi_security_inout_xlat; 413862306a36Sopenharmony_ci 413962306a36Sopenharmony_ci case START_STOP: 414062306a36Sopenharmony_ci return ata_scsi_start_stop_xlat; 414162306a36Sopenharmony_ci } 414262306a36Sopenharmony_ci 414362306a36Sopenharmony_ci return NULL; 414462306a36Sopenharmony_ci} 414562306a36Sopenharmony_ci 414662306a36Sopenharmony_ciint __ata_scsi_queuecmd(struct scsi_cmnd *scmd, struct ata_device *dev) 414762306a36Sopenharmony_ci{ 414862306a36Sopenharmony_ci struct ata_port *ap = dev->link->ap; 414962306a36Sopenharmony_ci u8 scsi_op = scmd->cmnd[0]; 415062306a36Sopenharmony_ci ata_xlat_func_t xlat_func; 415162306a36Sopenharmony_ci 415262306a36Sopenharmony_ci /* 415362306a36Sopenharmony_ci * scsi_queue_rq() will defer commands if scsi_host_in_recovery(). 415462306a36Sopenharmony_ci * However, this check is done without holding the ap->lock (a libata 415562306a36Sopenharmony_ci * specific lock), so we can have received an error irq since then, 415662306a36Sopenharmony_ci * therefore we must check if EH is pending, while holding ap->lock. 415762306a36Sopenharmony_ci */ 415862306a36Sopenharmony_ci if (ap->pflags & (ATA_PFLAG_EH_PENDING | ATA_PFLAG_EH_IN_PROGRESS)) 415962306a36Sopenharmony_ci return SCSI_MLQUEUE_DEVICE_BUSY; 416062306a36Sopenharmony_ci 416162306a36Sopenharmony_ci if (unlikely(!scmd->cmd_len)) 416262306a36Sopenharmony_ci goto bad_cdb_len; 416362306a36Sopenharmony_ci 416462306a36Sopenharmony_ci if (dev->class == ATA_DEV_ATA || dev->class == ATA_DEV_ZAC) { 416562306a36Sopenharmony_ci if (unlikely(scmd->cmd_len > dev->cdb_len)) 416662306a36Sopenharmony_ci goto bad_cdb_len; 416762306a36Sopenharmony_ci 416862306a36Sopenharmony_ci xlat_func = ata_get_xlat_func(dev, scsi_op); 416962306a36Sopenharmony_ci } else if (likely((scsi_op != ATA_16) || !atapi_passthru16)) { 417062306a36Sopenharmony_ci /* relay SCSI command to ATAPI device */ 417162306a36Sopenharmony_ci int len = COMMAND_SIZE(scsi_op); 417262306a36Sopenharmony_ci 417362306a36Sopenharmony_ci if (unlikely(len > scmd->cmd_len || 417462306a36Sopenharmony_ci len > dev->cdb_len || 417562306a36Sopenharmony_ci scmd->cmd_len > ATAPI_CDB_LEN)) 417662306a36Sopenharmony_ci goto bad_cdb_len; 417762306a36Sopenharmony_ci 417862306a36Sopenharmony_ci xlat_func = atapi_xlat; 417962306a36Sopenharmony_ci } else { 418062306a36Sopenharmony_ci /* ATA_16 passthru, treat as an ATA command */ 418162306a36Sopenharmony_ci if (unlikely(scmd->cmd_len > 16)) 418262306a36Sopenharmony_ci goto bad_cdb_len; 418362306a36Sopenharmony_ci 418462306a36Sopenharmony_ci xlat_func = ata_get_xlat_func(dev, scsi_op); 418562306a36Sopenharmony_ci } 418662306a36Sopenharmony_ci 418762306a36Sopenharmony_ci if (xlat_func) 418862306a36Sopenharmony_ci return ata_scsi_translate(dev, scmd, xlat_func); 418962306a36Sopenharmony_ci 419062306a36Sopenharmony_ci ata_scsi_simulate(dev, scmd); 419162306a36Sopenharmony_ci 419262306a36Sopenharmony_ci return 0; 419362306a36Sopenharmony_ci 419462306a36Sopenharmony_ci bad_cdb_len: 419562306a36Sopenharmony_ci scmd->result = DID_ERROR << 16; 419662306a36Sopenharmony_ci scsi_done(scmd); 419762306a36Sopenharmony_ci return 0; 419862306a36Sopenharmony_ci} 419962306a36Sopenharmony_ci 420062306a36Sopenharmony_ci/** 420162306a36Sopenharmony_ci * ata_scsi_queuecmd - Issue SCSI cdb to libata-managed device 420262306a36Sopenharmony_ci * @shost: SCSI host of command to be sent 420362306a36Sopenharmony_ci * @cmd: SCSI command to be sent 420462306a36Sopenharmony_ci * 420562306a36Sopenharmony_ci * In some cases, this function translates SCSI commands into 420662306a36Sopenharmony_ci * ATA taskfiles, and queues the taskfiles to be sent to 420762306a36Sopenharmony_ci * hardware. In other cases, this function simulates a 420862306a36Sopenharmony_ci * SCSI device by evaluating and responding to certain 420962306a36Sopenharmony_ci * SCSI commands. This creates the overall effect of 421062306a36Sopenharmony_ci * ATA and ATAPI devices appearing as SCSI devices. 421162306a36Sopenharmony_ci * 421262306a36Sopenharmony_ci * LOCKING: 421362306a36Sopenharmony_ci * ATA host lock 421462306a36Sopenharmony_ci * 421562306a36Sopenharmony_ci * RETURNS: 421662306a36Sopenharmony_ci * Return value from __ata_scsi_queuecmd() if @cmd can be queued, 421762306a36Sopenharmony_ci * 0 otherwise. 421862306a36Sopenharmony_ci */ 421962306a36Sopenharmony_ciint ata_scsi_queuecmd(struct Scsi_Host *shost, struct scsi_cmnd *cmd) 422062306a36Sopenharmony_ci{ 422162306a36Sopenharmony_ci struct ata_port *ap; 422262306a36Sopenharmony_ci struct ata_device *dev; 422362306a36Sopenharmony_ci struct scsi_device *scsidev = cmd->device; 422462306a36Sopenharmony_ci int rc = 0; 422562306a36Sopenharmony_ci unsigned long irq_flags; 422662306a36Sopenharmony_ci 422762306a36Sopenharmony_ci ap = ata_shost_to_port(shost); 422862306a36Sopenharmony_ci 422962306a36Sopenharmony_ci spin_lock_irqsave(ap->lock, irq_flags); 423062306a36Sopenharmony_ci 423162306a36Sopenharmony_ci dev = ata_scsi_find_dev(ap, scsidev); 423262306a36Sopenharmony_ci if (likely(dev)) 423362306a36Sopenharmony_ci rc = __ata_scsi_queuecmd(cmd, dev); 423462306a36Sopenharmony_ci else { 423562306a36Sopenharmony_ci cmd->result = (DID_BAD_TARGET << 16); 423662306a36Sopenharmony_ci scsi_done(cmd); 423762306a36Sopenharmony_ci } 423862306a36Sopenharmony_ci 423962306a36Sopenharmony_ci spin_unlock_irqrestore(ap->lock, irq_flags); 424062306a36Sopenharmony_ci 424162306a36Sopenharmony_ci return rc; 424262306a36Sopenharmony_ci} 424362306a36Sopenharmony_ciEXPORT_SYMBOL_GPL(ata_scsi_queuecmd); 424462306a36Sopenharmony_ci 424562306a36Sopenharmony_ci/** 424662306a36Sopenharmony_ci * ata_scsi_simulate - simulate SCSI command on ATA device 424762306a36Sopenharmony_ci * @dev: the target device 424862306a36Sopenharmony_ci * @cmd: SCSI command being sent to device. 424962306a36Sopenharmony_ci * 425062306a36Sopenharmony_ci * Interprets and directly executes a select list of SCSI commands 425162306a36Sopenharmony_ci * that can be handled internally. 425262306a36Sopenharmony_ci * 425362306a36Sopenharmony_ci * LOCKING: 425462306a36Sopenharmony_ci * spin_lock_irqsave(host lock) 425562306a36Sopenharmony_ci */ 425662306a36Sopenharmony_ci 425762306a36Sopenharmony_civoid ata_scsi_simulate(struct ata_device *dev, struct scsi_cmnd *cmd) 425862306a36Sopenharmony_ci{ 425962306a36Sopenharmony_ci struct ata_scsi_args args; 426062306a36Sopenharmony_ci const u8 *scsicmd = cmd->cmnd; 426162306a36Sopenharmony_ci u8 tmp8; 426262306a36Sopenharmony_ci 426362306a36Sopenharmony_ci args.dev = dev; 426462306a36Sopenharmony_ci args.id = dev->id; 426562306a36Sopenharmony_ci args.cmd = cmd; 426662306a36Sopenharmony_ci 426762306a36Sopenharmony_ci switch(scsicmd[0]) { 426862306a36Sopenharmony_ci case INQUIRY: 426962306a36Sopenharmony_ci if (scsicmd[1] & 2) /* is CmdDt set? */ 427062306a36Sopenharmony_ci ata_scsi_set_invalid_field(dev, cmd, 1, 0xff); 427162306a36Sopenharmony_ci else if ((scsicmd[1] & 1) == 0) /* is EVPD clear? */ 427262306a36Sopenharmony_ci ata_scsi_rbuf_fill(&args, ata_scsiop_inq_std); 427362306a36Sopenharmony_ci else switch (scsicmd[2]) { 427462306a36Sopenharmony_ci case 0x00: 427562306a36Sopenharmony_ci ata_scsi_rbuf_fill(&args, ata_scsiop_inq_00); 427662306a36Sopenharmony_ci break; 427762306a36Sopenharmony_ci case 0x80: 427862306a36Sopenharmony_ci ata_scsi_rbuf_fill(&args, ata_scsiop_inq_80); 427962306a36Sopenharmony_ci break; 428062306a36Sopenharmony_ci case 0x83: 428162306a36Sopenharmony_ci ata_scsi_rbuf_fill(&args, ata_scsiop_inq_83); 428262306a36Sopenharmony_ci break; 428362306a36Sopenharmony_ci case 0x89: 428462306a36Sopenharmony_ci ata_scsi_rbuf_fill(&args, ata_scsiop_inq_89); 428562306a36Sopenharmony_ci break; 428662306a36Sopenharmony_ci case 0xb0: 428762306a36Sopenharmony_ci ata_scsi_rbuf_fill(&args, ata_scsiop_inq_b0); 428862306a36Sopenharmony_ci break; 428962306a36Sopenharmony_ci case 0xb1: 429062306a36Sopenharmony_ci ata_scsi_rbuf_fill(&args, ata_scsiop_inq_b1); 429162306a36Sopenharmony_ci break; 429262306a36Sopenharmony_ci case 0xb2: 429362306a36Sopenharmony_ci ata_scsi_rbuf_fill(&args, ata_scsiop_inq_b2); 429462306a36Sopenharmony_ci break; 429562306a36Sopenharmony_ci case 0xb6: 429662306a36Sopenharmony_ci if (dev->flags & ATA_DFLAG_ZAC) 429762306a36Sopenharmony_ci ata_scsi_rbuf_fill(&args, ata_scsiop_inq_b6); 429862306a36Sopenharmony_ci else 429962306a36Sopenharmony_ci ata_scsi_set_invalid_field(dev, cmd, 2, 0xff); 430062306a36Sopenharmony_ci break; 430162306a36Sopenharmony_ci case 0xb9: 430262306a36Sopenharmony_ci if (dev->cpr_log) 430362306a36Sopenharmony_ci ata_scsi_rbuf_fill(&args, ata_scsiop_inq_b9); 430462306a36Sopenharmony_ci else 430562306a36Sopenharmony_ci ata_scsi_set_invalid_field(dev, cmd, 2, 0xff); 430662306a36Sopenharmony_ci break; 430762306a36Sopenharmony_ci default: 430862306a36Sopenharmony_ci ata_scsi_set_invalid_field(dev, cmd, 2, 0xff); 430962306a36Sopenharmony_ci break; 431062306a36Sopenharmony_ci } 431162306a36Sopenharmony_ci break; 431262306a36Sopenharmony_ci 431362306a36Sopenharmony_ci case MODE_SENSE: 431462306a36Sopenharmony_ci case MODE_SENSE_10: 431562306a36Sopenharmony_ci ata_scsi_rbuf_fill(&args, ata_scsiop_mode_sense); 431662306a36Sopenharmony_ci break; 431762306a36Sopenharmony_ci 431862306a36Sopenharmony_ci case READ_CAPACITY: 431962306a36Sopenharmony_ci ata_scsi_rbuf_fill(&args, ata_scsiop_read_cap); 432062306a36Sopenharmony_ci break; 432162306a36Sopenharmony_ci 432262306a36Sopenharmony_ci case SERVICE_ACTION_IN_16: 432362306a36Sopenharmony_ci if ((scsicmd[1] & 0x1f) == SAI_READ_CAPACITY_16) 432462306a36Sopenharmony_ci ata_scsi_rbuf_fill(&args, ata_scsiop_read_cap); 432562306a36Sopenharmony_ci else 432662306a36Sopenharmony_ci ata_scsi_set_invalid_field(dev, cmd, 1, 0xff); 432762306a36Sopenharmony_ci break; 432862306a36Sopenharmony_ci 432962306a36Sopenharmony_ci case REPORT_LUNS: 433062306a36Sopenharmony_ci ata_scsi_rbuf_fill(&args, ata_scsiop_report_luns); 433162306a36Sopenharmony_ci break; 433262306a36Sopenharmony_ci 433362306a36Sopenharmony_ci case REQUEST_SENSE: 433462306a36Sopenharmony_ci ata_scsi_set_sense(dev, cmd, 0, 0, 0); 433562306a36Sopenharmony_ci break; 433662306a36Sopenharmony_ci 433762306a36Sopenharmony_ci /* if we reach this, then writeback caching is disabled, 433862306a36Sopenharmony_ci * turning this into a no-op. 433962306a36Sopenharmony_ci */ 434062306a36Sopenharmony_ci case SYNCHRONIZE_CACHE: 434162306a36Sopenharmony_ci case SYNCHRONIZE_CACHE_16: 434262306a36Sopenharmony_ci fallthrough; 434362306a36Sopenharmony_ci 434462306a36Sopenharmony_ci /* no-op's, complete with success */ 434562306a36Sopenharmony_ci case REZERO_UNIT: 434662306a36Sopenharmony_ci case SEEK_6: 434762306a36Sopenharmony_ci case SEEK_10: 434862306a36Sopenharmony_ci case TEST_UNIT_READY: 434962306a36Sopenharmony_ci break; 435062306a36Sopenharmony_ci 435162306a36Sopenharmony_ci case SEND_DIAGNOSTIC: 435262306a36Sopenharmony_ci tmp8 = scsicmd[1] & ~(1 << 3); 435362306a36Sopenharmony_ci if (tmp8 != 0x4 || scsicmd[3] || scsicmd[4]) 435462306a36Sopenharmony_ci ata_scsi_set_invalid_field(dev, cmd, 1, 0xff); 435562306a36Sopenharmony_ci break; 435662306a36Sopenharmony_ci 435762306a36Sopenharmony_ci case MAINTENANCE_IN: 435862306a36Sopenharmony_ci if ((scsicmd[1] & 0x1f) == MI_REPORT_SUPPORTED_OPERATION_CODES) 435962306a36Sopenharmony_ci ata_scsi_rbuf_fill(&args, ata_scsiop_maint_in); 436062306a36Sopenharmony_ci else 436162306a36Sopenharmony_ci ata_scsi_set_invalid_field(dev, cmd, 1, 0xff); 436262306a36Sopenharmony_ci break; 436362306a36Sopenharmony_ci 436462306a36Sopenharmony_ci /* all other commands */ 436562306a36Sopenharmony_ci default: 436662306a36Sopenharmony_ci ata_scsi_set_sense(dev, cmd, ILLEGAL_REQUEST, 0x20, 0x0); 436762306a36Sopenharmony_ci /* "Invalid command operation code" */ 436862306a36Sopenharmony_ci break; 436962306a36Sopenharmony_ci } 437062306a36Sopenharmony_ci 437162306a36Sopenharmony_ci scsi_done(cmd); 437262306a36Sopenharmony_ci} 437362306a36Sopenharmony_ci 437462306a36Sopenharmony_ciint ata_scsi_add_hosts(struct ata_host *host, const struct scsi_host_template *sht) 437562306a36Sopenharmony_ci{ 437662306a36Sopenharmony_ci int i, rc; 437762306a36Sopenharmony_ci 437862306a36Sopenharmony_ci for (i = 0; i < host->n_ports; i++) { 437962306a36Sopenharmony_ci struct ata_port *ap = host->ports[i]; 438062306a36Sopenharmony_ci struct Scsi_Host *shost; 438162306a36Sopenharmony_ci 438262306a36Sopenharmony_ci rc = -ENOMEM; 438362306a36Sopenharmony_ci shost = scsi_host_alloc(sht, sizeof(struct ata_port *)); 438462306a36Sopenharmony_ci if (!shost) 438562306a36Sopenharmony_ci goto err_alloc; 438662306a36Sopenharmony_ci 438762306a36Sopenharmony_ci shost->eh_noresume = 1; 438862306a36Sopenharmony_ci *(struct ata_port **)&shost->hostdata[0] = ap; 438962306a36Sopenharmony_ci ap->scsi_host = shost; 439062306a36Sopenharmony_ci 439162306a36Sopenharmony_ci shost->transportt = ata_scsi_transport_template; 439262306a36Sopenharmony_ci shost->unique_id = ap->print_id; 439362306a36Sopenharmony_ci shost->max_id = 16; 439462306a36Sopenharmony_ci shost->max_lun = 1; 439562306a36Sopenharmony_ci shost->max_channel = 1; 439662306a36Sopenharmony_ci shost->max_cmd_len = 32; 439762306a36Sopenharmony_ci 439862306a36Sopenharmony_ci /* Schedule policy is determined by ->qc_defer() 439962306a36Sopenharmony_ci * callback and it needs to see every deferred qc. 440062306a36Sopenharmony_ci * Set host_blocked to 1 to prevent SCSI midlayer from 440162306a36Sopenharmony_ci * automatically deferring requests. 440262306a36Sopenharmony_ci */ 440362306a36Sopenharmony_ci shost->max_host_blocked = 1; 440462306a36Sopenharmony_ci 440562306a36Sopenharmony_ci rc = scsi_add_host_with_dma(shost, &ap->tdev, ap->host->dev); 440662306a36Sopenharmony_ci if (rc) 440762306a36Sopenharmony_ci goto err_alloc; 440862306a36Sopenharmony_ci } 440962306a36Sopenharmony_ci 441062306a36Sopenharmony_ci return 0; 441162306a36Sopenharmony_ci 441262306a36Sopenharmony_ci err_alloc: 441362306a36Sopenharmony_ci while (--i >= 0) { 441462306a36Sopenharmony_ci struct Scsi_Host *shost = host->ports[i]->scsi_host; 441562306a36Sopenharmony_ci 441662306a36Sopenharmony_ci /* scsi_host_put() is in ata_devres_release() */ 441762306a36Sopenharmony_ci scsi_remove_host(shost); 441862306a36Sopenharmony_ci } 441962306a36Sopenharmony_ci return rc; 442062306a36Sopenharmony_ci} 442162306a36Sopenharmony_ci 442262306a36Sopenharmony_ci#ifdef CONFIG_OF 442362306a36Sopenharmony_cistatic void ata_scsi_assign_ofnode(struct ata_device *dev, struct ata_port *ap) 442462306a36Sopenharmony_ci{ 442562306a36Sopenharmony_ci struct scsi_device *sdev = dev->sdev; 442662306a36Sopenharmony_ci struct device *d = ap->host->dev; 442762306a36Sopenharmony_ci struct device_node *np = d->of_node; 442862306a36Sopenharmony_ci struct device_node *child; 442962306a36Sopenharmony_ci 443062306a36Sopenharmony_ci for_each_available_child_of_node(np, child) { 443162306a36Sopenharmony_ci int ret; 443262306a36Sopenharmony_ci u32 val; 443362306a36Sopenharmony_ci 443462306a36Sopenharmony_ci ret = of_property_read_u32(child, "reg", &val); 443562306a36Sopenharmony_ci if (ret) 443662306a36Sopenharmony_ci continue; 443762306a36Sopenharmony_ci if (val == dev->devno) { 443862306a36Sopenharmony_ci dev_dbg(d, "found matching device node\n"); 443962306a36Sopenharmony_ci sdev->sdev_gendev.of_node = child; 444062306a36Sopenharmony_ci return; 444162306a36Sopenharmony_ci } 444262306a36Sopenharmony_ci } 444362306a36Sopenharmony_ci} 444462306a36Sopenharmony_ci#else 444562306a36Sopenharmony_cistatic void ata_scsi_assign_ofnode(struct ata_device *dev, struct ata_port *ap) 444662306a36Sopenharmony_ci{ 444762306a36Sopenharmony_ci} 444862306a36Sopenharmony_ci#endif 444962306a36Sopenharmony_ci 445062306a36Sopenharmony_civoid ata_scsi_scan_host(struct ata_port *ap, int sync) 445162306a36Sopenharmony_ci{ 445262306a36Sopenharmony_ci int tries = 5; 445362306a36Sopenharmony_ci struct ata_device *last_failed_dev = NULL; 445462306a36Sopenharmony_ci struct ata_link *link; 445562306a36Sopenharmony_ci struct ata_device *dev; 445662306a36Sopenharmony_ci 445762306a36Sopenharmony_ci repeat: 445862306a36Sopenharmony_ci ata_for_each_link(link, ap, EDGE) { 445962306a36Sopenharmony_ci ata_for_each_dev(dev, link, ENABLED) { 446062306a36Sopenharmony_ci struct scsi_device *sdev; 446162306a36Sopenharmony_ci int channel = 0, id = 0; 446262306a36Sopenharmony_ci 446362306a36Sopenharmony_ci if (dev->sdev) 446462306a36Sopenharmony_ci continue; 446562306a36Sopenharmony_ci 446662306a36Sopenharmony_ci if (ata_is_host_link(link)) 446762306a36Sopenharmony_ci id = dev->devno; 446862306a36Sopenharmony_ci else 446962306a36Sopenharmony_ci channel = link->pmp; 447062306a36Sopenharmony_ci 447162306a36Sopenharmony_ci sdev = __scsi_add_device(ap->scsi_host, channel, id, 0, 447262306a36Sopenharmony_ci NULL); 447362306a36Sopenharmony_ci if (!IS_ERR(sdev)) { 447462306a36Sopenharmony_ci dev->sdev = sdev; 447562306a36Sopenharmony_ci ata_scsi_assign_ofnode(dev, ap); 447662306a36Sopenharmony_ci scsi_device_put(sdev); 447762306a36Sopenharmony_ci } else { 447862306a36Sopenharmony_ci dev->sdev = NULL; 447962306a36Sopenharmony_ci } 448062306a36Sopenharmony_ci } 448162306a36Sopenharmony_ci } 448262306a36Sopenharmony_ci 448362306a36Sopenharmony_ci /* If we scanned while EH was in progress or allocation 448462306a36Sopenharmony_ci * failure occurred, scan would have failed silently. Check 448562306a36Sopenharmony_ci * whether all devices are attached. 448662306a36Sopenharmony_ci */ 448762306a36Sopenharmony_ci ata_for_each_link(link, ap, EDGE) { 448862306a36Sopenharmony_ci ata_for_each_dev(dev, link, ENABLED) { 448962306a36Sopenharmony_ci if (!dev->sdev) 449062306a36Sopenharmony_ci goto exit_loop; 449162306a36Sopenharmony_ci } 449262306a36Sopenharmony_ci } 449362306a36Sopenharmony_ci exit_loop: 449462306a36Sopenharmony_ci if (!link) 449562306a36Sopenharmony_ci return; 449662306a36Sopenharmony_ci 449762306a36Sopenharmony_ci /* we're missing some SCSI devices */ 449862306a36Sopenharmony_ci if (sync) { 449962306a36Sopenharmony_ci /* If caller requested synchrnous scan && we've made 450062306a36Sopenharmony_ci * any progress, sleep briefly and repeat. 450162306a36Sopenharmony_ci */ 450262306a36Sopenharmony_ci if (dev != last_failed_dev) { 450362306a36Sopenharmony_ci msleep(100); 450462306a36Sopenharmony_ci last_failed_dev = dev; 450562306a36Sopenharmony_ci goto repeat; 450662306a36Sopenharmony_ci } 450762306a36Sopenharmony_ci 450862306a36Sopenharmony_ci /* We might be failing to detect boot device, give it 450962306a36Sopenharmony_ci * a few more chances. 451062306a36Sopenharmony_ci */ 451162306a36Sopenharmony_ci if (--tries) { 451262306a36Sopenharmony_ci msleep(100); 451362306a36Sopenharmony_ci goto repeat; 451462306a36Sopenharmony_ci } 451562306a36Sopenharmony_ci 451662306a36Sopenharmony_ci ata_port_err(ap, 451762306a36Sopenharmony_ci "WARNING: synchronous SCSI scan failed without making any progress, switching to async\n"); 451862306a36Sopenharmony_ci } 451962306a36Sopenharmony_ci 452062306a36Sopenharmony_ci queue_delayed_work(system_long_wq, &ap->hotplug_task, 452162306a36Sopenharmony_ci round_jiffies_relative(HZ)); 452262306a36Sopenharmony_ci} 452362306a36Sopenharmony_ci 452462306a36Sopenharmony_ci/** 452562306a36Sopenharmony_ci * ata_scsi_offline_dev - offline attached SCSI device 452662306a36Sopenharmony_ci * @dev: ATA device to offline attached SCSI device for 452762306a36Sopenharmony_ci * 452862306a36Sopenharmony_ci * This function is called from ata_eh_hotplug() and responsible 452962306a36Sopenharmony_ci * for taking the SCSI device attached to @dev offline. This 453062306a36Sopenharmony_ci * function is called with host lock which protects dev->sdev 453162306a36Sopenharmony_ci * against clearing. 453262306a36Sopenharmony_ci * 453362306a36Sopenharmony_ci * LOCKING: 453462306a36Sopenharmony_ci * spin_lock_irqsave(host lock) 453562306a36Sopenharmony_ci * 453662306a36Sopenharmony_ci * RETURNS: 453762306a36Sopenharmony_ci * 1 if attached SCSI device exists, 0 otherwise. 453862306a36Sopenharmony_ci */ 453962306a36Sopenharmony_ciint ata_scsi_offline_dev(struct ata_device *dev) 454062306a36Sopenharmony_ci{ 454162306a36Sopenharmony_ci if (dev->sdev) { 454262306a36Sopenharmony_ci scsi_device_set_state(dev->sdev, SDEV_OFFLINE); 454362306a36Sopenharmony_ci return 1; 454462306a36Sopenharmony_ci } 454562306a36Sopenharmony_ci return 0; 454662306a36Sopenharmony_ci} 454762306a36Sopenharmony_ci 454862306a36Sopenharmony_ci/** 454962306a36Sopenharmony_ci * ata_scsi_remove_dev - remove attached SCSI device 455062306a36Sopenharmony_ci * @dev: ATA device to remove attached SCSI device for 455162306a36Sopenharmony_ci * 455262306a36Sopenharmony_ci * This function is called from ata_eh_scsi_hotplug() and 455362306a36Sopenharmony_ci * responsible for removing the SCSI device attached to @dev. 455462306a36Sopenharmony_ci * 455562306a36Sopenharmony_ci * LOCKING: 455662306a36Sopenharmony_ci * Kernel thread context (may sleep). 455762306a36Sopenharmony_ci */ 455862306a36Sopenharmony_cistatic void ata_scsi_remove_dev(struct ata_device *dev) 455962306a36Sopenharmony_ci{ 456062306a36Sopenharmony_ci struct ata_port *ap = dev->link->ap; 456162306a36Sopenharmony_ci struct scsi_device *sdev; 456262306a36Sopenharmony_ci unsigned long flags; 456362306a36Sopenharmony_ci 456462306a36Sopenharmony_ci /* Alas, we need to grab scan_mutex to ensure SCSI device 456562306a36Sopenharmony_ci * state doesn't change underneath us and thus 456662306a36Sopenharmony_ci * scsi_device_get() always succeeds. The mutex locking can 456762306a36Sopenharmony_ci * be removed if there is __scsi_device_get() interface which 456862306a36Sopenharmony_ci * increments reference counts regardless of device state. 456962306a36Sopenharmony_ci */ 457062306a36Sopenharmony_ci mutex_lock(&ap->scsi_host->scan_mutex); 457162306a36Sopenharmony_ci spin_lock_irqsave(ap->lock, flags); 457262306a36Sopenharmony_ci 457362306a36Sopenharmony_ci /* clearing dev->sdev is protected by host lock */ 457462306a36Sopenharmony_ci sdev = dev->sdev; 457562306a36Sopenharmony_ci dev->sdev = NULL; 457662306a36Sopenharmony_ci 457762306a36Sopenharmony_ci if (sdev) { 457862306a36Sopenharmony_ci /* If user initiated unplug races with us, sdev can go 457962306a36Sopenharmony_ci * away underneath us after the host lock and 458062306a36Sopenharmony_ci * scan_mutex are released. Hold onto it. 458162306a36Sopenharmony_ci */ 458262306a36Sopenharmony_ci if (scsi_device_get(sdev) == 0) { 458362306a36Sopenharmony_ci /* The following ensures the attached sdev is 458462306a36Sopenharmony_ci * offline on return from ata_scsi_offline_dev() 458562306a36Sopenharmony_ci * regardless it wins or loses the race 458662306a36Sopenharmony_ci * against this function. 458762306a36Sopenharmony_ci */ 458862306a36Sopenharmony_ci scsi_device_set_state(sdev, SDEV_OFFLINE); 458962306a36Sopenharmony_ci } else { 459062306a36Sopenharmony_ci WARN_ON(1); 459162306a36Sopenharmony_ci sdev = NULL; 459262306a36Sopenharmony_ci } 459362306a36Sopenharmony_ci } 459462306a36Sopenharmony_ci 459562306a36Sopenharmony_ci spin_unlock_irqrestore(ap->lock, flags); 459662306a36Sopenharmony_ci mutex_unlock(&ap->scsi_host->scan_mutex); 459762306a36Sopenharmony_ci 459862306a36Sopenharmony_ci if (sdev) { 459962306a36Sopenharmony_ci ata_dev_info(dev, "detaching (SCSI %s)\n", 460062306a36Sopenharmony_ci dev_name(&sdev->sdev_gendev)); 460162306a36Sopenharmony_ci 460262306a36Sopenharmony_ci scsi_remove_device(sdev); 460362306a36Sopenharmony_ci scsi_device_put(sdev); 460462306a36Sopenharmony_ci } 460562306a36Sopenharmony_ci} 460662306a36Sopenharmony_ci 460762306a36Sopenharmony_cistatic void ata_scsi_handle_link_detach(struct ata_link *link) 460862306a36Sopenharmony_ci{ 460962306a36Sopenharmony_ci struct ata_port *ap = link->ap; 461062306a36Sopenharmony_ci struct ata_device *dev; 461162306a36Sopenharmony_ci 461262306a36Sopenharmony_ci ata_for_each_dev(dev, link, ALL) { 461362306a36Sopenharmony_ci unsigned long flags; 461462306a36Sopenharmony_ci 461562306a36Sopenharmony_ci if (!(dev->flags & ATA_DFLAG_DETACHED)) 461662306a36Sopenharmony_ci continue; 461762306a36Sopenharmony_ci 461862306a36Sopenharmony_ci spin_lock_irqsave(ap->lock, flags); 461962306a36Sopenharmony_ci dev->flags &= ~ATA_DFLAG_DETACHED; 462062306a36Sopenharmony_ci spin_unlock_irqrestore(ap->lock, flags); 462162306a36Sopenharmony_ci 462262306a36Sopenharmony_ci if (zpodd_dev_enabled(dev)) 462362306a36Sopenharmony_ci zpodd_exit(dev); 462462306a36Sopenharmony_ci 462562306a36Sopenharmony_ci ata_scsi_remove_dev(dev); 462662306a36Sopenharmony_ci } 462762306a36Sopenharmony_ci} 462862306a36Sopenharmony_ci 462962306a36Sopenharmony_ci/** 463062306a36Sopenharmony_ci * ata_scsi_media_change_notify - send media change event 463162306a36Sopenharmony_ci * @dev: Pointer to the disk device with media change event 463262306a36Sopenharmony_ci * 463362306a36Sopenharmony_ci * Tell the block layer to send a media change notification 463462306a36Sopenharmony_ci * event. 463562306a36Sopenharmony_ci * 463662306a36Sopenharmony_ci * LOCKING: 463762306a36Sopenharmony_ci * spin_lock_irqsave(host lock) 463862306a36Sopenharmony_ci */ 463962306a36Sopenharmony_civoid ata_scsi_media_change_notify(struct ata_device *dev) 464062306a36Sopenharmony_ci{ 464162306a36Sopenharmony_ci if (dev->sdev) 464262306a36Sopenharmony_ci sdev_evt_send_simple(dev->sdev, SDEV_EVT_MEDIA_CHANGE, 464362306a36Sopenharmony_ci GFP_ATOMIC); 464462306a36Sopenharmony_ci} 464562306a36Sopenharmony_ci 464662306a36Sopenharmony_ci/** 464762306a36Sopenharmony_ci * ata_scsi_hotplug - SCSI part of hotplug 464862306a36Sopenharmony_ci * @work: Pointer to ATA port to perform SCSI hotplug on 464962306a36Sopenharmony_ci * 465062306a36Sopenharmony_ci * Perform SCSI part of hotplug. It's executed from a separate 465162306a36Sopenharmony_ci * workqueue after EH completes. This is necessary because SCSI 465262306a36Sopenharmony_ci * hot plugging requires working EH and hot unplugging is 465362306a36Sopenharmony_ci * synchronized with hot plugging with a mutex. 465462306a36Sopenharmony_ci * 465562306a36Sopenharmony_ci * LOCKING: 465662306a36Sopenharmony_ci * Kernel thread context (may sleep). 465762306a36Sopenharmony_ci */ 465862306a36Sopenharmony_civoid ata_scsi_hotplug(struct work_struct *work) 465962306a36Sopenharmony_ci{ 466062306a36Sopenharmony_ci struct ata_port *ap = 466162306a36Sopenharmony_ci container_of(work, struct ata_port, hotplug_task.work); 466262306a36Sopenharmony_ci int i; 466362306a36Sopenharmony_ci 466462306a36Sopenharmony_ci if (ap->pflags & ATA_PFLAG_UNLOADING) 466562306a36Sopenharmony_ci return; 466662306a36Sopenharmony_ci 466762306a36Sopenharmony_ci mutex_lock(&ap->scsi_scan_mutex); 466862306a36Sopenharmony_ci 466962306a36Sopenharmony_ci /* Unplug detached devices. We cannot use link iterator here 467062306a36Sopenharmony_ci * because PMP links have to be scanned even if PMP is 467162306a36Sopenharmony_ci * currently not attached. Iterate manually. 467262306a36Sopenharmony_ci */ 467362306a36Sopenharmony_ci ata_scsi_handle_link_detach(&ap->link); 467462306a36Sopenharmony_ci if (ap->pmp_link) 467562306a36Sopenharmony_ci for (i = 0; i < SATA_PMP_MAX_PORTS; i++) 467662306a36Sopenharmony_ci ata_scsi_handle_link_detach(&ap->pmp_link[i]); 467762306a36Sopenharmony_ci 467862306a36Sopenharmony_ci /* scan for new ones */ 467962306a36Sopenharmony_ci ata_scsi_scan_host(ap, 0); 468062306a36Sopenharmony_ci 468162306a36Sopenharmony_ci mutex_unlock(&ap->scsi_scan_mutex); 468262306a36Sopenharmony_ci} 468362306a36Sopenharmony_ci 468462306a36Sopenharmony_ci/** 468562306a36Sopenharmony_ci * ata_scsi_user_scan - indication for user-initiated bus scan 468662306a36Sopenharmony_ci * @shost: SCSI host to scan 468762306a36Sopenharmony_ci * @channel: Channel to scan 468862306a36Sopenharmony_ci * @id: ID to scan 468962306a36Sopenharmony_ci * @lun: LUN to scan 469062306a36Sopenharmony_ci * 469162306a36Sopenharmony_ci * This function is called when user explicitly requests bus 469262306a36Sopenharmony_ci * scan. Set probe pending flag and invoke EH. 469362306a36Sopenharmony_ci * 469462306a36Sopenharmony_ci * LOCKING: 469562306a36Sopenharmony_ci * SCSI layer (we don't care) 469662306a36Sopenharmony_ci * 469762306a36Sopenharmony_ci * RETURNS: 469862306a36Sopenharmony_ci * Zero. 469962306a36Sopenharmony_ci */ 470062306a36Sopenharmony_ciint ata_scsi_user_scan(struct Scsi_Host *shost, unsigned int channel, 470162306a36Sopenharmony_ci unsigned int id, u64 lun) 470262306a36Sopenharmony_ci{ 470362306a36Sopenharmony_ci struct ata_port *ap = ata_shost_to_port(shost); 470462306a36Sopenharmony_ci unsigned long flags; 470562306a36Sopenharmony_ci int devno, rc = 0; 470662306a36Sopenharmony_ci 470762306a36Sopenharmony_ci if (lun != SCAN_WILD_CARD && lun) 470862306a36Sopenharmony_ci return -EINVAL; 470962306a36Sopenharmony_ci 471062306a36Sopenharmony_ci if (!sata_pmp_attached(ap)) { 471162306a36Sopenharmony_ci if (channel != SCAN_WILD_CARD && channel) 471262306a36Sopenharmony_ci return -EINVAL; 471362306a36Sopenharmony_ci devno = id; 471462306a36Sopenharmony_ci } else { 471562306a36Sopenharmony_ci if (id != SCAN_WILD_CARD && id) 471662306a36Sopenharmony_ci return -EINVAL; 471762306a36Sopenharmony_ci devno = channel; 471862306a36Sopenharmony_ci } 471962306a36Sopenharmony_ci 472062306a36Sopenharmony_ci spin_lock_irqsave(ap->lock, flags); 472162306a36Sopenharmony_ci 472262306a36Sopenharmony_ci if (devno == SCAN_WILD_CARD) { 472362306a36Sopenharmony_ci struct ata_link *link; 472462306a36Sopenharmony_ci 472562306a36Sopenharmony_ci ata_for_each_link(link, ap, EDGE) { 472662306a36Sopenharmony_ci struct ata_eh_info *ehi = &link->eh_info; 472762306a36Sopenharmony_ci ehi->probe_mask |= ATA_ALL_DEVICES; 472862306a36Sopenharmony_ci ehi->action |= ATA_EH_RESET; 472962306a36Sopenharmony_ci } 473062306a36Sopenharmony_ci } else { 473162306a36Sopenharmony_ci struct ata_device *dev = ata_find_dev(ap, devno); 473262306a36Sopenharmony_ci 473362306a36Sopenharmony_ci if (dev) { 473462306a36Sopenharmony_ci struct ata_eh_info *ehi = &dev->link->eh_info; 473562306a36Sopenharmony_ci ehi->probe_mask |= 1 << dev->devno; 473662306a36Sopenharmony_ci ehi->action |= ATA_EH_RESET; 473762306a36Sopenharmony_ci } else 473862306a36Sopenharmony_ci rc = -EINVAL; 473962306a36Sopenharmony_ci } 474062306a36Sopenharmony_ci 474162306a36Sopenharmony_ci if (rc == 0) { 474262306a36Sopenharmony_ci ata_port_schedule_eh(ap); 474362306a36Sopenharmony_ci spin_unlock_irqrestore(ap->lock, flags); 474462306a36Sopenharmony_ci ata_port_wait_eh(ap); 474562306a36Sopenharmony_ci } else 474662306a36Sopenharmony_ci spin_unlock_irqrestore(ap->lock, flags); 474762306a36Sopenharmony_ci 474862306a36Sopenharmony_ci return rc; 474962306a36Sopenharmony_ci} 475062306a36Sopenharmony_ci 475162306a36Sopenharmony_ci/** 475262306a36Sopenharmony_ci * ata_scsi_dev_rescan - initiate scsi_rescan_device() 475362306a36Sopenharmony_ci * @work: Pointer to ATA port to perform scsi_rescan_device() 475462306a36Sopenharmony_ci * 475562306a36Sopenharmony_ci * After ATA pass thru (SAT) commands are executed successfully, 475662306a36Sopenharmony_ci * libata need to propagate the changes to SCSI layer. 475762306a36Sopenharmony_ci * 475862306a36Sopenharmony_ci * LOCKING: 475962306a36Sopenharmony_ci * Kernel thread context (may sleep). 476062306a36Sopenharmony_ci */ 476162306a36Sopenharmony_civoid ata_scsi_dev_rescan(struct work_struct *work) 476262306a36Sopenharmony_ci{ 476362306a36Sopenharmony_ci struct ata_port *ap = 476462306a36Sopenharmony_ci container_of(work, struct ata_port, scsi_rescan_task.work); 476562306a36Sopenharmony_ci struct ata_link *link; 476662306a36Sopenharmony_ci struct ata_device *dev; 476762306a36Sopenharmony_ci unsigned long flags; 476862306a36Sopenharmony_ci int ret = 0; 476962306a36Sopenharmony_ci 477062306a36Sopenharmony_ci mutex_lock(&ap->scsi_scan_mutex); 477162306a36Sopenharmony_ci spin_lock_irqsave(ap->lock, flags); 477262306a36Sopenharmony_ci 477362306a36Sopenharmony_ci ata_for_each_link(link, ap, EDGE) { 477462306a36Sopenharmony_ci ata_for_each_dev(dev, link, ENABLED) { 477562306a36Sopenharmony_ci struct scsi_device *sdev = dev->sdev; 477662306a36Sopenharmony_ci 477762306a36Sopenharmony_ci /* 477862306a36Sopenharmony_ci * If the port was suspended before this was scheduled, 477962306a36Sopenharmony_ci * bail out. 478062306a36Sopenharmony_ci */ 478162306a36Sopenharmony_ci if (ap->pflags & ATA_PFLAG_SUSPENDED) 478262306a36Sopenharmony_ci goto unlock; 478362306a36Sopenharmony_ci 478462306a36Sopenharmony_ci if (!sdev) 478562306a36Sopenharmony_ci continue; 478662306a36Sopenharmony_ci if (scsi_device_get(sdev)) 478762306a36Sopenharmony_ci continue; 478862306a36Sopenharmony_ci 478962306a36Sopenharmony_ci spin_unlock_irqrestore(ap->lock, flags); 479062306a36Sopenharmony_ci ret = scsi_rescan_device(sdev); 479162306a36Sopenharmony_ci scsi_device_put(sdev); 479262306a36Sopenharmony_ci spin_lock_irqsave(ap->lock, flags); 479362306a36Sopenharmony_ci 479462306a36Sopenharmony_ci if (ret) 479562306a36Sopenharmony_ci goto unlock; 479662306a36Sopenharmony_ci } 479762306a36Sopenharmony_ci } 479862306a36Sopenharmony_ci 479962306a36Sopenharmony_ciunlock: 480062306a36Sopenharmony_ci spin_unlock_irqrestore(ap->lock, flags); 480162306a36Sopenharmony_ci mutex_unlock(&ap->scsi_scan_mutex); 480262306a36Sopenharmony_ci 480362306a36Sopenharmony_ci /* Reschedule with a delay if scsi_rescan_device() returned an error */ 480462306a36Sopenharmony_ci if (ret) 480562306a36Sopenharmony_ci schedule_delayed_work(&ap->scsi_rescan_task, 480662306a36Sopenharmony_ci msecs_to_jiffies(5)); 480762306a36Sopenharmony_ci} 4808