aboutsummaryrefslogtreecommitdiffstats
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
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>
-rw-r--r--drivers/ata/libata-core.c94
-rw-r--r--drivers/ata/libata-scsi.c38
-rw-r--r--include/linux/ata.h1
-rw-r--r--include/linux/libata.h7
4 files changed, 138 insertions, 2 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
diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c
index 96abd42c9985..b86af1416dce 100644
--- a/drivers/ata/libata-scsi.c
+++ b/drivers/ata/libata-scsi.c
@@ -2144,6 +2144,7 @@ static unsigned int ata_scsiop_inq_std(struct ata_scsi_args *args, u8 *rbuf)
2144 */ 2144 */
2145static unsigned int ata_scsiop_inq_00(struct ata_scsi_args *args, u8 *rbuf) 2145static unsigned int ata_scsiop_inq_00(struct ata_scsi_args *args, u8 *rbuf)
2146{ 2146{
2147 int num_pages;
2147 const u8 pages[] = { 2148 const u8 pages[] = {
2148 0x00, /* page 0x00, this page */ 2149 0x00, /* page 0x00, this page */
2149 0x80, /* page 0x80, unit serial no page */ 2150 0x80, /* page 0x80, unit serial no page */
@@ -2152,10 +2153,14 @@ static unsigned int ata_scsiop_inq_00(struct ata_scsi_args *args, u8 *rbuf)
2152 0xb0, /* page 0xb0, block limits page */ 2153 0xb0, /* page 0xb0, block limits page */
2153 0xb1, /* page 0xb1, block device characteristics page */ 2154 0xb1, /* page 0xb1, block device characteristics page */
2154 0xb2, /* page 0xb2, thin provisioning page */ 2155 0xb2, /* page 0xb2, thin provisioning page */
2156 0xb6, /* page 0xb6, zoned block device characteristics */
2155 }; 2157 };
2156 2158
2157 rbuf[3] = sizeof(pages); /* number of supported VPD pages */ 2159 num_pages = sizeof(pages);
2158 memcpy(rbuf + 4, pages, sizeof(pages)); 2160 if (!(args->dev->flags & ATA_DFLAG_ZAC))
2161 num_pages--;
2162 rbuf[3] = num_pages; /* number of supported VPD pages */
2163 memcpy(rbuf + 4, pages, num_pages);
2159 return 0; 2164 return 0;
2160} 2165}
2161 2166
@@ -2343,6 +2348,26 @@ static unsigned int ata_scsiop_inq_b2(struct ata_scsi_args *args, u8 *rbuf)
2343 return 0; 2348 return 0;
2344} 2349}
2345 2350
2351static unsigned int ata_scsiop_inq_b6(struct ata_scsi_args *args, u8 *rbuf)
2352{
2353 /*
2354 * zbc-r05 SCSI Zoned Block device characteristics VPD page
2355 */
2356 rbuf[1] = 0xb6;
2357 rbuf[3] = 0x3C;
2358
2359 /*
2360 * URSWRZ bit is only meaningful for host-managed ZAC drives
2361 */
2362 if (args->dev->zac_zoned_cap & 1)
2363 rbuf[4] |= 1;
2364 put_unaligned_be32(args->dev->zac_zones_optimal_open, &rbuf[8]);
2365 put_unaligned_be32(args->dev->zac_zones_optimal_nonseq, &rbuf[12]);
2366 put_unaligned_be32(args->dev->zac_zones_max_open, &rbuf[16]);
2367
2368 return 0;
2369}
2370
2346/** 2371/**
2347 * ata_scsiop_noop - Command handler that simply returns success. 2372 * ata_scsiop_noop - Command handler that simply returns success.
2348 * @args: device IDENTIFY data / SCSI command of interest. 2373 * @args: device IDENTIFY data / SCSI command of interest.
@@ -2661,6 +2686,9 @@ static unsigned int ata_scsiop_read_cap(struct ata_scsi_args *args, u8 *rbuf)
2661 rbuf[14] |= 0x40; /* LBPRZ */ 2686 rbuf[14] |= 0x40; /* LBPRZ */
2662 } 2687 }
2663 } 2688 }
2689 if (ata_id_zoned_cap(args->id) ||
2690 args->dev->class == ATA_DEV_ZAC)
2691 rbuf[12] = (1 << 4); /* RC_BASIS */
2664 } 2692 }
2665 return 0; 2693 return 0;
2666} 2694}
@@ -4046,6 +4074,12 @@ void ata_scsi_simulate(struct ata_device *dev, struct scsi_cmnd *cmd)
4046 case 0xb2: 4074 case 0xb2:
4047 ata_scsi_rbuf_fill(&args, ata_scsiop_inq_b2); 4075 ata_scsi_rbuf_fill(&args, ata_scsiop_inq_b2);
4048 break; 4076 break;
4077 case 0xb6:
4078 if (dev->flags & ATA_DFLAG_ZAC) {
4079 ata_scsi_rbuf_fill(&args, ata_scsiop_inq_b6);
4080 break;
4081 }
4082 /* Fallthrough */
4049 default: 4083 default:
4050 ata_scsi_invalid_field(dev, cmd, 2); 4084 ata_scsi_invalid_field(dev, cmd, 2);
4051 break; 4085 break;
diff --git a/include/linux/ata.h b/include/linux/ata.h
index ac1cb9310dea..83e2a99866c2 100644
--- a/include/linux/ata.h
+++ b/include/linux/ata.h
@@ -338,6 +338,7 @@ enum {
338 ATA_LOG_NCQ_SEND_RECV = 0x13, 338 ATA_LOG_NCQ_SEND_RECV = 0x13,
339 ATA_LOG_SATA_ID_DEV_DATA = 0x30, 339 ATA_LOG_SATA_ID_DEV_DATA = 0x30,
340 ATA_LOG_SATA_SETTINGS = 0x08, 340 ATA_LOG_SATA_SETTINGS = 0x08,
341 ATA_LOG_ZONED_INFORMATION = 0x09,
341 ATA_LOG_DEVSLP_OFFSET = 0x30, 342 ATA_LOG_DEVSLP_OFFSET = 0x30,
342 ATA_LOG_DEVSLP_SIZE = 0x08, 343 ATA_LOG_DEVSLP_SIZE = 0x08,
343 ATA_LOG_DEVSLP_MDAT = 0x00, 344 ATA_LOG_DEVSLP_MDAT = 0x00,
diff --git a/include/linux/libata.h b/include/linux/libata.h
index 0019d4b51b11..d15c19e331d1 100644
--- a/include/linux/libata.h
+++ b/include/linux/libata.h
@@ -181,6 +181,7 @@ enum {
181 ATA_DFLAG_DEVSLP = (1 << 27), /* device supports Device Sleep */ 181 ATA_DFLAG_DEVSLP = (1 << 27), /* device supports Device Sleep */
182 ATA_DFLAG_ACPI_DISABLED = (1 << 28), /* ACPI for the device is disabled */ 182 ATA_DFLAG_ACPI_DISABLED = (1 << 28), /* ACPI for the device is disabled */
183 ATA_DFLAG_D_SENSE = (1 << 29), /* Descriptor sense requested */ 183 ATA_DFLAG_D_SENSE = (1 << 29), /* Descriptor sense requested */
184 ATA_DFLAG_ZAC = (1 << 30), /* ZAC device */
184 185
185 ATA_DEV_UNKNOWN = 0, /* unknown device */ 186 ATA_DEV_UNKNOWN = 0, /* unknown device */
186 ATA_DEV_ATA = 1, /* ATA device */ 187 ATA_DEV_ATA = 1, /* ATA device */
@@ -731,6 +732,12 @@ struct ata_device {
731 u8 ncq_send_recv_cmds[ATA_LOG_NCQ_SEND_RECV_SIZE]; 732 u8 ncq_send_recv_cmds[ATA_LOG_NCQ_SEND_RECV_SIZE];
732 u8 ncq_non_data_cmds[ATA_LOG_NCQ_NON_DATA_SIZE]; 733 u8 ncq_non_data_cmds[ATA_LOG_NCQ_NON_DATA_SIZE];
733 734
735 /* ZAC zone configuration */
736 u32 zac_zoned_cap;
737 u32 zac_zones_optimal_open;
738 u32 zac_zones_optimal_nonseq;
739 u32 zac_zones_max_open;
740
734 /* error history */ 741 /* error history */
735 int spdn_cnt; 742 int spdn_cnt;
736 /* ering is CLEAR_END, read comment above CLEAR_END */ 743 /* ering is CLEAR_END, read comment above CLEAR_END */