aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/ata/libata-core.c
diff options
context:
space:
mode:
authorHannes Reinecke <hare@suse.de>2016-04-25 06:45:56 -0400
committerTejun Heo <tj@kernel.org>2016-05-09 12:36:46 -0400
commit6d1003ae8db228b74ef61536364cd2a1bd973dd8 (patch)
treeac38f95df02f9ee1ebce2d0ade2e2928267fd2e3 /drivers/ata/libata-core.c
parent856c4663930988118d9f355aad66811dd6df06de (diff)
libata: support host-aware and host-managed ZAC devices
Byte 69 bits 0:1 in the IDENTIFY DEVICE data indicate a host-aware ZAC device. Host-managed ZAC devices have their own individual signature, and to not set the bits in the IDENTIFY DEVICE data. And whenever we detect a ZAC-compatible device we should be displaying the zoned block characteristics VPD page. Signed-off-by: Hannes Reinecke <hare@suse.de> Signed-off-by: Tejun Heo <tj@kernel.org>
Diffstat (limited to 'drivers/ata/libata-core.c')
-rw-r--r--drivers/ata/libata-core.c94
1 files changed, 94 insertions, 0 deletions
diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c
index 1528c7cc0089..97f31707b570 100644
--- a/drivers/ata/libata-core.c
+++ b/drivers/ata/libata-core.c
@@ -2227,6 +2227,99 @@ static void ata_dev_config_sense_reporting(struct ata_device *dev)
2227 } 2227 }
2228} 2228}
2229 2229
2230static void ata_dev_config_zac(struct ata_device *dev)
2231{
2232 struct ata_port *ap = dev->link->ap;
2233 unsigned int err_mask;
2234 u8 *identify_buf = ap->sector_buf;
2235 int log_index = ATA_LOG_SATA_ID_DEV_DATA * 2, i, found = 0;
2236 u16 log_pages;
2237
2238 dev->zac_zones_optimal_open = U32_MAX;
2239 dev->zac_zones_optimal_nonseq = U32_MAX;
2240 dev->zac_zones_max_open = U32_MAX;
2241
2242 /*
2243 * Always set the 'ZAC' flag for Host-managed devices.
2244 */
2245 if (dev->class == ATA_DEV_ZAC)
2246 dev->flags |= ATA_DFLAG_ZAC;
2247 else if (ata_id_zoned_cap(dev->id) == 0x01)
2248 /*
2249 * Check for host-aware devices.
2250 */
2251 dev->flags |= ATA_DFLAG_ZAC;
2252
2253 if (!(dev->flags & ATA_DFLAG_ZAC))
2254 return;
2255
2256 /*
2257 * Read Log Directory to figure out if IDENTIFY DEVICE log
2258 * is supported.
2259 */
2260 err_mask = ata_read_log_page(dev, ATA_LOG_DIRECTORY,
2261 0, ap->sector_buf, 1);
2262 if (err_mask) {
2263 ata_dev_info(dev,
2264 "failed to get Log Directory Emask 0x%x\n",
2265 err_mask);
2266 return;
2267 }
2268 log_pages = get_unaligned_le16(&ap->sector_buf[log_index]);
2269 if (log_pages == 0) {
2270 ata_dev_warn(dev,
2271 "ATA Identify Device Log not supported\n");
2272 return;
2273 }
2274 /*
2275 * Read IDENTIFY DEVICE data log, page 0, to figure out
2276 * if page 9 is supported.
2277 */
2278 err_mask = ata_read_log_page(dev, ATA_LOG_SATA_ID_DEV_DATA, 0,
2279 identify_buf, 1);
2280 if (err_mask) {
2281 ata_dev_info(dev,
2282 "failed to get Device Identify Log Emask 0x%x\n",
2283 err_mask);
2284 return;
2285 }
2286 log_pages = identify_buf[8];
2287 for (i = 0; i < log_pages; i++) {
2288 if (identify_buf[9 + i] == ATA_LOG_ZONED_INFORMATION) {
2289 found++;
2290 break;
2291 }
2292 }
2293 if (!found) {
2294 ata_dev_warn(dev,
2295 "ATA Zoned Information Log not supported\n");
2296 return;
2297 }
2298
2299 /*
2300 * Read IDENTIFY DEVICE data log, page 9 (Zoned-device information)
2301 */
2302 err_mask = ata_read_log_page(dev, ATA_LOG_SATA_ID_DEV_DATA,
2303 ATA_LOG_ZONED_INFORMATION,
2304 identify_buf, 1);
2305 if (!err_mask) {
2306 u64 zoned_cap, opt_open, opt_nonseq, max_open;
2307
2308 zoned_cap = get_unaligned_le64(&identify_buf[8]);
2309 if ((zoned_cap >> 63))
2310 dev->zac_zoned_cap = (zoned_cap & 1);
2311 opt_open = get_unaligned_le64(&identify_buf[24]);
2312 if ((opt_open >> 63))
2313 dev->zac_zones_optimal_open = (u32)opt_open;
2314 opt_nonseq = get_unaligned_le64(&identify_buf[32]);
2315 if ((opt_nonseq >> 63))
2316 dev->zac_zones_optimal_nonseq = (u32)opt_nonseq;
2317 max_open = get_unaligned_le64(&identify_buf[40]);
2318 if ((max_open >> 63))
2319 dev->zac_zones_max_open = (u32)max_open;
2320 }
2321}
2322
2230/** 2323/**
2231 * ata_dev_configure - Configure the specified ATA/ATAPI device 2324 * ata_dev_configure - Configure the specified ATA/ATAPI device
2232 * @dev: Target device to configure 2325 * @dev: Target device to configure
@@ -2450,6 +2543,7 @@ int ata_dev_configure(struct ata_device *dev)
2450 } 2543 }
2451 } 2544 }
2452 ata_dev_config_sense_reporting(dev); 2545 ata_dev_config_sense_reporting(dev);
2546 ata_dev_config_zac(dev);
2453 dev->cdb_len = 16; 2547 dev->cdb_len = 16;
2454 } 2548 }
2455 2549