mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2025-01-06 05:06:29 +00:00
for-5.15/libata-2021-08-30
-----BEGIN PGP SIGNATURE----- iQJEBAABCAAuFiEEwPw5LcreJtl1+l5K99NY+ylx4KYFAmEs7eQQHGF4Ym9lQGtl cm5lbC5kawAKCRD301j7KXHgpjgFEADdoNxMxT87aCXBZ50TrU9s8oS3nCgXhp4k CbDZFOccWRmn/EMA0H/sPMOVr6K1nZRwYN/6W9aja5yYw7DiI5HgyOZzFkeqWPXB +FoTXOHJxVYuXbbO3w9tTqATNYiMSTmolVMnsxH5R7cTFrV9OCWMwiUx0l/s8PB+ ohd7tRSXS4gQwENN/jVzOX7LCluzQ5LOi1C8xYdT0ARL52CIOScD2omtoaXf4BgP r/0i7D0pATGRjjV78c4xfc1req4PrfLyJUMpU4Eo3nzpwNxMDlrwmN41SLMPlMp4 SX/7KZ7fo+0a1jt76YD6pUmeXFgFoEJJEN239VX3VzCZYBPkYvfB7cjNdr26Sp/u v+2p4oNi5NneU1lItFRM57enAXlKmvM3EP8FeEceSCA+OWYo5cn4JUSaonxrscnB Et3CKjdizckAJ6cdIxqT6ecX9zWvLQwzMU2x6rRp3DalwXFt2sgFbKhldN2KguQi IfSYWEAEjYi3OtnPUZpR2geeRf2ypk2vKPmqGdh+6qEjlZ1fR+MZT2OlUeZyIT7p GwP8hey1tzEC4BpmFuEVPDv5xm8ko/yqQjjiF9/AbXva2l2+NyWSuGhm0qxUoMBP KwA90XKxwIq0j8eF7YaIi72Y6M7J+mEBtOdLiq526VDSRklagfUDD39Zs4q3SpQ4 yXUdEDbfOw== =LcKu -----END PGP SIGNATURE----- Merge tag 'for-5.15/libata-2021-08-30' of git://git.kernel.dk/linux-block Pull libata updates from Jens Axboe: "libata changes for the 5.15 release: - NCQ priority improvements (Damien, Niklas) - coccinelle warning fix (Jing) - dwc_460ex phy fix (Andy)" * tag 'for-5.15/libata-2021-08-30' of git://git.kernel.dk/linux-block: include:libata: fix boolreturn.cocci warnings docs: sysfs-block-device: document ncq_prio_supported docs: sysfs-block-device: improve ncq_prio_enable documentation libata: Introduce ncq_prio_supported sysfs sttribute libata: print feature list on device scan libata: fix ata_read_log_page() warning libata: cleanup NCQ priority handling libata: cleanup ata_dev_configure() libata: cleanup device sleep capability detection libata: simplify ata_scsi_rbuf_fill() libata: fix ata_host_start() ata: sata_dwc_460ex: No need to call phy_exit() befre phy_init()
This commit is contained in:
commit
44d7d3b0d1
@ -55,6 +55,43 @@ Date: Oct, 2016
|
||||
KernelVersion: v4.10
|
||||
Contact: linux-ide@vger.kernel.org
|
||||
Description:
|
||||
(RW) Write to the file to turn on or off the SATA ncq (native
|
||||
command queueing) support. By default this feature is turned
|
||||
off.
|
||||
(RW) Write to the file to turn on or off the SATA NCQ (native
|
||||
command queueing) priority support. By default this feature is
|
||||
turned off. If the device does not support the SATA NCQ
|
||||
priority feature, writing "1" to this file results in an error
|
||||
(see ncq_prio_supported).
|
||||
|
||||
|
||||
What: /sys/block/*/device/sas_ncq_prio_enable
|
||||
Date: Oct, 2016
|
||||
KernelVersion: v4.10
|
||||
Contact: linux-ide@vger.kernel.org
|
||||
Description:
|
||||
(RW) This is the equivalent of the ncq_prio_enable attribute
|
||||
file for SATA devices connected to a SAS host-bus-adapter
|
||||
(HBA) implementing support for the SATA NCQ priority feature.
|
||||
This file does not exist if the HBA driver does not implement
|
||||
support for the SATA NCQ priority feature, regardless of the
|
||||
device support for this feature (see sas_ncq_prio_supported).
|
||||
|
||||
|
||||
What: /sys/block/*/device/ncq_prio_supported
|
||||
Date: Aug, 2021
|
||||
KernelVersion: v5.15
|
||||
Contact: linux-ide@vger.kernel.org
|
||||
Description:
|
||||
(RO) Indicates if the device supports the SATA NCQ (native
|
||||
command queueing) priority feature.
|
||||
|
||||
|
||||
What: /sys/block/*/device/sas_ncq_prio_supported
|
||||
Date: Aug, 2021
|
||||
KernelVersion: v5.15
|
||||
Contact: linux-ide@vger.kernel.org
|
||||
Description:
|
||||
(RO) This is the equivalent of the ncq_prio_supported attribute
|
||||
file for SATA devices connected to a SAS host-bus-adapter
|
||||
(HBA) implementing support for the SATA NCQ priority feature.
|
||||
This file does not exist if the HBA driver does not implement
|
||||
support for the SATA NCQ priority feature, regardless of the
|
||||
device support for this feature.
|
||||
|
@ -125,6 +125,7 @@ EXPORT_SYMBOL_GPL(ahci_shost_attrs);
|
||||
struct device_attribute *ahci_sdev_attrs[] = {
|
||||
&dev_attr_sw_activity,
|
||||
&dev_attr_unload_heads,
|
||||
&dev_attr_ncq_prio_supported,
|
||||
&dev_attr_ncq_prio_enable,
|
||||
NULL
|
||||
};
|
||||
|
@ -159,6 +159,12 @@ MODULE_DESCRIPTION("Library module for ATA devices");
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_VERSION(DRV_VERSION);
|
||||
|
||||
static inline bool ata_dev_print_info(struct ata_device *dev)
|
||||
{
|
||||
struct ata_eh_context *ehc = &dev->link->eh_context;
|
||||
|
||||
return ehc->i.flags & ATA_EHI_PRINTINFO;
|
||||
}
|
||||
|
||||
static bool ata_sstatus_online(u32 sstatus)
|
||||
{
|
||||
@ -706,11 +712,9 @@ int ata_build_rw_tf(struct ata_taskfile *tf, struct ata_device *dev,
|
||||
if (tf->flags & ATA_TFLAG_FUA)
|
||||
tf->device |= 1 << 7;
|
||||
|
||||
if (dev->flags & ATA_DFLAG_NCQ_PRIO) {
|
||||
if (class == IOPRIO_CLASS_RT)
|
||||
tf->hob_nsect |= ATA_PRIO_HIGH <<
|
||||
ATA_SHIFT_PRIO;
|
||||
}
|
||||
if (dev->flags & ATA_DFLAG_NCQ_PRIO_ENABLE &&
|
||||
class == IOPRIO_CLASS_RT)
|
||||
tf->hob_nsect |= ATA_PRIO_HIGH << ATA_SHIFT_PRIO;
|
||||
} else if (dev->flags & ATA_DFLAG_LBA) {
|
||||
tf->flags |= ATA_TFLAG_LBA;
|
||||
|
||||
@ -1266,8 +1270,7 @@ static int ata_set_max_sectors(struct ata_device *dev, u64 new_sectors)
|
||||
*/
|
||||
static int ata_hpa_resize(struct ata_device *dev)
|
||||
{
|
||||
struct ata_eh_context *ehc = &dev->link->eh_context;
|
||||
int print_info = ehc->i.flags & ATA_EHI_PRINTINFO;
|
||||
bool print_info = ata_dev_print_info(dev);
|
||||
bool unlock_hpa = ata_ignore_hpa || dev->flags & ATA_DFLAG_UNLOCK_HPA;
|
||||
u64 sectors = ata_id_n_sectors(dev->id);
|
||||
u64 native_sectors;
|
||||
@ -2023,13 +2026,15 @@ unsigned int ata_read_log_page(struct ata_device *dev, u8 log,
|
||||
err_mask = ata_exec_internal(dev, &tf, NULL, DMA_FROM_DEVICE,
|
||||
buf, sectors * ATA_SECT_SIZE, 0);
|
||||
|
||||
if (err_mask && dma) {
|
||||
dev->horkage |= ATA_HORKAGE_NO_DMA_LOG;
|
||||
ata_dev_warn(dev, "READ LOG DMA EXT failed, trying PIO\n");
|
||||
goto retry;
|
||||
if (err_mask) {
|
||||
if (dma) {
|
||||
dev->horkage |= ATA_HORKAGE_NO_DMA_LOG;
|
||||
goto retry;
|
||||
}
|
||||
ata_dev_err(dev, "Read log page 0x%02x failed, Emask 0x%x\n",
|
||||
(unsigned int)page, err_mask);
|
||||
}
|
||||
|
||||
DPRINTK("EXIT, err_mask=%x\n", err_mask);
|
||||
return err_mask;
|
||||
}
|
||||
|
||||
@ -2058,12 +2063,8 @@ static bool ata_identify_page_supported(struct ata_device *dev, u8 page)
|
||||
*/
|
||||
err = ata_read_log_page(dev, ATA_LOG_IDENTIFY_DEVICE, 0, ap->sector_buf,
|
||||
1);
|
||||
if (err) {
|
||||
ata_dev_info(dev,
|
||||
"failed to get Device Identify Log Emask 0x%x\n",
|
||||
err);
|
||||
if (err)
|
||||
return false;
|
||||
}
|
||||
|
||||
for (i = 0; i < ap->sector_buf[8]; i++) {
|
||||
if (ap->sector_buf[9 + i] == page)
|
||||
@ -2127,11 +2128,7 @@ static void ata_dev_config_ncq_send_recv(struct ata_device *dev)
|
||||
}
|
||||
err_mask = ata_read_log_page(dev, ATA_LOG_NCQ_SEND_RECV,
|
||||
0, ap->sector_buf, 1);
|
||||
if (err_mask) {
|
||||
ata_dev_dbg(dev,
|
||||
"failed to get NCQ Send/Recv Log Emask 0x%x\n",
|
||||
err_mask);
|
||||
} else {
|
||||
if (!err_mask) {
|
||||
u8 *cmds = dev->ncq_send_recv_cmds;
|
||||
|
||||
dev->flags |= ATA_DFLAG_NCQ_SEND_RECV;
|
||||
@ -2157,11 +2154,7 @@ static void ata_dev_config_ncq_non_data(struct ata_device *dev)
|
||||
}
|
||||
err_mask = ata_read_log_page(dev, ATA_LOG_NCQ_NON_DATA,
|
||||
0, ap->sector_buf, 1);
|
||||
if (err_mask) {
|
||||
ata_dev_dbg(dev,
|
||||
"failed to get NCQ Non-Data Log Emask 0x%x\n",
|
||||
err_mask);
|
||||
} else {
|
||||
if (!err_mask) {
|
||||
u8 *cmds = dev->ncq_non_data_cmds;
|
||||
|
||||
memcpy(cmds, ap->sector_buf, ATA_LOG_NCQ_NON_DATA_SIZE);
|
||||
@ -2173,30 +2166,24 @@ static void ata_dev_config_ncq_prio(struct ata_device *dev)
|
||||
struct ata_port *ap = dev->link->ap;
|
||||
unsigned int err_mask;
|
||||
|
||||
if (!(dev->flags & ATA_DFLAG_NCQ_PRIO_ENABLE)) {
|
||||
dev->flags &= ~ATA_DFLAG_NCQ_PRIO;
|
||||
return;
|
||||
}
|
||||
|
||||
err_mask = ata_read_log_page(dev,
|
||||
ATA_LOG_IDENTIFY_DEVICE,
|
||||
ATA_LOG_SATA_SETTINGS,
|
||||
ap->sector_buf,
|
||||
1);
|
||||
if (err_mask) {
|
||||
ata_dev_dbg(dev,
|
||||
"failed to get Identify Device data, Emask 0x%x\n",
|
||||
err_mask);
|
||||
return;
|
||||
}
|
||||
if (err_mask)
|
||||
goto not_supported;
|
||||
|
||||
if (ap->sector_buf[ATA_LOG_NCQ_PRIO_OFFSET] & BIT(3)) {
|
||||
dev->flags |= ATA_DFLAG_NCQ_PRIO;
|
||||
} else {
|
||||
dev->flags &= ~ATA_DFLAG_NCQ_PRIO;
|
||||
ata_dev_dbg(dev, "SATA page does not support priority\n");
|
||||
}
|
||||
if (!(ap->sector_buf[ATA_LOG_NCQ_PRIO_OFFSET] & BIT(3)))
|
||||
goto not_supported;
|
||||
|
||||
dev->flags |= ATA_DFLAG_NCQ_PRIO;
|
||||
|
||||
return;
|
||||
|
||||
not_supported:
|
||||
dev->flags &= ~ATA_DFLAG_NCQ_PRIO_ENABLE;
|
||||
dev->flags &= ~ATA_DFLAG_NCQ_PRIO;
|
||||
}
|
||||
|
||||
static int ata_dev_config_ncq(struct ata_device *dev,
|
||||
@ -2346,11 +2333,8 @@ static void ata_dev_config_trusted(struct ata_device *dev)
|
||||
|
||||
err = ata_read_log_page(dev, ATA_LOG_IDENTIFY_DEVICE, ATA_LOG_SECURITY,
|
||||
ap->sector_buf, 1);
|
||||
if (err) {
|
||||
ata_dev_dbg(dev,
|
||||
"failed to read Security Log, Emask 0x%x\n", err);
|
||||
if (err)
|
||||
return;
|
||||
}
|
||||
|
||||
trusted_cap = get_unaligned_le64(&ap->sector_buf[40]);
|
||||
if (!(trusted_cap & (1ULL << 63))) {
|
||||
@ -2363,6 +2347,106 @@ static void ata_dev_config_trusted(struct ata_device *dev)
|
||||
dev->flags |= ATA_DFLAG_TRUSTED;
|
||||
}
|
||||
|
||||
static int ata_dev_config_lba(struct ata_device *dev)
|
||||
{
|
||||
struct ata_port *ap = dev->link->ap;
|
||||
const u16 *id = dev->id;
|
||||
const char *lba_desc;
|
||||
char ncq_desc[24];
|
||||
int ret;
|
||||
|
||||
dev->flags |= ATA_DFLAG_LBA;
|
||||
|
||||
if (ata_id_has_lba48(id)) {
|
||||
lba_desc = "LBA48";
|
||||
dev->flags |= ATA_DFLAG_LBA48;
|
||||
if (dev->n_sectors >= (1UL << 28) &&
|
||||
ata_id_has_flush_ext(id))
|
||||
dev->flags |= ATA_DFLAG_FLUSH_EXT;
|
||||
} else {
|
||||
lba_desc = "LBA";
|
||||
}
|
||||
|
||||
/* config NCQ */
|
||||
ret = ata_dev_config_ncq(dev, ncq_desc, sizeof(ncq_desc));
|
||||
|
||||
/* print device info to dmesg */
|
||||
if (ata_msg_drv(ap) && ata_dev_print_info(dev))
|
||||
ata_dev_info(dev,
|
||||
"%llu sectors, multi %u: %s %s\n",
|
||||
(unsigned long long)dev->n_sectors,
|
||||
dev->multi_count, lba_desc, ncq_desc);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void ata_dev_config_chs(struct ata_device *dev)
|
||||
{
|
||||
struct ata_port *ap = dev->link->ap;
|
||||
const u16 *id = dev->id;
|
||||
|
||||
if (ata_id_current_chs_valid(id)) {
|
||||
/* Current CHS translation is valid. */
|
||||
dev->cylinders = id[54];
|
||||
dev->heads = id[55];
|
||||
dev->sectors = id[56];
|
||||
} else {
|
||||
/* Default translation */
|
||||
dev->cylinders = id[1];
|
||||
dev->heads = id[3];
|
||||
dev->sectors = id[6];
|
||||
}
|
||||
|
||||
/* print device info to dmesg */
|
||||
if (ata_msg_drv(ap) && ata_dev_print_info(dev))
|
||||
ata_dev_info(dev,
|
||||
"%llu sectors, multi %u, CHS %u/%u/%u\n",
|
||||
(unsigned long long)dev->n_sectors,
|
||||
dev->multi_count, dev->cylinders,
|
||||
dev->heads, dev->sectors);
|
||||
}
|
||||
|
||||
static void ata_dev_config_devslp(struct ata_device *dev)
|
||||
{
|
||||
u8 *sata_setting = dev->link->ap->sector_buf;
|
||||
unsigned int err_mask;
|
||||
int i, j;
|
||||
|
||||
/*
|
||||
* Check device sleep capability. Get DevSlp timing variables
|
||||
* from SATA Settings page of Identify Device Data Log.
|
||||
*/
|
||||
if (!ata_id_has_devslp(dev->id))
|
||||
return;
|
||||
|
||||
err_mask = ata_read_log_page(dev,
|
||||
ATA_LOG_IDENTIFY_DEVICE,
|
||||
ATA_LOG_SATA_SETTINGS,
|
||||
sata_setting, 1);
|
||||
if (err_mask)
|
||||
return;
|
||||
|
||||
dev->flags |= ATA_DFLAG_DEVSLP;
|
||||
for (i = 0; i < ATA_LOG_DEVSLP_SIZE; i++) {
|
||||
j = ATA_LOG_DEVSLP_OFFSET + i;
|
||||
dev->devslp_timing[i] = sata_setting[j];
|
||||
}
|
||||
}
|
||||
|
||||
static void ata_dev_print_features(struct ata_device *dev)
|
||||
{
|
||||
if (!(dev->flags & ATA_DFLAG_FEATURES_MASK))
|
||||
return;
|
||||
|
||||
ata_dev_info(dev,
|
||||
"Features:%s%s%s%s%s\n",
|
||||
dev->flags & ATA_DFLAG_TRUSTED ? " Trust" : "",
|
||||
dev->flags & ATA_DFLAG_DA ? " Dev-Attention" : "",
|
||||
dev->flags & ATA_DFLAG_DEVSLP ? " Dev-Sleep" : "",
|
||||
dev->flags & ATA_DFLAG_NCQ_SEND_RECV ? " NCQ-sndrcv" : "",
|
||||
dev->flags & ATA_DFLAG_NCQ_PRIO ? " NCQ-prio" : "");
|
||||
}
|
||||
|
||||
/**
|
||||
* ata_dev_configure - Configure the specified ATA/ATAPI device
|
||||
* @dev: Target device to configure
|
||||
@ -2379,8 +2463,7 @@ static void ata_dev_config_trusted(struct ata_device *dev)
|
||||
int ata_dev_configure(struct ata_device *dev)
|
||||
{
|
||||
struct ata_port *ap = dev->link->ap;
|
||||
struct ata_eh_context *ehc = &dev->link->eh_context;
|
||||
int print_info = ehc->i.flags & ATA_EHI_PRINTINFO;
|
||||
bool print_info = ata_dev_print_info(dev);
|
||||
const u16 *id = dev->id;
|
||||
unsigned long xfer_mask;
|
||||
unsigned int err_mask;
|
||||
@ -2507,91 +2590,28 @@ int ata_dev_configure(struct ata_device *dev)
|
||||
dev->multi_count = cnt;
|
||||
}
|
||||
|
||||
/* print device info to dmesg */
|
||||
if (ata_msg_drv(ap) && print_info)
|
||||
ata_dev_info(dev, "%s: %s, %s, max %s\n",
|
||||
revbuf, modelbuf, fwrevbuf,
|
||||
ata_mode_string(xfer_mask));
|
||||
|
||||
if (ata_id_has_lba(id)) {
|
||||
const char *lba_desc;
|
||||
char ncq_desc[24];
|
||||
|
||||
lba_desc = "LBA";
|
||||
dev->flags |= ATA_DFLAG_LBA;
|
||||
if (ata_id_has_lba48(id)) {
|
||||
dev->flags |= ATA_DFLAG_LBA48;
|
||||
lba_desc = "LBA48";
|
||||
|
||||
if (dev->n_sectors >= (1UL << 28) &&
|
||||
ata_id_has_flush_ext(id))
|
||||
dev->flags |= ATA_DFLAG_FLUSH_EXT;
|
||||
}
|
||||
|
||||
/* config NCQ */
|
||||
rc = ata_dev_config_ncq(dev, ncq_desc, sizeof(ncq_desc));
|
||||
rc = ata_dev_config_lba(dev);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
/* print device info to dmesg */
|
||||
if (ata_msg_drv(ap) && print_info) {
|
||||
ata_dev_info(dev, "%s: %s, %s, max %s\n",
|
||||
revbuf, modelbuf, fwrevbuf,
|
||||
ata_mode_string(xfer_mask));
|
||||
ata_dev_info(dev,
|
||||
"%llu sectors, multi %u: %s %s\n",
|
||||
(unsigned long long)dev->n_sectors,
|
||||
dev->multi_count, lba_desc, ncq_desc);
|
||||
}
|
||||
} else {
|
||||
/* CHS */
|
||||
|
||||
/* Default translation */
|
||||
dev->cylinders = id[1];
|
||||
dev->heads = id[3];
|
||||
dev->sectors = id[6];
|
||||
|
||||
if (ata_id_current_chs_valid(id)) {
|
||||
/* Current CHS translation is valid. */
|
||||
dev->cylinders = id[54];
|
||||
dev->heads = id[55];
|
||||
dev->sectors = id[56];
|
||||
}
|
||||
|
||||
/* print device info to dmesg */
|
||||
if (ata_msg_drv(ap) && print_info) {
|
||||
ata_dev_info(dev, "%s: %s, %s, max %s\n",
|
||||
revbuf, modelbuf, fwrevbuf,
|
||||
ata_mode_string(xfer_mask));
|
||||
ata_dev_info(dev,
|
||||
"%llu sectors, multi %u, CHS %u/%u/%u\n",
|
||||
(unsigned long long)dev->n_sectors,
|
||||
dev->multi_count, dev->cylinders,
|
||||
dev->heads, dev->sectors);
|
||||
}
|
||||
ata_dev_config_chs(dev);
|
||||
}
|
||||
|
||||
/* Check and mark DevSlp capability. Get DevSlp timing variables
|
||||
* from SATA Settings page of Identify Device Data Log.
|
||||
*/
|
||||
if (ata_id_has_devslp(dev->id)) {
|
||||
u8 *sata_setting = ap->sector_buf;
|
||||
int i, j;
|
||||
|
||||
dev->flags |= ATA_DFLAG_DEVSLP;
|
||||
err_mask = ata_read_log_page(dev,
|
||||
ATA_LOG_IDENTIFY_DEVICE,
|
||||
ATA_LOG_SATA_SETTINGS,
|
||||
sata_setting,
|
||||
1);
|
||||
if (err_mask)
|
||||
ata_dev_dbg(dev,
|
||||
"failed to get Identify Device Data, Emask 0x%x\n",
|
||||
err_mask);
|
||||
else
|
||||
for (i = 0; i < ATA_LOG_DEVSLP_SIZE; i++) {
|
||||
j = ATA_LOG_DEVSLP_OFFSET + i;
|
||||
dev->devslp_timing[i] = sata_setting[j];
|
||||
}
|
||||
}
|
||||
ata_dev_config_devslp(dev);
|
||||
ata_dev_config_sense_reporting(dev);
|
||||
ata_dev_config_zac(dev);
|
||||
ata_dev_config_trusted(dev);
|
||||
dev->cdb_len = 32;
|
||||
|
||||
if (ata_msg_drv(ap) && print_info)
|
||||
ata_dev_print_features(dev);
|
||||
}
|
||||
|
||||
/* ATAPI-specific feature tests */
|
||||
@ -5573,7 +5593,7 @@ int ata_host_start(struct ata_host *host)
|
||||
have_stop = 1;
|
||||
}
|
||||
|
||||
if (host->ops->host_stop)
|
||||
if (host->ops && host->ops->host_stop)
|
||||
have_stop = 1;
|
||||
|
||||
if (have_stop) {
|
||||
|
@ -834,28 +834,46 @@ DEVICE_ATTR(link_power_management_policy, S_IRUGO | S_IWUSR,
|
||||
ata_scsi_lpm_show, ata_scsi_lpm_store);
|
||||
EXPORT_SYMBOL_GPL(dev_attr_link_power_management_policy);
|
||||
|
||||
static ssize_t ata_ncq_prio_supported_show(struct device *device,
|
||||
struct device_attribute *attr,
|
||||
char *buf)
|
||||
{
|
||||
struct scsi_device *sdev = to_scsi_device(device);
|
||||
struct ata_port *ap = ata_shost_to_port(sdev->host);
|
||||
struct ata_device *dev;
|
||||
bool ncq_prio_supported;
|
||||
int rc = 0;
|
||||
|
||||
spin_lock_irq(ap->lock);
|
||||
dev = ata_scsi_find_dev(ap, sdev);
|
||||
if (!dev)
|
||||
rc = -ENODEV;
|
||||
else
|
||||
ncq_prio_supported = dev->flags & ATA_DFLAG_NCQ_PRIO;
|
||||
spin_unlock_irq(ap->lock);
|
||||
|
||||
return rc ? rc : sysfs_emit(buf, "%u\n", ncq_prio_supported);
|
||||
}
|
||||
|
||||
DEVICE_ATTR(ncq_prio_supported, S_IRUGO, ata_ncq_prio_supported_show, NULL);
|
||||
EXPORT_SYMBOL_GPL(dev_attr_ncq_prio_supported);
|
||||
|
||||
static ssize_t ata_ncq_prio_enable_show(struct device *device,
|
||||
struct device_attribute *attr,
|
||||
char *buf)
|
||||
{
|
||||
struct scsi_device *sdev = to_scsi_device(device);
|
||||
struct ata_port *ap;
|
||||
struct ata_port *ap = ata_shost_to_port(sdev->host);
|
||||
struct ata_device *dev;
|
||||
bool ncq_prio_enable;
|
||||
int rc = 0;
|
||||
|
||||
ap = ata_shost_to_port(sdev->host);
|
||||
|
||||
spin_lock_irq(ap->lock);
|
||||
dev = ata_scsi_find_dev(ap, sdev);
|
||||
if (!dev) {
|
||||
if (!dev)
|
||||
rc = -ENODEV;
|
||||
goto unlock;
|
||||
}
|
||||
|
||||
ncq_prio_enable = dev->flags & ATA_DFLAG_NCQ_PRIO_ENABLE;
|
||||
|
||||
unlock:
|
||||
else
|
||||
ncq_prio_enable = dev->flags & ATA_DFLAG_NCQ_PRIO_ENABLE;
|
||||
spin_unlock_irq(ap->lock);
|
||||
|
||||
return rc ? rc : snprintf(buf, 20, "%u\n", ncq_prio_enable);
|
||||
@ -869,7 +887,7 @@ static ssize_t ata_ncq_prio_enable_store(struct device *device,
|
||||
struct ata_port *ap;
|
||||
struct ata_device *dev;
|
||||
long int input;
|
||||
int rc;
|
||||
int rc = 0;
|
||||
|
||||
rc = kstrtol(buf, 10, &input);
|
||||
if (rc)
|
||||
@ -883,27 +901,20 @@ static ssize_t ata_ncq_prio_enable_store(struct device *device,
|
||||
return -ENODEV;
|
||||
|
||||
spin_lock_irq(ap->lock);
|
||||
|
||||
if (!(dev->flags & ATA_DFLAG_NCQ_PRIO)) {
|
||||
rc = -EINVAL;
|
||||
goto unlock;
|
||||
}
|
||||
|
||||
if (input)
|
||||
dev->flags |= ATA_DFLAG_NCQ_PRIO_ENABLE;
|
||||
else
|
||||
dev->flags &= ~ATA_DFLAG_NCQ_PRIO_ENABLE;
|
||||
|
||||
dev->link->eh_info.action |= ATA_EH_REVALIDATE;
|
||||
dev->link->eh_info.flags |= ATA_EHI_QUIET;
|
||||
ata_port_schedule_eh(ap);
|
||||
unlock:
|
||||
spin_unlock_irq(ap->lock);
|
||||
|
||||
ata_port_wait_eh(ap);
|
||||
|
||||
if (input) {
|
||||
spin_lock_irq(ap->lock);
|
||||
if (!(dev->flags & ATA_DFLAG_NCQ_PRIO)) {
|
||||
dev->flags &= ~ATA_DFLAG_NCQ_PRIO_ENABLE;
|
||||
rc = -EIO;
|
||||
}
|
||||
spin_unlock_irq(ap->lock);
|
||||
}
|
||||
|
||||
return rc ? rc : len;
|
||||
}
|
||||
|
||||
@ -914,6 +925,7 @@ EXPORT_SYMBOL_GPL(dev_attr_ncq_prio_enable);
|
||||
struct device_attribute *ata_ncq_sdev_attrs[] = {
|
||||
&dev_attr_unload_heads,
|
||||
&dev_attr_ncq_prio_enable,
|
||||
&dev_attr_ncq_prio_supported,
|
||||
NULL
|
||||
};
|
||||
EXPORT_SYMBOL_GPL(ata_ncq_sdev_attrs);
|
||||
|
@ -1765,53 +1765,6 @@ struct ata_scsi_args {
|
||||
struct scsi_cmnd *cmd;
|
||||
};
|
||||
|
||||
/**
|
||||
* ata_scsi_rbuf_get - Map response buffer.
|
||||
* @cmd: SCSI command containing buffer to be mapped.
|
||||
* @flags: unsigned long variable to store irq enable status
|
||||
* @copy_in: copy in from user buffer
|
||||
*
|
||||
* Prepare buffer for simulated SCSI commands.
|
||||
*
|
||||
* LOCKING:
|
||||
* spin_lock_irqsave(ata_scsi_rbuf_lock) on success
|
||||
*
|
||||
* RETURNS:
|
||||
* Pointer to response buffer.
|
||||
*/
|
||||
static void *ata_scsi_rbuf_get(struct scsi_cmnd *cmd, bool copy_in,
|
||||
unsigned long *flags)
|
||||
{
|
||||
spin_lock_irqsave(&ata_scsi_rbuf_lock, *flags);
|
||||
|
||||
memset(ata_scsi_rbuf, 0, ATA_SCSI_RBUF_SIZE);
|
||||
if (copy_in)
|
||||
sg_copy_to_buffer(scsi_sglist(cmd), scsi_sg_count(cmd),
|
||||
ata_scsi_rbuf, ATA_SCSI_RBUF_SIZE);
|
||||
return ata_scsi_rbuf;
|
||||
}
|
||||
|
||||
/**
|
||||
* ata_scsi_rbuf_put - Unmap response buffer.
|
||||
* @cmd: SCSI command containing buffer to be unmapped.
|
||||
* @copy_out: copy out result
|
||||
* @flags: @flags passed to ata_scsi_rbuf_get()
|
||||
*
|
||||
* Returns rbuf buffer. The result is copied to @cmd's buffer if
|
||||
* @copy_back is true.
|
||||
*
|
||||
* LOCKING:
|
||||
* Unlocks ata_scsi_rbuf_lock.
|
||||
*/
|
||||
static inline void ata_scsi_rbuf_put(struct scsi_cmnd *cmd, bool copy_out,
|
||||
unsigned long *flags)
|
||||
{
|
||||
if (copy_out)
|
||||
sg_copy_from_buffer(scsi_sglist(cmd), scsi_sg_count(cmd),
|
||||
ata_scsi_rbuf, ATA_SCSI_RBUF_SIZE);
|
||||
spin_unlock_irqrestore(&ata_scsi_rbuf_lock, *flags);
|
||||
}
|
||||
|
||||
/**
|
||||
* ata_scsi_rbuf_fill - wrapper for SCSI command simulators
|
||||
* @args: device IDENTIFY data / SCSI command of interest.
|
||||
@ -1830,14 +1783,19 @@ static inline void ata_scsi_rbuf_put(struct scsi_cmnd *cmd, bool copy_out,
|
||||
static void ata_scsi_rbuf_fill(struct ata_scsi_args *args,
|
||||
unsigned int (*actor)(struct ata_scsi_args *args, u8 *rbuf))
|
||||
{
|
||||
u8 *rbuf;
|
||||
unsigned int rc;
|
||||
struct scsi_cmnd *cmd = args->cmd;
|
||||
unsigned long flags;
|
||||
|
||||
rbuf = ata_scsi_rbuf_get(cmd, false, &flags);
|
||||
rc = actor(args, rbuf);
|
||||
ata_scsi_rbuf_put(cmd, rc == 0, &flags);
|
||||
spin_lock_irqsave(&ata_scsi_rbuf_lock, flags);
|
||||
|
||||
memset(ata_scsi_rbuf, 0, ATA_SCSI_RBUF_SIZE);
|
||||
rc = actor(args, ata_scsi_rbuf);
|
||||
if (rc == 0)
|
||||
sg_copy_from_buffer(scsi_sglist(cmd), scsi_sg_count(cmd),
|
||||
ata_scsi_rbuf, ATA_SCSI_RBUF_SIZE);
|
||||
|
||||
spin_unlock_irqrestore(&ata_scsi_rbuf_lock, flags);
|
||||
|
||||
if (rc == 0)
|
||||
cmd->result = SAM_STAT_GOOD;
|
||||
|
@ -1259,24 +1259,20 @@ static int sata_dwc_probe(struct platform_device *ofdev)
|
||||
irq = irq_of_parse_and_map(np, 0);
|
||||
if (irq == NO_IRQ) {
|
||||
dev_err(&ofdev->dev, "no SATA DMA irq\n");
|
||||
err = -ENODEV;
|
||||
goto error_out;
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_SATA_DWC_OLD_DMA
|
||||
if (!of_find_property(np, "dmas", NULL)) {
|
||||
err = sata_dwc_dma_init_old(ofdev, hsdev);
|
||||
if (err)
|
||||
goto error_out;
|
||||
return err;
|
||||
}
|
||||
#endif
|
||||
|
||||
hsdev->phy = devm_phy_optional_get(hsdev->dev, "sata-phy");
|
||||
if (IS_ERR(hsdev->phy)) {
|
||||
err = PTR_ERR(hsdev->phy);
|
||||
hsdev->phy = NULL;
|
||||
goto error_out;
|
||||
}
|
||||
if (IS_ERR(hsdev->phy))
|
||||
return PTR_ERR(hsdev->phy);
|
||||
|
||||
err = phy_init(hsdev->phy);
|
||||
if (err)
|
||||
|
@ -161,6 +161,10 @@ enum {
|
||||
ATA_DFLAG_D_SENSE = (1 << 29), /* Descriptor sense requested */
|
||||
ATA_DFLAG_ZAC = (1 << 30), /* ZAC device */
|
||||
|
||||
ATA_DFLAG_FEATURES_MASK = ATA_DFLAG_TRUSTED | ATA_DFLAG_DA | \
|
||||
ATA_DFLAG_DEVSLP | ATA_DFLAG_NCQ_SEND_RECV | \
|
||||
ATA_DFLAG_NCQ_PRIO,
|
||||
|
||||
ATA_DEV_UNKNOWN = 0, /* unknown device */
|
||||
ATA_DEV_ATA = 1, /* ATA device */
|
||||
ATA_DEV_ATA_UNSUP = 2, /* ATA device (unsupported) */
|
||||
@ -535,6 +539,7 @@ typedef void (*ata_postreset_fn_t)(struct ata_link *link, unsigned int *classes)
|
||||
extern struct device_attribute dev_attr_unload_heads;
|
||||
#ifdef CONFIG_SATA_HOST
|
||||
extern struct device_attribute dev_attr_link_power_management_policy;
|
||||
extern struct device_attribute dev_attr_ncq_prio_supported;
|
||||
extern struct device_attribute dev_attr_ncq_prio_enable;
|
||||
extern struct device_attribute dev_attr_em_message_type;
|
||||
extern struct device_attribute dev_attr_em_message;
|
||||
@ -1454,7 +1459,7 @@ static inline bool sata_pmp_attached(struct ata_port *ap)
|
||||
|
||||
static inline bool ata_is_host_link(const struct ata_link *link)
|
||||
{
|
||||
return 1;
|
||||
return true;
|
||||
}
|
||||
#endif /* CONFIG_SATA_PMP */
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user