scsi_sa.c (273736) | scsi_sa.c (280438) |
---|---|
1/*- 2 * Implementation of SCSI Sequential Access Peripheral driver for CAM. 3 * 4 * Copyright (c) 1999, 2000 Matthew Jacob | 1/*- 2 * Implementation of SCSI Sequential Access Peripheral driver for CAM. 3 * 4 * Copyright (c) 1999, 2000 Matthew Jacob |
5 * Copyright (c) 2013, 2014, 2015 Spectra Logic Corporation |
|
5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions, and the following disclaimer, 12 * without modification, immediately at the beginning of the file. --- 9 unchanged lines hidden (view full) --- 22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26 * SUCH DAMAGE. 27 */ 28 29#include <sys/cdefs.h> | 6 * All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 1. Redistributions of source code must retain the above copyright 12 * notice, this list of conditions, and the following disclaimer, 13 * without modification, immediately at the beginning of the file. --- 9 unchanged lines hidden (view full) --- 23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27 * SUCH DAMAGE. 28 */ 29 30#include <sys/cdefs.h> |
30__FBSDID("$FreeBSD: stable/10/sys/cam/scsi/scsi_sa.c 273736 2014-10-27 14:38:00Z hselasky $"); | 31__FBSDID("$FreeBSD: stable/10/sys/cam/scsi/scsi_sa.c 280438 2015-03-24 14:36:10Z ken $"); |
31 32#include <sys/param.h> 33#include <sys/queue.h> 34#ifdef _KERNEL 35#include <sys/systm.h> 36#include <sys/kernel.h> 37#endif 38#include <sys/types.h> 39#include <sys/time.h> 40#include <sys/bio.h> 41#include <sys/limits.h> 42#include <sys/malloc.h> 43#include <sys/mtio.h> 44#ifdef _KERNEL 45#include <sys/conf.h> | 32 33#include <sys/param.h> 34#include <sys/queue.h> 35#ifdef _KERNEL 36#include <sys/systm.h> 37#include <sys/kernel.h> 38#endif 39#include <sys/types.h> 40#include <sys/time.h> 41#include <sys/bio.h> 42#include <sys/limits.h> 43#include <sys/malloc.h> 44#include <sys/mtio.h> 45#ifdef _KERNEL 46#include <sys/conf.h> |
47#include <sys/sbuf.h> |
|
46#include <sys/sysctl.h> 47#include <sys/taskqueue.h> 48#endif 49#include <sys/fcntl.h> 50#include <sys/devicestat.h> 51 52#ifndef _KERNEL 53#include <stdio.h> --- 10 unchanged lines hidden (view full) --- 64#include <cam/scsi/scsi_message.h> 65#include <cam/scsi/scsi_sa.h> 66 67#ifdef _KERNEL 68 69#include <opt_sa.h> 70 71#ifndef SA_IO_TIMEOUT | 48#include <sys/sysctl.h> 49#include <sys/taskqueue.h> 50#endif 51#include <sys/fcntl.h> 52#include <sys/devicestat.h> 53 54#ifndef _KERNEL 55#include <stdio.h> --- 10 unchanged lines hidden (view full) --- 66#include <cam/scsi/scsi_message.h> 67#include <cam/scsi/scsi_sa.h> 68 69#ifdef _KERNEL 70 71#include <opt_sa.h> 72 73#ifndef SA_IO_TIMEOUT |
72#define SA_IO_TIMEOUT 4 | 74#define SA_IO_TIMEOUT 32 |
73#endif 74#ifndef SA_SPACE_TIMEOUT 75#define SA_SPACE_TIMEOUT 1 * 60 76#endif 77#ifndef SA_REWIND_TIMEOUT 78#define SA_REWIND_TIMEOUT 2 * 60 79#endif 80#ifndef SA_ERASE_TIMEOUT 81#define SA_ERASE_TIMEOUT 4 * 60 82#endif | 75#endif 76#ifndef SA_SPACE_TIMEOUT 77#define SA_SPACE_TIMEOUT 1 * 60 78#endif 79#ifndef SA_REWIND_TIMEOUT 80#define SA_REWIND_TIMEOUT 2 * 60 81#endif 82#ifndef SA_ERASE_TIMEOUT 83#define SA_ERASE_TIMEOUT 4 * 60 84#endif |
85#ifndef SA_REP_DENSITY_TIMEOUT 86#define SA_REP_DENSITY_TIMEOUT 90 87#endif |
|
83 84#define SCSIOP_TIMEOUT (60 * 1000) /* not an option */ 85 86#define IO_TIMEOUT (SA_IO_TIMEOUT * 60 * 1000) 87#define REWIND_TIMEOUT (SA_REWIND_TIMEOUT * 60 * 1000) 88#define ERASE_TIMEOUT (SA_ERASE_TIMEOUT * 60 * 1000) 89#define SPACE_TIMEOUT (SA_SPACE_TIMEOUT * 60 * 1000) | 88 89#define SCSIOP_TIMEOUT (60 * 1000) /* not an option */ 90 91#define IO_TIMEOUT (SA_IO_TIMEOUT * 60 * 1000) 92#define REWIND_TIMEOUT (SA_REWIND_TIMEOUT * 60 * 1000) 93#define ERASE_TIMEOUT (SA_ERASE_TIMEOUT * 60 * 1000) 94#define SPACE_TIMEOUT (SA_SPACE_TIMEOUT * 60 * 1000) |
95#define REP_DENSITY_TIMEOUT (SA_REP_DENSITY_TIMEOUT * 60 * 1000) |
|
90 91/* 92 * Additional options that can be set for config: SA_1FM_AT_EOT 93 */ 94 95#ifndef UNUSED_PARAMETER 96#define UNUSED_PARAMETER(x) x = x 97#endif --- 30 unchanged lines hidden (view full) --- 128 SA_FLAG_EIO_PENDING = 0x0080, 129 SA_FLAG_EOF_PENDING = 0x0100, 130 SA_FLAG_ERR_PENDING = (SA_FLAG_EOM_PENDING|SA_FLAG_EIO_PENDING| 131 SA_FLAG_EOF_PENDING), 132 SA_FLAG_INVALID = 0x0200, 133 SA_FLAG_COMP_ENABLED = 0x0400, 134 SA_FLAG_COMP_SUPP = 0x0800, 135 SA_FLAG_COMP_UNSUPP = 0x1000, | 96 97/* 98 * Additional options that can be set for config: SA_1FM_AT_EOT 99 */ 100 101#ifndef UNUSED_PARAMETER 102#define UNUSED_PARAMETER(x) x = x 103#endif --- 30 unchanged lines hidden (view full) --- 134 SA_FLAG_EIO_PENDING = 0x0080, 135 SA_FLAG_EOF_PENDING = 0x0100, 136 SA_FLAG_ERR_PENDING = (SA_FLAG_EOM_PENDING|SA_FLAG_EIO_PENDING| 137 SA_FLAG_EOF_PENDING), 138 SA_FLAG_INVALID = 0x0200, 139 SA_FLAG_COMP_ENABLED = 0x0400, 140 SA_FLAG_COMP_SUPP = 0x0800, 141 SA_FLAG_COMP_UNSUPP = 0x1000, |
136 SA_FLAG_TAPE_FROZEN = 0x2000 | 142 SA_FLAG_TAPE_FROZEN = 0x2000, 143 SA_FLAG_PROTECT_SUPP = 0x4000, 144 145 SA_FLAG_COMPRESSION = (SA_FLAG_COMP_SUPP|SA_FLAG_COMP_ENABLED| 146 SA_FLAG_COMP_UNSUPP), 147 SA_FLAG_SCTX_INIT = 0x8000 |
137} sa_flags; 138 139typedef enum { 140 SA_MODE_REWIND = 0x00, 141 SA_MODE_NOREWIND = 0x01, 142 SA_MODE_OFFLINE = 0x02 143} sa_mode; 144 145typedef enum { | 148} sa_flags; 149 150typedef enum { 151 SA_MODE_REWIND = 0x00, 152 SA_MODE_NOREWIND = 0x01, 153 SA_MODE_OFFLINE = 0x02 154} sa_mode; 155 156typedef enum { |
146 SA_PARAM_NONE = 0x00, 147 SA_PARAM_BLOCKSIZE = 0x01, 148 SA_PARAM_DENSITY = 0x02, 149 SA_PARAM_COMPRESSION = 0x04, 150 SA_PARAM_BUFF_MODE = 0x08, 151 SA_PARAM_NUMBLOCKS = 0x10, 152 SA_PARAM_WP = 0x20, 153 SA_PARAM_SPEED = 0x40, 154 SA_PARAM_ALL = 0x7f | 157 SA_PARAM_NONE = 0x000, 158 SA_PARAM_BLOCKSIZE = 0x001, 159 SA_PARAM_DENSITY = 0x002, 160 SA_PARAM_COMPRESSION = 0x004, 161 SA_PARAM_BUFF_MODE = 0x008, 162 SA_PARAM_NUMBLOCKS = 0x010, 163 SA_PARAM_WP = 0x020, 164 SA_PARAM_SPEED = 0x040, 165 SA_PARAM_DENSITY_EXT = 0x080, 166 SA_PARAM_LBP = 0x100, 167 SA_PARAM_ALL = 0x1ff |
155} sa_params; 156 157typedef enum { | 168} sa_params; 169 170typedef enum { |
158 SA_QUIRK_NONE = 0x00, 159 SA_QUIRK_NOCOMP = 0x01, /* Can't deal with compression at all */ 160 SA_QUIRK_FIXED = 0x02, /* Force fixed mode */ 161 SA_QUIRK_VARIABLE = 0x04, /* Force variable mode */ 162 SA_QUIRK_2FM = 0x08, /* Needs Two File Marks at EOD */ 163 SA_QUIRK_1FM = 0x10, /* No more than 1 File Mark at EOD */ 164 SA_QUIRK_NODREAD = 0x20, /* Don't try and dummy read density */ 165 SA_QUIRK_NO_MODESEL = 0x40, /* Don't do mode select at all */ 166 SA_QUIRK_NO_CPAGE = 0x80 /* Don't use DEVICE COMPRESSION page */ | 171 SA_QUIRK_NONE = 0x000, 172 SA_QUIRK_NOCOMP = 0x001, /* Can't deal with compression at all*/ 173 SA_QUIRK_FIXED = 0x002, /* Force fixed mode */ 174 SA_QUIRK_VARIABLE = 0x004, /* Force variable mode */ 175 SA_QUIRK_2FM = 0x008, /* Needs Two File Marks at EOD */ 176 SA_QUIRK_1FM = 0x010, /* No more than 1 File Mark at EOD */ 177 SA_QUIRK_NODREAD = 0x020, /* Don't try and dummy read density */ 178 SA_QUIRK_NO_MODESEL = 0x040, /* Don't do mode select at all */ 179 SA_QUIRK_NO_CPAGE = 0x080, /* Don't use DEVICE COMPRESSION page */ 180 SA_QUIRK_NO_LONG_POS = 0x100 /* No long position information */ |
167} sa_quirks; 168 169#define SA_QUIRK_BIT_STRING \ 170 "\020" \ 171 "\001NOCOMP" \ 172 "\002FIXED" \ 173 "\003VARIABLE" \ 174 "\0042FM" \ 175 "\0051FM" \ 176 "\006NODREAD" \ 177 "\007NO_MODESEL" \ | 181} sa_quirks; 182 183#define SA_QUIRK_BIT_STRING \ 184 "\020" \ 185 "\001NOCOMP" \ 186 "\002FIXED" \ 187 "\003VARIABLE" \ 188 "\0042FM" \ 189 "\0051FM" \ 190 "\006NODREAD" \ 191 "\007NO_MODESEL" \ |
178 "\010NO_CPAGE" | 192 "\010NO_CPAGE" \ 193 "\011NO_LONG_POS" |
179 180#define SAMODE(z) (dev2unit(z) & 0x3) | 194 195#define SAMODE(z) (dev2unit(z) & 0x3) |
181#define SADENSITY(z) ((dev2unit(z) >> 2) & 0x3) | |
182#define SA_IS_CTRL(z) (dev2unit(z) & (1 << 4)) 183 184#define SA_NOT_CTLDEV 0 185#define SA_CTLDEV 1 186 187#define SA_ATYPE_R 0 188#define SA_ATYPE_NR 1 189#define SA_ATYPE_ER 2 | 196#define SA_IS_CTRL(z) (dev2unit(z) & (1 << 4)) 197 198#define SA_NOT_CTLDEV 0 199#define SA_CTLDEV 1 200 201#define SA_ATYPE_R 0 202#define SA_ATYPE_NR 1 203#define SA_ATYPE_ER 2 |
204#define SA_NUM_ATYPES 3 |
|
190 | 205 |
191#define SAMINOR(ctl, mode, access) \ 192 ((ctl << 4) | (mode << 2) | (access & 0x3)) | 206#define SAMINOR(ctl, access) \ 207 ((ctl << 4) | (access & 0x3)) |
193 | 208 |
194#define SA_NUM_MODES 4 | |
195struct sa_devs { 196 struct cdev *ctl_dev; | 209struct sa_devs { 210 struct cdev *ctl_dev; |
197 struct sa_mode_devs { 198 struct cdev *r_dev; 199 struct cdev *nr_dev; 200 struct cdev *er_dev; 201 } mode_devs[SA_NUM_MODES]; | 211 struct cdev *r_dev; 212 struct cdev *nr_dev; 213 struct cdev *er_dev; |
202}; 203 | 214}; 215 |
216#define SASBADDBASE(sb, indent, data, xfmt, name, type, xsize, desc) \ 217 sbuf_printf(sb, "%*s<%s type=\"%s\" size=\"%zd\" " \ 218 "fmt=\"%s\" desc=\"%s\">" #xfmt "</%s>\n", indent, "", \ 219 #name, #type, xsize, #xfmt, desc ? desc : "", data, #name); 220 221#define SASBADDINT(sb, indent, data, fmt, name) \ 222 SASBADDBASE(sb, indent, data, fmt, name, int, sizeof(data), \ 223 NULL) 224 225#define SASBADDINTDESC(sb, indent, data, fmt, name, desc) \ 226 SASBADDBASE(sb, indent, data, fmt, name, int, sizeof(data), \ 227 desc) 228 229#define SASBADDUINT(sb, indent, data, fmt, name) \ 230 SASBADDBASE(sb, indent, data, fmt, name, uint, sizeof(data), \ 231 NULL) 232 233#define SASBADDUINTDESC(sb, indent, data, fmt, name, desc) \ 234 SASBADDBASE(sb, indent, data, fmt, name, uint, sizeof(data), \ 235 desc) 236 237#define SASBADDFIXEDSTR(sb, indent, data, fmt, name) \ 238 SASBADDBASE(sb, indent, data, fmt, name, str, sizeof(data), \ 239 NULL) 240 241#define SASBADDFIXEDSTRDESC(sb, indent, data, fmt, name, desc) \ 242 SASBADDBASE(sb, indent, data, fmt, name, str, sizeof(data), \ 243 desc) 244 245#define SASBADDVARSTR(sb, indent, data, fmt, name, maxlen) \ 246 SASBADDBASE(sb, indent, data, fmt, name, str, maxlen, NULL) 247 248#define SASBADDVARSTRDESC(sb, indent, data, fmt, name, maxlen, desc) \ 249 SASBADDBASE(sb, indent, data, fmt, name, str, maxlen, desc) 250 251#define SASBADDNODE(sb, indent, name) { \ 252 sbuf_printf(sb, "%*s<%s type=\"%s\">\n", indent, "", #name, \ 253 "node"); \ 254 indent += 2; \ 255} 256 257#define SASBADDNODENUM(sb, indent, name, num) { \ 258 sbuf_printf(sb, "%*s<%s type=\"%s\" num=\"%d\">\n", indent, "", \ 259 #name, "node", num); \ 260 indent += 2; \ 261} 262 263#define SASBENDNODE(sb, indent, name) { \ 264 indent -= 2; \ 265 sbuf_printf(sb, "%*s</%s>\n", indent, "", #name); \ 266} 267 268#define SA_DENSITY_TYPES 4 269 270struct sa_prot_state { 271 int initialized; 272 uint32_t prot_method; 273 uint32_t pi_length; 274 uint32_t lbp_w; 275 uint32_t lbp_r; 276 uint32_t rbdp; 277}; 278 279struct sa_prot_info { 280 struct sa_prot_state cur_prot_state; 281 struct sa_prot_state pending_prot_state; 282}; 283 284/* 285 * A table mapping protection parameters to their types and values. 286 */ 287struct sa_prot_map { 288 char *name; 289 mt_param_set_type param_type; 290 off_t offset; 291 uint32_t min_val; 292 uint32_t max_val; 293 uint32_t *value; 294} sa_prot_table[] = { 295 { "prot_method", MT_PARAM_SET_UNSIGNED, 296 __offsetof(struct sa_prot_state, prot_method), 297 /*min_val*/ 0, /*max_val*/ 255, NULL }, 298 { "pi_length", MT_PARAM_SET_UNSIGNED, 299 __offsetof(struct sa_prot_state, pi_length), 300 /*min_val*/ 0, /*max_val*/ SA_CTRL_DP_PI_LENGTH_MASK, NULL }, 301 { "lbp_w", MT_PARAM_SET_UNSIGNED, 302 __offsetof(struct sa_prot_state, lbp_w), 303 /*min_val*/ 0, /*max_val*/ 1, NULL }, 304 { "lbp_r", MT_PARAM_SET_UNSIGNED, 305 __offsetof(struct sa_prot_state, lbp_r), 306 /*min_val*/ 0, /*max_val*/ 1, NULL }, 307 { "rbdp", MT_PARAM_SET_UNSIGNED, 308 __offsetof(struct sa_prot_state, rbdp), 309 /*min_val*/ 0, /*max_val*/ 1, NULL } 310}; 311 312#define SA_NUM_PROT_ENTS sizeof(sa_prot_table)/sizeof(sa_prot_table[0]) 313 314#define SA_PROT_ENABLED(softc) ((softc->flags & SA_FLAG_PROTECT_SUPP) \ 315 && (softc->prot_info.cur_prot_state.initialized != 0) \ 316 && (softc->prot_info.cur_prot_state.prot_method != 0)) 317 318#define SA_PROT_LEN(softc) softc->prot_info.cur_prot_state.pi_length 319 |
|
204struct sa_softc { 205 sa_state state; 206 sa_flags flags; 207 sa_quirks quirks; 208 u_int si_flags; | 320struct sa_softc { 321 sa_state state; 322 sa_flags flags; 323 sa_quirks quirks; 324 u_int si_flags; |
325 struct cam_periph *periph; |
|
209 struct bio_queue_head bio_queue; 210 int queue_count; 211 struct devstat *device_stats; 212 struct sa_devs devs; | 326 struct bio_queue_head bio_queue; 327 int queue_count; 328 struct devstat *device_stats; 329 struct sa_devs devs; |
330 int open_count; 331 int num_devs_to_destroy; |
|
213 int blk_gran; 214 int blk_mask; 215 int blk_shift; 216 u_int32_t max_blk; 217 u_int32_t min_blk; 218 u_int32_t maxio; 219 u_int32_t cpi_maxio; 220 int allow_io_split; --- 5 unchanged lines hidden (view full) --- 226 u_int8_t media_density; 227 u_int8_t speed; 228 u_int8_t scsi_rev; 229 u_int8_t dsreg; /* mtio mt_dsreg, redux */ 230 int buffer_mode; 231 int filemarks; 232 union ccb saved_ccb; 233 int last_resid_was_io; | 332 int blk_gran; 333 int blk_mask; 334 int blk_shift; 335 u_int32_t max_blk; 336 u_int32_t min_blk; 337 u_int32_t maxio; 338 u_int32_t cpi_maxio; 339 int allow_io_split; --- 5 unchanged lines hidden (view full) --- 345 u_int8_t media_density; 346 u_int8_t speed; 347 u_int8_t scsi_rev; 348 u_int8_t dsreg; /* mtio mt_dsreg, redux */ 349 int buffer_mode; 350 int filemarks; 351 union ccb saved_ccb; 352 int last_resid_was_io; |
353 uint8_t density_type_bits[SA_DENSITY_TYPES]; 354 int density_info_valid[SA_DENSITY_TYPES]; 355 uint8_t density_info[SA_DENSITY_TYPES][SRDS_MAX_LENGTH]; |
|
234 | 356 |
357 struct sa_prot_info prot_info; 358 359 int sili; 360 int eot_warn; 361 |
|
235 /* | 362 /* |
236 * Relative to BOT Location. | 363 * Current position information. -1 means that the given value is 364 * unknown. fileno and blkno are always calculated. blkno is 365 * relative to the previous file mark. rep_fileno and rep_blkno 366 * are as reported by the drive, if it supports the long form 367 * report for the READ POSITION command. rep_blkno is relative to 368 * the beginning of the partition. 369 * 370 * bop means that the drive is at the beginning of the partition. 371 * eop means that the drive is between early warning and end of 372 * partition, inside the current partition. 373 * bpew means that the position is in a PEWZ (Programmable Early 374 * Warning Zone) |
237 */ | 375 */ |
238 daddr_t fileno; 239 daddr_t blkno; | 376 daddr_t partition; /* Absolute from BOT */ 377 daddr_t fileno; /* Relative to beginning of partition */ 378 daddr_t blkno; /* Relative to last file mark */ 379 daddr_t rep_blkno; /* Relative to beginning of partition */ 380 daddr_t rep_fileno; /* Relative to beginning of partition */ 381 int bop; /* Beginning of Partition */ 382 int eop; /* End of Partition */ 383 int bpew; /* Beyond Programmable Early Warning */ |
240 241 /* 242 * Latched Error Info 243 */ 244 struct { 245 struct scsi_sense_data _last_io_sense; 246 u_int64_t _last_io_resid; 247 u_int8_t _last_io_cdb[CAM_MAX_CDBLEN]; --- 150 unchanged lines hidden (view full) --- 398static int sacheckeod(struct cam_periph *periph); 399static int sagetparams(struct cam_periph *periph, 400 sa_params params_to_get, 401 u_int32_t *blocksize, u_int8_t *density, 402 u_int32_t *numblocks, int *buff_mode, 403 u_int8_t *write_protect, u_int8_t *speed, 404 int *comp_supported, int *comp_enabled, 405 u_int32_t *comp_algorithm, | 384 385 /* 386 * Latched Error Info 387 */ 388 struct { 389 struct scsi_sense_data _last_io_sense; 390 u_int64_t _last_io_resid; 391 u_int8_t _last_io_cdb[CAM_MAX_CDBLEN]; --- 150 unchanged lines hidden (view full) --- 542static int sacheckeod(struct cam_periph *periph); 543static int sagetparams(struct cam_periph *periph, 544 sa_params params_to_get, 545 u_int32_t *blocksize, u_int8_t *density, 546 u_int32_t *numblocks, int *buff_mode, 547 u_int8_t *write_protect, u_int8_t *speed, 548 int *comp_supported, int *comp_enabled, 549 u_int32_t *comp_algorithm, |
406 sa_comp_t *comp_page); | 550 sa_comp_t *comp_page, 551 struct scsi_control_data_prot_subpage 552 *prot_page, int dp_size, 553 int prot_changeable); 554static int sasetprot(struct cam_periph *periph, 555 struct sa_prot_state *new_prot); |
407static int sasetparams(struct cam_periph *periph, 408 sa_params params_to_set, 409 u_int32_t blocksize, u_int8_t density, 410 u_int32_t comp_algorithm, 411 u_int32_t sense_flags); | 556static int sasetparams(struct cam_periph *periph, 557 sa_params params_to_set, 558 u_int32_t blocksize, u_int8_t density, 559 u_int32_t comp_algorithm, 560 u_int32_t sense_flags); |
561static int sasetsili(struct cam_periph *periph, 562 struct mtparamset *ps, int num_params); 563static int saseteotwarn(struct cam_periph *periph, 564 struct mtparamset *ps, int num_params); 565static void safillprot(struct sa_softc *softc, int *indent, 566 struct sbuf *sb); 567static void sapopulateprots(struct sa_prot_state *cur_state, 568 struct sa_prot_map *new_table, 569 int table_ents); 570static struct sa_prot_map *safindprotent(char *name, struct sa_prot_map *table, 571 int table_ents); 572static int sasetprotents(struct cam_periph *periph, 573 struct mtparamset *ps, int num_params); 574static struct sa_param_ent *safindparament(struct mtparamset *ps); 575static int saparamsetlist(struct cam_periph *periph, 576 struct mtsetlist *list, int need_copy); 577static int saextget(struct cdev *dev, struct cam_periph *periph, 578 struct sbuf *sb, struct mtextget *g); 579static int saparamget(struct sa_softc *softc, struct sbuf *sb); |
|
412static void saprevent(struct cam_periph *periph, int action); 413static int sarewind(struct cam_periph *periph); 414static int saspace(struct cam_periph *periph, int count, 415 scsi_space_code code); | 580static void saprevent(struct cam_periph *periph, int action); 581static int sarewind(struct cam_periph *periph); 582static int saspace(struct cam_periph *periph, int count, 583 scsi_space_code code); |
584static void sadevgonecb(void *arg); 585static void sasetupdev(struct sa_softc *softc, struct cdev *dev); |
|
416static int samount(struct cam_periph *, int, struct cdev *); 417static int saretension(struct cam_periph *periph); 418static int sareservereleaseunit(struct cam_periph *periph, 419 int reserve); 420static int saloadunload(struct cam_periph *periph, int load); 421static int saerase(struct cam_periph *periph, int longerase); 422static int sawritefilemarks(struct cam_periph *periph, | 586static int samount(struct cam_periph *, int, struct cdev *); 587static int saretension(struct cam_periph *periph); 588static int sareservereleaseunit(struct cam_periph *periph, 589 int reserve); 590static int saloadunload(struct cam_periph *periph, int load); 591static int saerase(struct cam_periph *periph, int longerase); 592static int sawritefilemarks(struct cam_periph *periph, |
423 int nmarks, int setmarks); | 593 int nmarks, int setmarks, int immed); 594static int sagetpos(struct cam_periph *periph); |
424static int sardpos(struct cam_periph *periph, int, u_int32_t *); | 595static int sardpos(struct cam_periph *periph, int, u_int32_t *); |
425static int sasetpos(struct cam_periph *periph, int, u_int32_t *); | 596static int sasetpos(struct cam_periph *periph, int, 597 struct mtlocate *); 598static void safilldenstypesb(struct sbuf *sb, int *indent, 599 uint8_t *buf, int buf_len, 600 int is_density); 601static void safilldensitysb(struct sa_softc *softc, int *indent, 602 struct sbuf *sb); |
426 427 428#ifndef SA_DEFAULT_IO_SPLIT 429#define SA_DEFAULT_IO_SPLIT 0 430#endif 431 432static int sa_allow_io_split = SA_DEFAULT_IO_SPLIT; 433 --- 25 unchanged lines hidden (view full) --- 459 .d_version = D_VERSION, 460 .d_open = saopen, 461 .d_close = saclose, 462 .d_read = physread, 463 .d_write = physwrite, 464 .d_ioctl = saioctl, 465 .d_strategy = sastrategy, 466 .d_name = "sa", | 603 604 605#ifndef SA_DEFAULT_IO_SPLIT 606#define SA_DEFAULT_IO_SPLIT 0 607#endif 608 609static int sa_allow_io_split = SA_DEFAULT_IO_SPLIT; 610 --- 25 unchanged lines hidden (view full) --- 636 .d_version = D_VERSION, 637 .d_open = saopen, 638 .d_close = saclose, 639 .d_read = physread, 640 .d_write = physwrite, 641 .d_ioctl = saioctl, 642 .d_strategy = sastrategy, 643 .d_name = "sa", |
467 .d_flags = D_TAPE, | 644 .d_flags = D_TAPE | D_TRACKCLOSE, |
468}; 469 470static int 471saopen(struct cdev *dev, int flags, int fmt, struct thread *td) 472{ 473 struct cam_periph *periph; 474 struct sa_softc *softc; 475 int error; --- 7 unchanged lines hidden (view full) --- 483 484 softc = (struct sa_softc *)periph->softc; 485 486 CAM_DEBUG(periph->path, CAM_DEBUG_TRACE|CAM_DEBUG_INFO, 487 ("saopen(%s): softc=0x%x\n", devtoname(dev), softc->flags)); 488 489 if (SA_IS_CTRL(dev)) { 490 softc->ctrl_mode = 1; | 645}; 646 647static int 648saopen(struct cdev *dev, int flags, int fmt, struct thread *td) 649{ 650 struct cam_periph *periph; 651 struct sa_softc *softc; 652 int error; --- 7 unchanged lines hidden (view full) --- 660 661 softc = (struct sa_softc *)periph->softc; 662 663 CAM_DEBUG(periph->path, CAM_DEBUG_TRACE|CAM_DEBUG_INFO, 664 ("saopen(%s): softc=0x%x\n", devtoname(dev), softc->flags)); 665 666 if (SA_IS_CTRL(dev)) { 667 softc->ctrl_mode = 1; |
668 softc->open_count++; |
|
491 cam_periph_unlock(periph); 492 return (0); 493 } 494 495 if ((error = cam_periph_hold(periph, PRIBIO|PCATCH)) != 0) { 496 cam_periph_unlock(periph); 497 cam_periph_release(periph); 498 return (error); --- 15 unchanged lines hidden (view full) --- 514 * 515 * If the mount fails and this was a non-blocking open, 516 * make this a 'open_pending_mount' action. 517 */ 518 error = samount(periph, flags, dev); 519 if (error && (flags & O_NONBLOCK)) { 520 softc->flags |= SA_FLAG_OPEN; 521 softc->open_pending_mount = 1; | 669 cam_periph_unlock(periph); 670 return (0); 671 } 672 673 if ((error = cam_periph_hold(periph, PRIBIO|PCATCH)) != 0) { 674 cam_periph_unlock(periph); 675 cam_periph_release(periph); 676 return (error); --- 15 unchanged lines hidden (view full) --- 692 * 693 * If the mount fails and this was a non-blocking open, 694 * make this a 'open_pending_mount' action. 695 */ 696 error = samount(periph, flags, dev); 697 if (error && (flags & O_NONBLOCK)) { 698 softc->flags |= SA_FLAG_OPEN; 699 softc->open_pending_mount = 1; |
700 softc->open_count++; |
|
522 cam_periph_unhold(periph); 523 cam_periph_unlock(periph); 524 return (0); 525 } 526 } 527 528 if (error) { 529 cam_periph_unhold(periph); 530 cam_periph_unlock(periph); 531 cam_periph_release(periph); 532 return (error); 533 } 534 535 saprevent(periph, PR_PREVENT); 536 softc->flags |= SA_FLAG_OPEN; | 701 cam_periph_unhold(periph); 702 cam_periph_unlock(periph); 703 return (0); 704 } 705 } 706 707 if (error) { 708 cam_periph_unhold(periph); 709 cam_periph_unlock(periph); 710 cam_periph_release(periph); 711 return (error); 712 } 713 714 saprevent(periph, PR_PREVENT); 715 softc->flags |= SA_FLAG_OPEN; |
716 softc->open_count++; |
|
537 538 cam_periph_unhold(periph); 539 cam_periph_unlock(periph); 540 return (error); 541} 542 543static int 544saclose(struct cdev *dev, int flag, int fmt, struct thread *td) 545{ 546 struct cam_periph *periph; 547 struct sa_softc *softc; | 717 718 cam_periph_unhold(periph); 719 cam_periph_unlock(periph); 720 return (error); 721} 722 723static int 724saclose(struct cdev *dev, int flag, int fmt, struct thread *td) 725{ 726 struct cam_periph *periph; 727 struct sa_softc *softc; |
548 int mode, error, writing, tmp; | 728 int mode, error, writing, tmp, i; |
549 int closedbits = SA_FLAG_OPEN; 550 551 mode = SAMODE(dev); 552 periph = (struct cam_periph *)dev->si_drv1; 553 if (periph == NULL) 554 return (ENXIO); 555 556 cam_periph_lock(periph); 557 558 softc = (struct sa_softc *)periph->softc; 559 560 CAM_DEBUG(periph->path, CAM_DEBUG_TRACE|CAM_DEBUG_INFO, 561 ("saclose(%s): softc=0x%x\n", devtoname(dev), softc->flags)); 562 563 564 softc->open_rdonly = 0; 565 if (SA_IS_CTRL(dev)) { 566 softc->ctrl_mode = 0; | 729 int closedbits = SA_FLAG_OPEN; 730 731 mode = SAMODE(dev); 732 periph = (struct cam_periph *)dev->si_drv1; 733 if (periph == NULL) 734 return (ENXIO); 735 736 cam_periph_lock(periph); 737 738 softc = (struct sa_softc *)periph->softc; 739 740 CAM_DEBUG(periph->path, CAM_DEBUG_TRACE|CAM_DEBUG_INFO, 741 ("saclose(%s): softc=0x%x\n", devtoname(dev), softc->flags)); 742 743 744 softc->open_rdonly = 0; 745 if (SA_IS_CTRL(dev)) { 746 softc->ctrl_mode = 0; |
747 softc->open_count--; |
|
567 cam_periph_unlock(periph); 568 cam_periph_release(periph); 569 return (0); 570 } 571 572 if (softc->open_pending_mount) { 573 softc->flags &= ~SA_FLAG_OPEN; 574 softc->open_pending_mount = 0; | 748 cam_periph_unlock(periph); 749 cam_periph_release(periph); 750 return (0); 751 } 752 753 if (softc->open_pending_mount) { 754 softc->flags &= ~SA_FLAG_OPEN; 755 softc->open_pending_mount = 0; |
756 softc->open_count--; |
|
575 cam_periph_unlock(periph); 576 cam_periph_release(periph); 577 return (0); 578 } 579 580 if ((error = cam_periph_hold(periph, PRIBIO)) != 0) { 581 cam_periph_unlock(periph); 582 return (error); --- 88 unchanged lines hidden (view full) --- 671 */ 672 softc->filemarks = 0; 673 softc->flags &= ~SA_FLAG_TAPE_WRITTEN; 674 675 /* 676 * And we are no longer open for business. 677 */ 678 softc->flags &= ~closedbits; | 757 cam_periph_unlock(periph); 758 cam_periph_release(periph); 759 return (0); 760 } 761 762 if ((error = cam_periph_hold(periph, PRIBIO)) != 0) { 763 cam_periph_unlock(periph); 764 return (error); --- 88 unchanged lines hidden (view full) --- 853 */ 854 softc->filemarks = 0; 855 softc->flags &= ~SA_FLAG_TAPE_WRITTEN; 856 857 /* 858 * And we are no longer open for business. 859 */ 860 softc->flags &= ~closedbits; |
861 softc->open_count--; |
|
679 680 /* | 862 863 /* |
864 * Invalidate any density information that depends on having tape 865 * media in the drive. 866 */ 867 for (i = 0; i < SA_DENSITY_TYPES; i++) { 868 if (softc->density_type_bits[i] & SRDS_MEDIA) 869 softc->density_info_valid[i] = 0; 870 } 871 872 /* |
|
681 * Inform users if tape state if frozen.... 682 */ 683 if (softc->flags & SA_FLAG_TAPE_FROZEN) { 684 xpt_print(periph->path, "tape is now frozen- use an OFFLINE, " 685 "REWIND or MTEOM command to clear this state.\n"); 686 } 687 688 /* release the device if it is no longer mounted */ --- 130 unchanged lines hidden (view full) --- 819 * Schedule ourselves for performing the work. 820 */ 821 xpt_schedule(periph, CAM_PRIORITY_NORMAL); 822 cam_periph_unlock(periph); 823 824 return; 825} 826 | 873 * Inform users if tape state if frozen.... 874 */ 875 if (softc->flags & SA_FLAG_TAPE_FROZEN) { 876 xpt_print(periph->path, "tape is now frozen- use an OFFLINE, " 877 "REWIND or MTEOM command to clear this state.\n"); 878 } 879 880 /* release the device if it is no longer mounted */ --- 130 unchanged lines hidden (view full) --- 1011 * Schedule ourselves for performing the work. 1012 */ 1013 xpt_schedule(periph, CAM_PRIORITY_NORMAL); 1014 cam_periph_unlock(periph); 1015 1016 return; 1017} 1018 |
1019static int 1020sasetsili(struct cam_periph *periph, struct mtparamset *ps, int num_params) 1021{ 1022 uint32_t sili_blocksize; 1023 struct sa_softc *softc; 1024 int error; |
|
827 | 1025 |
1026 error = 0; 1027 softc = (struct sa_softc *)periph->softc; 1028 1029 if (ps->value_type != MT_PARAM_SET_SIGNED) { 1030 snprintf(ps->error_str, sizeof(ps->error_str), 1031 "sili is a signed parameter"); 1032 goto bailout; 1033 } 1034 if ((ps->value.value_signed < 0) 1035 || (ps->value.value_signed > 1)) { 1036 snprintf(ps->error_str, sizeof(ps->error_str), 1037 "invalid sili value %jd", (intmax_t)ps->value.value_signed); 1038 goto bailout_error; 1039 } 1040 /* 1041 * We only set the SILI flag in variable block 1042 * mode. You'll get a check condition in fixed 1043 * block mode if things don't line up in any case. 1044 */ 1045 if (softc->flags & SA_FLAG_FIXED) { 1046 snprintf(ps->error_str, sizeof(ps->error_str), 1047 "can't set sili bit in fixed block mode"); 1048 goto bailout_error; 1049 } 1050 if (softc->sili == ps->value.value_signed) 1051 goto bailout; 1052 1053 if (ps->value.value_signed == 1) 1054 sili_blocksize = 4; 1055 else 1056 sili_blocksize = 0; 1057 1058 error = sasetparams(periph, SA_PARAM_BLOCKSIZE, 1059 sili_blocksize, 0, 0, SF_QUIET_IR); 1060 if (error != 0) { 1061 snprintf(ps->error_str, sizeof(ps->error_str), 1062 "sasetparams() returned error %d", error); 1063 goto bailout_error; 1064 } 1065 1066 softc->sili = ps->value.value_signed; 1067 1068bailout: 1069 ps->status = MT_PARAM_STATUS_OK; 1070 return (error); 1071 1072bailout_error: 1073 ps->status = MT_PARAM_STATUS_ERROR; 1074 if (error == 0) 1075 error = EINVAL; 1076 1077 return (error); 1078} 1079 1080static int 1081saseteotwarn(struct cam_periph *periph, struct mtparamset *ps, int num_params) 1082{ 1083 struct sa_softc *softc; 1084 int error; 1085 1086 error = 0; 1087 softc = (struct sa_softc *)periph->softc; 1088 1089 if (ps->value_type != MT_PARAM_SET_SIGNED) { 1090 snprintf(ps->error_str, sizeof(ps->error_str), 1091 "eot_warn is a signed parameter"); 1092 ps->status = MT_PARAM_STATUS_ERROR; 1093 goto bailout; 1094 } 1095 if ((ps->value.value_signed < 0) 1096 || (ps->value.value_signed > 1)) { 1097 snprintf(ps->error_str, sizeof(ps->error_str), 1098 "invalid eot_warn value %jd\n", 1099 (intmax_t)ps->value.value_signed); 1100 ps->status = MT_PARAM_STATUS_ERROR; 1101 goto bailout; 1102 } 1103 softc->eot_warn = ps->value.value_signed; 1104 ps->status = MT_PARAM_STATUS_OK; 1105bailout: 1106 if (ps->status != MT_PARAM_STATUS_OK) 1107 error = EINVAL; 1108 1109 return (error); 1110} 1111 1112 1113static void 1114safillprot(struct sa_softc *softc, int *indent, struct sbuf *sb) 1115{ 1116 int tmpint; 1117 1118 SASBADDNODE(sb, *indent, protection); 1119 if (softc->flags & SA_FLAG_PROTECT_SUPP) 1120 tmpint = 1; 1121 else 1122 tmpint = 0; 1123 SASBADDINTDESC(sb, *indent, tmpint, %d, protection_supported, 1124 "Set to 1 if protection information is supported"); 1125 1126 if ((tmpint != 0) 1127 && (softc->prot_info.cur_prot_state.initialized != 0)) { 1128 struct sa_prot_state *prot; 1129 1130 prot = &softc->prot_info.cur_prot_state; 1131 1132 SASBADDUINTDESC(sb, *indent, prot->prot_method, %u, 1133 prot_method, "Current Protection Method"); 1134 SASBADDUINTDESC(sb, *indent, prot->pi_length, %u, 1135 pi_length, "Length of Protection Information"); 1136 SASBADDUINTDESC(sb, *indent, prot->lbp_w, %u, 1137 lbp_w, "Check Protection on Writes"); 1138 SASBADDUINTDESC(sb, *indent, prot->lbp_r, %u, 1139 lbp_r, "Check and Include Protection on Reads"); 1140 SASBADDUINTDESC(sb, *indent, prot->rbdp, %u, 1141 rbdp, "Transfer Protection Information for RECOVER " 1142 "BUFFERED DATA command"); 1143 } 1144 SASBENDNODE(sb, *indent, protection); 1145} 1146 1147static void 1148sapopulateprots(struct sa_prot_state *cur_state, struct sa_prot_map *new_table, 1149 int table_ents) 1150{ 1151 int i; 1152 1153 bcopy(sa_prot_table, new_table, min(table_ents * sizeof(*new_table), 1154 sizeof(sa_prot_table))); 1155 1156 table_ents = min(table_ents, SA_NUM_PROT_ENTS); 1157 1158 for (i = 0; i < table_ents; i++) 1159 new_table[i].value = (uint32_t *)((uint8_t *)cur_state + 1160 new_table[i].offset); 1161 1162 return; 1163} 1164 1165static struct sa_prot_map * 1166safindprotent(char *name, struct sa_prot_map *table, int table_ents) 1167{ 1168 char *prot_name = "protection."; 1169 int i, prot_len; 1170 1171 prot_len = strlen(prot_name); 1172 1173 /* 1174 * This shouldn't happen, but we check just in case. 1175 */ 1176 if (strncmp(name, prot_name, prot_len) != 0) 1177 goto bailout; 1178 1179 for (i = 0; i < table_ents; i++) { 1180 if (strcmp(&name[prot_len], table[i].name) != 0) 1181 continue; 1182 return (&table[i]); 1183 } 1184bailout: 1185 return (NULL); 1186} 1187 1188static int 1189sasetprotents(struct cam_periph *periph, struct mtparamset *ps, int num_params) 1190{ 1191 struct sa_softc *softc; 1192 struct sa_prot_map prot_ents[SA_NUM_PROT_ENTS]; 1193 struct sa_prot_state new_state; 1194 int error; 1195 int i; 1196 1197 softc = (struct sa_softc *)periph->softc; 1198 error = 0; 1199 1200 /* 1201 * Make sure that this tape drive supports protection information. 1202 * Otherwise we can't set anything. 1203 */ 1204 if ((softc->flags & SA_FLAG_PROTECT_SUPP) == 0) { 1205 snprintf(ps[0].error_str, sizeof(ps[0].error_str), 1206 "Protection information is not supported for this device"); 1207 ps[0].status = MT_PARAM_STATUS_ERROR; 1208 goto bailout; 1209 } 1210 1211 /* 1212 * We can't operate with physio(9) splitting enabled, because there 1213 * is no way to insure (especially in variable block mode) that 1214 * what the user writes (with a checksum block at the end) will 1215 * make it into the sa(4) driver intact. 1216 */ 1217 if ((softc->si_flags & SI_NOSPLIT) == 0) { 1218 snprintf(ps[0].error_str, sizeof(ps[0].error_str), 1219 "Protection information cannot be enabled with I/O " 1220 "splitting"); 1221 ps[0].status = MT_PARAM_STATUS_ERROR; 1222 goto bailout; 1223 } 1224 1225 /* 1226 * Take the current cached protection state and use that as the 1227 * basis for our new entries. 1228 */ 1229 bcopy(&softc->prot_info.cur_prot_state, &new_state, sizeof(new_state)); 1230 1231 /* 1232 * Populate the table mapping property names to pointers into the 1233 * state structure. 1234 */ 1235 sapopulateprots(&new_state, prot_ents, SA_NUM_PROT_ENTS); 1236 1237 /* 1238 * For each parameter the user passed in, make sure the name, type 1239 * and value are valid. 1240 */ 1241 for (i = 0; i < num_params; i++) { 1242 struct sa_prot_map *ent; 1243 1244 ent = safindprotent(ps[i].value_name, prot_ents, 1245 SA_NUM_PROT_ENTS); 1246 if (ent == NULL) { 1247 ps[i].status = MT_PARAM_STATUS_ERROR; 1248 snprintf(ps[i].error_str, sizeof(ps[i].error_str), 1249 "Invalid protection entry name %s", 1250 ps[i].value_name); 1251 error = EINVAL; 1252 goto bailout; 1253 } 1254 if (ent->param_type != ps[i].value_type) { 1255 ps[i].status = MT_PARAM_STATUS_ERROR; 1256 snprintf(ps[i].error_str, sizeof(ps[i].error_str), 1257 "Supplied type %d does not match actual type %d", 1258 ps[i].value_type, ent->param_type); 1259 error = EINVAL; 1260 goto bailout; 1261 } 1262 if ((ps[i].value.value_unsigned < ent->min_val) 1263 || (ps[i].value.value_unsigned > ent->max_val)) { 1264 ps[i].status = MT_PARAM_STATUS_ERROR; 1265 snprintf(ps[i].error_str, sizeof(ps[i].error_str), 1266 "Value %ju is outside valid range %u - %u", 1267 (uintmax_t)ps[i].value.value_unsigned, ent->min_val, 1268 ent->max_val); 1269 error = EINVAL; 1270 goto bailout; 1271 } 1272 *(ent->value) = ps[i].value.value_unsigned; 1273 } 1274 1275 /* 1276 * Actually send the protection settings to the drive. 1277 */ 1278 error = sasetprot(periph, &new_state); 1279 if (error != 0) { 1280 for (i = 0; i < num_params; i++) { 1281 ps[i].status = MT_PARAM_STATUS_ERROR; 1282 snprintf(ps[i].error_str, sizeof(ps[i].error_str), 1283 "Unable to set parameter, see dmesg(8)"); 1284 } 1285 goto bailout; 1286 } 1287 1288 /* 1289 * Let the user know that his settings were stored successfully. 1290 */ 1291 for (i = 0; i < num_params; i++) 1292 ps[i].status = MT_PARAM_STATUS_OK; 1293 1294bailout: 1295 return (error); 1296} 1297/* 1298 * Entry handlers generally only handle a single entry. Node handlers will 1299 * handle a contiguous range of parameters to set in a single call. 1300 */ 1301typedef enum { 1302 SA_PARAM_TYPE_ENTRY, 1303 SA_PARAM_TYPE_NODE 1304} sa_param_type; 1305 1306struct sa_param_ent { 1307 char *name; 1308 sa_param_type param_type; 1309 int (*set_func)(struct cam_periph *periph, struct mtparamset *ps, 1310 int num_params); 1311} sa_param_table[] = { 1312 {"sili", SA_PARAM_TYPE_ENTRY, sasetsili }, 1313 {"eot_warn", SA_PARAM_TYPE_ENTRY, saseteotwarn }, 1314 {"protection.", SA_PARAM_TYPE_NODE, sasetprotents } 1315}; 1316 1317static struct sa_param_ent * 1318safindparament(struct mtparamset *ps) 1319{ 1320 unsigned int i; 1321 1322 for (i = 0; i < sizeof(sa_param_table) /sizeof(sa_param_table[0]); i++){ 1323 /* 1324 * For entries, we compare all of the characters. For 1325 * nodes, we only compare the first N characters. The node 1326 * handler will decode the rest. 1327 */ 1328 if (sa_param_table[i].param_type == SA_PARAM_TYPE_ENTRY) { 1329 if (strcmp(ps->value_name, sa_param_table[i].name) != 0) 1330 continue; 1331 } else { 1332 if (strncmp(ps->value_name, sa_param_table[i].name, 1333 strlen(sa_param_table[i].name)) != 0) 1334 continue; 1335 } 1336 return (&sa_param_table[i]); 1337 } 1338 1339 return (NULL); 1340} 1341 1342/* 1343 * Go through a list of parameters, coalescing contiguous parameters with 1344 * the same parent node into a single call to a set_func. 1345 */ 1346static int 1347saparamsetlist(struct cam_periph *periph, struct mtsetlist *list, 1348 int need_copy) 1349{ 1350 int i, contig_ents; 1351 int error; 1352 struct mtparamset *params, *first; 1353 struct sa_param_ent *first_ent; 1354 1355 error = 0; 1356 params = NULL; 1357 1358 if (list->num_params == 0) 1359 /* Nothing to do */ 1360 goto bailout; 1361 1362 /* 1363 * Verify that the user has the correct structure size. 1364 */ 1365 if ((list->num_params * sizeof(struct mtparamset)) != 1366 list->param_len) { 1367 xpt_print(periph->path, "%s: length of params %d != " 1368 "sizeof(struct mtparamset) %zd * num_params %d\n", 1369 __func__, list->param_len, sizeof(struct mtparamset), 1370 list->num_params); 1371 error = EINVAL; 1372 goto bailout; 1373 } 1374 1375 if (need_copy != 0) { 1376 /* 1377 * XXX KDM will dropping the lock cause an issue here? 1378 */ 1379 cam_periph_unlock(periph); 1380 params = malloc(list->param_len, M_SCSISA, M_WAITOK | M_ZERO); 1381 error = copyin(list->params, params, list->param_len); 1382 cam_periph_lock(periph); 1383 1384 if (error != 0) 1385 goto bailout; 1386 } else { 1387 params = list->params; 1388 } 1389 1390 contig_ents = 0; 1391 first = NULL; 1392 first_ent = NULL; 1393 for (i = 0; i < list->num_params; i++) { 1394 struct sa_param_ent *ent; 1395 1396 ent = safindparament(¶ms[i]); 1397 if (ent == NULL) { 1398 snprintf(params[i].error_str, 1399 sizeof(params[i].error_str), 1400 "%s: cannot find parameter %s", __func__, 1401 params[i].value_name); 1402 params[i].status = MT_PARAM_STATUS_ERROR; 1403 break; 1404 } 1405 1406 if (first != NULL) { 1407 if (first_ent == ent) { 1408 /* 1409 * We're still in a contiguous list of 1410 * parameters that can be handled by one 1411 * node handler. 1412 */ 1413 contig_ents++; 1414 continue; 1415 } else { 1416 error = first_ent->set_func(periph, first, 1417 contig_ents); 1418 first = NULL; 1419 first_ent = NULL; 1420 contig_ents = 0; 1421 if (error != 0) { 1422 error = 0; 1423 break; 1424 } 1425 } 1426 } 1427 if (ent->param_type == SA_PARAM_TYPE_NODE) { 1428 first = ¶ms[i]; 1429 first_ent = ent; 1430 contig_ents = 1; 1431 } else { 1432 error = ent->set_func(periph, ¶ms[i], 1); 1433 if (error != 0) { 1434 error = 0; 1435 break; 1436 } 1437 } 1438 } 1439 if (first != NULL) 1440 first_ent->set_func(periph, first, contig_ents); 1441 1442bailout: 1443 if (need_copy != 0) { 1444 if (error != EFAULT) { 1445 cam_periph_unlock(periph); 1446 copyout(params, list->params, list->param_len); 1447 cam_periph_lock(periph); 1448 } 1449 free(params, M_SCSISA); 1450 } 1451 return (error); 1452} 1453 1454static int 1455sagetparams_common(struct cdev *dev, struct cam_periph *periph) 1456{ 1457 struct sa_softc *softc; 1458 u_int8_t write_protect; 1459 int comp_enabled, comp_supported, error; 1460 1461 softc = (struct sa_softc *)periph->softc; 1462 1463 if (softc->open_pending_mount) 1464 return (0); 1465 1466 /* The control device may issue getparams() if there are no opens. */ 1467 if (SA_IS_CTRL(dev) && (softc->flags & SA_FLAG_OPEN) != 0) 1468 return (0); 1469 1470 error = sagetparams(periph, SA_PARAM_ALL, &softc->media_blksize, 1471 &softc->media_density, &softc->media_numblks, &softc->buffer_mode, 1472 &write_protect, &softc->speed, &comp_supported, &comp_enabled, 1473 &softc->comp_algorithm, NULL, NULL, 0, 0); 1474 if (error) 1475 return (error); 1476 if (write_protect) 1477 softc->flags |= SA_FLAG_TAPE_WP; 1478 else 1479 softc->flags &= ~SA_FLAG_TAPE_WP; 1480 softc->flags &= ~SA_FLAG_COMPRESSION; 1481 if (comp_supported) { 1482 if (softc->saved_comp_algorithm == 0) 1483 softc->saved_comp_algorithm = 1484 softc->comp_algorithm; 1485 softc->flags |= SA_FLAG_COMP_SUPP; 1486 if (comp_enabled) 1487 softc->flags |= SA_FLAG_COMP_ENABLED; 1488 } else 1489 softc->flags |= SA_FLAG_COMP_UNSUPP; 1490 1491 return (0); 1492} 1493 |
|
828#define PENDING_MOUNT_CHECK(softc, periph, dev) \ 829 if (softc->open_pending_mount) { \ 830 error = samount(periph, 0, dev); \ 831 if (error) { \ 832 break; \ 833 } \ 834 saprevent(periph, PR_PREVENT); \ 835 softc->open_pending_mount = 0; \ --- 27 unchanged lines hidden (view full) --- 863 * and MTCOMP (but need to be the only one accessing this 864 * device to run those). 865 */ 866 867 if (SA_IS_CTRL(dev)) { 868 switch (cmd) { 869 case MTIOCGETEOTMODEL: 870 case MTIOCGET: | 1494#define PENDING_MOUNT_CHECK(softc, periph, dev) \ 1495 if (softc->open_pending_mount) { \ 1496 error = samount(periph, 0, dev); \ 1497 if (error) { \ 1498 break; \ 1499 } \ 1500 saprevent(periph, PR_PREVENT); \ 1501 softc->open_pending_mount = 0; \ --- 27 unchanged lines hidden (view full) --- 1529 * and MTCOMP (but need to be the only one accessing this 1530 * device to run those). 1531 */ 1532 1533 if (SA_IS_CTRL(dev)) { 1534 switch (cmd) { 1535 case MTIOCGETEOTMODEL: 1536 case MTIOCGET: |
1537 case MTIOCEXTGET: 1538 case MTIOCPARAMGET: 1539 case MTIOCRBLIM: |
|
871 break; 872 case MTIOCERRSTAT: 873 /* 874 * If the periph isn't already locked, lock it 875 * so our MTIOCERRSTAT can reset latched error stats. 876 * 877 * If the periph is already locked, skip it because 878 * we're just getting status and it'll be up to the --- 55 unchanged lines hidden (view full) --- 934 /* 935 * Find the device that the user is talking about 936 */ 937 switch (cmd) { 938 case MTIOCGET: 939 { 940 struct mtget *g = (struct mtget *)arg; 941 | 1540 break; 1541 case MTIOCERRSTAT: 1542 /* 1543 * If the periph isn't already locked, lock it 1544 * so our MTIOCERRSTAT can reset latched error stats. 1545 * 1546 * If the periph is already locked, skip it because 1547 * we're just getting status and it'll be up to the --- 55 unchanged lines hidden (view full) --- 1603 /* 1604 * Find the device that the user is talking about 1605 */ 1606 switch (cmd) { 1607 case MTIOCGET: 1608 { 1609 struct mtget *g = (struct mtget *)arg; 1610 |
942 /* 943 * If this isn't the control mode device, actually go out 944 * and ask the drive again what it's set to. 945 */ 946 if (!SA_IS_CTRL(dev) && !softc->open_pending_mount) { 947 u_int8_t write_protect; 948 int comp_enabled, comp_supported; 949 error = sagetparams(periph, SA_PARAM_ALL, 950 &softc->media_blksize, &softc->media_density, 951 &softc->media_numblks, &softc->buffer_mode, 952 &write_protect, &softc->speed, &comp_supported, 953 &comp_enabled, &softc->comp_algorithm, NULL); 954 if (error) 955 break; 956 if (write_protect) 957 softc->flags |= SA_FLAG_TAPE_WP; 958 else 959 softc->flags &= ~SA_FLAG_TAPE_WP; 960 softc->flags &= ~(SA_FLAG_COMP_SUPP| 961 SA_FLAG_COMP_ENABLED|SA_FLAG_COMP_UNSUPP); 962 if (comp_supported) { 963 if (softc->saved_comp_algorithm == 0) 964 softc->saved_comp_algorithm = 965 softc->comp_algorithm; 966 softc->flags |= SA_FLAG_COMP_SUPP; 967 if (comp_enabled) 968 softc->flags |= SA_FLAG_COMP_ENABLED; 969 } else 970 softc->flags |= SA_FLAG_COMP_UNSUPP; 971 } | 1611 error = sagetparams_common(dev, periph); 1612 if (error) 1613 break; |
972 bzero(g, sizeof(struct mtget)); 973 g->mt_type = MT_ISAR; 974 if (softc->flags & SA_FLAG_COMP_UNSUPP) { 975 g->mt_comp = MT_COMP_UNSUPP; 976 g->mt_comp0 = MT_COMP_UNSUPP; 977 g->mt_comp1 = MT_COMP_UNSUPP; 978 g->mt_comp2 = MT_COMP_UNSUPP; 979 g->mt_comp3 = MT_COMP_UNSUPP; --- 35 unchanged lines hidden (view full) --- 1015 if (SA_IS_CTRL(dev) == 0 || didlockperiph) { 1016 softc->last_ctl_resid = 0; 1017 } 1018 } 1019 } 1020 error = 0; 1021 break; 1022 } | 1614 bzero(g, sizeof(struct mtget)); 1615 g->mt_type = MT_ISAR; 1616 if (softc->flags & SA_FLAG_COMP_UNSUPP) { 1617 g->mt_comp = MT_COMP_UNSUPP; 1618 g->mt_comp0 = MT_COMP_UNSUPP; 1619 g->mt_comp1 = MT_COMP_UNSUPP; 1620 g->mt_comp2 = MT_COMP_UNSUPP; 1621 g->mt_comp3 = MT_COMP_UNSUPP; --- 35 unchanged lines hidden (view full) --- 1657 if (SA_IS_CTRL(dev) == 0 || didlockperiph) { 1658 softc->last_ctl_resid = 0; 1659 } 1660 } 1661 } 1662 error = 0; 1663 break; 1664 } |
1665 case MTIOCEXTGET: 1666 case MTIOCPARAMGET: 1667 { 1668 struct mtextget *g = (struct mtextget *)arg; 1669 char *tmpstr2; 1670 struct sbuf *sb; 1671 1672 /* 1673 * Report drive status using an XML format. 1674 */ 1675 1676 /* 1677 * XXX KDM will dropping the lock cause any problems here? 1678 */ 1679 cam_periph_unlock(periph); 1680 sb = sbuf_new(NULL, NULL, g->alloc_len, SBUF_FIXEDLEN); 1681 if (sb == NULL) { 1682 g->status = MT_EXT_GET_ERROR; 1683 snprintf(g->error_str, sizeof(g->error_str), 1684 "Unable to allocate %d bytes for status info", 1685 g->alloc_len); 1686 cam_periph_lock(periph); 1687 goto extget_bailout; 1688 } 1689 cam_periph_lock(periph); 1690 1691 if (cmd == MTIOCEXTGET) 1692 error = saextget(dev, periph, sb, g); 1693 else 1694 error = saparamget(softc, sb); 1695 1696 if (error != 0) 1697 goto extget_bailout; 1698 1699 error = sbuf_finish(sb); 1700 if (error == ENOMEM) { 1701 g->status = MT_EXT_GET_NEED_MORE_SPACE; 1702 error = 0; 1703 } else if (error != 0) { 1704 g->status = MT_EXT_GET_ERROR; 1705 snprintf(g->error_str, sizeof(g->error_str), 1706 "Error %d returned from sbuf_finish()", error); 1707 } else 1708 g->status = MT_EXT_GET_OK; 1709 1710 error = 0; 1711 tmpstr2 = sbuf_data(sb); 1712 g->fill_len = strlen(tmpstr2) + 1; 1713 cam_periph_unlock(periph); 1714 1715 error = copyout(tmpstr2, g->status_xml, g->fill_len); 1716 1717 cam_periph_lock(periph); 1718 1719extget_bailout: 1720 sbuf_delete(sb); 1721 break; 1722 } 1723 case MTIOCPARAMSET: 1724 { 1725 struct mtsetlist list; 1726 struct mtparamset *ps = (struct mtparamset *)arg; 1727 1728 bzero(&list, sizeof(list)); 1729 list.num_params = 1; 1730 list.param_len = sizeof(*ps); 1731 list.params = ps; 1732 1733 error = saparamsetlist(periph, &list, /*need_copy*/ 0); 1734 break; 1735 } 1736 case MTIOCSETLIST: 1737 { 1738 struct mtsetlist *list = (struct mtsetlist *)arg; 1739 1740 error = saparamsetlist(periph, list, /*need_copy*/ 1); 1741 break; 1742 } |
|
1023 case MTIOCERRSTAT: 1024 { 1025 struct scsi_tape_errors *sep = 1026 &((union mterrstat *)arg)->scsi_errstat; 1027 1028 CAM_DEBUG(periph->path, CAM_DEBUG_TRACE, 1029 ("saioctl: MTIOCERRSTAT\n")); 1030 --- 4 unchanged lines hidden (view full) --- 1035 bcopy((caddr_t) &softc->last_io_cdb, sep->io_cdb, 1036 sizeof (sep->io_cdb)); 1037 sep->ctl_resid = softc->last_ctl_resid; 1038 bcopy((caddr_t) &softc->last_ctl_sense, sep->ctl_sense, 1039 sizeof (sep->ctl_sense)); 1040 bcopy((caddr_t) &softc->last_ctl_cdb, sep->ctl_cdb, 1041 sizeof (sep->ctl_cdb)); 1042 | 1743 case MTIOCERRSTAT: 1744 { 1745 struct scsi_tape_errors *sep = 1746 &((union mterrstat *)arg)->scsi_errstat; 1747 1748 CAM_DEBUG(periph->path, CAM_DEBUG_TRACE, 1749 ("saioctl: MTIOCERRSTAT\n")); 1750 --- 4 unchanged lines hidden (view full) --- 1755 bcopy((caddr_t) &softc->last_io_cdb, sep->io_cdb, 1756 sizeof (sep->io_cdb)); 1757 sep->ctl_resid = softc->last_ctl_resid; 1758 bcopy((caddr_t) &softc->last_ctl_sense, sep->ctl_sense, 1759 sizeof (sep->ctl_sense)); 1760 bcopy((caddr_t) &softc->last_ctl_cdb, sep->ctl_cdb, 1761 sizeof (sep->ctl_cdb)); 1762 |
1043 if ((SA_IS_CTRL(dev) == 0 && softc->open_pending_mount) || | 1763 if ((SA_IS_CTRL(dev) == 0 && !softc->open_pending_mount) || |
1044 didlockperiph) 1045 bzero((caddr_t) &softc->errinfo, 1046 sizeof (softc->errinfo)); 1047 error = 0; 1048 break; 1049 } 1050 case MTIOCTOP: 1051 { --- 10 unchanged lines hidden (view full) --- 1062 mt->mt_op, mt->mt_count)); 1063 1064 count = mt->mt_count; 1065 switch (mt->mt_op) { 1066 case MTWEOF: /* write an end-of-file marker */ 1067 /* 1068 * We don't need to clear the SA_FLAG_TAPE_WRITTEN 1069 * flag because by keeping track of filemarks | 1764 didlockperiph) 1765 bzero((caddr_t) &softc->errinfo, 1766 sizeof (softc->errinfo)); 1767 error = 0; 1768 break; 1769 } 1770 case MTIOCTOP: 1771 { --- 10 unchanged lines hidden (view full) --- 1782 mt->mt_op, mt->mt_count)); 1783 1784 count = mt->mt_count; 1785 switch (mt->mt_op) { 1786 case MTWEOF: /* write an end-of-file marker */ 1787 /* 1788 * We don't need to clear the SA_FLAG_TAPE_WRITTEN 1789 * flag because by keeping track of filemarks |
1070 * we have last written we know ehether or not | 1790 * we have last written we know whether or not |
1071 * we need to write more when we close the device. 1072 */ | 1791 * we need to write more when we close the device. 1792 */ |
1073 error = sawritefilemarks(periph, count, FALSE); | 1793 error = sawritefilemarks(periph, count, FALSE, FALSE); |
1074 break; | 1794 break; |
1795 case MTWEOFI: 1796 /* write an end-of-file marker without waiting */ 1797 error = sawritefilemarks(periph, count, FALSE, TRUE); 1798 break; |
|
1075 case MTWSS: /* write a setmark */ | 1799 case MTWSS: /* write a setmark */ |
1076 error = sawritefilemarks(periph, count, TRUE); | 1800 error = sawritefilemarks(periph, count, TRUE, FALSE); |
1077 break; 1078 case MTBSR: /* backward space record */ 1079 case MTFSR: /* forward space record */ 1080 case MTBSF: /* backward space file */ 1081 case MTFSF: /* forward space file */ 1082 case MTBSS: /* backward space setmark */ 1083 case MTFSS: /* forward space setmark */ 1084 case MTEOD: /* space to end of recorded medium */ --- 108 unchanged lines hidden (view full) --- 1193 if (error == 0) { 1194 error = saloadunload(periph, FALSE); 1195 if (error == 0) { 1196 softc->flags &= ~SA_FLAG_TAPE_MOUNTED; 1197 } 1198 } 1199 break; 1200 | 1801 break; 1802 case MTBSR: /* backward space record */ 1803 case MTFSR: /* forward space record */ 1804 case MTBSF: /* backward space file */ 1805 case MTFSF: /* forward space file */ 1806 case MTBSS: /* backward space setmark */ 1807 case MTFSS: /* forward space setmark */ 1808 case MTEOD: /* space to end of recorded medium */ --- 108 unchanged lines hidden (view full) --- 1917 if (error == 0) { 1918 error = saloadunload(periph, FALSE); 1919 if (error == 0) { 1920 softc->flags &= ~SA_FLAG_TAPE_MOUNTED; 1921 } 1922 } 1923 break; 1924 |
1925 case MTLOAD: 1926 error = saloadunload(periph, TRUE); 1927 break; |
|
1201 case MTNOP: /* no operation, sets status only */ 1202 case MTCACHE: /* enable controller cache */ 1203 case MTNOCACHE: /* disable controller cache */ 1204 error = 0; 1205 break; 1206 1207 case MTSETBSIZ: /* Set block size for device */ 1208 1209 PENDING_MOUNT_CHECK(softc, periph, dev); 1210 | 1928 case MTNOP: /* no operation, sets status only */ 1929 case MTCACHE: /* enable controller cache */ 1930 case MTNOCACHE: /* disable controller cache */ 1931 error = 0; 1932 break; 1933 1934 case MTSETBSIZ: /* Set block size for device */ 1935 1936 PENDING_MOUNT_CHECK(softc, periph, dev); 1937 |
1938 if ((softc->sili != 0) 1939 && (count != 0)) { 1940 xpt_print(periph->path, "Can't enter fixed " 1941 "block mode with SILI enabled\n"); 1942 error = EINVAL; 1943 break; 1944 } |
|
1211 error = sasetparams(periph, SA_PARAM_BLOCKSIZE, count, 1212 0, 0, 0); 1213 if (error == 0) { 1214 softc->last_media_blksize = 1215 softc->media_blksize; 1216 softc->media_blksize = count; 1217 if (count) { 1218 softc->flags |= SA_FLAG_FIXED; --- 69 unchanged lines hidden (view full) --- 1288 PENDING_MOUNT_CHECK(softc, periph, dev); 1289 error = sardpos(periph, 0, (u_int32_t *) arg); 1290 break; 1291 case MTIOCRDHPOS: 1292 PENDING_MOUNT_CHECK(softc, periph, dev); 1293 error = sardpos(periph, 1, (u_int32_t *) arg); 1294 break; 1295 case MTIOCSLOCATE: | 1945 error = sasetparams(periph, SA_PARAM_BLOCKSIZE, count, 1946 0, 0, 0); 1947 if (error == 0) { 1948 softc->last_media_blksize = 1949 softc->media_blksize; 1950 softc->media_blksize = count; 1951 if (count) { 1952 softc->flags |= SA_FLAG_FIXED; --- 69 unchanged lines hidden (view full) --- 2022 PENDING_MOUNT_CHECK(softc, periph, dev); 2023 error = sardpos(periph, 0, (u_int32_t *) arg); 2024 break; 2025 case MTIOCRDHPOS: 2026 PENDING_MOUNT_CHECK(softc, periph, dev); 2027 error = sardpos(periph, 1, (u_int32_t *) arg); 2028 break; 2029 case MTIOCSLOCATE: |
2030 case MTIOCHLOCATE: { 2031 struct mtlocate locate_info; 2032 int hard; 2033 2034 bzero(&locate_info, sizeof(locate_info)); 2035 locate_info.logical_id = *((uint32_t *)arg); 2036 if (cmd == MTIOCSLOCATE) 2037 hard = 0; 2038 else 2039 hard = 1; 2040 |
|
1296 PENDING_MOUNT_CHECK(softc, periph, dev); | 2041 PENDING_MOUNT_CHECK(softc, periph, dev); |
1297 error = sasetpos(periph, 0, (u_int32_t *) arg); | 2042 2043 error = sasetpos(periph, hard, &locate_info); |
1298 break; | 2044 break; |
1299 case MTIOCHLOCATE: | 2045 } 2046 case MTIOCEXTLOCATE: |
1300 PENDING_MOUNT_CHECK(softc, periph, dev); | 2047 PENDING_MOUNT_CHECK(softc, periph, dev); |
1301 error = sasetpos(periph, 1, (u_int32_t *) arg); | 2048 error = sasetpos(periph, /*hard*/ 0, (struct mtlocate *)arg); 2049 softc->flags &= 2050 ~(SA_FLAG_TAPE_WRITTEN|SA_FLAG_TAPE_FROZEN); 2051 softc->flags &= ~SA_FLAG_ERR_PENDING; 2052 softc->filemarks = 0; |
1302 break; 1303 case MTIOCGETEOTMODEL: 1304 error = 0; 1305 if (softc->quirks & SA_QUIRK_1FM) 1306 mode = 1; 1307 else 1308 mode = 2; 1309 *((u_int32_t *) arg) = mode; --- 9 unchanged lines hidden (view full) --- 1319 softc->quirks &= ~SA_QUIRK_1FM; 1320 softc->quirks |= SA_QUIRK_2FM; 1321 break; 1322 default: 1323 error = EINVAL; 1324 break; 1325 } 1326 break; | 2053 break; 2054 case MTIOCGETEOTMODEL: 2055 error = 0; 2056 if (softc->quirks & SA_QUIRK_1FM) 2057 mode = 1; 2058 else 2059 mode = 2; 2060 *((u_int32_t *) arg) = mode; --- 9 unchanged lines hidden (view full) --- 2070 softc->quirks &= ~SA_QUIRK_1FM; 2071 softc->quirks |= SA_QUIRK_2FM; 2072 break; 2073 default: 2074 error = EINVAL; 2075 break; 2076 } 2077 break; |
2078 case MTIOCRBLIM: { 2079 struct mtrblim *rblim; 2080 2081 rblim = (struct mtrblim *)arg; 2082 2083 rblim->granularity = softc->blk_gran; 2084 rblim->min_block_length = softc->min_blk; 2085 rblim->max_block_length = softc->max_blk; 2086 break; 2087 } |
|
1327 default: 1328 error = cam_periph_ioctl(periph, cmd, arg, saerror); 1329 break; 1330 } 1331 1332 /* 1333 * Check to see if we cleared a frozen state 1334 */ 1335 if (error == 0 && (softc->flags & SA_FLAG_TAPE_FROZEN)) { 1336 switch(cmd) { 1337 case MTIOCRDSPOS: 1338 case MTIOCRDHPOS: 1339 case MTIOCSLOCATE: 1340 case MTIOCHLOCATE: | 2088 default: 2089 error = cam_periph_ioctl(periph, cmd, arg, saerror); 2090 break; 2091 } 2092 2093 /* 2094 * Check to see if we cleared a frozen state 2095 */ 2096 if (error == 0 && (softc->flags & SA_FLAG_TAPE_FROZEN)) { 2097 switch(cmd) { 2098 case MTIOCRDSPOS: 2099 case MTIOCRDHPOS: 2100 case MTIOCSLOCATE: 2101 case MTIOCHLOCATE: |
2102 /* 2103 * XXX KDM look at this. 2104 */ |
|
1341 softc->fileno = (daddr_t) -1; 1342 softc->blkno = (daddr_t) -1; | 2105 softc->fileno = (daddr_t) -1; 2106 softc->blkno = (daddr_t) -1; |
2107 softc->rep_blkno = (daddr_t) -1; 2108 softc->rep_fileno = (daddr_t) -1; 2109 softc->partition = (daddr_t) -1; |
|
1343 softc->flags &= ~SA_FLAG_TAPE_FROZEN; 1344 xpt_print(periph->path, 1345 "tape state now unfrozen.\n"); 1346 break; 1347 default: 1348 break; 1349 } 1350 } --- 16 unchanged lines hidden (view full) --- 1367 1368 if (status != CAM_REQ_CMP) { 1369 printf("sa: Failed to attach master async callback " 1370 "due to status 0x%x!\n", status); 1371 } 1372} 1373 1374static void | 2110 softc->flags &= ~SA_FLAG_TAPE_FROZEN; 2111 xpt_print(periph->path, 2112 "tape state now unfrozen.\n"); 2113 break; 2114 default: 2115 break; 2116 } 2117 } --- 16 unchanged lines hidden (view full) --- 2134 2135 if (status != CAM_REQ_CMP) { 2136 printf("sa: Failed to attach master async callback " 2137 "due to status 0x%x!\n", status); 2138 } 2139} 2140 2141static void |
2142sadevgonecb(void *arg) 2143{ 2144 struct cam_periph *periph; 2145 struct mtx *mtx; 2146 struct sa_softc *softc; 2147 2148 periph = (struct cam_periph *)arg; 2149 softc = (struct sa_softc *)periph->softc; 2150 2151 mtx = cam_periph_mtx(periph); 2152 mtx_lock(mtx); 2153 2154 softc->num_devs_to_destroy--; 2155 if (softc->num_devs_to_destroy == 0) { 2156 int i; 2157 2158 /* 2159 * When we have gotten all of our callbacks, we will get 2160 * no more close calls from devfs. So if we have any 2161 * dangling opens, we need to release the reference held 2162 * for that particular context. 2163 */ 2164 for (i = 0; i < softc->open_count; i++) 2165 cam_periph_release_locked(periph); 2166 2167 softc->open_count = 0; 2168 2169 /* 2170 * Release the reference held for devfs, all of our 2171 * instances are gone now. 2172 */ 2173 cam_periph_release_locked(periph); 2174 } 2175 2176 /* 2177 * We reference the lock directly here, instead of using 2178 * cam_periph_unlock(). The reason is that the final call to 2179 * cam_periph_release_locked() above could result in the periph 2180 * getting freed. If that is the case, dereferencing the periph 2181 * with a cam_periph_unlock() call would cause a page fault. 2182 */ 2183 mtx_unlock(mtx); 2184} 2185 2186static void |
|
1375saoninvalidate(struct cam_periph *periph) 1376{ 1377 struct sa_softc *softc; 1378 1379 softc = (struct sa_softc *)periph->softc; 1380 1381 /* 1382 * De-register any async callbacks. --- 4 unchanged lines hidden (view full) --- 1387 1388 /* 1389 * Return all queued I/O with ENXIO. 1390 * XXX Handle any transactions queued to the card 1391 * with XPT_ABORT_CCB. 1392 */ 1393 bioq_flush(&softc->bio_queue, NULL, ENXIO); 1394 softc->queue_count = 0; | 2187saoninvalidate(struct cam_periph *periph) 2188{ 2189 struct sa_softc *softc; 2190 2191 softc = (struct sa_softc *)periph->softc; 2192 2193 /* 2194 * De-register any async callbacks. --- 4 unchanged lines hidden (view full) --- 2199 2200 /* 2201 * Return all queued I/O with ENXIO. 2202 * XXX Handle any transactions queued to the card 2203 * with XPT_ABORT_CCB. 2204 */ 2205 bioq_flush(&softc->bio_queue, NULL, ENXIO); 2206 softc->queue_count = 0; |
2207 2208 /* 2209 * Tell devfs that all of our devices have gone away, and ask for a 2210 * callback when it has cleaned up its state. 2211 */ 2212 destroy_dev_sched_cb(softc->devs.ctl_dev, sadevgonecb, periph); 2213 destroy_dev_sched_cb(softc->devs.r_dev, sadevgonecb, periph); 2214 destroy_dev_sched_cb(softc->devs.nr_dev, sadevgonecb, periph); 2215 destroy_dev_sched_cb(softc->devs.er_dev, sadevgonecb, periph); |
|
1395} 1396 1397static void 1398sacleanup(struct cam_periph *periph) 1399{ 1400 struct sa_softc *softc; | 2216} 2217 2218static void 2219sacleanup(struct cam_periph *periph) 2220{ 2221 struct sa_softc *softc; |
1401 int i; | |
1402 1403 softc = (struct sa_softc *)periph->softc; 1404 | 2222 2223 softc = (struct sa_softc *)periph->softc; 2224 |
1405 devstat_remove_entry(softc->device_stats); | |
1406 cam_periph_unlock(periph); | 2225 cam_periph_unlock(periph); |
1407 destroy_dev(softc->devs.ctl_dev); 1408 for (i = 0; i < SA_NUM_MODES; i++) { 1409 destroy_dev(softc->devs.mode_devs[i].r_dev); 1410 destroy_dev(softc->devs.mode_devs[i].nr_dev); 1411 destroy_dev(softc->devs.mode_devs[i].er_dev); 1412 } | 2226 2227 if ((softc->flags & SA_FLAG_SCTX_INIT) != 0 2228 && sysctl_ctx_free(&softc->sysctl_ctx) != 0) 2229 xpt_print(periph->path, "can't remove sysctl context\n"); 2230 |
1413 cam_periph_lock(periph); | 2231 cam_periph_lock(periph); |
2232 2233 devstat_remove_entry(softc->device_stats); 2234 |
|
1414 free(softc, M_SCSISA); 1415} 1416 1417static void 1418saasync(void *callback_arg, u_int32_t code, 1419 struct cam_path *path, void *arg) 1420{ 1421 struct cam_periph *periph; --- 33 unchanged lines hidden (view full) --- 1455 } 1456 default: 1457 cam_periph_async(periph, code, path, arg); 1458 break; 1459 } 1460} 1461 1462static void | 2235 free(softc, M_SCSISA); 2236} 2237 2238static void 2239saasync(void *callback_arg, u_int32_t code, 2240 struct cam_path *path, void *arg) 2241{ 2242 struct cam_periph *periph; --- 33 unchanged lines hidden (view full) --- 2276 } 2277 default: 2278 cam_periph_async(periph, code, path, arg); 2279 break; 2280 } 2281} 2282 2283static void |
2284sasetupdev(struct sa_softc *softc, struct cdev *dev) 2285{ 2286 dev->si_drv1 = softc->periph; 2287 dev->si_iosize_max = softc->maxio; 2288 dev->si_flags |= softc->si_flags; 2289 /* 2290 * Keep a count of how many non-alias devices we have created, 2291 * so we can make sure we clean them all up on shutdown. Aliases 2292 * are cleaned up when we destroy the device they're an alias for. 2293 */ 2294 if ((dev->si_flags & SI_ALIAS) == 0) 2295 softc->num_devs_to_destroy++; 2296} 2297 2298static void |
|
1463sasysctlinit(void *context, int pending) 1464{ 1465 struct cam_periph *periph; 1466 struct sa_softc *softc; 1467 char tmpstr[80], tmpstr2[80]; 1468 1469 periph = (struct cam_periph *)context; 1470 /* 1471 * If the periph is invalid, no need to setup the sysctls. 1472 */ 1473 if (periph->flags & CAM_PERIPH_INVALID) 1474 goto bailout; 1475 1476 softc = (struct sa_softc *)periph->softc; 1477 1478 snprintf(tmpstr, sizeof(tmpstr), "CAM SA unit %d", periph->unit_number); 1479 snprintf(tmpstr2, sizeof(tmpstr2), "%u", periph->unit_number); 1480 1481 sysctl_ctx_init(&softc->sysctl_ctx); | 2299sasysctlinit(void *context, int pending) 2300{ 2301 struct cam_periph *periph; 2302 struct sa_softc *softc; 2303 char tmpstr[80], tmpstr2[80]; 2304 2305 periph = (struct cam_periph *)context; 2306 /* 2307 * If the periph is invalid, no need to setup the sysctls. 2308 */ 2309 if (periph->flags & CAM_PERIPH_INVALID) 2310 goto bailout; 2311 2312 softc = (struct sa_softc *)periph->softc; 2313 2314 snprintf(tmpstr, sizeof(tmpstr), "CAM SA unit %d", periph->unit_number); 2315 snprintf(tmpstr2, sizeof(tmpstr2), "%u", periph->unit_number); 2316 2317 sysctl_ctx_init(&softc->sysctl_ctx); |
2318 softc->flags |= SA_FLAG_SCTX_INIT; |
|
1482 softc->sysctl_tree = SYSCTL_ADD_NODE(&softc->sysctl_ctx, 1483 SYSCTL_STATIC_CHILDREN(_kern_cam_sa), OID_AUTO, tmpstr2, 1484 CTLFLAG_RD, 0, tmpstr); 1485 if (softc->sysctl_tree == NULL) 1486 goto bailout; 1487 1488 SYSCTL_ADD_INT(&softc->sysctl_ctx, SYSCTL_CHILDREN(softc->sysctl_tree), 1489 OID_AUTO, "allow_io_split", CTLFLAG_RDTUN | CTLFLAG_NOFETCH, --- 15 unchanged lines hidden (view full) --- 1505static cam_status 1506saregister(struct cam_periph *periph, void *arg) 1507{ 1508 struct sa_softc *softc; 1509 struct ccb_getdev *cgd; 1510 struct ccb_pathinq cpi; 1511 caddr_t match; 1512 char tmpstr[80]; | 2319 softc->sysctl_tree = SYSCTL_ADD_NODE(&softc->sysctl_ctx, 2320 SYSCTL_STATIC_CHILDREN(_kern_cam_sa), OID_AUTO, tmpstr2, 2321 CTLFLAG_RD, 0, tmpstr); 2322 if (softc->sysctl_tree == NULL) 2323 goto bailout; 2324 2325 SYSCTL_ADD_INT(&softc->sysctl_ctx, SYSCTL_CHILDREN(softc->sysctl_tree), 2326 OID_AUTO, "allow_io_split", CTLFLAG_RDTUN | CTLFLAG_NOFETCH, --- 15 unchanged lines hidden (view full) --- 2342static cam_status 2343saregister(struct cam_periph *periph, void *arg) 2344{ 2345 struct sa_softc *softc; 2346 struct ccb_getdev *cgd; 2347 struct ccb_pathinq cpi; 2348 caddr_t match; 2349 char tmpstr[80]; |
1513 int i; | |
1514 1515 cgd = (struct ccb_getdev *)arg; 1516 if (cgd == NULL) { 1517 printf("saregister: no getdev CCB, can't register device\n"); 1518 return (CAM_REQ_CMP_ERR); 1519 } 1520 1521 softc = (struct sa_softc *) 1522 malloc(sizeof (*softc), M_SCSISA, M_NOWAIT | M_ZERO); 1523 if (softc == NULL) { 1524 printf("saregister: Unable to probe new device. " 1525 "Unable to allocate softc\n"); 1526 return (CAM_REQ_CMP_ERR); 1527 } 1528 softc->scsi_rev = SID_ANSI_REV(&cgd->inq_data); 1529 softc->state = SA_STATE_NORMAL; 1530 softc->fileno = (daddr_t) -1; 1531 softc->blkno = (daddr_t) -1; | 2350 2351 cgd = (struct ccb_getdev *)arg; 2352 if (cgd == NULL) { 2353 printf("saregister: no getdev CCB, can't register device\n"); 2354 return (CAM_REQ_CMP_ERR); 2355 } 2356 2357 softc = (struct sa_softc *) 2358 malloc(sizeof (*softc), M_SCSISA, M_NOWAIT | M_ZERO); 2359 if (softc == NULL) { 2360 printf("saregister: Unable to probe new device. " 2361 "Unable to allocate softc\n"); 2362 return (CAM_REQ_CMP_ERR); 2363 } 2364 softc->scsi_rev = SID_ANSI_REV(&cgd->inq_data); 2365 softc->state = SA_STATE_NORMAL; 2366 softc->fileno = (daddr_t) -1; 2367 softc->blkno = (daddr_t) -1; |
2368 softc->rep_fileno = (daddr_t) -1; 2369 softc->rep_blkno = (daddr_t) -1; 2370 softc->partition = (daddr_t) -1; 2371 softc->bop = -1; 2372 softc->eop = -1; 2373 softc->bpew = -1; |
|
1532 1533 bioq_init(&softc->bio_queue); | 2374 2375 bioq_init(&softc->bio_queue); |
2376 softc->periph = periph; |
|
1534 periph->softc = softc; 1535 1536 /* 1537 * See if this device has any quirks. 1538 */ 1539 match = cam_quirkmatch((caddr_t)&cgd->inq_data, 1540 (caddr_t)sa_quirk_table, 1541 sizeof(sa_quirk_table)/sizeof(*sa_quirk_table), 1542 sizeof(*sa_quirk_table), scsi_inquiry_match); 1543 1544 if (match != NULL) { 1545 softc->quirks = ((struct sa_quirk_entry *)match)->quirks; 1546 softc->last_media_blksize = 1547 ((struct sa_quirk_entry *)match)->prefblk; 1548 } else 1549 softc->quirks = SA_QUIRK_NONE; 1550 | 2377 periph->softc = softc; 2378 2379 /* 2380 * See if this device has any quirks. 2381 */ 2382 match = cam_quirkmatch((caddr_t)&cgd->inq_data, 2383 (caddr_t)sa_quirk_table, 2384 sizeof(sa_quirk_table)/sizeof(*sa_quirk_table), 2385 sizeof(*sa_quirk_table), scsi_inquiry_match); 2386 2387 if (match != NULL) { 2388 softc->quirks = ((struct sa_quirk_entry *)match)->quirks; 2389 softc->last_media_blksize = 2390 ((struct sa_quirk_entry *)match)->prefblk; 2391 } else 2392 softc->quirks = SA_QUIRK_NONE; 2393 |
2394 /* 2395 * Long format data for READ POSITION was introduced in SSC, which 2396 * was after SCSI-2. (Roughly equivalent to SCSI-3.) If the drive 2397 * reports that it is SCSI-2 or older, it is unlikely to support 2398 * long position data, but it might. Some drives from that era 2399 * claim to be SCSI-2, but do support long position information. 2400 * So, instead of immediately disabling long position information 2401 * for SCSI-2 devices, we'll try one pass through sagetpos(), and 2402 * then disable long position information if we get an error. 2403 */ 2404 if (cgd->inq_data.version <= SCSI_REV_CCS) 2405 softc->quirks |= SA_QUIRK_NO_LONG_POS; 2406 2407 if (cgd->inq_data.spc3_flags & SPC3_SID_PROTECT) { 2408 struct ccb_dev_advinfo cdai; 2409 struct scsi_vpd_extended_inquiry_data ext_inq; 2410 2411 bzero(&ext_inq, sizeof(ext_inq)); 2412 2413 xpt_setup_ccb(&cdai.ccb_h, periph->path, CAM_PRIORITY_NORMAL); 2414 2415 cdai.ccb_h.func_code = XPT_DEV_ADVINFO; 2416 cdai.flags = CDAI_FLAG_NONE; 2417 cdai.buftype = CDAI_TYPE_EXT_INQ; 2418 cdai.bufsiz = sizeof(ext_inq); 2419 cdai.buf = (uint8_t *)&ext_inq; 2420 xpt_action((union ccb *)&cdai); 2421 2422 if ((cdai.ccb_h.status & CAM_DEV_QFRZN) != 0) 2423 cam_release_devq(cdai.ccb_h.path, 0, 0, 0, FALSE); 2424 if ((cdai.ccb_h.status == CAM_REQ_CMP) 2425 && (ext_inq.flags1 & SVPD_EID_SA_SPT_LBP)) 2426 softc->flags |= SA_FLAG_PROTECT_SUPP; 2427 } 2428 |
|
1551 bzero(&cpi, sizeof(cpi)); 1552 xpt_setup_ccb(&cpi.ccb_h, periph->path, CAM_PRIORITY_NORMAL); 1553 cpi.ccb_h.func_code = XPT_PATH_INQ; 1554 xpt_action((union ccb *)&cpi); 1555 1556 /* 1557 * The SA driver supports a blocksize, but we don't know the 1558 * blocksize until we media is inserted. So, set a flag to --- 50 unchanged lines hidden (view full) --- 1609 1610 /* 1611 * If the SIM supports unmapped I/O, let physio know that we can 1612 * handle unmapped buffers. 1613 */ 1614 if (cpi.hba_misc & PIM_UNMAPPED) 1615 softc->si_flags |= SI_UNMAPPED; 1616 | 2429 bzero(&cpi, sizeof(cpi)); 2430 xpt_setup_ccb(&cpi.ccb_h, periph->path, CAM_PRIORITY_NORMAL); 2431 cpi.ccb_h.func_code = XPT_PATH_INQ; 2432 xpt_action((union ccb *)&cpi); 2433 2434 /* 2435 * The SA driver supports a blocksize, but we don't know the 2436 * blocksize until we media is inserted. So, set a flag to --- 50 unchanged lines hidden (view full) --- 2487 2488 /* 2489 * If the SIM supports unmapped I/O, let physio know that we can 2490 * handle unmapped buffers. 2491 */ 2492 if (cpi.hba_misc & PIM_UNMAPPED) 2493 softc->si_flags |= SI_UNMAPPED; 2494 |
2495 /* 2496 * Acquire a reference to the periph before we create the devfs 2497 * instances for it. We'll release this reference once the devfs 2498 * instances have been freed. 2499 */ 2500 if (cam_periph_acquire(periph) != CAM_REQ_CMP) { 2501 xpt_print(periph->path, "%s: lost periph during " 2502 "registration!\n", __func__); 2503 cam_periph_lock(periph); 2504 return (CAM_REQ_CMP_ERR); 2505 } 2506 |
|
1617 softc->devs.ctl_dev = make_dev(&sa_cdevsw, SAMINOR(SA_CTLDEV, | 2507 softc->devs.ctl_dev = make_dev(&sa_cdevsw, SAMINOR(SA_CTLDEV, |
1618 0, SA_ATYPE_R), UID_ROOT, GID_OPERATOR, | 2508 SA_ATYPE_R), UID_ROOT, GID_OPERATOR, |
1619 0660, "%s%d.ctl", periph->periph_name, periph->unit_number); | 2509 0660, "%s%d.ctl", periph->periph_name, periph->unit_number); |
1620 softc->devs.ctl_dev->si_drv1 = periph; 1621 softc->devs.ctl_dev->si_iosize_max = softc->maxio; 1622 softc->devs.ctl_dev->si_flags |= softc->si_flags; | 2510 sasetupdev(softc, softc->devs.ctl_dev); |
1623 | 2511 |
1624 for (i = 0; i < SA_NUM_MODES; i++) { | 2512 softc->devs.r_dev = make_dev(&sa_cdevsw, SAMINOR(SA_NOT_CTLDEV, 2513 SA_ATYPE_R), UID_ROOT, GID_OPERATOR, 2514 0660, "%s%d", periph->periph_name, periph->unit_number); 2515 sasetupdev(softc, softc->devs.r_dev); |
1625 | 2516 |
1626 softc->devs.mode_devs[i].r_dev = make_dev(&sa_cdevsw, 1627 SAMINOR(SA_NOT_CTLDEV, i, SA_ATYPE_R), 1628 UID_ROOT, GID_OPERATOR, 0660, "%s%d.%d", 1629 periph->periph_name, periph->unit_number, i); 1630 softc->devs.mode_devs[i].r_dev->si_drv1 = periph; 1631 softc->devs.mode_devs[i].r_dev->si_iosize_max = softc->maxio; 1632 softc->devs.mode_devs[i].r_dev->si_flags |= softc->si_flags; | 2517 softc->devs.nr_dev = make_dev(&sa_cdevsw, SAMINOR(SA_NOT_CTLDEV, 2518 SA_ATYPE_NR), UID_ROOT, GID_OPERATOR, 2519 0660, "n%s%d", periph->periph_name, periph->unit_number); 2520 sasetupdev(softc, softc->devs.nr_dev); |
1633 | 2521 |
1634 softc->devs.mode_devs[i].nr_dev = make_dev(&sa_cdevsw, 1635 SAMINOR(SA_NOT_CTLDEV, i, SA_ATYPE_NR), 1636 UID_ROOT, GID_OPERATOR, 0660, "n%s%d.%d", 1637 periph->periph_name, periph->unit_number, i); 1638 softc->devs.mode_devs[i].nr_dev->si_drv1 = periph; 1639 softc->devs.mode_devs[i].nr_dev->si_iosize_max = softc->maxio; 1640 softc->devs.mode_devs[i].nr_dev->si_flags |= softc->si_flags; | 2522 softc->devs.er_dev = make_dev(&sa_cdevsw, SAMINOR(SA_NOT_CTLDEV, 2523 SA_ATYPE_ER), UID_ROOT, GID_OPERATOR, 2524 0660, "e%s%d", periph->periph_name, periph->unit_number); 2525 sasetupdev(softc, softc->devs.er_dev); |
1641 | 2526 |
1642 softc->devs.mode_devs[i].er_dev = make_dev(&sa_cdevsw, 1643 SAMINOR(SA_NOT_CTLDEV, i, SA_ATYPE_ER), 1644 UID_ROOT, GID_OPERATOR, 0660, "e%s%d.%d", 1645 periph->periph_name, periph->unit_number, i); 1646 softc->devs.mode_devs[i].er_dev->si_drv1 = periph; 1647 softc->devs.mode_devs[i].er_dev->si_iosize_max = softc->maxio; 1648 softc->devs.mode_devs[i].er_dev->si_flags |= softc->si_flags; 1649 1650 /* 1651 * Make the (well known) aliases for the first mode. 1652 */ 1653 if (i == 0) { 1654 struct cdev *alias; 1655 1656 alias = make_dev_alias(softc->devs.mode_devs[i].r_dev, 1657 "%s%d", periph->periph_name, periph->unit_number); 1658 alias->si_drv1 = periph; 1659 alias->si_iosize_max = softc->maxio; 1660 alias->si_flags |= softc->si_flags; 1661 1662 alias = make_dev_alias(softc->devs.mode_devs[i].nr_dev, 1663 "n%s%d", periph->periph_name, periph->unit_number); 1664 alias->si_drv1 = periph; 1665 alias->si_iosize_max = softc->maxio; 1666 alias->si_flags |= softc->si_flags; 1667 1668 alias = make_dev_alias(softc->devs.mode_devs[i].er_dev, 1669 "e%s%d", periph->periph_name, periph->unit_number); 1670 alias->si_drv1 = periph; 1671 alias->si_iosize_max = softc->maxio; 1672 alias->si_flags |= softc->si_flags; 1673 } 1674 } | |
1675 cam_periph_lock(periph); 1676 | 2527 cam_periph_lock(periph); 2528 |
2529 softc->density_type_bits[0] = 0; 2530 softc->density_type_bits[1] = SRDS_MEDIA; 2531 softc->density_type_bits[2] = SRDS_MEDIUM_TYPE; 2532 softc->density_type_bits[3] = SRDS_MEDIUM_TYPE | SRDS_MEDIA; |
|
1677 /* 1678 * Bump the peripheral refcount for the sysctl thread, in case we 1679 * get invalidated before the thread has a chance to run. 1680 */ 1681 cam_periph_acquire(periph); 1682 taskqueue_enqueue(taskqueue_thread, &softc->sysctl_task); 1683 1684 /* --- 34 unchanged lines hidden (view full) --- 1719 struct bio *done_bp; 1720again: 1721 softc->queue_count--; 1722 bioq_remove(&softc->bio_queue, bp); 1723 bp->bio_resid = bp->bio_bcount; 1724 done_bp = bp; 1725 if ((softc->flags & SA_FLAG_EOM_PENDING) != 0) { 1726 /* | 2533 /* 2534 * Bump the peripheral refcount for the sysctl thread, in case we 2535 * get invalidated before the thread has a chance to run. 2536 */ 2537 cam_periph_acquire(periph); 2538 taskqueue_enqueue(taskqueue_thread, &softc->sysctl_task); 2539 2540 /* --- 34 unchanged lines hidden (view full) --- 2575 struct bio *done_bp; 2576again: 2577 softc->queue_count--; 2578 bioq_remove(&softc->bio_queue, bp); 2579 bp->bio_resid = bp->bio_bcount; 2580 done_bp = bp; 2581 if ((softc->flags & SA_FLAG_EOM_PENDING) != 0) { 2582 /* |
1727 * We now just clear errors in this case 1728 * and let the residual be the notifier. | 2583 * We have two different behaviors for 2584 * writes when we hit either Early Warning 2585 * or the PEWZ (Programmable Early Warning 2586 * Zone). The default behavior is that 2587 * for all writes that are currently 2588 * queued after the write where we saw the 2589 * early warning, we will return the write 2590 * with the residual equal to the count. 2591 * i.e. tell the application that 0 bytes 2592 * were written. 2593 * 2594 * The alternate behavior, which is enabled 2595 * when eot_warn is set, is that in 2596 * addition to setting the residual equal 2597 * to the count, we will set the error 2598 * to ENOSPC. 2599 * 2600 * In either case, once queued writes are 2601 * cleared out, we clear the error flag 2602 * (see below) and the application is free to 2603 * attempt to write more. |
1729 */ | 2604 */ |
1730 bp->bio_error = 0; | 2605 if (softc->eot_warn != 0) { 2606 bp->bio_flags |= BIO_ERROR; 2607 bp->bio_error = ENOSPC; 2608 } else 2609 bp->bio_error = 0; |
1731 } else if ((softc->flags & SA_FLAG_EOF_PENDING) != 0) { 1732 /* 1733 * This can only happen if we're reading 1734 * in fixed length mode. In this case, 1735 * we dump the rest of the list the 1736 * same way. 1737 */ 1738 bp->bio_error = 0; --- 20 unchanged lines hidden (view full) --- 1759 xpt_release_ccb(start_ccb); 1760 biodone(done_bp); 1761 } else { 1762 u_int32_t length; 1763 1764 bioq_remove(&softc->bio_queue, bp); 1765 softc->queue_count--; 1766 | 2610 } else if ((softc->flags & SA_FLAG_EOF_PENDING) != 0) { 2611 /* 2612 * This can only happen if we're reading 2613 * in fixed length mode. In this case, 2614 * we dump the rest of the list the 2615 * same way. 2616 */ 2617 bp->bio_error = 0; --- 20 unchanged lines hidden (view full) --- 2638 xpt_release_ccb(start_ccb); 2639 biodone(done_bp); 2640 } else { 2641 u_int32_t length; 2642 2643 bioq_remove(&softc->bio_queue, bp); 2644 softc->queue_count--; 2645 |
2646 length = bp->bio_bcount; 2647 |
|
1767 if ((softc->flags & SA_FLAG_FIXED) != 0) { 1768 if (softc->blk_shift != 0) { | 2648 if ((softc->flags & SA_FLAG_FIXED) != 0) { 2649 if (softc->blk_shift != 0) { |
1769 length = 1770 bp->bio_bcount >> softc->blk_shift; | 2650 length = length >> softc->blk_shift; |
1771 } else if (softc->media_blksize != 0) { | 2651 } else if (softc->media_blksize != 0) { |
1772 length = bp->bio_bcount / 1773 softc->media_blksize; | 2652 length = length / softc->media_blksize; |
1774 } else { 1775 bp->bio_error = EIO; 1776 xpt_print(periph->path, "zero blocksize" 1777 " for FIXED length writes?\n"); 1778 biodone(bp); 1779 break; 1780 } 1781#if 0 1782 CAM_DEBUG(start_ccb->ccb_h.path, CAM_DEBUG_INFO, 1783 ("issuing a %d fixed record %s\n", 1784 length, (bp->bio_cmd == BIO_READ)? "read" : 1785 "write")); 1786#endif 1787 } else { | 2653 } else { 2654 bp->bio_error = EIO; 2655 xpt_print(periph->path, "zero blocksize" 2656 " for FIXED length writes?\n"); 2657 biodone(bp); 2658 break; 2659 } 2660#if 0 2661 CAM_DEBUG(start_ccb->ccb_h.path, CAM_DEBUG_INFO, 2662 ("issuing a %d fixed record %s\n", 2663 length, (bp->bio_cmd == BIO_READ)? "read" : 2664 "write")); 2665#endif 2666 } else { |
1788 length = bp->bio_bcount; | |
1789#if 0 1790 CAM_DEBUG(start_ccb->ccb_h.path, CAM_DEBUG_INFO, 1791 ("issuing a %d variable byte %s\n", 1792 length, (bp->bio_cmd == BIO_READ)? "read" : 1793 "write")); 1794#endif 1795 } 1796 devstat_start_transaction_bio(softc->device_stats, bp); --- 11 unchanged lines hidden (view full) --- 1808 * in the mode page to something other than 0. 1809 * 1810 * I believe that this is a non-issue. If user apps 1811 * don't adjust their read size to match our record 1812 * size, that's just life. Anyway, the typical usage 1813 * would be to issue, e.g., 64KB reads and occasionally 1814 * have to do deal with 512 byte or 1KB intermediate 1815 * records. | 2667#if 0 2668 CAM_DEBUG(start_ccb->ccb_h.path, CAM_DEBUG_INFO, 2669 ("issuing a %d variable byte %s\n", 2670 length, (bp->bio_cmd == BIO_READ)? "read" : 2671 "write")); 2672#endif 2673 } 2674 devstat_start_transaction_bio(softc->device_stats, bp); --- 11 unchanged lines hidden (view full) --- 2686 * in the mode page to something other than 0. 2687 * 2688 * I believe that this is a non-issue. If user apps 2689 * don't adjust their read size to match our record 2690 * size, that's just life. Anyway, the typical usage 2691 * would be to issue, e.g., 64KB reads and occasionally 2692 * have to do deal with 512 byte or 1KB intermediate 2693 * records. |
2694 * 2695 * That said, though, we now support setting the 2696 * SILI bit on reads, and we set the blocksize to 4 2697 * bytes when we do that. This gives us 2698 * compatibility with software that wants this, 2699 * although the only real difference between that 2700 * and not setting the SILI bit on reads is that we 2701 * won't get a check condition on reads where our 2702 * request size is larger than the block on tape. 2703 * That probably only makes a real difference in 2704 * non-packetized SCSI, where you have to go back 2705 * to the drive to request sense and thus incur 2706 * more latency. |
|
1816 */ 1817 softc->dsreg = (bp->bio_cmd == BIO_READ)? 1818 MTIO_DSREG_RD : MTIO_DSREG_WR; 1819 scsi_sa_read_write(&start_ccb->csio, 0, sadone, 1820 MSG_SIMPLE_Q_TAG, (bp->bio_cmd == BIO_READ ? 1821 SCSI_RW_READ : SCSI_RW_WRITE) | 1822 ((bp->bio_flags & BIO_UNMAPPED) != 0 ? | 2707 */ 2708 softc->dsreg = (bp->bio_cmd == BIO_READ)? 2709 MTIO_DSREG_RD : MTIO_DSREG_WR; 2710 scsi_sa_read_write(&start_ccb->csio, 0, sadone, 2711 MSG_SIMPLE_Q_TAG, (bp->bio_cmd == BIO_READ ? 2712 SCSI_RW_READ : SCSI_RW_WRITE) | 2713 ((bp->bio_flags & BIO_UNMAPPED) != 0 ? |
1823 SCSI_RW_BIO : 0), FALSE, | 2714 SCSI_RW_BIO : 0), softc->sili, |
1824 (softc->flags & SA_FLAG_FIXED) != 0, length, 1825 (bp->bio_flags & BIO_UNMAPPED) != 0 ? (void *)bp : 1826 bp->bio_data, bp->bio_bcount, SSD_FULL_SIZE, 1827 IO_TIMEOUT); 1828 start_ccb->ccb_h.ccb_pflags &= ~SA_POSITION_UPDATED; 1829 start_ccb->ccb_h.ccb_bp = bp; 1830 bp = bioq_first(&softc->bio_queue); 1831 xpt_action(start_ccb); --- 169 unchanged lines hidden (view full) --- 2001 struct scsi_read_block_limits_data *rblim = NULL; 2002 int comp_enabled, comp_supported; 2003 u_int8_t write_protect, guessing = 0; 2004 2005 /* 2006 * Clear out old state. 2007 */ 2008 softc->flags &= ~(SA_FLAG_TAPE_WP|SA_FLAG_TAPE_WRITTEN| | 2715 (softc->flags & SA_FLAG_FIXED) != 0, length, 2716 (bp->bio_flags & BIO_UNMAPPED) != 0 ? (void *)bp : 2717 bp->bio_data, bp->bio_bcount, SSD_FULL_SIZE, 2718 IO_TIMEOUT); 2719 start_ccb->ccb_h.ccb_pflags &= ~SA_POSITION_UPDATED; 2720 start_ccb->ccb_h.ccb_bp = bp; 2721 bp = bioq_first(&softc->bio_queue); 2722 xpt_action(start_ccb); --- 169 unchanged lines hidden (view full) --- 2892 struct scsi_read_block_limits_data *rblim = NULL; 2893 int comp_enabled, comp_supported; 2894 u_int8_t write_protect, guessing = 0; 2895 2896 /* 2897 * Clear out old state. 2898 */ 2899 softc->flags &= ~(SA_FLAG_TAPE_WP|SA_FLAG_TAPE_WRITTEN| |
2009 SA_FLAG_ERR_PENDING|SA_FLAG_COMP_ENABLED| 2010 SA_FLAG_COMP_SUPP|SA_FLAG_COMP_UNSUPP); | 2900 SA_FLAG_ERR_PENDING|SA_FLAG_COMPRESSION); |
2011 softc->filemarks = 0; 2012 2013 /* 2014 * *Very* first off, make sure we're loaded to BOT. 2015 */ 2016 scsi_load_unload(&ccb->csio, 2, sadone, MSG_SIMPLE_Q_TAG, FALSE, 2017 FALSE, FALSE, 1, SSD_FULL_SIZE, REWIND_TIMEOUT); 2018 error = cam_periph_runccb(ccb, saerror, 0, SF_NO_PRINT, --- 92 unchanged lines hidden (view full) --- 2111 */ 2112 error = sagetparams(periph, SA_PARAM_ALL, 2113 &softc->media_blksize, 2114 &softc->media_density, 2115 &softc->media_numblks, 2116 &softc->buffer_mode, &write_protect, 2117 &softc->speed, &comp_supported, 2118 &comp_enabled, &softc->comp_algorithm, | 2901 softc->filemarks = 0; 2902 2903 /* 2904 * *Very* first off, make sure we're loaded to BOT. 2905 */ 2906 scsi_load_unload(&ccb->csio, 2, sadone, MSG_SIMPLE_Q_TAG, FALSE, 2907 FALSE, FALSE, 1, SSD_FULL_SIZE, REWIND_TIMEOUT); 2908 error = cam_periph_runccb(ccb, saerror, 0, SF_NO_PRINT, --- 92 unchanged lines hidden (view full) --- 3001 */ 3002 error = sagetparams(periph, SA_PARAM_ALL, 3003 &softc->media_blksize, 3004 &softc->media_density, 3005 &softc->media_numblks, 3006 &softc->buffer_mode, &write_protect, 3007 &softc->speed, &comp_supported, 3008 &comp_enabled, &softc->comp_algorithm, |
2119 NULL); | 3009 NULL, NULL, 0, 0); |
2120 2121 if (error != 0) { 2122 /* 2123 * We could work a little harder here. We could 2124 * adjust our attempts to get information. It 2125 * might be an ancient tape drive. If someone 2126 * nudges us, we'll do that. 2127 */ --- 230 unchanged lines hidden (view full) --- 2358exit: 2359 if (rblim != NULL) 2360 free(rblim, M_SCSISA); 2361 2362 if (error != 0) { 2363 softc->dsreg = MTIO_DSREG_NIL; 2364 } else { 2365 softc->fileno = softc->blkno = 0; | 3010 3011 if (error != 0) { 3012 /* 3013 * We could work a little harder here. We could 3014 * adjust our attempts to get information. It 3015 * might be an ancient tape drive. If someone 3016 * nudges us, we'll do that. 3017 */ --- 230 unchanged lines hidden (view full) --- 3248exit: 3249 if (rblim != NULL) 3250 free(rblim, M_SCSISA); 3251 3252 if (error != 0) { 3253 softc->dsreg = MTIO_DSREG_NIL; 3254 } else { 3255 softc->fileno = softc->blkno = 0; |
3256 softc->rep_fileno = softc->rep_blkno = -1; 3257 softc->partition = 0; |
|
2366 softc->dsreg = MTIO_DSREG_REST; 2367 } 2368#ifdef SA_1FM_AT_EOD 2369 if ((softc->quirks & SA_QUIRK_2FM) == 0) 2370 softc->quirks |= SA_QUIRK_1FM; 2371#else 2372 if ((softc->quirks & SA_QUIRK_1FM) == 0) 2373 softc->quirks |= SA_QUIRK_2FM; --- 43 unchanged lines hidden (view full) --- 2417sacheckeod(struct cam_periph *periph) 2418{ 2419 int error; 2420 int markswanted; 2421 2422 markswanted = samarkswanted(periph); 2423 2424 if (markswanted > 0) { | 3258 softc->dsreg = MTIO_DSREG_REST; 3259 } 3260#ifdef SA_1FM_AT_EOD 3261 if ((softc->quirks & SA_QUIRK_2FM) == 0) 3262 softc->quirks |= SA_QUIRK_1FM; 3263#else 3264 if ((softc->quirks & SA_QUIRK_1FM) == 0) 3265 softc->quirks |= SA_QUIRK_2FM; --- 43 unchanged lines hidden (view full) --- 3309sacheckeod(struct cam_periph *periph) 3310{ 3311 int error; 3312 int markswanted; 3313 3314 markswanted = samarkswanted(periph); 3315 3316 if (markswanted > 0) { |
2425 error = sawritefilemarks(periph, markswanted, FALSE); | 3317 error = sawritefilemarks(periph, markswanted, FALSE, FALSE); |
2426 } else { 2427 error = 0; 2428 } 2429 return (error); 2430} 2431 2432static int 2433saerror(union ccb *ccb, u_int32_t cflgs, u_int32_t sflgs) --- 203 unchanged lines hidden (view full) --- 2637 return (error); 2638} 2639 2640static int 2641sagetparams(struct cam_periph *periph, sa_params params_to_get, 2642 u_int32_t *blocksize, u_int8_t *density, u_int32_t *numblocks, 2643 int *buff_mode, u_int8_t *write_protect, u_int8_t *speed, 2644 int *comp_supported, int *comp_enabled, u_int32_t *comp_algorithm, | 3318 } else { 3319 error = 0; 3320 } 3321 return (error); 3322} 3323 3324static int 3325saerror(union ccb *ccb, u_int32_t cflgs, u_int32_t sflgs) --- 203 unchanged lines hidden (view full) --- 3529 return (error); 3530} 3531 3532static int 3533sagetparams(struct cam_periph *periph, sa_params params_to_get, 3534 u_int32_t *blocksize, u_int8_t *density, u_int32_t *numblocks, 3535 int *buff_mode, u_int8_t *write_protect, u_int8_t *speed, 3536 int *comp_supported, int *comp_enabled, u_int32_t *comp_algorithm, |
2645 sa_comp_t *tcs) | 3537 sa_comp_t *tcs, struct scsi_control_data_prot_subpage *prot_page, 3538 int dp_size, int prot_changeable) |
2646{ 2647 union ccb *ccb; 2648 void *mode_buffer; 2649 struct scsi_mode_header_6 *mode_hdr; 2650 struct scsi_mode_blk_desc *mode_blk; 2651 int mode_buffer_len; 2652 struct sa_softc *softc; 2653 u_int8_t cpage; --- 141 unchanged lines hidden (view full) --- 2795 *comp_enabled = 2796 (cp->sel_comp_alg != SA_COMP_NONE)? TRUE : FALSE; 2797 *comp_algorithm = cp->sel_comp_alg; 2798 } 2799 if (tcs != NULL) 2800 bcopy(ntcs, tcs, sizeof (sa_comp_t)); 2801 } 2802 | 3539{ 3540 union ccb *ccb; 3541 void *mode_buffer; 3542 struct scsi_mode_header_6 *mode_hdr; 3543 struct scsi_mode_blk_desc *mode_blk; 3544 int mode_buffer_len; 3545 struct sa_softc *softc; 3546 u_int8_t cpage; --- 141 unchanged lines hidden (view full) --- 3688 *comp_enabled = 3689 (cp->sel_comp_alg != SA_COMP_NONE)? TRUE : FALSE; 3690 *comp_algorithm = cp->sel_comp_alg; 3691 } 3692 if (tcs != NULL) 3693 bcopy(ntcs, tcs, sizeof (sa_comp_t)); 3694 } 3695 |
3696 if ((params_to_get & SA_PARAM_DENSITY_EXT) 3697 && (softc->scsi_rev >= SCSI_REV_SPC)) { 3698 int i; 3699 3700 for (i = 0; i < SA_DENSITY_TYPES; i++) { 3701 scsi_report_density_support(&ccb->csio, 3702 /*retries*/ 1, 3703 /*cbfcnp*/ sadone, 3704 /*tag_action*/ MSG_SIMPLE_Q_TAG, 3705 /*media*/ softc->density_type_bits[i] & SRDS_MEDIA, 3706 /*medium_type*/ softc->density_type_bits[i] & 3707 SRDS_MEDIUM_TYPE, 3708 /*data_ptr*/ softc->density_info[i], 3709 /*length*/ sizeof(softc->density_info[i]), 3710 /*sense_len*/ SSD_FULL_SIZE, 3711 /*timeout*/ REP_DENSITY_TIMEOUT); 3712 error = cam_periph_runccb(ccb, saerror, 0, SF_NO_PRINT, 3713 softc->device_stats); 3714 status = ccb->ccb_h.status & CAM_STATUS_MASK; 3715 3716 /* 3717 * Some tape drives won't support this command at 3718 * all, but hopefully we'll minimize that with the 3719 * check for SPC or greater support above. If they 3720 * don't support the default report (neither the 3721 * MEDIA or MEDIUM_TYPE bits set), then there is 3722 * really no point in continuing on to look for 3723 * other reports. 3724 */ 3725 if ((error != 0) 3726 || (status != CAM_REQ_CMP)) { 3727 error = 0; 3728 softc->density_info_valid[i] = 0; 3729 if (softc->density_type_bits[i] == 0) 3730 break; 3731 else 3732 continue; 3733 } 3734 softc->density_info_valid[i] = ccb->csio.dxfer_len - 3735 ccb->csio.resid; 3736 } 3737 } 3738 3739 /* 3740 * Get logical block protection parameters if the drive supports it. 3741 */ 3742 if ((params_to_get & SA_PARAM_LBP) 3743 && (softc->flags & SA_FLAG_PROTECT_SUPP)) { 3744 struct scsi_mode_header_10 *mode10_hdr; 3745 struct scsi_control_data_prot_subpage *dp_page; 3746 struct scsi_mode_sense_10 *cdb; 3747 struct sa_prot_state *prot; 3748 int dp_len, returned_len; 3749 3750 if (dp_size == 0) 3751 dp_size = sizeof(*dp_page); 3752 3753 dp_len = sizeof(*mode10_hdr) + dp_size; 3754 mode10_hdr = malloc(dp_len, M_SCSISA, M_NOWAIT | M_ZERO); 3755 if (mode10_hdr == NULL) { 3756 error = ENOMEM; 3757 goto sagetparamsexit; 3758 } 3759 3760 scsi_mode_sense_len(&ccb->csio, 3761 /*retries*/ 5, 3762 /*cbfcnp*/ sadone, 3763 /*tag_action*/ MSG_SIMPLE_Q_TAG, 3764 /*dbd*/ TRUE, 3765 /*page_code*/ (prot_changeable == 0) ? 3766 SMS_PAGE_CTRL_CURRENT : 3767 SMS_PAGE_CTRL_CHANGEABLE, 3768 /*page*/ SMS_CONTROL_MODE_PAGE, 3769 /*param_buf*/ (uint8_t *)mode10_hdr, 3770 /*param_len*/ dp_len, 3771 /*minimum_cmd_size*/ 10, 3772 /*sense_len*/ SSD_FULL_SIZE, 3773 /*timeout*/ SCSIOP_TIMEOUT); 3774 /* 3775 * XXX KDM we need to be able to set the subpage in the 3776 * fill function. 3777 */ 3778 cdb = (struct scsi_mode_sense_10 *)ccb->csio.cdb_io.cdb_bytes; 3779 cdb->subpage = SA_CTRL_DP_SUBPAGE_CODE; 3780 3781 error = cam_periph_runccb(ccb, saerror, 0, SF_NO_PRINT, 3782 softc->device_stats); 3783 if (error != 0) { 3784 free(mode10_hdr, M_SCSISA); 3785 goto sagetparamsexit; 3786 } 3787 3788 status = ccb->ccb_h.status & CAM_STATUS_MASK; 3789 if (status != CAM_REQ_CMP) { 3790 error = EINVAL; 3791 free(mode10_hdr, M_SCSISA); 3792 goto sagetparamsexit; 3793 } 3794 3795 /* 3796 * The returned data length at least has to be long enough 3797 * for us to look at length in the mode page header. 3798 */ 3799 returned_len = ccb->csio.dxfer_len - ccb->csio.resid; 3800 if (returned_len < sizeof(mode10_hdr->data_length)) { 3801 error = EINVAL; 3802 free(mode10_hdr, M_SCSISA); 3803 goto sagetparamsexit; 3804 } 3805 3806 returned_len = min(returned_len, 3807 sizeof(mode10_hdr->data_length) + 3808 scsi_2btoul(mode10_hdr->data_length)); 3809 3810 dp_page = (struct scsi_control_data_prot_subpage *) 3811 &mode10_hdr[1]; 3812 3813 /* 3814 * We also have to have enough data to include the prot_bits 3815 * in the subpage. 3816 */ 3817 if (returned_len < (sizeof(*mode10_hdr) + 3818 __offsetof(struct scsi_control_data_prot_subpage, prot_bits) 3819 + sizeof(dp_page->prot_bits))) { 3820 error = EINVAL; 3821 free(mode10_hdr, M_SCSISA); 3822 goto sagetparamsexit; 3823 } 3824 3825 prot = &softc->prot_info.cur_prot_state; 3826 prot->prot_method = dp_page->prot_method; 3827 prot->pi_length = dp_page->pi_length & 3828 SA_CTRL_DP_PI_LENGTH_MASK; 3829 prot->lbp_w = (dp_page->prot_bits & SA_CTRL_DP_LBP_W) ? 1 :0; 3830 prot->lbp_r = (dp_page->prot_bits & SA_CTRL_DP_LBP_R) ? 1 :0; 3831 prot->rbdp = (dp_page->prot_bits & SA_CTRL_DP_RBDP) ? 1 :0; 3832 prot->initialized = 1; 3833 3834 if (prot_page != NULL) 3835 bcopy(dp_page, prot_page, min(sizeof(*prot_page), 3836 sizeof(*dp_page))); 3837 3838 free(mode10_hdr, M_SCSISA); 3839 } 3840 |
|
2803 if (CAM_DEBUGGED(periph->path, CAM_DEBUG_INFO)) { 2804 int idx; 2805 char *xyz = mode_buffer; 2806 xpt_print_path(periph->path); 2807 printf("Mode Sense Data="); 2808 for (idx = 0; idx < mode_buffer_len; idx++) 2809 printf(" 0x%02x", xyz[idx] & 0xff); 2810 printf("\n"); 2811 } 2812 2813sagetparamsexit: 2814 2815 xpt_release_ccb(ccb); 2816 free(mode_buffer, M_SCSISA); 2817 return (error); 2818} 2819 2820/* | 3841 if (CAM_DEBUGGED(periph->path, CAM_DEBUG_INFO)) { 3842 int idx; 3843 char *xyz = mode_buffer; 3844 xpt_print_path(periph->path); 3845 printf("Mode Sense Data="); 3846 for (idx = 0; idx < mode_buffer_len; idx++) 3847 printf(" 0x%02x", xyz[idx] & 0xff); 3848 printf("\n"); 3849 } 3850 3851sagetparamsexit: 3852 3853 xpt_release_ccb(ccb); 3854 free(mode_buffer, M_SCSISA); 3855 return (error); 3856} 3857 3858/* |
3859 * Set protection information to the pending protection information stored 3860 * in the softc. 3861 */ 3862static int 3863sasetprot(struct cam_periph *periph, struct sa_prot_state *new_prot) 3864{ 3865 struct sa_softc *softc; 3866 struct scsi_control_data_prot_subpage *dp_page, *dp_changeable; 3867 struct scsi_mode_header_10 *mode10_hdr, *mode10_changeable; 3868 union ccb *ccb; 3869 uint8_t current_speed; 3870 size_t dp_size, dp_page_length; 3871 int dp_len, buff_mode; 3872 int error; 3873 3874 softc = (struct sa_softc *)periph->softc; 3875 mode10_hdr = NULL; 3876 mode10_changeable = NULL; 3877 ccb = NULL; 3878 3879 /* 3880 * Start off with the size set to the actual length of the page 3881 * that we have defined. 3882 */ 3883 dp_size = sizeof(*dp_changeable); 3884 dp_page_length = dp_size - 3885 __offsetof(struct scsi_control_data_prot_subpage, prot_method); 3886 3887retry_length: 3888 3889 dp_len = sizeof(*mode10_changeable) + dp_size; 3890 mode10_changeable = malloc(dp_len, M_SCSISA, M_NOWAIT | M_ZERO); 3891 if (mode10_changeable == NULL) { 3892 error = ENOMEM; 3893 goto bailout; 3894 } 3895 3896 dp_changeable = 3897 (struct scsi_control_data_prot_subpage *)&mode10_changeable[1]; 3898 3899 /* 3900 * First get the data protection page changeable parameters mask. 3901 * We need to know which parameters the drive supports changing. 3902 * We also need to know what the drive claims that its page length 3903 * is. The reason is that IBM drives in particular are very picky 3904 * about the page length. They want it (the length set in the 3905 * page structure itself) to be 28 bytes, and they want the 3906 * parameter list length specified in the mode select header to be 3907 * 40 bytes. So, to work with IBM drives as well as any other tape 3908 * drive, find out what the drive claims the page length is, and 3909 * make sure that we match that. 3910 */ 3911 error = sagetparams(periph, SA_PARAM_SPEED | SA_PARAM_LBP, 3912 NULL, NULL, NULL, &buff_mode, NULL, ¤t_speed, NULL, NULL, 3913 NULL, NULL, dp_changeable, dp_size, /*prot_changeable*/ 1); 3914 if (error != 0) 3915 goto bailout; 3916 3917 if (scsi_2btoul(dp_changeable->length) > dp_page_length) { 3918 dp_page_length = scsi_2btoul(dp_changeable->length); 3919 dp_size = dp_page_length + 3920 __offsetof(struct scsi_control_data_prot_subpage, 3921 prot_method); 3922 free(mode10_changeable, M_SCSISA); 3923 mode10_changeable = NULL; 3924 goto retry_length; 3925 } 3926 3927 mode10_hdr = malloc(dp_len, M_SCSISA, M_NOWAIT | M_ZERO); 3928 if (mode10_hdr == NULL) { 3929 error = ENOMEM; 3930 goto bailout; 3931 } 3932 3933 dp_page = (struct scsi_control_data_prot_subpage *)&mode10_hdr[1]; 3934 3935 /* 3936 * Now grab the actual current settings in the page. 3937 */ 3938 error = sagetparams(periph, SA_PARAM_SPEED | SA_PARAM_LBP, 3939 NULL, NULL, NULL, &buff_mode, NULL, ¤t_speed, NULL, NULL, 3940 NULL, NULL, dp_page, dp_size, /*prot_changeable*/ 0); 3941 if (error != 0) 3942 goto bailout; 3943 3944 /* These two fields need to be 0 for MODE SELECT */ 3945 scsi_ulto2b(0, mode10_hdr->data_length); 3946 mode10_hdr->medium_type = 0; 3947 /* We are not including a block descriptor */ 3948 scsi_ulto2b(0, mode10_hdr->blk_desc_len); 3949 3950 mode10_hdr->dev_spec = current_speed; 3951 /* if set, set single-initiator buffering mode */ 3952 if (softc->buffer_mode == SMH_SA_BUF_MODE_SIBUF) { 3953 mode10_hdr->dev_spec |= SMH_SA_BUF_MODE_SIBUF; 3954 } 3955 3956 /* 3957 * For each field, make sure that the drive allows changing it 3958 * before bringing in the user's setting. 3959 */ 3960 if (dp_changeable->prot_method != 0) 3961 dp_page->prot_method = new_prot->prot_method; 3962 3963 if (dp_changeable->pi_length & SA_CTRL_DP_PI_LENGTH_MASK) { 3964 dp_page->pi_length &= ~SA_CTRL_DP_PI_LENGTH_MASK; 3965 dp_page->pi_length |= (new_prot->pi_length & 3966 SA_CTRL_DP_PI_LENGTH_MASK); 3967 } 3968 if (dp_changeable->prot_bits & SA_CTRL_DP_LBP_W) { 3969 if (new_prot->lbp_w) 3970 dp_page->prot_bits |= SA_CTRL_DP_LBP_W; 3971 else 3972 dp_page->prot_bits &= ~SA_CTRL_DP_LBP_W; 3973 } 3974 3975 if (dp_changeable->prot_bits & SA_CTRL_DP_LBP_R) { 3976 if (new_prot->lbp_r) 3977 dp_page->prot_bits |= SA_CTRL_DP_LBP_R; 3978 else 3979 dp_page->prot_bits &= ~SA_CTRL_DP_LBP_R; 3980 } 3981 3982 if (dp_changeable->prot_bits & SA_CTRL_DP_RBDP) { 3983 if (new_prot->rbdp) 3984 dp_page->prot_bits |= SA_CTRL_DP_RBDP; 3985 else 3986 dp_page->prot_bits &= ~SA_CTRL_DP_RBDP; 3987 } 3988 3989 ccb = cam_periph_getccb(periph, 1); 3990 3991 scsi_mode_select_len(&ccb->csio, 3992 /*retries*/ 5, 3993 /*cbfcnp*/ sadone, 3994 /*tag_action*/ MSG_SIMPLE_Q_TAG, 3995 /*scsi_page_fmt*/ TRUE, 3996 /*save_pages*/ FALSE, 3997 /*param_buf*/ (uint8_t *)mode10_hdr, 3998 /*param_len*/ dp_len, 3999 /*minimum_cmd_size*/ 10, 4000 /*sense_len*/ SSD_FULL_SIZE, 4001 /*timeout*/ SCSIOP_TIMEOUT); 4002 4003 error = cam_periph_runccb(ccb, saerror, 0, 0, softc->device_stats); 4004 if (error != 0) 4005 goto bailout; 4006 4007 if ((ccb->ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) { 4008 error = EINVAL; 4009 goto bailout; 4010 } 4011 4012 /* 4013 * The operation was successful. We could just copy the settings 4014 * the user requested, but just in case the drive ignored some of 4015 * our settings, let's ask for status again. 4016 */ 4017 error = sagetparams(periph, SA_PARAM_SPEED | SA_PARAM_LBP, 4018 NULL, NULL, NULL, &buff_mode, NULL, ¤t_speed, NULL, NULL, 4019 NULL, NULL, dp_page, dp_size, 0); 4020 4021bailout: 4022 if (ccb != NULL) 4023 xpt_release_ccb(ccb); 4024 free(mode10_hdr, M_SCSISA); 4025 free(mode10_changeable, M_SCSISA); 4026 return (error); 4027} 4028 4029/* |
|
2821 * The purpose of this function is to set one of four different parameters 2822 * for a tape drive: 2823 * - blocksize 2824 * - density 2825 * - compression / compression algorithm 2826 * - buffering mode 2827 * 2828 * The assumption is that this will be called from saioctl(), and therefore --- 35 unchanged lines hidden (view full) --- 2864 * write protection, we won't try to get the current value. We 2865 * always want to get the blocksize, so we can set it back to the 2866 * proper value. 2867 */ 2868 error = sagetparams(periph, 2869 params_to_set | SA_PARAM_BLOCKSIZE | SA_PARAM_SPEED, 2870 ¤t_blocksize, ¤t_density, NULL, &buff_mode, NULL, 2871 ¤t_speed, &comp_supported, &comp_enabled, | 4030 * The purpose of this function is to set one of four different parameters 4031 * for a tape drive: 4032 * - blocksize 4033 * - density 4034 * - compression / compression algorithm 4035 * - buffering mode 4036 * 4037 * The assumption is that this will be called from saioctl(), and therefore --- 35 unchanged lines hidden (view full) --- 4073 * write protection, we won't try to get the current value. We 4074 * always want to get the blocksize, so we can set it back to the 4075 * proper value. 4076 */ 4077 error = sagetparams(periph, 4078 params_to_set | SA_PARAM_BLOCKSIZE | SA_PARAM_SPEED, 4079 ¤t_blocksize, ¤t_density, NULL, &buff_mode, NULL, 4080 ¤t_speed, &comp_supported, &comp_enabled, |
2872 ¤t_calg, ccomp); | 4081 ¤t_calg, ccomp, NULL, 0, 0); |
2873 2874 if (error != 0) { 2875 free(ccomp, M_SCSISA); 2876 return (error); 2877 } 2878 2879 mode_buffer_len = sizeof(*mode_hdr) + sizeof(*mode_blk); 2880 if (params_to_set & SA_PARAM_COMPRESSION) --- 262 unchanged lines hidden (view full) --- 3143 softc->comp_algorithm = calg; 3144 } 3145 } 3146 3147 free(mode_buffer, M_SCSISA); 3148 return (error); 3149} 3150 | 4082 4083 if (error != 0) { 4084 free(ccomp, M_SCSISA); 4085 return (error); 4086 } 4087 4088 mode_buffer_len = sizeof(*mode_hdr) + sizeof(*mode_blk); 4089 if (params_to_set & SA_PARAM_COMPRESSION) --- 262 unchanged lines hidden (view full) --- 4352 softc->comp_algorithm = calg; 4353 } 4354 } 4355 4356 free(mode_buffer, M_SCSISA); 4357 return (error); 4358} 4359 |
4360static int 4361saextget(struct cdev *dev, struct cam_periph *periph, struct sbuf *sb, 4362 struct mtextget *g) 4363{ 4364 int indent, error; 4365 char tmpstr[80]; 4366 struct sa_softc *softc; 4367 int tmpint; 4368 uint32_t maxio_tmp; 4369 struct ccb_getdev cgd; 4370 4371 softc = (struct sa_softc *)periph->softc; 4372 4373 error = 0; 4374 4375 error = sagetparams_common(dev, periph); 4376 if (error) 4377 goto extget_bailout; 4378 if (!SA_IS_CTRL(dev) && !softc->open_pending_mount) 4379 sagetpos(periph); 4380 4381 indent = 0; 4382 SASBADDNODE(sb, indent, mtextget); 4383 /* 4384 * Basic CAM peripheral information. 4385 */ 4386 SASBADDVARSTR(sb, indent, periph->periph_name, %s, periph_name, 4387 strlen(periph->periph_name) + 1); 4388 SASBADDUINT(sb, indent, periph->unit_number, %u, unit_number); 4389 xpt_setup_ccb(&cgd.ccb_h, 4390 periph->path, 4391 CAM_PRIORITY_NORMAL); 4392 cgd.ccb_h.func_code = XPT_GDEV_TYPE; 4393 xpt_action((union ccb *)&cgd); 4394 if ((cgd.ccb_h.status & CAM_STATUS_MASK) != CAM_REQ_CMP) { 4395 g->status = MT_EXT_GET_ERROR; 4396 snprintf(g->error_str, sizeof(g->error_str), 4397 "Error %#x returned for XPT_GDEV_TYPE CCB", 4398 cgd.ccb_h.status); 4399 goto extget_bailout; 4400 } 4401 4402 cam_strvis(tmpstr, cgd.inq_data.vendor, 4403 sizeof(cgd.inq_data.vendor), sizeof(tmpstr)); 4404 SASBADDVARSTRDESC(sb, indent, tmpstr, %s, vendor, 4405 sizeof(cgd.inq_data.vendor) + 1, "SCSI Vendor ID"); 4406 4407 cam_strvis(tmpstr, cgd.inq_data.product, 4408 sizeof(cgd.inq_data.product), sizeof(tmpstr)); 4409 SASBADDVARSTRDESC(sb, indent, tmpstr, %s, product, 4410 sizeof(cgd.inq_data.product) + 1, "SCSI Product ID"); 4411 4412 cam_strvis(tmpstr, cgd.inq_data.revision, 4413 sizeof(cgd.inq_data.revision), sizeof(tmpstr)); 4414 SASBADDVARSTRDESC(sb, indent, tmpstr, %s, revision, 4415 sizeof(cgd.inq_data.revision) + 1, "SCSI Revision"); 4416 4417 if (cgd.serial_num_len > 0) { 4418 char *tmpstr2; 4419 size_t ts2_len; 4420 int ts2_malloc; 4421 4422 ts2_len = 0; 4423 4424 if (cgd.serial_num_len > sizeof(tmpstr)) { 4425 ts2_len = cgd.serial_num_len + 1; 4426 ts2_malloc = 1; 4427 tmpstr2 = malloc(ts2_len, M_SCSISA, M_WAITOK | M_ZERO); 4428 } else { 4429 ts2_len = sizeof(tmpstr); 4430 ts2_malloc = 0; 4431 tmpstr2 = tmpstr; 4432 } 4433 4434 cam_strvis(tmpstr2, cgd.serial_num, cgd.serial_num_len, 4435 ts2_len); 4436 4437 SASBADDVARSTRDESC(sb, indent, tmpstr2, %s, serial_num, 4438 (ssize_t)cgd.serial_num_len + 1, "Serial Number"); 4439 if (ts2_malloc != 0) 4440 free(tmpstr2, M_SCSISA); 4441 } else { 4442 /* 4443 * We return a serial_num element in any case, but it will 4444 * be empty if the device has no serial number. 4445 */ 4446 tmpstr[0] = '\0'; 4447 SASBADDVARSTRDESC(sb, indent, tmpstr, %s, serial_num, 4448 (ssize_t)0, "Serial Number"); 4449 } 4450 4451 SASBADDUINTDESC(sb, indent, softc->maxio, %u, maxio, 4452 "Maximum I/O size allowed by driver and controller"); 4453 4454 SASBADDUINTDESC(sb, indent, softc->cpi_maxio, %u, cpi_maxio, 4455 "Maximum I/O size reported by controller"); 4456 4457 SASBADDUINTDESC(sb, indent, softc->max_blk, %u, max_blk, 4458 "Maximum block size supported by tape drive and media"); 4459 4460 SASBADDUINTDESC(sb, indent, softc->min_blk, %u, min_blk, 4461 "Minimum block size supported by tape drive and media"); 4462 4463 SASBADDUINTDESC(sb, indent, softc->blk_gran, %u, blk_gran, 4464 "Block granularity supported by tape drive and media"); 4465 4466 maxio_tmp = min(softc->max_blk, softc->maxio); 4467 4468 SASBADDUINTDESC(sb, indent, maxio_tmp, %u, max_effective_iosize, 4469 "Maximum possible I/O size"); 4470 4471 SASBADDINTDESC(sb, indent, softc->flags & SA_FLAG_FIXED ? 1 : 0, %d, 4472 fixed_mode, "Set to 1 for fixed block mode, 0 for variable block"); 4473 4474 /* 4475 * XXX KDM include SIM, bus, target, LUN? 4476 */ 4477 if (softc->flags & SA_FLAG_COMP_UNSUPP) 4478 tmpint = 0; 4479 else 4480 tmpint = 1; 4481 SASBADDINTDESC(sb, indent, tmpint, %d, compression_supported, 4482 "Set to 1 if compression is supported, 0 if not"); 4483 if (softc->flags & SA_FLAG_COMP_ENABLED) 4484 tmpint = 1; 4485 else 4486 tmpint = 0; 4487 SASBADDINTDESC(sb, indent, tmpint, %d, compression_enabled, 4488 "Set to 1 if compression is enabled, 0 if not"); 4489 SASBADDUINTDESC(sb, indent, softc->comp_algorithm, %u, 4490 compression_algorithm, "Numeric compression algorithm"); 4491 4492 safillprot(softc, &indent, sb); 4493 4494 SASBADDUINTDESC(sb, indent, softc->media_blksize, %u, 4495 media_blocksize, "Block size reported by drive or set by user"); 4496 SASBADDINTDESC(sb, indent, (intmax_t)softc->fileno, %jd, 4497 calculated_fileno, "Calculated file number, -1 if unknown"); 4498 SASBADDINTDESC(sb, indent, (intmax_t)softc->blkno, %jd, 4499 calculated_rel_blkno, "Calculated block number relative to file, " 4500 "set to -1 if unknown"); 4501 SASBADDINTDESC(sb, indent, (intmax_t)softc->rep_fileno, %jd, 4502 reported_fileno, "File number reported by drive, -1 if unknown"); 4503 SASBADDINTDESC(sb, indent, (intmax_t)softc->rep_blkno, %jd, 4504 reported_blkno, "Block number relative to BOP/BOT reported by " 4505 "drive, -1 if unknown"); 4506 SASBADDINTDESC(sb, indent, (intmax_t)softc->partition, %jd, 4507 partition, "Current partition number, 0 is the default"); 4508 SASBADDINTDESC(sb, indent, softc->bop, %d, bop, 4509 "Set to 1 if drive is at the beginning of partition/tape, 0 if " 4510 "not, -1 if unknown"); 4511 SASBADDINTDESC(sb, indent, softc->eop, %d, eop, 4512 "Set to 1 if drive is past early warning, 0 if not, -1 if unknown"); 4513 SASBADDINTDESC(sb, indent, softc->bpew, %d, bpew, 4514 "Set to 1 if drive is past programmable early warning, 0 if not, " 4515 "-1 if unknown"); 4516 SASBADDINTDESC(sb, indent, (intmax_t)softc->last_io_resid, %jd, 4517 residual, "Residual for the last I/O"); 4518 /* 4519 * XXX KDM should we send a string with the current driver 4520 * status already decoded instead of a numeric value? 4521 */ 4522 SASBADDINTDESC(sb, indent, softc->dsreg, %d, dsreg, 4523 "Current state of the driver"); 4524 4525 safilldensitysb(softc, &indent, sb); 4526 4527 SASBENDNODE(sb, indent, mtextget); 4528 4529extget_bailout: 4530 4531 return (error); 4532} 4533 4534static int 4535saparamget(struct sa_softc *softc, struct sbuf *sb) 4536{ 4537 int indent; 4538 4539 indent = 0; 4540 SASBADDNODE(sb, indent, mtparamget); 4541 SASBADDINTDESC(sb, indent, softc->sili, %d, sili, 4542 "Suppress an error on underlength variable reads"); 4543 SASBADDINTDESC(sb, indent, softc->eot_warn, %d, eot_warn, 4544 "Return an error to warn that end of tape is approaching"); 4545 safillprot(softc, &indent, sb); 4546 SASBENDNODE(sb, indent, mtparamget); 4547 4548 return (0); 4549} 4550 |
|
3151static void 3152saprevent(struct cam_periph *periph, int action) 3153{ 3154 struct sa_softc *softc; 3155 union ccb *ccb; 3156 int error, sf; 3157 3158 softc = (struct sa_softc *)periph->softc; --- 43 unchanged lines hidden (view full) --- 3202 scsi_rewind(&ccb->csio, 2, sadone, MSG_SIMPLE_Q_TAG, FALSE, 3203 SSD_FULL_SIZE, REWIND_TIMEOUT); 3204 3205 softc->dsreg = MTIO_DSREG_REW; 3206 error = cam_periph_runccb(ccb, saerror, 0, 0, softc->device_stats); 3207 softc->dsreg = MTIO_DSREG_REST; 3208 3209 xpt_release_ccb(ccb); | 4551static void 4552saprevent(struct cam_periph *periph, int action) 4553{ 4554 struct sa_softc *softc; 4555 union ccb *ccb; 4556 int error, sf; 4557 4558 softc = (struct sa_softc *)periph->softc; --- 43 unchanged lines hidden (view full) --- 4602 scsi_rewind(&ccb->csio, 2, sadone, MSG_SIMPLE_Q_TAG, FALSE, 4603 SSD_FULL_SIZE, REWIND_TIMEOUT); 4604 4605 softc->dsreg = MTIO_DSREG_REW; 4606 error = cam_periph_runccb(ccb, saerror, 0, 0, softc->device_stats); 4607 softc->dsreg = MTIO_DSREG_REST; 4608 4609 xpt_release_ccb(ccb); |
3210 if (error == 0) 3211 softc->fileno = softc->blkno = (daddr_t) 0; 3212 else | 4610 if (error == 0) { 4611 softc->partition = softc->fileno = softc->blkno = (daddr_t) 0; 4612 softc->rep_fileno = softc->rep_blkno = (daddr_t) 0; 4613 } else { |
3213 softc->fileno = softc->blkno = (daddr_t) -1; | 4614 softc->fileno = softc->blkno = (daddr_t) -1; |
4615 softc->partition = (daddr_t) -1; 4616 softc->rep_fileno = softc->rep_blkno = (daddr_t) -1; 4617 } |
|
3214 return (error); 3215} 3216 3217static int 3218saspace(struct cam_periph *periph, int count, scsi_space_code code) 3219{ 3220 union ccb *ccb; 3221 struct sa_softc *softc; --- 35 unchanged lines hidden (view full) --- 3257 * In the former case, we know our new record number (0). In 3258 * the latter case, we have absolutely no idea what the real 3259 * record number is- we've stopped between the end of the last 3260 * record in the previous file and the filemark that stopped 3261 * our spacing backwards. 3262 */ 3263 if (error) { 3264 softc->fileno = softc->blkno = (daddr_t) -1; | 4618 return (error); 4619} 4620 4621static int 4622saspace(struct cam_periph *periph, int count, scsi_space_code code) 4623{ 4624 union ccb *ccb; 4625 struct sa_softc *softc; --- 35 unchanged lines hidden (view full) --- 4661 * In the former case, we know our new record number (0). In 4662 * the latter case, we have absolutely no idea what the real 4663 * record number is- we've stopped between the end of the last 4664 * record in the previous file and the filemark that stopped 4665 * our spacing backwards. 4666 */ 4667 if (error) { 4668 softc->fileno = softc->blkno = (daddr_t) -1; |
4669 softc->rep_blkno = softc->partition = (daddr_t) -1; 4670 softc->rep_fileno = (daddr_t) -1; |
|
3265 } else if (code == SS_SETMARKS || code == SS_EOD) { 3266 softc->fileno = softc->blkno = (daddr_t) -1; 3267 } else if (code == SS_FILEMARKS && softc->fileno != (daddr_t) -1) { 3268 softc->fileno += (count - softc->last_ctl_resid); 3269 if (softc->fileno < 0) /* we must of hit BOT */ 3270 softc->fileno = 0; 3271 softc->blkno = 0; 3272 } else if (code == SS_BLOCKS && softc->blkno != (daddr_t) -1) { 3273 softc->blkno += (count - softc->last_ctl_resid); 3274 if (count < 0) { 3275 if (softc->last_ctl_resid || softc->blkno < 0) { 3276 if (softc->fileno == 0) { 3277 softc->blkno = 0; 3278 } else { 3279 softc->blkno = (daddr_t) -1; 3280 } 3281 } 3282 } 3283 } | 4671 } else if (code == SS_SETMARKS || code == SS_EOD) { 4672 softc->fileno = softc->blkno = (daddr_t) -1; 4673 } else if (code == SS_FILEMARKS && softc->fileno != (daddr_t) -1) { 4674 softc->fileno += (count - softc->last_ctl_resid); 4675 if (softc->fileno < 0) /* we must of hit BOT */ 4676 softc->fileno = 0; 4677 softc->blkno = 0; 4678 } else if (code == SS_BLOCKS && softc->blkno != (daddr_t) -1) { 4679 softc->blkno += (count - softc->last_ctl_resid); 4680 if (count < 0) { 4681 if (softc->last_ctl_resid || softc->blkno < 0) { 4682 if (softc->fileno == 0) { 4683 softc->blkno = 0; 4684 } else { 4685 softc->blkno = (daddr_t) -1; 4686 } 4687 } 4688 } 4689 } |
4690 if (error == 0) 4691 sagetpos(periph); 4692 |
|
3284 return (error); 3285} 3286 3287static int | 4693 return (error); 4694} 4695 4696static int |
3288sawritefilemarks(struct cam_periph *periph, int nmarks, int setmarks) | 4697sawritefilemarks(struct cam_periph *periph, int nmarks, int setmarks, int immed) |
3289{ 3290 union ccb *ccb; 3291 struct sa_softc *softc; 3292 int error, nwm = 0; 3293 3294 softc = (struct sa_softc *)periph->softc; 3295 if (softc->open_rdonly) 3296 return (EBADF); 3297 3298 ccb = cam_periph_getccb(periph, 1); 3299 /* 3300 * Clear residual because we will be using it. 3301 */ 3302 softc->last_ctl_resid = 0; 3303 3304 softc->dsreg = MTIO_DSREG_FMK; 3305 /* this *must* not be retried */ 3306 scsi_write_filemarks(&ccb->csio, 0, sadone, MSG_SIMPLE_Q_TAG, | 4698{ 4699 union ccb *ccb; 4700 struct sa_softc *softc; 4701 int error, nwm = 0; 4702 4703 softc = (struct sa_softc *)periph->softc; 4704 if (softc->open_rdonly) 4705 return (EBADF); 4706 4707 ccb = cam_periph_getccb(periph, 1); 4708 /* 4709 * Clear residual because we will be using it. 4710 */ 4711 softc->last_ctl_resid = 0; 4712 4713 softc->dsreg = MTIO_DSREG_FMK; 4714 /* this *must* not be retried */ 4715 scsi_write_filemarks(&ccb->csio, 0, sadone, MSG_SIMPLE_Q_TAG, |
3307 FALSE, setmarks, nmarks, SSD_FULL_SIZE, IO_TIMEOUT); | 4716 immed, setmarks, nmarks, SSD_FULL_SIZE, IO_TIMEOUT); |
3308 softc->dsreg = MTIO_DSREG_REST; 3309 3310 3311 error = cam_periph_runccb(ccb, saerror, 0, 0, softc->device_stats); 3312 3313 if (error == 0 && nmarks) { 3314 struct sa_softc *softc = (struct sa_softc *)periph->softc; 3315 nwm = nmarks - softc->last_ctl_resid; 3316 softc->filemarks += nwm; 3317 } 3318 3319 xpt_release_ccb(ccb); 3320 3321 /* 3322 * Update relative positions (if we're doing that). 3323 */ 3324 if (error) { | 4717 softc->dsreg = MTIO_DSREG_REST; 4718 4719 4720 error = cam_periph_runccb(ccb, saerror, 0, 0, softc->device_stats); 4721 4722 if (error == 0 && nmarks) { 4723 struct sa_softc *softc = (struct sa_softc *)periph->softc; 4724 nwm = nmarks - softc->last_ctl_resid; 4725 softc->filemarks += nwm; 4726 } 4727 4728 xpt_release_ccb(ccb); 4729 4730 /* 4731 * Update relative positions (if we're doing that). 4732 */ 4733 if (error) { |
3325 softc->fileno = softc->blkno = (daddr_t) -1; | 4734 softc->fileno = softc->blkno = softc->partition = (daddr_t) -1; |
3326 } else if (softc->fileno != (daddr_t) -1) { 3327 softc->fileno += nwm; 3328 softc->blkno = 0; 3329 } | 4735 } else if (softc->fileno != (daddr_t) -1) { 4736 softc->fileno += nwm; 4737 softc->blkno = 0; 4738 } |
4739 4740 /* 4741 * Ask the tape drive for position information. 4742 */ 4743 sagetpos(periph); 4744 4745 /* 4746 * If we got valid position information, since we just wrote a file 4747 * mark, we know we're at the file mark and block 0 after that 4748 * filemark. 4749 */ 4750 if (softc->rep_fileno != (daddr_t) -1) { 4751 softc->fileno = softc->rep_fileno; 4752 softc->blkno = 0; 4753 } 4754 |
|
3330 return (error); 3331} 3332 3333static int | 4755 return (error); 4756} 4757 4758static int |
4759sagetpos(struct cam_periph *periph) 4760{ 4761 union ccb *ccb; 4762 struct scsi_tape_position_long_data long_pos; 4763 struct sa_softc *softc = (struct sa_softc *)periph->softc; 4764 int error; 4765 4766 if (softc->quirks & SA_QUIRK_NO_LONG_POS) { 4767 softc->rep_fileno = (daddr_t) -1; 4768 softc->rep_blkno = (daddr_t) -1; 4769 softc->bop = softc->eop = softc->bpew = -1; 4770 return (EOPNOTSUPP); 4771 } 4772 4773 bzero(&long_pos, sizeof(long_pos)); 4774 4775 ccb = cam_periph_getccb(periph, CAM_PRIORITY_NORMAL); 4776 scsi_read_position_10(&ccb->csio, 4777 /*retries*/ 1, 4778 /*cbfcnp*/ sadone, 4779 /*tag_action*/ MSG_SIMPLE_Q_TAG, 4780 /*service_action*/ SA_RPOS_LONG_FORM, 4781 /*data_ptr*/ (uint8_t *)&long_pos, 4782 /*length*/ sizeof(long_pos), 4783 /*sense_len*/ SSD_FULL_SIZE, 4784 /*timeout*/ SCSIOP_TIMEOUT); 4785 4786 softc->dsreg = MTIO_DSREG_RBSY; 4787 error = cam_periph_runccb(ccb, saerror, 0, SF_QUIET_IR, 4788 softc->device_stats); 4789 softc->dsreg = MTIO_DSREG_REST; 4790 4791 if (error == 0) { 4792 if (long_pos.flags & SA_RPOS_LONG_MPU) { 4793 /* 4794 * If the drive doesn't know what file mark it is 4795 * on, our calculated filemark isn't going to be 4796 * accurate either. 4797 */ 4798 softc->fileno = (daddr_t) -1; 4799 softc->rep_fileno = (daddr_t) -1; 4800 } else { 4801 softc->fileno = softc->rep_fileno = 4802 scsi_8btou64(long_pos.logical_file_num); 4803 } 4804 4805 if (long_pos.flags & SA_RPOS_LONG_LONU) { 4806 softc->partition = (daddr_t) -1; 4807 softc->rep_blkno = (daddr_t) -1; 4808 /* 4809 * If the tape drive doesn't know its block 4810 * position, we can't claim to know it either. 4811 */ 4812 softc->blkno = (daddr_t) -1; 4813 } else { 4814 softc->partition = scsi_4btoul(long_pos.partition); 4815 softc->rep_blkno = 4816 scsi_8btou64(long_pos.logical_object_num); 4817 } 4818 if (long_pos.flags & SA_RPOS_LONG_BOP) 4819 softc->bop = 1; 4820 else 4821 softc->bop = 0; 4822 4823 if (long_pos.flags & SA_RPOS_LONG_EOP) 4824 softc->eop = 1; 4825 else 4826 softc->eop = 0; 4827 4828 if (long_pos.flags & SA_RPOS_LONG_BPEW) 4829 softc->bpew = 1; 4830 else 4831 softc->bpew = 0; 4832 } else if (error == EINVAL) { 4833 /* 4834 * If this drive returned an invalid-request type error, 4835 * then it likely doesn't support the long form report. 4836 */ 4837 softc->quirks |= SA_QUIRK_NO_LONG_POS; 4838 } 4839 4840 if (error != 0) { 4841 softc->rep_fileno = softc->rep_blkno = (daddr_t) -1; 4842 softc->partition = (daddr_t) -1; 4843 softc->bop = softc->eop = softc->bpew = -1; 4844 } 4845 4846 xpt_release_ccb(ccb); 4847 4848 return (error); 4849} 4850 4851static int |
|
3334sardpos(struct cam_periph *periph, int hard, u_int32_t *blkptr) 3335{ 3336 struct scsi_tape_position_data loc; 3337 union ccb *ccb; 3338 struct sa_softc *softc = (struct sa_softc *)periph->softc; 3339 int error; 3340 3341 /* 3342 * We try and flush any buffered writes here if we were writing 3343 * and we're trying to get hardware block position. It eats 3344 * up performance substantially, but I'm wary of drive firmware. 3345 * 3346 * I think that *logical* block position is probably okay- 3347 * but hardware block position might have to wait for data 3348 * to hit media to be valid. Caveat Emptor. 3349 */ 3350 3351 if (hard && (softc->flags & SA_FLAG_TAPE_WRITTEN)) { | 4852sardpos(struct cam_periph *periph, int hard, u_int32_t *blkptr) 4853{ 4854 struct scsi_tape_position_data loc; 4855 union ccb *ccb; 4856 struct sa_softc *softc = (struct sa_softc *)periph->softc; 4857 int error; 4858 4859 /* 4860 * We try and flush any buffered writes here if we were writing 4861 * and we're trying to get hardware block position. It eats 4862 * up performance substantially, but I'm wary of drive firmware. 4863 * 4864 * I think that *logical* block position is probably okay- 4865 * but hardware block position might have to wait for data 4866 * to hit media to be valid. Caveat Emptor. 4867 */ 4868 4869 if (hard && (softc->flags & SA_FLAG_TAPE_WRITTEN)) { |
3352 error = sawritefilemarks(periph, 0, 0); | 4870 error = sawritefilemarks(periph, 0, 0, 0); |
3353 if (error && error != EACCES) 3354 return (error); 3355 } 3356 3357 ccb = cam_periph_getccb(periph, 1); 3358 scsi_read_position(&ccb->csio, 1, sadone, MSG_SIMPLE_Q_TAG, 3359 hard, &loc, SSD_FULL_SIZE, SCSIOP_TIMEOUT); 3360 softc->dsreg = MTIO_DSREG_RBSY; --- 8 unchanged lines hidden (view full) --- 3369 } 3370 } 3371 3372 xpt_release_ccb(ccb); 3373 return (error); 3374} 3375 3376static int | 4871 if (error && error != EACCES) 4872 return (error); 4873 } 4874 4875 ccb = cam_periph_getccb(periph, 1); 4876 scsi_read_position(&ccb->csio, 1, sadone, MSG_SIMPLE_Q_TAG, 4877 hard, &loc, SSD_FULL_SIZE, SCSIOP_TIMEOUT); 4878 softc->dsreg = MTIO_DSREG_RBSY; --- 8 unchanged lines hidden (view full) --- 4887 } 4888 } 4889 4890 xpt_release_ccb(ccb); 4891 return (error); 4892} 4893 4894static int |
3377sasetpos(struct cam_periph *periph, int hard, u_int32_t *blkptr) | 4895sasetpos(struct cam_periph *periph, int hard, struct mtlocate *locate_info) |
3378{ 3379 union ccb *ccb; 3380 struct sa_softc *softc; | 4896{ 4897 union ccb *ccb; 4898 struct sa_softc *softc; |
4899 int locate16; 4900 int immed, cp; |
|
3381 int error; 3382 3383 /* 3384 * We used to try and flush any buffered writes here. 3385 * Now we push this onto user applications to either 3386 * flush the pending writes themselves (via a zero count 3387 * WRITE FILEMARKS command) or they can trust their tape 3388 * drive to do this correctly for them. 3389 */ 3390 3391 softc = (struct sa_softc *)periph->softc; 3392 ccb = cam_periph_getccb(periph, 1); 3393 | 4901 int error; 4902 4903 /* 4904 * We used to try and flush any buffered writes here. 4905 * Now we push this onto user applications to either 4906 * flush the pending writes themselves (via a zero count 4907 * WRITE FILEMARKS command) or they can trust their tape 4908 * drive to do this correctly for them. 4909 */ 4910 4911 softc = (struct sa_softc *)periph->softc; 4912 ccb = cam_periph_getccb(periph, 1); 4913 |
3394 3395 scsi_set_position(&ccb->csio, 1, sadone, MSG_SIMPLE_Q_TAG, 3396 hard, *blkptr, SSD_FULL_SIZE, SPACE_TIMEOUT); | 4914 cp = locate_info->flags & MT_LOCATE_FLAG_CHANGE_PART ? 1 : 0; 4915 immed = locate_info->flags & MT_LOCATE_FLAG_IMMED ? 1 : 0; |
3397 | 4916 |
4917 /* 4918 * Determine whether we have to use LOCATE or LOCATE16. The hard 4919 * bit is only possible with LOCATE, but the new ioctls do not 4920 * allow setting that bit. So we can't get into the situation of 4921 * having the hard bit set with a block address that is larger than 4922 * 32-bits. 4923 */ 4924 if (hard != 0) 4925 locate16 = 0; 4926 else if ((locate_info->dest_type != MT_LOCATE_DEST_OBJECT) 4927 || (locate_info->block_address_mode != MT_LOCATE_BAM_IMPLICIT) 4928 || (locate_info->logical_id > SA_SPOS_MAX_BLK)) 4929 locate16 = 1; 4930 else 4931 locate16 = 0; |
|
3398 | 4932 |
4933 if (locate16 != 0) { 4934 scsi_locate_16(&ccb->csio, 4935 /*retries*/ 1, 4936 /*cbfcnp*/ sadone, 4937 /*tag_action*/ MSG_SIMPLE_Q_TAG, 4938 /*immed*/ immed, 4939 /*cp*/ cp, 4940 /*dest_type*/ locate_info->dest_type, 4941 /*bam*/ locate_info->block_address_mode, 4942 /*partition*/ locate_info->partition, 4943 /*logical_id*/ locate_info->logical_id, 4944 /*sense_len*/ SSD_FULL_SIZE, 4945 /*timeout*/ SPACE_TIMEOUT); 4946 } else { 4947 uint32_t blk_pointer; 4948 4949 blk_pointer = locate_info->logical_id; 4950 4951 scsi_locate_10(&ccb->csio, 4952 /*retries*/ 1, 4953 /*cbfcnp*/ sadone, 4954 /*tag_action*/ MSG_SIMPLE_Q_TAG, 4955 /*immed*/ immed, 4956 /*cp*/ cp, 4957 /*hard*/ hard, 4958 /*partition*/ locate_info->partition, 4959 /*block_address*/ locate_info->logical_id, 4960 /*sense_len*/ SSD_FULL_SIZE, 4961 /*timeout*/ SPACE_TIMEOUT); 4962 } 4963 |
|
3399 softc->dsreg = MTIO_DSREG_POS; 3400 error = cam_periph_runccb(ccb, saerror, 0, 0, softc->device_stats); 3401 softc->dsreg = MTIO_DSREG_REST; 3402 xpt_release_ccb(ccb); | 4964 softc->dsreg = MTIO_DSREG_POS; 4965 error = cam_periph_runccb(ccb, saerror, 0, 0, softc->device_stats); 4966 softc->dsreg = MTIO_DSREG_REST; 4967 xpt_release_ccb(ccb); |
4968 |
|
3403 /* | 4969 /* |
3404 * Note relative file && block number position as now unknown. | 4970 * We assume the calculated file and block numbers are unknown 4971 * unless we have enough information to populate them. |
3405 */ 3406 softc->fileno = softc->blkno = (daddr_t) -1; | 4972 */ 4973 softc->fileno = softc->blkno = (daddr_t) -1; |
4974 4975 /* 4976 * If the user requested changing the partition and the request 4977 * succeeded, note the partition. 4978 */ 4979 if ((error == 0) 4980 && (cp != 0)) 4981 softc->partition = locate_info->partition; 4982 else 4983 softc->partition = (daddr_t) -1; 4984 4985 if (error == 0) { 4986 switch (locate_info->dest_type) { 4987 case MT_LOCATE_DEST_FILE: 4988 /* 4989 * This is the only case where we can reliably 4990 * calculate the file and block numbers. 4991 */ 4992 softc->fileno = locate_info->logical_id; 4993 softc->blkno = 0; 4994 break; 4995 case MT_LOCATE_DEST_OBJECT: 4996 case MT_LOCATE_DEST_SET: 4997 case MT_LOCATE_DEST_EOD: 4998 default: 4999 break; 5000 } 5001 } 5002 5003 /* 5004 * Ask the drive for current position information. 5005 */ 5006 sagetpos(periph); 5007 |
|
3407 return (error); 3408} 3409 3410static int 3411saretension(struct cam_periph *periph) 3412{ 3413 union ccb *ccb; 3414 struct sa_softc *softc; --- 7 unchanged lines hidden (view full) --- 3422 scsi_load_unload(&ccb->csio, 5, sadone, MSG_SIMPLE_Q_TAG, FALSE, 3423 FALSE, TRUE, TRUE, SSD_FULL_SIZE, ERASE_TIMEOUT); 3424 3425 softc->dsreg = MTIO_DSREG_TEN; 3426 error = cam_periph_runccb(ccb, saerror, 0, 0, softc->device_stats); 3427 softc->dsreg = MTIO_DSREG_REST; 3428 3429 xpt_release_ccb(ccb); | 5008 return (error); 5009} 5010 5011static int 5012saretension(struct cam_periph *periph) 5013{ 5014 union ccb *ccb; 5015 struct sa_softc *softc; --- 7 unchanged lines hidden (view full) --- 5023 scsi_load_unload(&ccb->csio, 5, sadone, MSG_SIMPLE_Q_TAG, FALSE, 5024 FALSE, TRUE, TRUE, SSD_FULL_SIZE, ERASE_TIMEOUT); 5025 5026 softc->dsreg = MTIO_DSREG_TEN; 5027 error = cam_periph_runccb(ccb, saerror, 0, 0, softc->device_stats); 5028 softc->dsreg = MTIO_DSREG_REST; 5029 5030 xpt_release_ccb(ccb); |
3430 if (error == 0) 3431 softc->fileno = softc->blkno = (daddr_t) 0; 3432 else 3433 softc->fileno = softc->blkno = (daddr_t) -1; | 5031 if (error == 0) { 5032 softc->partition = softc->fileno = softc->blkno = (daddr_t) 0; 5033 sagetpos(periph); 5034 } else 5035 softc->partition = softc->fileno = softc->blkno = (daddr_t) -1; |
3434 return (error); 3435} 3436 3437static int 3438sareservereleaseunit(struct cam_periph *periph, int reserve) 3439{ 3440 union ccb *ccb; 3441 struct sa_softc *softc; --- 37 unchanged lines hidden (view full) --- 3479 scsi_load_unload(&ccb->csio, 5, sadone, MSG_SIMPLE_Q_TAG, FALSE, 3480 FALSE, FALSE, load, SSD_FULL_SIZE, REWIND_TIMEOUT); 3481 3482 softc->dsreg = (load)? MTIO_DSREG_LD : MTIO_DSREG_UNL; 3483 error = cam_periph_runccb(ccb, saerror, 0, 0, softc->device_stats); 3484 softc->dsreg = MTIO_DSREG_REST; 3485 xpt_release_ccb(ccb); 3486 | 5036 return (error); 5037} 5038 5039static int 5040sareservereleaseunit(struct cam_periph *periph, int reserve) 5041{ 5042 union ccb *ccb; 5043 struct sa_softc *softc; --- 37 unchanged lines hidden (view full) --- 5081 scsi_load_unload(&ccb->csio, 5, sadone, MSG_SIMPLE_Q_TAG, FALSE, 5082 FALSE, FALSE, load, SSD_FULL_SIZE, REWIND_TIMEOUT); 5083 5084 softc->dsreg = (load)? MTIO_DSREG_LD : MTIO_DSREG_UNL; 5085 error = cam_periph_runccb(ccb, saerror, 0, 0, softc->device_stats); 5086 softc->dsreg = MTIO_DSREG_REST; 5087 xpt_release_ccb(ccb); 5088 |
3487 if (error || load == 0) 3488 softc->fileno = softc->blkno = (daddr_t) -1; 3489 else if (error == 0) 3490 softc->fileno = softc->blkno = (daddr_t) 0; | 5089 if (error || load == 0) { 5090 softc->partition = softc->fileno = softc->blkno = (daddr_t) -1; 5091 softc->rep_fileno = softc->rep_blkno = (daddr_t) -1; 5092 } else if (error == 0) { 5093 softc->partition = softc->fileno = softc->blkno = (daddr_t) 0; 5094 sagetpos(periph); 5095 } |
3491 return (error); 3492} 3493 3494static int 3495saerase(struct cam_periph *periph, int longerase) 3496{ 3497 3498 union ccb *ccb; --- 12 unchanged lines hidden (view full) --- 3511 softc->dsreg = MTIO_DSREG_ZER; 3512 error = cam_periph_runccb(ccb, saerror, 0, 0, softc->device_stats); 3513 softc->dsreg = MTIO_DSREG_REST; 3514 3515 xpt_release_ccb(ccb); 3516 return (error); 3517} 3518 | 5096 return (error); 5097} 5098 5099static int 5100saerase(struct cam_periph *periph, int longerase) 5101{ 5102 5103 union ccb *ccb; --- 12 unchanged lines hidden (view full) --- 5116 softc->dsreg = MTIO_DSREG_ZER; 5117 error = cam_periph_runccb(ccb, saerror, 0, 0, softc->device_stats); 5118 softc->dsreg = MTIO_DSREG_REST; 5119 5120 xpt_release_ccb(ccb); 5121 return (error); 5122} 5123 |
5124/* 5125 * Fill an sbuf with density data in XML format. This particular macro 5126 * works for multi-byte integer fields. 5127 * 5128 * Note that 1 byte fields aren't supported here. The reason is that the 5129 * compiler does not evaluate the sizeof(), and assumes that any of the 5130 * sizes are possible for a given field. So passing in a multi-byte 5131 * field will result in a warning that the assignment makes an integer 5132 * from a pointer without a cast, if there is an assignment in the 1 byte 5133 * case. 5134 */ 5135#define SAFILLDENSSB(dens_data, sb, indent, field, desc_remain, \ 5136 len_to_go, cur_offset, desc){ \ 5137 size_t cur_field_len; \ 5138 \ 5139 cur_field_len = sizeof(dens_data->field); \ 5140 if (desc_remain < cur_field_len) { \ 5141 len_to_go -= desc_remain; \ 5142 cur_offset += desc_remain; \ 5143 continue; \ 5144 } \ 5145 len_to_go -= cur_field_len; \ 5146 cur_offset += cur_field_len; \ 5147 desc_remain -= cur_field_len; \ 5148 \ 5149 switch (sizeof(dens_data->field)) { \ 5150 case 1: \ 5151 KASSERT(1 == 0, ("Programmer error, invalid 1 byte " \ 5152 "field width for SAFILLDENSFIELD")); \ 5153 break; \ 5154 case 2: \ 5155 SASBADDUINTDESC(sb, indent, \ 5156 scsi_2btoul(dens_data->field), %u, field, desc); \ 5157 break; \ 5158 case 3: \ 5159 SASBADDUINTDESC(sb, indent, \ 5160 scsi_3btoul(dens_data->field), %u, field, desc); \ 5161 break; \ 5162 case 4: \ 5163 SASBADDUINTDESC(sb, indent, \ 5164 scsi_4btoul(dens_data->field), %u, field, desc); \ 5165 break; \ 5166 case 8: \ 5167 SASBADDUINTDESC(sb, indent, \ 5168 (uintmax_t)scsi_8btou64(dens_data->field), %ju, \ 5169 field, desc); \ 5170 break; \ 5171 default: \ 5172 break; \ 5173 } \ 5174}; 5175/* 5176 * Fill an sbuf with density data in XML format. This particular macro 5177 * works for strings. 5178 */ 5179#define SAFILLDENSSBSTR(dens_data, sb, indent, field, desc_remain, \ 5180 len_to_go, cur_offset, desc){ \ 5181 size_t cur_field_len; \ 5182 char tmpstr[32]; \ 5183 \ 5184 cur_field_len = sizeof(dens_data->field); \ 5185 if (desc_remain < cur_field_len) { \ 5186 len_to_go -= desc_remain; \ 5187 cur_offset += desc_remain; \ 5188 continue; \ 5189 } \ 5190 len_to_go -= cur_field_len; \ 5191 cur_offset += cur_field_len; \ 5192 desc_remain -= cur_field_len; \ 5193 \ 5194 cam_strvis(tmpstr, dens_data->field, \ 5195 sizeof(dens_data->field), sizeof(tmpstr)); \ 5196 SASBADDVARSTRDESC(sb, indent, tmpstr, %s, field, \ 5197 strlen(tmpstr) + 1, desc); \ 5198}; 5199 5200/* 5201 * Fill an sbuf with density data descriptors. 5202 */ 5203static void 5204safilldenstypesb(struct sbuf *sb, int *indent, uint8_t *buf, int buf_len, 5205 int is_density) 5206{ 5207 struct scsi_density_hdr *hdr; 5208 uint32_t hdr_len; 5209 int len_to_go, cur_offset; 5210 int length_offset; 5211 int num_reports, need_close; 5212 5213 /* 5214 * We need at least the header length. Note that this isn't an 5215 * error, not all tape drives will have every data type. 5216 */ 5217 if (buf_len < sizeof(*hdr)) 5218 goto bailout; 5219 5220 5221 hdr = (struct scsi_density_hdr *)buf; 5222 hdr_len = scsi_2btoul(hdr->length); 5223 len_to_go = min(buf_len - sizeof(*hdr), hdr_len); 5224 if (is_density) { 5225 length_offset = __offsetof(struct scsi_density_data, 5226 bits_per_mm); 5227 } else { 5228 length_offset = __offsetof(struct scsi_medium_type_data, 5229 num_density_codes); 5230 } 5231 cur_offset = sizeof(*hdr); 5232 5233 num_reports = 0; 5234 need_close = 0; 5235 5236 while (len_to_go > length_offset) { 5237 struct scsi_density_data *dens_data; 5238 struct scsi_medium_type_data *type_data; 5239 int desc_remain; 5240 size_t cur_field_len; 5241 5242 dens_data = NULL; 5243 type_data = NULL; 5244 5245 if (is_density) { 5246 dens_data =(struct scsi_density_data *)&buf[cur_offset]; 5247 if (dens_data->byte2 & SDD_DLV) 5248 desc_remain = scsi_2btoul(dens_data->length); 5249 else 5250 desc_remain = SDD_DEFAULT_LENGTH - 5251 length_offset; 5252 } else { 5253 type_data = (struct scsi_medium_type_data *) 5254 &buf[cur_offset]; 5255 desc_remain = scsi_2btoul(type_data->length); 5256 } 5257 5258 len_to_go -= length_offset; 5259 desc_remain = min(desc_remain, len_to_go); 5260 cur_offset += length_offset; 5261 5262 if (need_close != 0) { 5263 SASBENDNODE(sb, *indent, density_entry); 5264 } 5265 5266 SASBADDNODENUM(sb, *indent, density_entry, num_reports); 5267 num_reports++; 5268 need_close = 1; 5269 5270 if (is_density) { 5271 SASBADDUINTDESC(sb, *indent, 5272 dens_data->primary_density_code, %u, 5273 primary_density_code, "Primary Density Code"); 5274 SASBADDUINTDESC(sb, *indent, 5275 dens_data->secondary_density_code, %u, 5276 secondary_density_code, "Secondary Density Code"); 5277 SASBADDUINTDESC(sb, *indent, 5278 dens_data->byte2 & ~SDD_DLV, %#x, density_flags, 5279 "Density Flags"); 5280 5281 SAFILLDENSSB(dens_data, sb, *indent, bits_per_mm, 5282 desc_remain, len_to_go, cur_offset, "Bits per mm"); 5283 SAFILLDENSSB(dens_data, sb, *indent, media_width, 5284 desc_remain, len_to_go, cur_offset, "Media width"); 5285 SAFILLDENSSB(dens_data, sb, *indent, tracks, 5286 desc_remain, len_to_go, cur_offset, 5287 "Number of Tracks"); 5288 SAFILLDENSSB(dens_data, sb, *indent, capacity, 5289 desc_remain, len_to_go, cur_offset, "Capacity"); 5290 5291 SAFILLDENSSBSTR(dens_data, sb, *indent, assigning_org, 5292 desc_remain, len_to_go, cur_offset, 5293 "Assigning Organization"); 5294 5295 SAFILLDENSSBSTR(dens_data, sb, *indent, density_name, 5296 desc_remain, len_to_go, cur_offset, "Density Name"); 5297 5298 SAFILLDENSSBSTR(dens_data, sb, *indent, description, 5299 desc_remain, len_to_go, cur_offset, "Description"); 5300 } else { 5301 int i; 5302 5303 SASBADDUINTDESC(sb, *indent, type_data->medium_type, 5304 %u, medium_type, "Medium Type"); 5305 5306 cur_field_len = 5307 __offsetof(struct scsi_medium_type_data, 5308 media_width) - 5309 __offsetof(struct scsi_medium_type_data, 5310 num_density_codes); 5311 5312 if (desc_remain < cur_field_len) { 5313 len_to_go -= desc_remain; 5314 cur_offset += desc_remain; 5315 continue; 5316 } 5317 len_to_go -= cur_field_len; 5318 cur_offset += cur_field_len; 5319 desc_remain -= cur_field_len; 5320 5321 SASBADDINTDESC(sb, *indent, 5322 type_data->num_density_codes, %d, 5323 num_density_codes, "Number of Density Codes"); 5324 SASBADDNODE(sb, *indent, density_code_list); 5325 for (i = 0; i < type_data->num_density_codes; 5326 i++) { 5327 SASBADDUINTDESC(sb, *indent, 5328 type_data->primary_density_codes[i], %u, 5329 density_code, "Density Code"); 5330 } 5331 SASBENDNODE(sb, *indent, density_code_list); 5332 5333 SAFILLDENSSB(type_data, sb, *indent, media_width, 5334 desc_remain, len_to_go, cur_offset, 5335 "Media width"); 5336 SAFILLDENSSB(type_data, sb, *indent, medium_length, 5337 desc_remain, len_to_go, cur_offset, 5338 "Medium length"); 5339 5340 /* 5341 * Account for the two reserved bytes. 5342 */ 5343 cur_field_len = sizeof(type_data->reserved2); 5344 if (desc_remain < cur_field_len) { 5345 len_to_go -= desc_remain; 5346 cur_offset += desc_remain; 5347 continue; 5348 } 5349 len_to_go -= cur_field_len; 5350 cur_offset += cur_field_len; 5351 desc_remain -= cur_field_len; 5352 5353 SAFILLDENSSBSTR(type_data, sb, *indent, assigning_org, 5354 desc_remain, len_to_go, cur_offset, 5355 "Assigning Organization"); 5356 SAFILLDENSSBSTR(type_data, sb, *indent, 5357 medium_type_name, desc_remain, len_to_go, 5358 cur_offset, "Medium type name"); 5359 SAFILLDENSSBSTR(type_data, sb, *indent, description, 5360 desc_remain, len_to_go, cur_offset, "Description"); 5361 5362 } 5363 } 5364 if (need_close != 0) { 5365 SASBENDNODE(sb, *indent, density_entry); 5366 } 5367 5368bailout: 5369 return; 5370} 5371 5372/* 5373 * Fill an sbuf with density data information 5374 */ 5375static void 5376safilldensitysb(struct sa_softc *softc, int *indent, struct sbuf *sb) 5377{ 5378 int i, is_density; 5379 5380 SASBADDNODE(sb, *indent, mtdensity); 5381 SASBADDUINTDESC(sb, *indent, softc->media_density, %u, media_density, 5382 "Current Medium Density"); 5383 is_density = 0; 5384 for (i = 0; i < SA_DENSITY_TYPES; i++) { 5385 int tmpint; 5386 5387 if (softc->density_info_valid[i] == 0) 5388 continue; 5389 5390 SASBADDNODE(sb, *indent, density_report); 5391 if (softc->density_type_bits[i] & SRDS_MEDIUM_TYPE) { 5392 tmpint = 1; 5393 is_density = 0; 5394 } else { 5395 tmpint = 0; 5396 is_density = 1; 5397 } 5398 SASBADDINTDESC(sb, *indent, tmpint, %d, medium_type_report, 5399 "Medium type report"); 5400 5401 if (softc->density_type_bits[i] & SRDS_MEDIA) 5402 tmpint = 1; 5403 else 5404 tmpint = 0; 5405 SASBADDINTDESC(sb, *indent, tmpint, %d, media_report, 5406 "Media report"); 5407 5408 safilldenstypesb(sb, indent, softc->density_info[i], 5409 softc->density_info_valid[i], is_density); 5410 SASBENDNODE(sb, *indent, density_report); 5411 } 5412 SASBENDNODE(sb, *indent, mtdensity); 5413} 5414 |
|
3519#endif /* _KERNEL */ 3520 3521/* 3522 * Read tape block limits command. 3523 */ 3524void 3525scsi_read_block_limits(struct ccb_scsiio *csio, u_int32_t retries, 3526 void (*cbfcnp)(struct cam_periph *, union ccb *), --- 193 unchanged lines hidden (view full) --- 3720 (u_int8_t *)sbp, sizeof (*sbp), sense_len, sizeof(*scmd), timeout); 3721 scmd = (struct scsi_tape_read_position *)&csio->cdb_io.cdb_bytes; 3722 bzero(scmd, sizeof(*scmd)); 3723 scmd->opcode = READ_POSITION; 3724 scmd->byte1 = hardsoft; 3725} 3726 3727/* | 5415#endif /* _KERNEL */ 5416 5417/* 5418 * Read tape block limits command. 5419 */ 5420void 5421scsi_read_block_limits(struct ccb_scsiio *csio, u_int32_t retries, 5422 void (*cbfcnp)(struct cam_periph *, union ccb *), --- 193 unchanged lines hidden (view full) --- 5616 (u_int8_t *)sbp, sizeof (*sbp), sense_len, sizeof(*scmd), timeout); 5617 scmd = (struct scsi_tape_read_position *)&csio->cdb_io.cdb_bytes; 5618 bzero(scmd, sizeof(*scmd)); 5619 scmd->opcode = READ_POSITION; 5620 scmd->byte1 = hardsoft; 5621} 5622 5623/* |
5624 * Read Tape Position command. 5625 */ 5626void 5627scsi_read_position_10(struct ccb_scsiio *csio, u_int32_t retries, 5628 void (*cbfcnp)(struct cam_periph *, union ccb *), 5629 u_int8_t tag_action, int service_action, 5630 u_int8_t *data_ptr, u_int32_t length, 5631 u_int32_t sense_len, u_int32_t timeout) 5632{ 5633 struct scsi_tape_read_position *scmd; 5634 5635 cam_fill_csio(csio, 5636 retries, 5637 cbfcnp, 5638 /*flags*/CAM_DIR_IN, 5639 tag_action, 5640 /*data_ptr*/data_ptr, 5641 /*dxfer_len*/length, 5642 sense_len, 5643 sizeof(*scmd), 5644 timeout); 5645 5646 5647 scmd = (struct scsi_tape_read_position *)&csio->cdb_io.cdb_bytes; 5648 bzero(scmd, sizeof(*scmd)); 5649 scmd->opcode = READ_POSITION; 5650 scmd->byte1 = service_action; 5651 /* 5652 * The length is only currently set (as of SSC4r03) if the extended 5653 * form is specified. The other forms have fixed lengths. 5654 */ 5655 if (service_action == SA_RPOS_EXTENDED_FORM) 5656 scsi_ulto2b(length, scmd->length); 5657} 5658 5659/* |
|
3728 * Set Tape Position command. 3729 */ 3730void 3731scsi_set_position(struct ccb_scsiio *csio, u_int32_t retries, 3732 void (*cbfcnp)(struct cam_periph *, union ccb *), 3733 u_int8_t tag_action, int hardsoft, u_int32_t blkno, 3734 u_int8_t sense_len, u_int32_t timeout) 3735{ 3736 struct scsi_tape_locate *scmd; 3737 3738 cam_fill_csio(csio, retries, cbfcnp, CAM_DIR_NONE, tag_action, 3739 (u_int8_t *)NULL, 0, sense_len, sizeof(*scmd), timeout); 3740 scmd = (struct scsi_tape_locate *)&csio->cdb_io.cdb_bytes; 3741 bzero(scmd, sizeof(*scmd)); 3742 scmd->opcode = LOCATE; 3743 if (hardsoft) 3744 scmd->byte1 |= SA_SPOS_BT; 3745 scsi_ulto4b(blkno, scmd->blkaddr); 3746} | 5660 * Set Tape Position command. 5661 */ 5662void 5663scsi_set_position(struct ccb_scsiio *csio, u_int32_t retries, 5664 void (*cbfcnp)(struct cam_periph *, union ccb *), 5665 u_int8_t tag_action, int hardsoft, u_int32_t blkno, 5666 u_int8_t sense_len, u_int32_t timeout) 5667{ 5668 struct scsi_tape_locate *scmd; 5669 5670 cam_fill_csio(csio, retries, cbfcnp, CAM_DIR_NONE, tag_action, 5671 (u_int8_t *)NULL, 0, sense_len, sizeof(*scmd), timeout); 5672 scmd = (struct scsi_tape_locate *)&csio->cdb_io.cdb_bytes; 5673 bzero(scmd, sizeof(*scmd)); 5674 scmd->opcode = LOCATE; 5675 if (hardsoft) 5676 scmd->byte1 |= SA_SPOS_BT; 5677 scsi_ulto4b(blkno, scmd->blkaddr); 5678} |
5679 5680/* 5681 * XXX KDM figure out how to make a compatibility function. 5682 */ 5683void 5684scsi_locate_10(struct ccb_scsiio *csio, u_int32_t retries, 5685 void (*cbfcnp)(struct cam_periph *, union ccb *), 5686 u_int8_t tag_action, int immed, int cp, int hard, 5687 int64_t partition, u_int32_t block_address, 5688 int sense_len, u_int32_t timeout) 5689{ 5690 struct scsi_tape_locate *scmd; 5691 5692 cam_fill_csio(csio, 5693 retries, 5694 cbfcnp, 5695 CAM_DIR_NONE, 5696 tag_action, 5697 /*data_ptr*/ NULL, 5698 /*dxfer_len*/ 0, 5699 sense_len, 5700 sizeof(*scmd), 5701 timeout); 5702 scmd = (struct scsi_tape_locate *)&csio->cdb_io.cdb_bytes; 5703 bzero(scmd, sizeof(*scmd)); 5704 scmd->opcode = LOCATE; 5705 if (immed) 5706 scmd->byte1 |= SA_SPOS_IMMED; 5707 if (cp) 5708 scmd->byte1 |= SA_SPOS_CP; 5709 if (hard) 5710 scmd->byte1 |= SA_SPOS_BT; 5711 scsi_ulto4b(block_address, scmd->blkaddr); 5712 scmd->partition = partition; 5713} 5714 5715void 5716scsi_locate_16(struct ccb_scsiio *csio, u_int32_t retries, 5717 void (*cbfcnp)(struct cam_periph *, union ccb *), 5718 u_int8_t tag_action, int immed, int cp, u_int8_t dest_type, 5719 int bam, int64_t partition, u_int64_t logical_id, 5720 int sense_len, u_int32_t timeout) 5721{ 5722 5723 struct scsi_locate_16 *scsi_cmd; 5724 5725 cam_fill_csio(csio, 5726 retries, 5727 cbfcnp, 5728 /*flags*/CAM_DIR_NONE, 5729 tag_action, 5730 /*data_ptr*/NULL, 5731 /*dxfer_len*/0, 5732 sense_len, 5733 sizeof(*scsi_cmd), 5734 timeout); 5735 5736 scsi_cmd = (struct scsi_locate_16 *)&csio->cdb_io.cdb_bytes; 5737 bzero(scsi_cmd, sizeof(*scsi_cmd)); 5738 scsi_cmd->opcode = LOCATE_16; 5739 if (immed) 5740 scsi_cmd->byte1 |= SA_LC_IMMEDIATE; 5741 if (cp) 5742 scsi_cmd->byte1 |= SA_LC_CP; 5743 scsi_cmd->byte1 |= (dest_type << SA_LC_DEST_TYPE_SHIFT); 5744 5745 scsi_cmd->byte2 |= bam; 5746 scsi_cmd->partition = partition; 5747 scsi_u64to8b(logical_id, scsi_cmd->logical_id); 5748} 5749 5750void 5751scsi_report_density_support(struct ccb_scsiio *csio, u_int32_t retries, 5752 void (*cbfcnp)(struct cam_periph *, union ccb *), 5753 u_int8_t tag_action, int media, int medium_type, 5754 u_int8_t *data_ptr, u_int32_t length, 5755 u_int32_t sense_len, u_int32_t timeout) 5756{ 5757 struct scsi_report_density_support *scsi_cmd; 5758 5759 scsi_cmd =(struct scsi_report_density_support *)&csio->cdb_io.cdb_bytes; 5760 bzero(scsi_cmd, sizeof(*scsi_cmd)); 5761 5762 scsi_cmd->opcode = REPORT_DENSITY_SUPPORT; 5763 if (media != 0) 5764 scsi_cmd->byte1 |= SRDS_MEDIA; 5765 if (medium_type != 0) 5766 scsi_cmd->byte1 |= SRDS_MEDIUM_TYPE; 5767 5768 scsi_ulto2b(length, scsi_cmd->length); 5769 5770 cam_fill_csio(csio, 5771 retries, 5772 cbfcnp, 5773 /*flags*/CAM_DIR_IN, 5774 tag_action, 5775 /*data_ptr*/data_ptr, 5776 /*dxfer_len*/length, 5777 sense_len, 5778 sizeof(*scsi_cmd), 5779 timeout); 5780} 5781 5782void 5783scsi_set_capacity(struct ccb_scsiio *csio, u_int32_t retries, 5784 void (*cbfcnp)(struct cam_periph *, union ccb *), 5785 u_int8_t tag_action, int byte1, u_int32_t proportion, 5786 u_int32_t sense_len, u_int32_t timeout) 5787{ 5788 struct scsi_set_capacity *scsi_cmd; 5789 5790 scsi_cmd = (struct scsi_set_capacity *)&csio->cdb_io.cdb_bytes; 5791 bzero(scsi_cmd, sizeof(*scsi_cmd)); 5792 5793 scsi_cmd->opcode = SET_CAPACITY; 5794 5795 scsi_cmd->byte1 = byte1; 5796 scsi_ulto2b(proportion, scsi_cmd->cap_proportion); 5797 5798 cam_fill_csio(csio, 5799 retries, 5800 cbfcnp, 5801 /*flags*/CAM_DIR_NONE, 5802 tag_action, 5803 /*data_ptr*/NULL, 5804 /*dxfer_len*/0, 5805 sense_len, 5806 sizeof(*scsi_cmd), 5807 timeout); 5808} 5809 5810void 5811scsi_format_medium(struct ccb_scsiio *csio, u_int32_t retries, 5812 void (*cbfcnp)(struct cam_periph *, union ccb *), 5813 u_int8_t tag_action, int byte1, int byte2, 5814 u_int8_t *data_ptr, u_int32_t dxfer_len, 5815 u_int32_t sense_len, u_int32_t timeout) 5816{ 5817 struct scsi_format_medium *scsi_cmd; 5818 5819 scsi_cmd = (struct scsi_format_medium*)&csio->cdb_io.cdb_bytes; 5820 bzero(scsi_cmd, sizeof(*scsi_cmd)); 5821 5822 scsi_cmd->opcode = FORMAT_MEDIUM; 5823 5824 scsi_cmd->byte1 = byte1; 5825 scsi_cmd->byte2 = byte2; 5826 5827 scsi_ulto2b(dxfer_len, scsi_cmd->length); 5828 5829 cam_fill_csio(csio, 5830 retries, 5831 cbfcnp, 5832 /*flags*/(dxfer_len > 0) ? CAM_DIR_OUT : CAM_DIR_NONE, 5833 tag_action, 5834 /*data_ptr*/ data_ptr, 5835 /*dxfer_len*/ dxfer_len, 5836 sense_len, 5837 sizeof(*scsi_cmd), 5838 timeout); 5839} 5840 5841void 5842scsi_allow_overwrite(struct ccb_scsiio *csio, u_int32_t retries, 5843 void (*cbfcnp)(struct cam_periph *, union ccb *), 5844 u_int8_t tag_action, int allow_overwrite, int partition, 5845 u_int64_t logical_id, u_int32_t sense_len, u_int32_t timeout) 5846{ 5847 struct scsi_allow_overwrite *scsi_cmd; 5848 5849 scsi_cmd = (struct scsi_allow_overwrite *)&csio->cdb_io.cdb_bytes; 5850 bzero(scsi_cmd, sizeof(*scsi_cmd)); 5851 5852 scsi_cmd->opcode = ALLOW_OVERWRITE; 5853 5854 scsi_cmd->allow_overwrite = allow_overwrite; 5855 scsi_cmd->partition = partition; 5856 scsi_u64to8b(logical_id, scsi_cmd->logical_id); 5857 5858 cam_fill_csio(csio, 5859 retries, 5860 cbfcnp, 5861 CAM_DIR_NONE, 5862 tag_action, 5863 /*data_ptr*/ NULL, 5864 /*dxfer_len*/ 0, 5865 sense_len, 5866 sizeof(*scsi_cmd), 5867 timeout); 5868} |
|