1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 /* 22 * Copyright 2012 DEY Storage Systems, Inc. All rights reserved. 23 * Copyright 2016 Nexenta Systems, Inc. All rights reserved. 24 * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved. 25 * Copyright 2019 Western Digital Corporation. 26 * Copyright 2020 Joyent, Inc. 27 */ 28 29 #ifndef _SYS_BLKDEV_H 30 #define _SYS_BLKDEV_H 31 32 #include <sys/types.h> 33 #include <sys/ksynch.h> 34 #include <sys/ddi.h> 35 #include <sys/sunddi.h> 36 37 #ifdef __cplusplus 38 extern "C" { 39 #endif 40 41 /* 42 * This describes a fairly simple block device. The idea here is that 43 * these things want to take advantage of the common labelling support, 44 * but do not need all the capabilities of SCSA. So we make quite a few 45 * simplifications: 46 * 47 * 1) Device block size is a power of 2 greater or equal to 512 bytes. 48 * An optional physical block size can be reported if the underlying 49 * device uses larger block sizes internally, so that writes can be 50 * aligned properly. 51 * 52 * 2) Non-rotating media. We assume a simple linear layout. 53 * 54 * 3) Fixed queue depth, for each device. The adapter driver reports 55 * the queue depth at registration. We don't have any form of 56 * dynamic flow control. 57 * 58 * 4) Negligible power management support. The framework does not support 59 * fine grained power management. If the adapter driver wants to use 60 * such, it will need to manage power on its own. 61 * 62 * 5) Suspend/resume support managed by the adapter driver. We don't 63 * support suspend/resume directly. The adapter device driver will 64 * need to manage this on its own behalf. 65 * 66 * 6) No request priorities. Transfers are assumed to execute in 67 * roughly FIFO order. The adapter driver may reorder them, but the 68 * submitter has no control over that. 69 * 70 * 7) No request cancellation. Once submitted, the job completes or 71 * fails. It cannot be canceled. 72 * 73 * 8) Limited support for removable media. There is no support for 74 * locking bay doors or mechanised media bays. This could be 75 * added, but at present the only such interesting devices are 76 * covered by the SCSI disk driver. 77 */ 78 79 typedef struct bd_handle *bd_handle_t; 80 typedef struct bd_xfer bd_xfer_t; 81 typedef struct bd_drive bd_drive_t; 82 typedef struct bd_media bd_media_t; 83 typedef struct bd_free_info bd_free_info_t; 84 typedef struct bd_ops bd_ops_t; 85 86 struct dkioc_free_list_s; 87 88 struct bd_xfer { 89 /* 90 * NB: If using DMA the br_ndmac will be non-zero. Otherwise 91 * the br_kaddr will be non-NULL. 92 */ 93 diskaddr_t x_blkno; 94 size_t x_nblks; 95 ddi_dma_handle_t x_dmah; 96 ddi_dma_cookie_t x_dmac; 97 unsigned x_ndmac; 98 caddr_t x_kaddr; 99 unsigned x_flags; 100 unsigned x_qnum; 101 const struct dkioc_free_list_s *x_dfl; 102 }; 103 104 #define BD_XFER_POLL (1U << 0) /* no interrupts (dump) */ 105 106 struct bd_drive { 107 uint32_t d_qsize; 108 uint32_t d_maxxfer; 109 boolean_t d_removable; 110 boolean_t d_hotpluggable; 111 int d_target; 112 int d_lun; 113 size_t d_vendor_len; 114 char *d_vendor; 115 size_t d_product_len; 116 char *d_product; 117 size_t d_model_len; 118 char *d_model; 119 size_t d_serial_len; 120 char *d_serial; 121 size_t d_revision_len; 122 char *d_revision; 123 uint8_t d_eui64[8]; 124 /* Added at the end to maintain binary compatibility */ 125 uint32_t d_qcount; 126 127 /* 128 * Required starting alignment for free_space requests (in logical 129 * blocks). Must be >= 1. 130 */ 131 uint64_t d_free_align; 132 133 /* 134 * Maximum number of segments supported in a free space request. 135 * 0 implies no limit. 136 */ 137 uint64_t d_max_free_seg; 138 139 /* 140 * Maximum number of logical blocks allowed in a free space request. 141 * 0 implies no limit. 142 */ 143 uint64_t d_max_free_blks; 144 145 /* 146 * Maximum number of logical blocks to free in a single segment. 147 * 0 implies no limit. If no limit, d_max_free_blks must also be 0. 148 * If > 0, d_max_free_seg_blks must be <= d_max_free_blks (basically 149 * you can't set a bigger value of d_max_free_seg_blks than 150 * d_max_free_blks). 151 */ 152 uint64_t d_max_free_seg_blks; 153 }; 154 155 struct bd_media { 156 /* 157 * NB: The block size must be a power of two not less than 158 * DEV_BSIZE (512). Other values of the block size will 159 * simply not function and the media will be rejected. 160 * 161 * The block size must also divide evenly into the device's 162 * d_maxxfer field. If the maxxfer is a power of two larger 163 * than the block size, then this will automatically be 164 * satisfied. 165 * 166 * The physical block size (m_pblksize) must be 0 or a power 167 * of two not less than the block size. 168 */ 169 uint64_t m_nblks; 170 uint32_t m_blksize; 171 boolean_t m_readonly; 172 boolean_t m_solidstate; 173 uint32_t m_pblksize; 174 }; 175 176 #define BD_INFO_FLAG_REMOVABLE (1U << 0) 177 #define BD_INFO_FLAG_HOTPLUGGABLE (1U << 1) 178 #define BD_INFO_FLAG_READ_ONLY (1U << 2) 179 180 /* 181 * When adding a new version of the bd_ops_t struct, be sure to update 182 * BD_OPS_CURRENT_VERSION 183 */ 184 typedef enum { 185 BD_OPS_VERSION_0 = 0, 186 BD_OPS_VERSION_1 = 1, 187 BD_OPS_VERSION_2 = 2, 188 } bd_version_t; 189 #define BD_OPS_CURRENT_VERSION BD_OPS_VERSION_2 190 191 struct bd_ops { 192 bd_version_t o_version; 193 void (*o_drive_info)(void *, bd_drive_t *); 194 int (*o_media_info)(void *, bd_media_t *); 195 int (*o_devid_init)(void *, dev_info_t *, ddi_devid_t *); 196 int (*o_sync_cache)(void *, bd_xfer_t *); 197 int (*o_read)(void *, bd_xfer_t *); 198 int (*o_write)(void *, bd_xfer_t *); 199 int (*o_free_space)(void *, bd_xfer_t *); 200 }; 201 202 struct bd_errstats { 203 /* these are managed by blkdev itself */ 204 kstat_named_t bd_softerrs; 205 kstat_named_t bd_harderrs; 206 kstat_named_t bd_transerrs; 207 kstat_named_t bd_model; 208 kstat_named_t bd_vid; 209 kstat_named_t bd_pid; 210 kstat_named_t bd_revision; 211 kstat_named_t bd_serial; 212 kstat_named_t bd_capacity; 213 214 /* the following are updated on behalf of the HW driver */ 215 kstat_named_t bd_rq_media_err; 216 kstat_named_t bd_rq_ntrdy_err; 217 kstat_named_t bd_rq_nodev_err; 218 kstat_named_t bd_rq_recov_err; 219 kstat_named_t bd_rq_illrq_err; 220 kstat_named_t bd_rq_pfa_err; 221 }; 222 223 #define BD_ERR_MEDIA 0 224 #define BD_ERR_NTRDY 1 225 #define BD_ERR_NODEV 2 226 #define BD_ERR_RECOV 3 227 #define BD_ERR_ILLRQ 4 228 #define BD_ERR_PFA 5 229 230 /* 231 * Note, one handler *per* address. Drivers with multiple targets at 232 * different addresses must use separate handles. 233 */ 234 bd_handle_t bd_alloc_handle(void *, bd_ops_t *, ddi_dma_attr_t *, int); 235 void bd_free_handle(bd_handle_t); 236 int bd_attach_handle(dev_info_t *, bd_handle_t); 237 int bd_detach_handle(bd_handle_t); 238 void bd_state_change(bd_handle_t); 239 void bd_xfer_done(bd_xfer_t *, int); 240 void bd_error(bd_xfer_t *, int); 241 void bd_mod_init(struct dev_ops *); 242 void bd_mod_fini(struct dev_ops *); 243 244 #ifdef __cplusplus 245 } 246 #endif 247 248 #endif /* _SYS_BLKDEV_H */ 249