1/* 2 * linux/kernel/scsi_debug.c 3 * 4 * Copyright (C) 1992 Eric Youngdale 5 * Simulate a host adapter with 2 disks attached. Do a lot of checking 6 * to make sure that we are not getting blocks mixed up, and PANIC if 7 * anything out of the ordinary is seen. 8 * 9 * This version is more generic, simulating a variable number of disk 10 * (or disk like devices) sharing a common amount of RAM (default 8 MB 11 * but can be set at driver/module load time). 12 * 13 * For documentation see http://www.torque.net/sg/sdebug.html 14 * 15 * D. Gilbert (dpg) work for Magneto-Optical device test [20010421] 16 * dpg: work for devfs large number of disks [20010809] 17 * use vmalloc() more inquiry+mode_sense [20020302] 18 * add timers for delayed responses [20020721] 19 */ 20 21#include <linux/config.h> 22#include <linux/module.h> 23 24#include <linux/kernel.h> 25#include <linux/sched.h> 26#include <linux/errno.h> 27#include <linux/timer.h> 28#include <linux/types.h> 29#include <linux/string.h> 30#include <linux/genhd.h> 31#include <linux/fs.h> 32#include <linux/init.h> 33#include <linux/proc_fs.h> 34#include <linux/smp_lock.h> 35#include <linux/vmalloc.h> 36 37#include <asm/io.h> 38 39#include <linux/blk.h> 40#include "scsi.h" 41#include "hosts.h" 42 43#include <linux/stat.h> 44 45#ifndef LINUX_VERSION_CODE 46#include <linux/version.h> 47#endif 48 49#include "scsi_debug.h" 50 51static const char * scsi_debug_version_str = "Version: 0.61 (20020815)"; 52 53 54#ifndef SCSI_CMD_READ_16 55#define SCSI_CMD_READ_16 0x88 56#endif 57#ifndef SCSI_CMD_WRITE_16 58#define SCSI_CMD_WRITE_16 0x8a 59#endif 60#ifndef REPORT_LUNS 61#define REPORT_LUNS 0xa0 62#endif 63 64/* A few options that we want selected */ 65#define DEF_NR_FAKE_DEVS 1 66#define DEF_DEV_SIZE_MB 8 67#define DEF_FAKE_BLK0 0 68#define DEF_EVERY_NTH 100 69#define DEF_DELAY 1 70 71#define DEF_OPTS 0 72#define SCSI_DEBUG_OPT_NOISE 1 73#define SCSI_DEBUG_OPT_MEDIUM_ERR 2 74#define SCSI_DEBUG_OPT_EVERY_NTH 4 75 76#define OPT_MEDIUM_ERR_ADDR 0x1234 77 78static int scsi_debug_num_devs = DEF_NR_FAKE_DEVS; 79static int scsi_debug_opts = DEF_OPTS; 80static int scsi_debug_every_nth = DEF_EVERY_NTH; 81static int scsi_debug_cmnd_count = 0; 82static int scsi_debug_delay = DEF_DELAY; 83 84#define NR_HOSTS_PRESENT (((scsi_debug_num_devs - 1) / 7) + 1) 85#define N_HEAD 8 86#define N_SECTOR 32 87#define DEV_READONLY(TGT) (0) 88#define DEV_REMOVEABLE(TGT) (0) 89#define PERIPH_DEVICE_TYPE(TGT) (TYPE_DISK); 90 91static int scsi_debug_dev_size_mb = DEF_DEV_SIZE_MB; 92#define STORE_SIZE (scsi_debug_dev_size_mb * 1024 * 1024) 93 94/* default sector size is 512 bytes, 2**9 bytes */ 95#define POW2_SECT_SIZE 9 96#define SECT_SIZE (1 << POW2_SECT_SIZE) 97 98#define N_CYLINDER (STORE_SIZE / (SECT_SIZE * N_SECTOR * N_HEAD)) 99 100/* Time to wait before completing a command */ 101#define CAPACITY (N_HEAD * N_SECTOR * N_CYLINDER) 102#define SECT_SIZE_PER(TGT) SECT_SIZE 103 104 105#define SDEBUG_SENSE_LEN 32 106 107struct sdebug_dev_info { 108 Scsi_Device * sdp; 109 unsigned char sense_buff[SDEBUG_SENSE_LEN]; /* weak nexus */ 110 char reset; 111}; 112static struct sdebug_dev_info * devInfop; 113 114typedef void (* done_funct_t) (Scsi_Cmnd *); 115 116struct sdebug_queued_cmd { 117 int in_use; 118 struct timer_list cmnd_timer; 119 done_funct_t done_funct; 120 struct scsi_cmnd * a_cmnd; 121 int scsi_result; 122}; 123static struct sdebug_queued_cmd queued_arr[SCSI_DEBUG_CANQUEUE]; 124 125static unsigned char * fake_storep; /* ramdisk storage */ 126 127static unsigned char broken_buff[SDEBUG_SENSE_LEN]; 128 129static int num_aborts = 0; 130static int num_dev_resets = 0; 131static int num_bus_resets = 0; 132static int num_host_resets = 0; 133 134static spinlock_t queued_arr_lock = SPIN_LOCK_UNLOCKED; 135static rwlock_t atomic_rw = RW_LOCK_UNLOCKED; 136 137 138/* function declarations */ 139static int resp_inquiry(unsigned char * cmd, int target, unsigned char * buff, 140 int bufflen, struct sdebug_dev_info * devip); 141static int resp_mode_sense(unsigned char * cmd, int target, 142 unsigned char * buff, int bufflen, 143 struct sdebug_dev_info * devip); 144static int resp_read(Scsi_Cmnd * SCpnt, int upper_blk, int block, 145 int num, struct sdebug_dev_info * devip); 146static int resp_write(Scsi_Cmnd * SCpnt, int upper_blk, int block, int num, 147 struct sdebug_dev_info * devip); 148static int resp_report_luns(unsigned char * cmd, unsigned char * buff, 149 int bufflen, struct sdebug_dev_info * devip); 150static void timer_intr_handler(unsigned long); 151static struct sdebug_dev_info * devInfoReg(Scsi_Device * sdp); 152static void mk_sense_buffer(struct sdebug_dev_info * devip, int key, 153 int asc, int asq, int inbandLen); 154static int check_reset(Scsi_Cmnd * SCpnt, struct sdebug_dev_info * devip); 155static int schedule_resp(struct scsi_cmnd * cmnd, 156 struct sdebug_dev_info * devip, 157 done_funct_t done, int scsi_result, int delta_jiff); 158static void init_all_queued(void); 159static void stop_all_queued(void); 160static int stop_queued_cmnd(struct scsi_cmnd * cmnd); 161static int inquiry_evpd_83(unsigned char * arr, int dev_id_num, 162 const char * dev_id_str, int dev_id_str_len); 163 164 165static Scsi_Host_Template driver_template = SCSI_DEBUG_TEMPLATE; 166 167 168static 169int scsi_debug_queuecommand(Scsi_Cmnd * SCpnt, done_funct_t done) 170{ 171 unsigned char *cmd = (unsigned char *) SCpnt->cmnd; 172 int block; 173 int upper_blk; 174 unsigned char *buff; 175 int errsts = 0; 176 int target = SCpnt->target; 177 int bufflen = SCpnt->request_bufflen; 178 int num, capac; 179 struct sdebug_dev_info * devip = NULL; 180 unsigned char * sbuff; 181 182 if (done == NULL) 183 return 0; /* assume mid level reprocessing command */ 184 185 if (SCpnt->use_sg) { /* just use first element */ 186 struct scatterlist *sgpnt = (struct scatterlist *) 187 SCpnt->request_buffer; 188 189 buff = sgpnt[0].address; 190 bufflen = sgpnt[0].length; 191 /* READ and WRITE process scatterlist themselves */ 192 } 193 else 194 buff = (unsigned char *) SCpnt->request_buffer; 195 if (NULL == buff) { 196 printk(KERN_WARNING "scsi_debug:qc: buff was NULL??\n"); 197 buff = broken_buff; /* just point at dummy */ 198 bufflen = SDEBUG_SENSE_LEN; 199 } 200 201 if(target == driver_template.this_id) { 202 printk(KERN_WARNING 203 "scsi_debug: initiator's id used as target!\n"); 204 return schedule_resp(SCpnt, NULL, done, 0, 0); 205 } 206 207 if ((target > driver_template.this_id) || (SCpnt->lun != 0)) 208 return schedule_resp(SCpnt, NULL, done, 209 DID_NO_CONNECT << 16, 0); 210 if (NULL == SCpnt->device->hostdata) { 211 devip = devInfoReg(SCpnt->device); 212 if (NULL == devip) 213 return schedule_resp(SCpnt, NULL, done, 214 DID_NO_CONNECT << 16, 0); 215 SCpnt->device->hostdata = devip; 216 } 217 devip = SCpnt->device->hostdata; 218 219 if ((SCSI_DEBUG_OPT_EVERY_NTH & scsi_debug_opts) && 220 (scsi_debug_every_nth > 0) && 221 (++scsi_debug_cmnd_count >= scsi_debug_every_nth)) { 222 scsi_debug_cmnd_count =0; 223 return 0; /* ignore command causing timeout */ 224 } 225 226 switch (*cmd) { 227 case INQUIRY: /* mandatory */ 228 /* assume INQUIRY called first so setup max_cmd_len */ 229 if (SCpnt->host->max_cmd_len != SCSI_DEBUG_MAX_CMD_LEN) 230 SCpnt->host->max_cmd_len = SCSI_DEBUG_MAX_CMD_LEN; 231 errsts = resp_inquiry(cmd, target, buff, bufflen, devip); 232 break; 233 case REQUEST_SENSE: /* mandatory */ 234 /* Since this driver indicates autosense by placing the 235 * sense buffer in the scsi_cmnd structure in the response 236 * (when CHECK_CONDITION is set), the mid level shouldn't 237 * need to call REQUEST_SENSE */ 238 if (devip) { 239 sbuff = devip->sense_buff; 240 memcpy(buff, sbuff, (bufflen < SDEBUG_SENSE_LEN) ? 241 bufflen : SDEBUG_SENSE_LEN); 242 mk_sense_buffer(devip, 0, 0x0, 0, 7); 243 } else { 244 memset(buff, 0, bufflen); 245 buff[0] = 0x70; 246 } 247 break; 248 case START_STOP: 249 errsts = check_reset(SCpnt, devip); 250 break; 251 case ALLOW_MEDIUM_REMOVAL: 252 if ((errsts = check_reset(SCpnt, devip))) 253 break; 254 if (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts) 255 printk("\tMedium removal %s\n", 256 cmd[4] ? "inhibited" : "enabled"); 257 break; 258 case SEND_DIAGNOSTIC: /* mandatory */ 259 memset(buff, 0, bufflen); 260 break; 261 case TEST_UNIT_READY: /* mandatory */ 262 memset(buff, 0, bufflen); 263 break; 264 case RESERVE: 265 errsts = check_reset(SCpnt, devip); 266 memset(buff, 0, bufflen); 267 break; 268 case RESERVE_10: 269 errsts = check_reset(SCpnt, devip); 270 memset(buff, 0, bufflen); 271 break; 272 case RELEASE: 273 errsts = check_reset(SCpnt, devip); 274 memset(buff, 0, bufflen); 275 break; 276 case RELEASE_10: 277 errsts = check_reset(SCpnt, devip); 278 memset(buff, 0, bufflen); 279 break; 280 case READ_CAPACITY: 281 errsts = check_reset(SCpnt, devip); 282 memset(buff, 0, bufflen); 283 if (bufflen > 7) { 284 capac = CAPACITY - 1; 285 buff[0] = (capac >> 24); 286 buff[1] = (capac >> 16) & 0xff; 287 buff[2] = (capac >> 8) & 0xff; 288 buff[3] = capac & 0xff; 289 buff[6] = (SECT_SIZE_PER(target) >> 8) & 0xff; 290 buff[7] = SECT_SIZE_PER(target) & 0xff; 291 } 292 break; 293 case SCSI_CMD_READ_16: /* SBC-2 */ 294 case READ_12: 295 case READ_10: 296 case READ_6: 297 if ((errsts = check_reset(SCpnt, devip))) 298 break; 299 upper_blk = 0; 300 if ((*cmd) == SCSI_CMD_READ_16) { 301 upper_blk = cmd[5] + (cmd[4] << 8) + 302 (cmd[3] << 16) + (cmd[2] << 24); 303 block = cmd[9] + (cmd[8] << 8) + 304 (cmd[7] << 16) + (cmd[6] << 24); 305 num = cmd[13] + (cmd[12] << 8) + 306 (cmd[11] << 16) + (cmd[10] << 24); 307 } else if ((*cmd) == READ_12) { 308 block = cmd[5] + (cmd[4] << 8) + 309 (cmd[3] << 16) + (cmd[2] << 24); 310 num = cmd[9] + (cmd[8] << 8) + 311 (cmd[7] << 16) + (cmd[6] << 24); 312 } else if ((*cmd) == READ_10) { 313 block = cmd[5] + (cmd[4] << 8) + 314 (cmd[3] << 16) + (cmd[2] << 24); 315 num = cmd[8] + (cmd[7] << 8); 316 } else { 317 block = cmd[3] + (cmd[2] << 8) + 318 ((cmd[1] & 0x1f) << 16); 319 num = cmd[4]; 320 } 321 errsts = resp_read(SCpnt, upper_blk, block, num, devip); 322 break; 323 case REPORT_LUNS: 324 errsts = resp_report_luns(cmd, buff, bufflen, devip); 325 break; 326 case SCSI_CMD_WRITE_16: /* SBC-2 */ 327 case WRITE_12: 328 case WRITE_10: 329 case WRITE_6: 330 if ((errsts = check_reset(SCpnt, devip))) 331 break; 332 upper_blk = 0; 333 if ((*cmd) == SCSI_CMD_WRITE_16) { 334 upper_blk = cmd[5] + (cmd[4] << 8) + 335 (cmd[3] << 16) + (cmd[2] << 24); 336 block = cmd[9] + (cmd[8] << 8) + 337 (cmd[7] << 16) + (cmd[6] << 24); 338 num = cmd[13] + (cmd[12] << 8) + 339 (cmd[11] << 16) + (cmd[10] << 24); 340 } else if ((*cmd) == WRITE_12) { 341 block = cmd[5] + (cmd[4] << 8) + 342 (cmd[3] << 16) + (cmd[2] << 24); 343 num = cmd[9] + (cmd[8] << 8) + 344 (cmd[7] << 16) + (cmd[6] << 24); 345 } else if ((*cmd) == WRITE_10) { 346 block = cmd[5] + (cmd[4] << 8) + 347 (cmd[3] << 16) + (cmd[2] << 24); 348 num = cmd[8] + (cmd[7] << 8); 349 } else { 350 block = cmd[3] + (cmd[2] << 8) + 351 ((cmd[1] & 0x1f) << 16); 352 num = cmd[4]; 353 } 354 errsts = resp_write(SCpnt, upper_blk, block, num, devip); 355 break; 356 case MODE_SENSE: 357 case MODE_SENSE_10: 358 errsts = resp_mode_sense(cmd, target, buff, bufflen, devip); 359 break; 360 default: 361 if ((errsts = check_reset(SCpnt, devip))) 362 break; 363 mk_sense_buffer(devip, ILLEGAL_REQUEST, 0x20, 0, 14); 364 errsts = (COMMAND_COMPLETE << 8) | (CHECK_CONDITION << 1); 365 break; 366 } 367 return schedule_resp(SCpnt, devip, done, errsts, scsi_debug_delay); 368} 369 370static int scsi_debug_ioctl(Scsi_Device *dev, int cmd, void *arg) 371{ 372 if (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts) { 373 printk(KERN_INFO "scsi_debug: ioctl: cmd=0x%x\n", cmd); 374 } 375 /* return -ENOTTY; // Unix mandates this but apps get upset */ 376 return -EINVAL; 377} 378 379static int check_reset(Scsi_Cmnd * SCpnt, struct sdebug_dev_info * devip) 380{ 381 if (devip->reset) { 382 devip->reset = 0; 383 mk_sense_buffer(devip, UNIT_ATTENTION, 0x29, 0, 14); 384 return (COMMAND_COMPLETE << 8) | (CHECK_CONDITION << 1); 385 } 386 return 0; 387} 388 389#define SDEBUG_LONG_INQ_SZ 58 390#define SDEBUG_MAX_INQ_ARR_SZ 128 391 392static const char * vendor_id = "Linux "; 393static const char * product_id = "scsi_debug "; 394static const char * product_rev = "0004"; 395 396static int inquiry_evpd_83(unsigned char * arr, int dev_id_num, 397 const char * dev_id_str, int dev_id_str_len) 398{ 399 int num; 400 401 /* Two identification descriptors: */ 402 /* T10 vendor identifier field format (faked) */ 403 arr[0] = 0x2; /* ASCII */ 404 arr[1] = 0x1; 405 arr[2] = 0x0; 406 memcpy(&arr[4], vendor_id, 8); 407 memcpy(&arr[12], product_id, 16); 408 memcpy(&arr[28], dev_id_str, dev_id_str_len); 409 num = 8 + 16 + dev_id_str_len; 410 arr[3] = num; 411 num += 4; 412 /* NAA IEEE registered identifier (faked) */ 413 arr[num] = 0x1; /* binary */ 414 arr[num + 1] = 0x3; 415 arr[num + 2] = 0x0; 416 arr[num + 3] = 0x8; 417 arr[num + 4] = 0x51; /* ieee company id=0x123456 (faked) */ 418 arr[num + 5] = 0x23; 419 arr[num + 6] = 0x45; 420 arr[num + 7] = 0x60; 421 arr[num + 8] = (dev_id_num >> 24); 422 arr[num + 9] = (dev_id_num >> 16) & 0xff; 423 arr[num + 10] = (dev_id_num >> 8) & 0xff; 424 arr[num + 11] = dev_id_num & 0xff; 425 return num + 12; 426} 427 428static int resp_inquiry(unsigned char * cmd, int target, unsigned char * buff, 429 int bufflen, struct sdebug_dev_info * devip) 430{ 431 unsigned char pq_pdt; 432 unsigned char arr[SDEBUG_MAX_INQ_ARR_SZ]; 433 int min_len = bufflen > SDEBUG_MAX_INQ_ARR_SZ ? 434 SDEBUG_MAX_INQ_ARR_SZ : bufflen; 435 436 if (bufflen < cmd[4]) 437 printk(KERN_INFO "scsi_debug: inquiry: bufflen=%d " 438 "< alloc_length=%d\n", bufflen, (int)cmd[4]); 439 memset(buff, 0, bufflen); 440 memset(arr, 0, SDEBUG_MAX_INQ_ARR_SZ); 441 pq_pdt = PERIPH_DEVICE_TYPE(target); 442 arr[0] = pq_pdt; 443 if (0x2 & cmd[1]) { /* CMDDT bit set */ 444 mk_sense_buffer(devip, ILLEGAL_REQUEST, 0x24, 0, 14); 445 return (COMMAND_COMPLETE << 8) | (CHECK_CONDITION << 1); 446 } else if (0x1 & cmd[1]) { /* EVPD bit set */ 447 int dev_id_num, len; 448 char dev_id_str[6]; 449 450 dev_id_num = ((devip->sdp->host->host_no + 1) * 1000) + 451 devip->sdp->id; 452 len = snprintf(dev_id_str, 6, "%d", dev_id_num); 453 len = (len > 6) ? 6 : len; 454 if (0 == cmd[2]) { /* supported vital product data pages */ 455 arr[3] = 3; 456 arr[4] = 0x0; /* this page */ 457 arr[5] = 0x80; /* unit serial number */ 458 arr[6] = 0x83; /* device identification */ 459 } else if (0x80 == cmd[2]) { /* unit serial number */ 460 arr[1] = 0x80; 461 arr[3] = len; 462 memcpy(&arr[4], dev_id_str, len); 463 } else if (0x83 == cmd[2]) { /* device identification */ 464 arr[1] = 0x83; 465 arr[3] = inquiry_evpd_83(&arr[4], dev_id_num, 466 dev_id_str, len); 467 } else { 468 /* Illegal request, invalid field in cdb */ 469 mk_sense_buffer(devip, ILLEGAL_REQUEST, 0x24, 0, 14); 470 return (COMMAND_COMPLETE << 8) | (CHECK_CONDITION << 1); 471 } 472 memcpy(buff, arr, min_len); 473 return 0; 474 } 475 /* drops through here for a standard inquiry */ 476 arr[1] = DEV_REMOVEABLE(target) ? 0x80 : 0; /* Removable disk */ 477 arr[2] = 3; /* claim SCSI 3 */ 478 arr[4] = SDEBUG_LONG_INQ_SZ - 5; 479 arr[7] = 0x3a; /* claim: WBUS16, SYNC, LINKED + CMDQUE */ 480 memcpy(&arr[8], vendor_id, 8); 481 memcpy(&arr[16], product_id, 16); 482 memcpy(&arr[32], product_rev, 4); 483 memcpy(buff, arr, min_len); 484 return 0; 485} 486 487/* <<Following mode page info copied from ST318451LW>> */ 488 489static int resp_err_recov_pg(unsigned char * p, int pcontrol, int target) 490{ /* Read-Write Error Recovery page for mode_sense */ 491 unsigned char err_recov_pg[] = {0x1, 0xa, 0xc0, 11, 240, 0, 0, 0, 492 5, 0, 0xff, 0xff}; 493 494 memcpy(p, err_recov_pg, sizeof(err_recov_pg)); 495 if (1 == pcontrol) 496 memset(p + 2, 0, sizeof(err_recov_pg) - 2); 497 return sizeof(err_recov_pg); 498} 499 500static int resp_disconnect_pg(unsigned char * p, int pcontrol, int target) 501{ /* Disconnect-Reconnect page for mode_sense */ 502 unsigned char disconnect_pg[] = {0x2, 0xe, 128, 128, 0, 10, 0, 0, 503 0, 0, 0, 0, 0, 0, 0, 0}; 504 505 memcpy(p, disconnect_pg, sizeof(disconnect_pg)); 506 if (1 == pcontrol) 507 memset(p + 2, 0, sizeof(disconnect_pg) - 2); 508 return sizeof(disconnect_pg); 509} 510 511static int resp_format_pg(unsigned char * p, int pcontrol, int target) 512{ /* Format device page for mode_sense */ 513 unsigned char format_pg[] = {0x3, 0x16, 0, 0, 0, 0, 0, 0, 514 0, 0, 0, 0, 0, 0, 0, 0, 515 0, 0, 0, 0, 0x40, 0, 0, 0}; 516 517 memcpy(p, format_pg, sizeof(format_pg)); 518 p[10] = (N_SECTOR >> 8) & 0xff; 519 p[11] = N_SECTOR & 0xff; 520 p[12] = (SECT_SIZE >> 8) & 0xff; 521 p[13] = SECT_SIZE & 0xff; 522 if (DEV_REMOVEABLE(target)) 523 p[20] |= 0x20; /* should agree with INQUIRY */ 524 if (1 == pcontrol) 525 memset(p + 2, 0, sizeof(format_pg) - 2); 526 return sizeof(format_pg); 527} 528 529static int resp_caching_pg(unsigned char * p, int pcontrol, int target) 530{ /* Caching page for mode_sense */ 531 unsigned char caching_pg[] = {0x8, 18, 0x14, 0, 0xff, 0xff, 0, 0, 532 0xff, 0xff, 0xff, 0xff, 0x80, 0x14, 0, 0, 0, 0, 0, 0}; 533 534 memcpy(p, caching_pg, sizeof(caching_pg)); 535 if (1 == pcontrol) 536 memset(p + 2, 0, sizeof(caching_pg) - 2); 537 return sizeof(caching_pg); 538} 539 540static int resp_ctrl_m_pg(unsigned char * p, int pcontrol, int target) 541{ /* Control mode page for mode_sense */ 542 unsigned char ctrl_m_pg[] = {0xa, 10, 2, 0, 0, 0, 0, 0, 543 0, 0, 0x2, 0x4b}; 544 545 memcpy(p, ctrl_m_pg, sizeof(ctrl_m_pg)); 546 if (1 == pcontrol) 547 memset(p + 2, 0, sizeof(ctrl_m_pg) - 2); 548 return sizeof(ctrl_m_pg); 549} 550 551 552#define SDEBUG_MAX_MSENSE_SZ 256 553 554static int resp_mode_sense(unsigned char * cmd, int target, 555 unsigned char * buff, int bufflen, 556 struct sdebug_dev_info * devip) 557{ 558 unsigned char dbd; 559 int pcontrol, pcode; 560 unsigned char dev_spec; 561 int alloc_len, msense_6, offset, len; 562 unsigned char * ap; 563 unsigned char arr[SDEBUG_MAX_MSENSE_SZ]; 564 int min_len = bufflen > SDEBUG_MAX_MSENSE_SZ ? 565 SDEBUG_MAX_MSENSE_SZ : bufflen; 566 567 SCSI_LOG_LLQUEUE(3, printk("Mode sense ...(%p %d)\n", buff, bufflen)); 568 dbd = cmd[1] & 0x8; 569 pcontrol = (cmd[2] & 0xc0) >> 6; 570 pcode = cmd[2] & 0x3f; 571 msense_6 = (MODE_SENSE == cmd[0]); 572 alloc_len = msense_6 ? cmd[4] : ((cmd[7] << 8) | cmd[6]); 573 /* printk(KERN_INFO "msense: dbd=%d pcontrol=%d pcode=%d " 574 "msense_6=%d alloc_len=%d\n", dbd, pcontrol, pcode, " 575 "msense_6, alloc_len); */ 576 if (bufflen < alloc_len) 577 printk(KERN_INFO "scsi_debug: mode_sense: bufflen=%d " 578 "< alloc_length=%d\n", bufflen, alloc_len); 579 memset(buff, 0, bufflen); 580 memset(arr, 0, SDEBUG_MAX_MSENSE_SZ); 581 if (0x3 == pcontrol) { /* Saving values not supported */ 582 mk_sense_buffer(devip, ILLEGAL_REQUEST, 0x39, 0, 14); 583 return (COMMAND_COMPLETE << 8) | (CHECK_CONDITION << 1); 584 } 585 dev_spec = DEV_READONLY(target) ? 0x80 : 0x0; 586 if (msense_6) { 587 arr[2] = dev_spec; 588 offset = 4; 589 } else { 590 arr[3] = dev_spec; 591 offset = 8; 592 } 593 ap = arr + offset; 594 595 switch (pcode) { 596 case 0x1: /* Read-Write error recovery page, direct access */ 597 len = resp_err_recov_pg(ap, pcontrol, target); 598 offset += len; 599 break; 600 case 0x2: /* Disconnect-Reconnect page, all devices */ 601 len = resp_disconnect_pg(ap, pcontrol, target); 602 offset += len; 603 break; 604 case 0x3: /* Format device page, direct access */ 605 len = resp_format_pg(ap, pcontrol, target); 606 offset += len; 607 break; 608 case 0x8: /* Caching page, direct access */ 609 len = resp_caching_pg(ap, pcontrol, target); 610 offset += len; 611 break; 612 case 0xa: /* Control Mode page, all devices */ 613 len = resp_ctrl_m_pg(ap, pcontrol, target); 614 offset += len; 615 break; 616 case 0x3f: /* Read all Mode pages */ 617 len = resp_err_recov_pg(ap, pcontrol, target); 618 len += resp_disconnect_pg(ap + len, pcontrol, target); 619 len += resp_caching_pg(ap + len, pcontrol, target); 620 len += resp_ctrl_m_pg(ap + len, pcontrol, target); 621 offset += len; 622 break; 623 default: 624 mk_sense_buffer(devip, ILLEGAL_REQUEST, 0x24, 0, 14); 625 return (COMMAND_COMPLETE << 8) | (CHECK_CONDITION << 1); 626 } 627 if (msense_6) 628 arr[0] = offset - 1; 629 else { 630 offset -= 2; 631 arr[0] = (offset >> 8) & 0xff; 632 arr[1] = offset & 0xff; 633 } 634 memcpy(buff, arr, min_len); 635 return 0; 636} 637 638static int resp_read(Scsi_Cmnd * SCpnt, int upper_blk, int block, int num, 639 struct sdebug_dev_info * devip) 640{ 641 unsigned char *buff = (unsigned char *) SCpnt->request_buffer; 642 int nbytes, sgcount; 643 struct scatterlist *sgpnt = NULL; 644 int bufflen = SCpnt->request_bufflen; 645 unsigned long iflags; 646 647 if (upper_blk || (block + num > CAPACITY)) { 648 mk_sense_buffer(devip, ILLEGAL_REQUEST, 0x21, 0, 14); 649 return (COMMAND_COMPLETE << 8) | (CHECK_CONDITION << 1); 650 } 651 if ((SCSI_DEBUG_OPT_MEDIUM_ERR & scsi_debug_opts) && 652 (block >= OPT_MEDIUM_ERR_ADDR) && 653 (block < (OPT_MEDIUM_ERR_ADDR + num))) { 654 mk_sense_buffer(devip, MEDIUM_ERROR, 0x11, 0, 14); 655 /* claim unrecoverable read error */ 656 return (COMMAND_COMPLETE << 8) | (CHECK_CONDITION << 1); 657 } 658 read_lock_irqsave(&atomic_rw, iflags); 659 sgcount = 0; 660 nbytes = bufflen; 661 /* printk(KERN_INFO "scsi_debug_read: block=%d, tot_bufflen=%d\n", 662 block, bufflen); */ 663 if (SCpnt->use_sg) { 664 sgcount = 0; 665 sgpnt = (struct scatterlist *) buff; 666 buff = sgpnt[sgcount].address; 667 bufflen = sgpnt[sgcount].length; 668 } 669 do { 670 memcpy(buff, fake_storep + (block * SECT_SIZE), bufflen); 671 nbytes -= bufflen; 672 if (SCpnt->use_sg) { 673 block += bufflen >> POW2_SECT_SIZE; 674 sgcount++; 675 if (nbytes) { 676 buff = sgpnt[sgcount].address; 677 bufflen = sgpnt[sgcount].length; 678 } 679 } else if (nbytes > 0) 680 printk(KERN_WARNING "scsi_debug:resp_read: unexpected " 681 "nbytes=%d\n", nbytes); 682 } while (nbytes); 683 read_unlock_irqrestore(&atomic_rw, iflags); 684 return 0; 685} 686 687static int resp_write(Scsi_Cmnd * SCpnt, int upper_blk, int block, int num, 688 struct sdebug_dev_info * devip) 689{ 690 unsigned char *buff = (unsigned char *) SCpnt->request_buffer; 691 int nbytes, sgcount; 692 struct scatterlist *sgpnt = NULL; 693 int bufflen = SCpnt->request_bufflen; 694 unsigned long iflags; 695 696 if (upper_blk || (block + num > CAPACITY)) { 697 mk_sense_buffer(devip, ILLEGAL_REQUEST, 0x21, 0, 14); 698 return (COMMAND_COMPLETE << 8) | (CHECK_CONDITION << 1); 699 } 700 701 write_lock_irqsave(&atomic_rw, iflags); 702 sgcount = 0; 703 nbytes = bufflen; 704 if (SCpnt->use_sg) { 705 sgcount = 0; 706 sgpnt = (struct scatterlist *) buff; 707 buff = sgpnt[sgcount].address; 708 bufflen = sgpnt[sgcount].length; 709 } 710 do { 711 memcpy(fake_storep + (block * SECT_SIZE), buff, bufflen); 712 713 nbytes -= bufflen; 714 if (SCpnt->use_sg) { 715 block += bufflen >> POW2_SECT_SIZE; 716 sgcount++; 717 if (nbytes) { 718 buff = sgpnt[sgcount].address; 719 bufflen = sgpnt[sgcount].length; 720 } 721 } else if (nbytes > 0) 722 printk(KERN_WARNING "scsi_debug:resp_write: " 723 "unexpected nbytes=%d\n", nbytes); 724 } while (nbytes); 725 write_unlock_irqrestore(&atomic_rw, iflags); 726 return 0; 727} 728 729static int resp_report_luns(unsigned char * cmd, unsigned char * buff, 730 int bufflen, struct sdebug_dev_info * devip) 731{ 732 unsigned int alloc_len; 733 int select_report = (int)cmd[2]; 734 735 alloc_len = cmd[9] + (cmd[8] << 8) + (cmd[7] << 16) + (cmd[6] << 24); 736 if ((alloc_len < 16) || (select_report > 2)) { 737 mk_sense_buffer(devip, ILLEGAL_REQUEST, 0x24, 0, 14); 738 return (COMMAND_COMPLETE << 8) | (CHECK_CONDITION << 1); 739 } 740 if (bufflen > 3) { 741 memset(buff, 0, bufflen); 742 buff[3] = 8; 743 } 744 return 0; 745} 746 747/* When timer goes off this function is called. */ 748static void timer_intr_handler(unsigned long indx) 749{ 750 struct sdebug_queued_cmd * sqcp; 751 unsigned int iflags; 752 753 if (indx >= SCSI_DEBUG_CANQUEUE) { 754 printk(KERN_ERR "scsi_debug:timer_intr_handler: indx too " 755 "large\n"); 756 return; 757 } 758 spin_lock_irqsave(&queued_arr_lock, iflags); 759 sqcp = &queued_arr[(int)indx]; 760 if (! sqcp->in_use) { 761 printk(KERN_ERR "scsi_debug:timer_intr_handler: Unexpected " 762 "interrupt\n"); 763 spin_unlock_irqrestore(&queued_arr_lock, iflags); 764 return; 765 } 766 sqcp->in_use = 0; 767 if (sqcp->done_funct) 768 sqcp->done_funct(sqcp->a_cmnd); /* callback to mid level */ 769 sqcp->done_funct = NULL; 770 spin_unlock_irqrestore(&queued_arr_lock, iflags); 771} 772 773static int initialized = 0; 774static int num_present = 0; 775static const char * sdebug_proc_name = "scsi_debug"; 776 777static int scsi_debug_detect(Scsi_Host_Template * tpnt) 778{ 779 int k, sz; 780 781 if (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts) 782 printk(KERN_INFO "scsi_debug: detect\n"); 783 if (0 == initialized) { 784 ++initialized; 785 sz = sizeof(struct sdebug_dev_info) * scsi_debug_num_devs; 786 devInfop = vmalloc(sz); 787 if (NULL == devInfop) { 788 printk(KERN_ERR "scsi_debug_detect: out of " 789 "memory, 0.5\n"); 790 return 0; 791 } 792 memset(devInfop, 0, sz); 793 sz = STORE_SIZE; 794 fake_storep = vmalloc(sz); 795 if (NULL == fake_storep) { 796 printk(KERN_ERR "scsi_debug_detect: out of memory" 797 ", 0\n"); 798 return 0; 799 } 800 memset(fake_storep, 0, sz); 801 init_all_queued(); 802 tpnt->proc_name = (char *)sdebug_proc_name; 803 for (num_present = 0, k = 0; k < NR_HOSTS_PRESENT; k++) { 804 if (NULL == scsi_register(tpnt, 0)) 805 printk(KERN_ERR "scsi_debug_detect: " 806 "scsi_register failed k=%d\n", k); 807 else 808 ++num_present; 809 } 810 return num_present; 811 } else { 812 printk(KERN_WARNING "scsi_debug_detect: called again\n"); 813 return 0; 814 } 815} 816 817 818static int num_releases = 0; 819 820static int scsi_debug_release(struct Scsi_Host * hpnt) 821{ 822 if (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts) 823 printk(KERN_INFO "scsi_debug: release\n"); 824 stop_all_queued(); 825 scsi_unregister(hpnt); 826 if (++num_releases == num_present) { 827 vfree(fake_storep); 828 vfree(devInfop); 829 } 830 return 0; 831} 832 833static struct sdebug_dev_info * devInfoReg(Scsi_Device * sdp) 834{ 835 int k; 836 struct sdebug_dev_info * devip; 837 838 for (k = 0; k < scsi_debug_num_devs; ++k) { 839 devip = &devInfop[k]; 840 if (devip->sdp == sdp) 841 return devip; 842 } 843 for (k = 0; k < scsi_debug_num_devs; ++k) { 844 devip = &devInfop[k]; 845 if (NULL == devip->sdp) { 846 devip->sdp = sdp; 847 devip->reset = 1; 848 memset(devip->sense_buff, 0, SDEBUG_SENSE_LEN); 849 devip->sense_buff[0] = 0x70; 850 return devip; 851 } 852 } 853 return NULL; 854} 855 856static void mk_sense_buffer(struct sdebug_dev_info * devip, int key, 857 int asc, int asq, int inbandLen) 858{ 859 unsigned char * sbuff; 860 861 sbuff = devip->sense_buff; 862 memset(sbuff, 0, SDEBUG_SENSE_LEN); 863 if (inbandLen > SDEBUG_SENSE_LEN) 864 inbandLen = SDEBUG_SENSE_LEN; 865 sbuff[0] = 0x70; 866 sbuff[2] = key; 867 sbuff[7] = (inbandLen > 7) ? (inbandLen - 8) : 0; 868 sbuff[12] = asc; 869 sbuff[13] = asq; 870} 871 872static int scsi_debug_abort(Scsi_Cmnd * SCpnt) 873{ 874 if (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts) 875 printk(KERN_INFO "scsi_debug: abort\n"); 876 ++num_aborts; 877 stop_queued_cmnd(SCpnt); 878 return SUCCESS; 879} 880 881static int scsi_debug_biosparam(Disk * disk, kdev_t dev, int *info) 882{ 883 if (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts) 884 printk(KERN_INFO "scsi_debug: biosparam\n"); 885 /* int size = disk->capacity; */ 886 info[0] = N_HEAD; 887 info[1] = N_SECTOR; 888 info[2] = N_CYLINDER; 889 if (info[2] >= 1024) 890 info[2] = 1024; 891 return 0; 892} 893 894static int scsi_debug_device_reset(Scsi_Cmnd * SCpnt) 895{ 896 Scsi_Device * sdp; 897 int k; 898 899 if (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts) 900 printk(KERN_INFO "scsi_debug: device_reset\n"); 901 ++num_dev_resets; 902 if (SCpnt && ((sdp = SCpnt->device))) { 903 for (k = 0; k < scsi_debug_num_devs; ++k) { 904 if (sdp->hostdata == (devInfop + k)) 905 break; 906 } 907 if (k < scsi_debug_num_devs) 908 devInfop[k].reset = 1; 909 } 910 return SUCCESS; 911} 912 913static int scsi_debug_bus_reset(Scsi_Cmnd * SCpnt) 914{ 915 Scsi_Device * sdp; 916 struct Scsi_Host * hp; 917 int k; 918 919 if (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts) 920 printk(KERN_INFO "scsi_debug: bus_reset\n"); 921 ++num_bus_resets; 922 if (SCpnt && ((sdp = SCpnt->device)) && ((hp = sdp->host))) { 923 for (k = 0; k < scsi_debug_num_devs; ++k) { 924 if (hp == devInfop[k].sdp->host) 925 devInfop[k].reset = 1; 926 } 927 } 928 return SUCCESS; 929} 930 931static int scsi_debug_host_reset(Scsi_Cmnd * SCpnt) 932{ 933 int k; 934 935 if (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts) 936 printk(KERN_INFO "scsi_debug: host_reset\n"); 937 ++num_host_resets; 938 for (k = 0; k < scsi_debug_num_devs; ++k) 939 devInfop[k].reset = 1; 940 stop_all_queued(); 941 942 return SUCCESS; 943} 944 945/* Returns 1 if found 'cmnd' and deleted its timer. else returns 0 */ 946static int stop_queued_cmnd(struct scsi_cmnd * cmnd) 947{ 948 unsigned long iflags; 949 int k; 950 struct sdebug_queued_cmd * sqcp; 951 952 spin_lock_irqsave(&queued_arr_lock, iflags); 953 for (k = 0; k < SCSI_DEBUG_CANQUEUE; ++k) { 954 sqcp = &queued_arr[k]; 955 if (sqcp->in_use && (cmnd == sqcp->a_cmnd)) { 956 del_timer_sync(&sqcp->cmnd_timer); 957 sqcp->in_use = 0; 958 sqcp->a_cmnd = NULL; 959 break; 960 } 961 } 962 spin_unlock_irqrestore(&queued_arr_lock, iflags); 963 return (k < SCSI_DEBUG_CANQUEUE) ? 1 : 0; 964} 965 966/* Deletes (stops) timers of all queued commands */ 967static void stop_all_queued(void) 968{ 969 unsigned long iflags; 970 int k; 971 struct sdebug_queued_cmd * sqcp; 972 973 spin_lock_irqsave(&queued_arr_lock, iflags); 974 for (k = 0; k < SCSI_DEBUG_CANQUEUE; ++k) { 975 sqcp = &queued_arr[k]; 976 if (sqcp->in_use && sqcp->a_cmnd) { 977 del_timer_sync(&sqcp->cmnd_timer); 978 sqcp->in_use = 0; 979 sqcp->a_cmnd = NULL; 980 } 981 } 982 spin_unlock_irqrestore(&queued_arr_lock, iflags); 983} 984 985/* Initializes timers in queued array */ 986static void init_all_queued(void) 987{ 988 unsigned long iflags; 989 int k; 990 struct sdebug_queued_cmd * sqcp; 991 992 spin_lock_irqsave(&queued_arr_lock, iflags); 993 for (k = 0; k < SCSI_DEBUG_CANQUEUE; ++k) { 994 sqcp = &queued_arr[k]; 995 init_timer(&sqcp->cmnd_timer); 996 sqcp->in_use = 0; 997 sqcp->a_cmnd = NULL; 998 } 999 spin_unlock_irqrestore(&queued_arr_lock, iflags); 1000} 1001 1002static int schedule_resp(struct scsi_cmnd * cmnd, 1003 struct sdebug_dev_info * devip, 1004 done_funct_t done, int scsi_result, int delta_jiff) 1005{ 1006 int k, num; 1007 1008 if (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts) { 1009 printk(KERN_INFO "scsi_debug: cmd "); 1010 for (k = 0, num = cmnd->cmd_len; k < num; ++k) 1011 printk("%02x ", (int)cmnd->cmnd[k]); 1012 printk("result=0x%x\n", scsi_result); 1013 } 1014 if (cmnd && devip) { 1015 /* simulate autosense by this driver */ 1016 if (CHECK_CONDITION == status_byte(scsi_result)) 1017 memcpy(cmnd->sense_buffer, devip->sense_buff, 1018 (SCSI_SENSE_BUFFERSIZE > SDEBUG_SENSE_LEN) ? 1019 SDEBUG_SENSE_LEN : SCSI_SENSE_BUFFERSIZE); 1020 } 1021 if (delta_jiff <= 0) { 1022 if (cmnd) 1023 cmnd->result = scsi_result; 1024 if (done) 1025 done(cmnd); 1026 return 0; 1027 } else { 1028 unsigned long iflags; 1029 int k; 1030 struct sdebug_queued_cmd * sqcp = NULL; 1031 1032 spin_lock_irqsave(&queued_arr_lock, iflags); 1033 for (k = 0; k < SCSI_DEBUG_CANQUEUE; ++k) { 1034 sqcp = &queued_arr[k]; 1035 if (! sqcp->in_use) 1036 break; 1037 } 1038 if (k >= SCSI_DEBUG_CANQUEUE) { 1039 spin_unlock_irqrestore(&queued_arr_lock, iflags); 1040 printk(KERN_WARNING "scsi_debug: can_queue exceeded\n"); 1041 return 1; /* report busy to mid level */ 1042 } 1043 sqcp->in_use = 1; 1044 sqcp->a_cmnd = cmnd; 1045 sqcp->scsi_result = scsi_result; 1046 sqcp->done_funct = done; 1047 sqcp->cmnd_timer.function = timer_intr_handler; 1048 sqcp->cmnd_timer.data = k; 1049 sqcp->cmnd_timer.expires = jiffies + delta_jiff; 1050 add_timer(&sqcp->cmnd_timer); 1051 spin_unlock_irqrestore(&queued_arr_lock, iflags); 1052 return 0; 1053 } 1054} 1055 1056#ifndef MODULE 1057static int __init num_devs_setup(char *str) 1058{ 1059 int tmp; 1060 1061 if (get_option(&str, &tmp) == 1) { 1062 if (tmp > 0) 1063 scsi_debug_num_devs = tmp; 1064 return 1; 1065 } else { 1066 printk(KERN_INFO "scsi_debug_num_devs: usage scsi_debug_num_devs=<n> " 1067 "(<n> can be from 1 to around 2000)\n"); 1068 return 0; 1069 } 1070} 1071__setup("scsi_debug_num_devs=", num_devs_setup); 1072 1073static int __init dev_size_mb_setup(char *str) 1074{ 1075 int tmp; 1076 1077 if (get_option(&str, &tmp) == 1) { 1078 if (tmp > 0) 1079 scsi_debug_dev_size_mb = tmp; 1080 return 1; 1081 } else { 1082 printk(KERN_INFO "scsi_debug_dev_size_mb: usage " 1083 "scsi_debug_dev_size_mb=<n>\n" 1084 " (<n> is number of MB ram shared by all devs\n"); 1085 return 0; 1086 } 1087} 1088__setup("scsi_debug_dev_size_mb=", dev_size_mb_setup); 1089 1090static int __init opts_setup(char *str) 1091{ 1092 int tmp; 1093 1094 if (get_option(&str, &tmp) == 1) { 1095 if (tmp > 0) 1096 scsi_debug_opts = tmp; 1097 return 1; 1098 } else { 1099 printk(KERN_INFO "scsi_debug_opts: usage " 1100 "scsi_debug_opts=<n>\n" 1101 " (1->noise, 2->medium_error, 4->... (can be or-ed)\n"); 1102 return 0; 1103 } 1104} 1105__setup("scsi_debug_opts=", opts_setup); 1106 1107static int __init every_nth_setup(char *str) 1108{ 1109 int tmp; 1110 1111 if (get_option(&str, &tmp) == 1) { 1112 if (tmp > 0) 1113 scsi_debug_every_nth = tmp; 1114 return 1; 1115 } else { 1116 printk(KERN_INFO "scsi_debug_every_nth: usage " 1117 "scsi_debug_every_nth=<n>\n" 1118 " timeout every nth command (when ...)\n"); 1119 return 0; 1120 } 1121} 1122__setup("scsi_debug_every_nth=", every_nth_setup); 1123 1124static int __init delay_setup(char *str) 1125{ 1126 int tmp; 1127 1128 if (get_option(&str, &tmp) == 1) { 1129 scsi_debug_delay = tmp; 1130 return 1; 1131 } else { 1132 printk(KERN_INFO "scsi_debug_delay: usage " 1133 "scsi_debug_delay=<n>\n" 1134 " delay response <n> jiffies\n"); 1135 return 0; 1136 } 1137} 1138__setup("scsi_debug_delay=", delay_setup); 1139 1140#endif 1141 1142MODULE_AUTHOR("Eric Youngdale + Douglas Gilbert"); 1143MODULE_DESCRIPTION("SCSI debug adapter driver"); 1144MODULE_PARM(scsi_debug_num_devs, "i"); 1145MODULE_PARM_DESC(scsi_debug_num_devs, "number of SCSI devices to simulate"); 1146MODULE_PARM(scsi_debug_dev_size_mb, "i"); 1147MODULE_PARM_DESC(scsi_debug_dev_size_mb, "size in MB of ram shared by devs"); 1148MODULE_PARM(scsi_debug_opts, "i"); 1149MODULE_PARM_DESC(scsi_debug_opts, "1->noise, 2->medium_error, 4->..."); 1150MODULE_PARM(scsi_debug_every_nth, "i"); 1151MODULE_PARM_DESC(scsi_debug_every_nth, "timeout every nth command(def=100)"); 1152MODULE_PARM(scsi_debug_delay, "i"); 1153MODULE_PARM_DESC(scsi_debug_delay, "# of jiffies to delay response(def=1)"); 1154#ifdef MODULE_LICENSE 1155MODULE_LICENSE("GPL"); 1156#endif 1157 1158static char sdebug_info[256]; 1159 1160static const char * scsi_debug_info(struct Scsi_Host * shp) 1161{ 1162 sprintf(sdebug_info, "scsi_debug, %s, num_devs=%d, " 1163 "dev_size_mb=%d, opts=0x%x", scsi_debug_version_str, 1164 scsi_debug_num_devs, scsi_debug_dev_size_mb, 1165 scsi_debug_opts); 1166 return sdebug_info; 1167} 1168 1169/* scsi_debug_proc_info 1170 * Used if the driver currently has no own support for /proc/scsi 1171 */ 1172static int scsi_debug_proc_info(char *buffer, char **start, off_t offset, 1173 int length, int inode, int inout) 1174{ 1175 int len, pos, begin; 1176 int orig_length; 1177 1178 orig_length = length; 1179 1180 if (inout == 1) { 1181 char arr[16]; 1182 int minLen = length > 15 ? 15 : length; 1183 1184 if (!capable(CAP_SYS_ADMIN) || !capable(CAP_SYS_RAWIO)) 1185 return -EACCES; 1186 memcpy(arr, buffer, minLen); 1187 arr[minLen] = '\0'; 1188 if (1 != sscanf(arr, "%d", &pos)) 1189 return -EINVAL; 1190 scsi_debug_opts = pos; 1191 if (SCSI_DEBUG_OPT_EVERY_NTH & scsi_debug_opts) 1192 scsi_debug_cmnd_count = 0; 1193 return length; 1194 } 1195 begin = 0; 1196 pos = len = sprintf(buffer, "scsi_debug adapter driver, %s\n" 1197 "num_devs=%d, shared (ram) size=%d MB, opts=0x%x, " 1198 "every_nth=%d(curr:%d)\n" 1199 "sector_size=%d bytes, cylinders=%d, heads=%d, sectors=%d, " 1200 "delay=%d\nnumber of aborts=%d, device_reset=%d, bus_resets=%d, " 1201 "host_resets=%d\n", 1202 scsi_debug_version_str, scsi_debug_num_devs, 1203 scsi_debug_dev_size_mb, scsi_debug_opts, scsi_debug_every_nth, 1204 scsi_debug_cmnd_count, 1205 SECT_SIZE, N_CYLINDER, N_HEAD, N_SECTOR, scsi_debug_delay, 1206 num_aborts, num_dev_resets, num_bus_resets, num_host_resets); 1207 if (pos < offset) { 1208 len = 0; 1209 begin = pos; 1210 } 1211 *start = buffer + (offset - begin); /* Start of wanted data */ 1212 len -= (offset - begin); 1213 if (len > length) 1214 len = length; 1215 1216 return (len); 1217} 1218 1219#include "scsi_module.c" 1220