18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */ 28c2ecf20Sopenharmony_ci#ifndef _SCSI_DISK_H 38c2ecf20Sopenharmony_ci#define _SCSI_DISK_H 48c2ecf20Sopenharmony_ci 58c2ecf20Sopenharmony_ci/* 68c2ecf20Sopenharmony_ci * More than enough for everybody ;) The huge number of majors 78c2ecf20Sopenharmony_ci * is a leftover from 16bit dev_t days, we don't really need that 88c2ecf20Sopenharmony_ci * much numberspace. 98c2ecf20Sopenharmony_ci */ 108c2ecf20Sopenharmony_ci#define SD_MAJORS 16 118c2ecf20Sopenharmony_ci 128c2ecf20Sopenharmony_ci/* 138c2ecf20Sopenharmony_ci * Time out in seconds for disks and Magneto-opticals (which are slower). 148c2ecf20Sopenharmony_ci */ 158c2ecf20Sopenharmony_ci#define SD_TIMEOUT (30 * HZ) 168c2ecf20Sopenharmony_ci#define SD_MOD_TIMEOUT (75 * HZ) 178c2ecf20Sopenharmony_ci/* 188c2ecf20Sopenharmony_ci * Flush timeout is a multiplier over the standard device timeout which is 198c2ecf20Sopenharmony_ci * user modifiable via sysfs but initially set to SD_TIMEOUT 208c2ecf20Sopenharmony_ci */ 218c2ecf20Sopenharmony_ci#define SD_FLUSH_TIMEOUT_MULTIPLIER 2 228c2ecf20Sopenharmony_ci#define SD_WRITE_SAME_TIMEOUT (120 * HZ) 238c2ecf20Sopenharmony_ci 248c2ecf20Sopenharmony_ci/* 258c2ecf20Sopenharmony_ci * Number of allowed retries 268c2ecf20Sopenharmony_ci */ 278c2ecf20Sopenharmony_ci#define SD_MAX_RETRIES 5 288c2ecf20Sopenharmony_ci#define SD_PASSTHROUGH_RETRIES 1 298c2ecf20Sopenharmony_ci#define SD_MAX_MEDIUM_TIMEOUTS 2 308c2ecf20Sopenharmony_ci 318c2ecf20Sopenharmony_ci/* 328c2ecf20Sopenharmony_ci * Size of the initial data buffer for mode and read capacity data 338c2ecf20Sopenharmony_ci */ 348c2ecf20Sopenharmony_ci#define SD_BUF_SIZE 512 358c2ecf20Sopenharmony_ci 368c2ecf20Sopenharmony_ci/* 378c2ecf20Sopenharmony_ci * Number of sectors at the end of the device to avoid multi-sector 388c2ecf20Sopenharmony_ci * accesses to in the case of last_sector_bug 398c2ecf20Sopenharmony_ci */ 408c2ecf20Sopenharmony_ci#define SD_LAST_BUGGY_SECTORS 8 418c2ecf20Sopenharmony_ci 428c2ecf20Sopenharmony_cienum { 438c2ecf20Sopenharmony_ci SD_EXT_CDB_SIZE = 32, /* Extended CDB size */ 448c2ecf20Sopenharmony_ci SD_MEMPOOL_SIZE = 2, /* CDB pool size */ 458c2ecf20Sopenharmony_ci}; 468c2ecf20Sopenharmony_ci 478c2ecf20Sopenharmony_cienum { 488c2ecf20Sopenharmony_ci SD_DEF_XFER_BLOCKS = 0xffff, 498c2ecf20Sopenharmony_ci SD_MAX_XFER_BLOCKS = 0xffffffff, 508c2ecf20Sopenharmony_ci SD_MAX_WS10_BLOCKS = 0xffff, 518c2ecf20Sopenharmony_ci SD_MAX_WS16_BLOCKS = 0x7fffff, 528c2ecf20Sopenharmony_ci}; 538c2ecf20Sopenharmony_ci 548c2ecf20Sopenharmony_cienum { 558c2ecf20Sopenharmony_ci SD_LBP_FULL = 0, /* Full logical block provisioning */ 568c2ecf20Sopenharmony_ci SD_LBP_UNMAP, /* Use UNMAP command */ 578c2ecf20Sopenharmony_ci SD_LBP_WS16, /* Use WRITE SAME(16) with UNMAP bit */ 588c2ecf20Sopenharmony_ci SD_LBP_WS10, /* Use WRITE SAME(10) with UNMAP bit */ 598c2ecf20Sopenharmony_ci SD_LBP_ZERO, /* Use WRITE SAME(10) with zero payload */ 608c2ecf20Sopenharmony_ci SD_LBP_DISABLE, /* Discard disabled due to failed cmd */ 618c2ecf20Sopenharmony_ci}; 628c2ecf20Sopenharmony_ci 638c2ecf20Sopenharmony_cienum { 648c2ecf20Sopenharmony_ci SD_ZERO_WRITE = 0, /* Use WRITE(10/16) command */ 658c2ecf20Sopenharmony_ci SD_ZERO_WS, /* Use WRITE SAME(10/16) command */ 668c2ecf20Sopenharmony_ci SD_ZERO_WS16_UNMAP, /* Use WRITE SAME(16) with UNMAP */ 678c2ecf20Sopenharmony_ci SD_ZERO_WS10_UNMAP, /* Use WRITE SAME(10) with UNMAP */ 688c2ecf20Sopenharmony_ci}; 698c2ecf20Sopenharmony_ci 708c2ecf20Sopenharmony_cistruct scsi_disk { 718c2ecf20Sopenharmony_ci struct scsi_driver *driver; /* always &sd_template */ 728c2ecf20Sopenharmony_ci struct scsi_device *device; 738c2ecf20Sopenharmony_ci struct device dev; 748c2ecf20Sopenharmony_ci struct gendisk *disk; 758c2ecf20Sopenharmony_ci struct opal_dev *opal_dev; 768c2ecf20Sopenharmony_ci#ifdef CONFIG_BLK_DEV_ZONED 778c2ecf20Sopenharmony_ci u32 nr_zones; 788c2ecf20Sopenharmony_ci u32 rev_nr_zones; 798c2ecf20Sopenharmony_ci u32 zone_blocks; 808c2ecf20Sopenharmony_ci u32 rev_zone_blocks; 818c2ecf20Sopenharmony_ci u32 zones_optimal_open; 828c2ecf20Sopenharmony_ci u32 zones_optimal_nonseq; 838c2ecf20Sopenharmony_ci u32 zones_max_open; 848c2ecf20Sopenharmony_ci u32 *zones_wp_offset; 858c2ecf20Sopenharmony_ci spinlock_t zones_wp_offset_lock; 868c2ecf20Sopenharmony_ci u32 *rev_wp_offset; 878c2ecf20Sopenharmony_ci struct mutex rev_mutex; 888c2ecf20Sopenharmony_ci struct work_struct zone_wp_offset_work; 898c2ecf20Sopenharmony_ci char *zone_wp_update_buf; 908c2ecf20Sopenharmony_ci#endif 918c2ecf20Sopenharmony_ci atomic_t openers; 928c2ecf20Sopenharmony_ci sector_t capacity; /* size in logical blocks */ 938c2ecf20Sopenharmony_ci int max_retries; 948c2ecf20Sopenharmony_ci u32 max_xfer_blocks; 958c2ecf20Sopenharmony_ci u32 opt_xfer_blocks; 968c2ecf20Sopenharmony_ci u32 max_ws_blocks; 978c2ecf20Sopenharmony_ci u32 max_unmap_blocks; 988c2ecf20Sopenharmony_ci u32 unmap_granularity; 998c2ecf20Sopenharmony_ci u32 unmap_alignment; 1008c2ecf20Sopenharmony_ci u32 index; 1018c2ecf20Sopenharmony_ci unsigned int physical_block_size; 1028c2ecf20Sopenharmony_ci unsigned int max_medium_access_timeouts; 1038c2ecf20Sopenharmony_ci unsigned int medium_access_timed_out; 1048c2ecf20Sopenharmony_ci u8 media_present; 1058c2ecf20Sopenharmony_ci u8 write_prot; 1068c2ecf20Sopenharmony_ci u8 protection_type;/* Data Integrity Field */ 1078c2ecf20Sopenharmony_ci u8 provisioning_mode; 1088c2ecf20Sopenharmony_ci u8 zeroing_mode; 1098c2ecf20Sopenharmony_ci unsigned ATO : 1; /* state of disk ATO bit */ 1108c2ecf20Sopenharmony_ci unsigned cache_override : 1; /* temp override of WCE,RCD */ 1118c2ecf20Sopenharmony_ci unsigned WCE : 1; /* state of disk WCE bit */ 1128c2ecf20Sopenharmony_ci unsigned RCD : 1; /* state of disk RCD bit, unused */ 1138c2ecf20Sopenharmony_ci unsigned DPOFUA : 1; /* state of disk DPOFUA bit */ 1148c2ecf20Sopenharmony_ci unsigned first_scan : 1; 1158c2ecf20Sopenharmony_ci unsigned lbpme : 1; 1168c2ecf20Sopenharmony_ci unsigned lbprz : 1; 1178c2ecf20Sopenharmony_ci unsigned lbpu : 1; 1188c2ecf20Sopenharmony_ci unsigned lbpws : 1; 1198c2ecf20Sopenharmony_ci unsigned lbpws10 : 1; 1208c2ecf20Sopenharmony_ci unsigned lbpvpd : 1; 1218c2ecf20Sopenharmony_ci unsigned ws10 : 1; 1228c2ecf20Sopenharmony_ci unsigned ws16 : 1; 1238c2ecf20Sopenharmony_ci unsigned rc_basis: 2; 1248c2ecf20Sopenharmony_ci unsigned zoned: 2; 1258c2ecf20Sopenharmony_ci unsigned urswrz : 1; 1268c2ecf20Sopenharmony_ci unsigned security : 1; 1278c2ecf20Sopenharmony_ci unsigned ignore_medium_access_errors : 1; 1288c2ecf20Sopenharmony_ci}; 1298c2ecf20Sopenharmony_ci#define to_scsi_disk(obj) container_of(obj,struct scsi_disk,dev) 1308c2ecf20Sopenharmony_ci 1318c2ecf20Sopenharmony_cistatic inline struct scsi_disk *scsi_disk(struct gendisk *disk) 1328c2ecf20Sopenharmony_ci{ 1338c2ecf20Sopenharmony_ci return container_of(disk->private_data, struct scsi_disk, driver); 1348c2ecf20Sopenharmony_ci} 1358c2ecf20Sopenharmony_ci 1368c2ecf20Sopenharmony_ci#define sd_printk(prefix, sdsk, fmt, a...) \ 1378c2ecf20Sopenharmony_ci (sdsk)->disk ? \ 1388c2ecf20Sopenharmony_ci sdev_prefix_printk(prefix, (sdsk)->device, \ 1398c2ecf20Sopenharmony_ci (sdsk)->disk->disk_name, fmt, ##a) : \ 1408c2ecf20Sopenharmony_ci sdev_printk(prefix, (sdsk)->device, fmt, ##a) 1418c2ecf20Sopenharmony_ci 1428c2ecf20Sopenharmony_ci#define sd_first_printk(prefix, sdsk, fmt, a...) \ 1438c2ecf20Sopenharmony_ci do { \ 1448c2ecf20Sopenharmony_ci if ((sdsk)->first_scan) \ 1458c2ecf20Sopenharmony_ci sd_printk(prefix, sdsk, fmt, ##a); \ 1468c2ecf20Sopenharmony_ci } while (0) 1478c2ecf20Sopenharmony_ci 1488c2ecf20Sopenharmony_cistatic inline int scsi_medium_access_command(struct scsi_cmnd *scmd) 1498c2ecf20Sopenharmony_ci{ 1508c2ecf20Sopenharmony_ci switch (scmd->cmnd[0]) { 1518c2ecf20Sopenharmony_ci case READ_6: 1528c2ecf20Sopenharmony_ci case READ_10: 1538c2ecf20Sopenharmony_ci case READ_12: 1548c2ecf20Sopenharmony_ci case READ_16: 1558c2ecf20Sopenharmony_ci case SYNCHRONIZE_CACHE: 1568c2ecf20Sopenharmony_ci case VERIFY: 1578c2ecf20Sopenharmony_ci case VERIFY_12: 1588c2ecf20Sopenharmony_ci case VERIFY_16: 1598c2ecf20Sopenharmony_ci case WRITE_6: 1608c2ecf20Sopenharmony_ci case WRITE_10: 1618c2ecf20Sopenharmony_ci case WRITE_12: 1628c2ecf20Sopenharmony_ci case WRITE_16: 1638c2ecf20Sopenharmony_ci case WRITE_SAME: 1648c2ecf20Sopenharmony_ci case WRITE_SAME_16: 1658c2ecf20Sopenharmony_ci case UNMAP: 1668c2ecf20Sopenharmony_ci return 1; 1678c2ecf20Sopenharmony_ci case VARIABLE_LENGTH_CMD: 1688c2ecf20Sopenharmony_ci switch (scmd->cmnd[9]) { 1698c2ecf20Sopenharmony_ci case READ_32: 1708c2ecf20Sopenharmony_ci case VERIFY_32: 1718c2ecf20Sopenharmony_ci case WRITE_32: 1728c2ecf20Sopenharmony_ci case WRITE_SAME_32: 1738c2ecf20Sopenharmony_ci return 1; 1748c2ecf20Sopenharmony_ci } 1758c2ecf20Sopenharmony_ci } 1768c2ecf20Sopenharmony_ci 1778c2ecf20Sopenharmony_ci return 0; 1788c2ecf20Sopenharmony_ci} 1798c2ecf20Sopenharmony_ci 1808c2ecf20Sopenharmony_cistatic inline sector_t logical_to_sectors(struct scsi_device *sdev, sector_t blocks) 1818c2ecf20Sopenharmony_ci{ 1828c2ecf20Sopenharmony_ci return blocks << (ilog2(sdev->sector_size) - 9); 1838c2ecf20Sopenharmony_ci} 1848c2ecf20Sopenharmony_ci 1858c2ecf20Sopenharmony_cistatic inline unsigned int logical_to_bytes(struct scsi_device *sdev, sector_t blocks) 1868c2ecf20Sopenharmony_ci{ 1878c2ecf20Sopenharmony_ci return blocks * sdev->sector_size; 1888c2ecf20Sopenharmony_ci} 1898c2ecf20Sopenharmony_ci 1908c2ecf20Sopenharmony_cistatic inline sector_t bytes_to_logical(struct scsi_device *sdev, unsigned int bytes) 1918c2ecf20Sopenharmony_ci{ 1928c2ecf20Sopenharmony_ci return bytes >> ilog2(sdev->sector_size); 1938c2ecf20Sopenharmony_ci} 1948c2ecf20Sopenharmony_ci 1958c2ecf20Sopenharmony_cistatic inline sector_t sectors_to_logical(struct scsi_device *sdev, sector_t sector) 1968c2ecf20Sopenharmony_ci{ 1978c2ecf20Sopenharmony_ci return sector >> (ilog2(sdev->sector_size) - 9); 1988c2ecf20Sopenharmony_ci} 1998c2ecf20Sopenharmony_ci 2008c2ecf20Sopenharmony_ci#ifdef CONFIG_BLK_DEV_INTEGRITY 2018c2ecf20Sopenharmony_ci 2028c2ecf20Sopenharmony_ciextern void sd_dif_config_host(struct scsi_disk *); 2038c2ecf20Sopenharmony_ci 2048c2ecf20Sopenharmony_ci#else /* CONFIG_BLK_DEV_INTEGRITY */ 2058c2ecf20Sopenharmony_ci 2068c2ecf20Sopenharmony_cistatic inline void sd_dif_config_host(struct scsi_disk *disk) 2078c2ecf20Sopenharmony_ci{ 2088c2ecf20Sopenharmony_ci} 2098c2ecf20Sopenharmony_ci 2108c2ecf20Sopenharmony_ci#endif /* CONFIG_BLK_DEV_INTEGRITY */ 2118c2ecf20Sopenharmony_ci 2128c2ecf20Sopenharmony_cistatic inline int sd_is_zoned(struct scsi_disk *sdkp) 2138c2ecf20Sopenharmony_ci{ 2148c2ecf20Sopenharmony_ci return sdkp->zoned == 1 || sdkp->device->type == TYPE_ZBC; 2158c2ecf20Sopenharmony_ci} 2168c2ecf20Sopenharmony_ci 2178c2ecf20Sopenharmony_ci#ifdef CONFIG_BLK_DEV_ZONED 2188c2ecf20Sopenharmony_ci 2198c2ecf20Sopenharmony_civoid sd_zbc_release_disk(struct scsi_disk *sdkp); 2208c2ecf20Sopenharmony_ciint sd_zbc_read_zones(struct scsi_disk *sdkp, unsigned char *buffer); 2218c2ecf20Sopenharmony_ciint sd_zbc_revalidate_zones(struct scsi_disk *sdkp); 2228c2ecf20Sopenharmony_ciblk_status_t sd_zbc_setup_zone_mgmt_cmnd(struct scsi_cmnd *cmd, 2238c2ecf20Sopenharmony_ci unsigned char op, bool all); 2248c2ecf20Sopenharmony_ciunsigned int sd_zbc_complete(struct scsi_cmnd *cmd, unsigned int good_bytes, 2258c2ecf20Sopenharmony_ci struct scsi_sense_hdr *sshdr); 2268c2ecf20Sopenharmony_ciint sd_zbc_report_zones(struct gendisk *disk, sector_t sector, 2278c2ecf20Sopenharmony_ci unsigned int nr_zones, report_zones_cb cb, void *data); 2288c2ecf20Sopenharmony_ci 2298c2ecf20Sopenharmony_ciblk_status_t sd_zbc_prepare_zone_append(struct scsi_cmnd *cmd, sector_t *lba, 2308c2ecf20Sopenharmony_ci unsigned int nr_blocks); 2318c2ecf20Sopenharmony_ci 2328c2ecf20Sopenharmony_ci#else /* CONFIG_BLK_DEV_ZONED */ 2338c2ecf20Sopenharmony_ci 2348c2ecf20Sopenharmony_cistatic inline void sd_zbc_release_disk(struct scsi_disk *sdkp) {} 2358c2ecf20Sopenharmony_ci 2368c2ecf20Sopenharmony_cistatic inline int sd_zbc_read_zones(struct scsi_disk *sdkp, 2378c2ecf20Sopenharmony_ci unsigned char *buf) 2388c2ecf20Sopenharmony_ci{ 2398c2ecf20Sopenharmony_ci return 0; 2408c2ecf20Sopenharmony_ci} 2418c2ecf20Sopenharmony_ci 2428c2ecf20Sopenharmony_cistatic inline int sd_zbc_revalidate_zones(struct scsi_disk *sdkp) 2438c2ecf20Sopenharmony_ci{ 2448c2ecf20Sopenharmony_ci return 0; 2458c2ecf20Sopenharmony_ci} 2468c2ecf20Sopenharmony_ci 2478c2ecf20Sopenharmony_cistatic inline blk_status_t sd_zbc_setup_zone_mgmt_cmnd(struct scsi_cmnd *cmd, 2488c2ecf20Sopenharmony_ci unsigned char op, 2498c2ecf20Sopenharmony_ci bool all) 2508c2ecf20Sopenharmony_ci{ 2518c2ecf20Sopenharmony_ci return BLK_STS_TARGET; 2528c2ecf20Sopenharmony_ci} 2538c2ecf20Sopenharmony_ci 2548c2ecf20Sopenharmony_cistatic inline unsigned int sd_zbc_complete(struct scsi_cmnd *cmd, 2558c2ecf20Sopenharmony_ci unsigned int good_bytes, struct scsi_sense_hdr *sshdr) 2568c2ecf20Sopenharmony_ci{ 2578c2ecf20Sopenharmony_ci return good_bytes; 2588c2ecf20Sopenharmony_ci} 2598c2ecf20Sopenharmony_ci 2608c2ecf20Sopenharmony_cistatic inline blk_status_t sd_zbc_prepare_zone_append(struct scsi_cmnd *cmd, 2618c2ecf20Sopenharmony_ci sector_t *lba, 2628c2ecf20Sopenharmony_ci unsigned int nr_blocks) 2638c2ecf20Sopenharmony_ci{ 2648c2ecf20Sopenharmony_ci return BLK_STS_TARGET; 2658c2ecf20Sopenharmony_ci} 2668c2ecf20Sopenharmony_ci 2678c2ecf20Sopenharmony_ci#define sd_zbc_report_zones NULL 2688c2ecf20Sopenharmony_ci 2698c2ecf20Sopenharmony_ci#endif /* CONFIG_BLK_DEV_ZONED */ 2708c2ecf20Sopenharmony_ci 2718c2ecf20Sopenharmony_civoid sd_print_sense_hdr(struct scsi_disk *sdkp, struct scsi_sense_hdr *sshdr); 2728c2ecf20Sopenharmony_civoid sd_print_result(const struct scsi_disk *sdkp, const char *msg, int result); 2738c2ecf20Sopenharmony_ci 2748c2ecf20Sopenharmony_ci#endif /* _SCSI_DISK_H */ 275