aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/scsi/scsi_debug.c507
1 files changed, 233 insertions, 274 deletions
diff --git a/drivers/scsi/scsi_debug.c b/drivers/scsi/scsi_debug.c
index 681b591fc4c0..4f4c5b7bdef5 100644
--- a/drivers/scsi/scsi_debug.c
+++ b/drivers/scsi/scsi_debug.c
@@ -235,56 +235,11 @@ static unsigned char ctrl_m_pg[] = {0xa, 10, 2, 0, 0, 0, 0, 0,
235static unsigned char iec_m_pg[] = {0x1c, 0xa, 0x08, 0, 0, 0, 0, 0, 235static unsigned char iec_m_pg[] = {0x1c, 0xa, 0x08, 0, 0, 0, 0, 0,
236 0, 0, 0x0, 0x0}; 236 0, 0, 0x0, 0x0};
237 237
238/* function declarations */
239static int resp_inquiry(struct scsi_cmnd * SCpnt, int target,
240 struct sdebug_dev_info * devip);
241static int resp_requests(struct scsi_cmnd * SCpnt,
242 struct sdebug_dev_info * devip);
243static int resp_start_stop(struct scsi_cmnd * scp,
244 struct sdebug_dev_info * devip);
245static int resp_report_tgtpgs(struct scsi_cmnd * scp,
246 struct sdebug_dev_info * devip);
247static int resp_readcap(struct scsi_cmnd * SCpnt,
248 struct sdebug_dev_info * devip);
249static int resp_readcap16(struct scsi_cmnd * SCpnt,
250 struct sdebug_dev_info * devip);
251static int resp_mode_sense(struct scsi_cmnd * scp, int target,
252 struct sdebug_dev_info * devip);
253static int resp_mode_select(struct scsi_cmnd * scp, int mselect6,
254 struct sdebug_dev_info * devip);
255static int resp_log_sense(struct scsi_cmnd * scp,
256 struct sdebug_dev_info * devip);
257static int resp_read(struct scsi_cmnd * SCpnt, unsigned long long lba,
258 unsigned int num, struct sdebug_dev_info * devip);
259static int resp_write(struct scsi_cmnd * SCpnt, unsigned long long lba,
260 unsigned int num, struct sdebug_dev_info * devip);
261static int resp_report_luns(struct scsi_cmnd * SCpnt,
262 struct sdebug_dev_info * devip);
263static int resp_xdwriteread(struct scsi_cmnd *scp, unsigned long long lba,
264 unsigned int num, struct sdebug_dev_info *devip);
265static int fill_from_dev_buffer(struct scsi_cmnd * scp, unsigned char * arr,
266 int arr_len);
267static int fetch_to_dev_buffer(struct scsi_cmnd * scp, unsigned char * arr,
268 int max_arr_len);
269static void timer_intr_handler(unsigned long);
270static struct sdebug_dev_info * devInfoReg(struct scsi_device * sdev); 238static struct sdebug_dev_info * devInfoReg(struct scsi_device * sdev);
271static void mk_sense_buffer(struct sdebug_dev_info * devip, int key, 239static void mk_sense_buffer(struct sdebug_dev_info * devip, int key,
272 int asc, int asq); 240 int asc, int asq);
273static int check_readiness(struct scsi_cmnd * SCpnt, int reset_only,
274 struct sdebug_dev_info * devip);
275static int schedule_resp(struct scsi_cmnd * cmnd,
276 struct sdebug_dev_info * devip,
277 done_funct_t done, int scsi_result, int delta_jiff);
278static void __init sdebug_build_parts(unsigned char * ramp);
279static void __init init_all_queued(void);
280static void stop_all_queued(void); 241static void stop_all_queued(void);
281static int stop_queued_cmnd(struct scsi_cmnd * cmnd); 242static int stop_queued_cmnd(struct scsi_cmnd * cmnd);
282static int inquiry_evpd_83(unsigned char * arr, int port_group_id,
283 int target_dev_id, int dev_id_num,
284 const char * dev_id_str, int dev_id_str_len);
285static int inquiry_evpd_88(unsigned char * arr, int target_dev_id);
286static int do_create_driverfs_files(void);
287static void do_remove_driverfs_files(void);
288 243
289static int sdebug_add_adapter(void); 244static int sdebug_add_adapter(void);
290static void sdebug_remove_adapter(void); 245static void sdebug_remove_adapter(void);
@@ -330,235 +285,6 @@ static void get_data_transfer_info(unsigned char *cmd,
330 } 285 }
331} 286}
332 287
333static
334int scsi_debug_queuecommand(struct scsi_cmnd * SCpnt, done_funct_t done)
335{
336 unsigned char *cmd = (unsigned char *) SCpnt->cmnd;
337 int len, k;
338 unsigned int num;
339 unsigned long long lba;
340 int errsts = 0;
341 int target = SCpnt->device->id;
342 struct sdebug_dev_info * devip = NULL;
343 int inj_recovered = 0;
344 int inj_transport = 0;
345 int delay_override = 0;
346
347 scsi_set_resid(SCpnt, 0);
348 if ((SCSI_DEBUG_OPT_NOISE & scsi_debug_opts) && cmd) {
349 printk(KERN_INFO "scsi_debug: cmd ");
350 for (k = 0, len = SCpnt->cmd_len; k < len; ++k)
351 printk("%02x ", (int)cmd[k]);
352 printk("\n");
353 }
354
355 if (target == SCpnt->device->host->hostt->this_id) {
356 printk(KERN_INFO "scsi_debug: initiator's id used as "
357 "target!\n");
358 return schedule_resp(SCpnt, NULL, done,
359 DID_NO_CONNECT << 16, 0);
360 }
361
362 if ((SCpnt->device->lun >= scsi_debug_max_luns) &&
363 (SCpnt->device->lun != SAM2_WLUN_REPORT_LUNS))
364 return schedule_resp(SCpnt, NULL, done,
365 DID_NO_CONNECT << 16, 0);
366 devip = devInfoReg(SCpnt->device);
367 if (NULL == devip)
368 return schedule_resp(SCpnt, NULL, done,
369 DID_NO_CONNECT << 16, 0);
370
371 if ((scsi_debug_every_nth != 0) &&
372 (++scsi_debug_cmnd_count >= abs(scsi_debug_every_nth))) {
373 scsi_debug_cmnd_count = 0;
374 if (scsi_debug_every_nth < -1)
375 scsi_debug_every_nth = -1;
376 if (SCSI_DEBUG_OPT_TIMEOUT & scsi_debug_opts)
377 return 0; /* ignore command causing timeout */
378 else if (SCSI_DEBUG_OPT_RECOVERED_ERR & scsi_debug_opts)
379 inj_recovered = 1; /* to reads and writes below */
380 else if (SCSI_DEBUG_OPT_TRANSPORT_ERR & scsi_debug_opts)
381 inj_transport = 1; /* to reads and writes below */
382 }
383
384 if (devip->wlun) {
385 switch (*cmd) {
386 case INQUIRY:
387 case REQUEST_SENSE:
388 case TEST_UNIT_READY:
389 case REPORT_LUNS:
390 break; /* only allowable wlun commands */
391 default:
392 if (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts)
393 printk(KERN_INFO "scsi_debug: Opcode: 0x%x "
394 "not supported for wlun\n", *cmd);
395 mk_sense_buffer(devip, ILLEGAL_REQUEST,
396 INVALID_OPCODE, 0);
397 errsts = check_condition_result;
398 return schedule_resp(SCpnt, devip, done, errsts,
399 0);
400 }
401 }
402
403 switch (*cmd) {
404 case INQUIRY: /* mandatory, ignore unit attention */
405 delay_override = 1;
406 errsts = resp_inquiry(SCpnt, target, devip);
407 break;
408 case REQUEST_SENSE: /* mandatory, ignore unit attention */
409 delay_override = 1;
410 errsts = resp_requests(SCpnt, devip);
411 break;
412 case REZERO_UNIT: /* actually this is REWIND for SSC */
413 case START_STOP:
414 errsts = resp_start_stop(SCpnt, devip);
415 break;
416 case ALLOW_MEDIUM_REMOVAL:
417 if ((errsts = check_readiness(SCpnt, 1, devip)))
418 break;
419 if (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts)
420 printk(KERN_INFO "scsi_debug: Medium removal %s\n",
421 cmd[4] ? "inhibited" : "enabled");
422 break;
423 case SEND_DIAGNOSTIC: /* mandatory */
424 errsts = check_readiness(SCpnt, 1, devip);
425 break;
426 case TEST_UNIT_READY: /* mandatory */
427 delay_override = 1;
428 errsts = check_readiness(SCpnt, 0, devip);
429 break;
430 case RESERVE:
431 errsts = check_readiness(SCpnt, 1, devip);
432 break;
433 case RESERVE_10:
434 errsts = check_readiness(SCpnt, 1, devip);
435 break;
436 case RELEASE:
437 errsts = check_readiness(SCpnt, 1, devip);
438 break;
439 case RELEASE_10:
440 errsts = check_readiness(SCpnt, 1, devip);
441 break;
442 case READ_CAPACITY:
443 errsts = resp_readcap(SCpnt, devip);
444 break;
445 case SERVICE_ACTION_IN:
446 if (SAI_READ_CAPACITY_16 != cmd[1]) {
447 mk_sense_buffer(devip, ILLEGAL_REQUEST,
448 INVALID_OPCODE, 0);
449 errsts = check_condition_result;
450 break;
451 }
452 errsts = resp_readcap16(SCpnt, devip);
453 break;
454 case MAINTENANCE_IN:
455 if (MI_REPORT_TARGET_PGS != cmd[1]) {
456 mk_sense_buffer(devip, ILLEGAL_REQUEST,
457 INVALID_OPCODE, 0);
458 errsts = check_condition_result;
459 break;
460 }
461 errsts = resp_report_tgtpgs(SCpnt, devip);
462 break;
463 case READ_16:
464 case READ_12:
465 case READ_10:
466 case READ_6:
467 if ((errsts = check_readiness(SCpnt, 0, devip)))
468 break;
469 if (scsi_debug_fake_rw)
470 break;
471 get_data_transfer_info(cmd, &lba, &num);
472 errsts = resp_read(SCpnt, lba, num, devip);
473 if (inj_recovered && (0 == errsts)) {
474 mk_sense_buffer(devip, RECOVERED_ERROR,
475 THRESHOLD_EXCEEDED, 0);
476 errsts = check_condition_result;
477 } else if (inj_transport && (0 == errsts)) {
478 mk_sense_buffer(devip, ABORTED_COMMAND,
479 TRANSPORT_PROBLEM, ACK_NAK_TO);
480 errsts = check_condition_result;
481 }
482 break;
483 case REPORT_LUNS: /* mandatory, ignore unit attention */
484 delay_override = 1;
485 errsts = resp_report_luns(SCpnt, devip);
486 break;
487 case VERIFY: /* 10 byte SBC-2 command */
488 errsts = check_readiness(SCpnt, 0, devip);
489 break;
490 case WRITE_16:
491 case WRITE_12:
492 case WRITE_10:
493 case WRITE_6:
494 if ((errsts = check_readiness(SCpnt, 0, devip)))
495 break;
496 if (scsi_debug_fake_rw)
497 break;
498 get_data_transfer_info(cmd, &lba, &num);
499 errsts = resp_write(SCpnt, lba, num, devip);
500 if (inj_recovered && (0 == errsts)) {
501 mk_sense_buffer(devip, RECOVERED_ERROR,
502 THRESHOLD_EXCEEDED, 0);
503 errsts = check_condition_result;
504 }
505 break;
506 case MODE_SENSE:
507 case MODE_SENSE_10:
508 errsts = resp_mode_sense(SCpnt, target, devip);
509 break;
510 case MODE_SELECT:
511 errsts = resp_mode_select(SCpnt, 1, devip);
512 break;
513 case MODE_SELECT_10:
514 errsts = resp_mode_select(SCpnt, 0, devip);
515 break;
516 case LOG_SENSE:
517 errsts = resp_log_sense(SCpnt, devip);
518 break;
519 case SYNCHRONIZE_CACHE:
520 delay_override = 1;
521 errsts = check_readiness(SCpnt, 0, devip);
522 break;
523 case WRITE_BUFFER:
524 errsts = check_readiness(SCpnt, 1, devip);
525 break;
526 case XDWRITEREAD_10:
527 if (!scsi_bidi_cmnd(SCpnt)) {
528 mk_sense_buffer(devip, ILLEGAL_REQUEST,
529 INVALID_FIELD_IN_CDB, 0);
530 errsts = check_condition_result;
531 break;
532 }
533
534 errsts = check_readiness(SCpnt, 0, devip);
535 if (errsts)
536 break;
537 if (scsi_debug_fake_rw)
538 break;
539 get_data_transfer_info(cmd, &lba, &num);
540 errsts = resp_read(SCpnt, lba, num, devip);
541 if (errsts)
542 break;
543 errsts = resp_write(SCpnt, lba, num, devip);
544 if (errsts)
545 break;
546 errsts = resp_xdwriteread(SCpnt, lba, num, devip);
547 break;
548 default:
549 if (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts)
550 printk(KERN_INFO "scsi_debug: Opcode: 0x%x not "
551 "supported\n", *cmd);
552 if ((errsts = check_readiness(SCpnt, 1, devip)))
553 break; /* Unit attention takes precedence */
554 mk_sense_buffer(devip, ILLEGAL_REQUEST, INVALID_OPCODE, 0);
555 errsts = check_condition_result;
556 break;
557 }
558 return schedule_resp(SCpnt, devip, done, errsts,
559 (delay_override ? 0 : scsi_debug_delay));
560}
561
562static int scsi_debug_ioctl(struct scsi_device *dev, int cmd, void __user *arg) 288static int scsi_debug_ioctl(struct scsi_device *dev, int cmd, void __user *arg)
563{ 289{
564 if (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts) { 290 if (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts) {
@@ -2999,6 +2725,239 @@ static void sdebug_remove_adapter(void)
2999 --scsi_debug_add_host; 2725 --scsi_debug_add_host;
3000} 2726}
3001 2727
2728static
2729int scsi_debug_queuecommand(struct scsi_cmnd *SCpnt, done_funct_t done)
2730{
2731 unsigned char *cmd = (unsigned char *) SCpnt->cmnd;
2732 int len, k;
2733 unsigned int num;
2734 unsigned long long lba;
2735 int errsts = 0;
2736 int target = SCpnt->device->id;
2737 struct sdebug_dev_info *devip = NULL;
2738 int inj_recovered = 0;
2739 int inj_transport = 0;
2740 int delay_override = 0;
2741
2742 scsi_set_resid(SCpnt, 0);
2743 if ((SCSI_DEBUG_OPT_NOISE & scsi_debug_opts) && cmd) {
2744 printk(KERN_INFO "scsi_debug: cmd ");
2745 for (k = 0, len = SCpnt->cmd_len; k < len; ++k)
2746 printk("%02x ", (int)cmd[k]);
2747 printk("\n");
2748 }
2749
2750 if (target == SCpnt->device->host->hostt->this_id) {
2751 printk(KERN_INFO "scsi_debug: initiator's id used as "
2752 "target!\n");
2753 return schedule_resp(SCpnt, NULL, done,
2754 DID_NO_CONNECT << 16, 0);
2755 }
2756
2757 if ((SCpnt->device->lun >= scsi_debug_max_luns) &&
2758 (SCpnt->device->lun != SAM2_WLUN_REPORT_LUNS))
2759 return schedule_resp(SCpnt, NULL, done,
2760 DID_NO_CONNECT << 16, 0);
2761 devip = devInfoReg(SCpnt->device);
2762 if (NULL == devip)
2763 return schedule_resp(SCpnt, NULL, done,
2764 DID_NO_CONNECT << 16, 0);
2765
2766 if ((scsi_debug_every_nth != 0) &&
2767 (++scsi_debug_cmnd_count >= abs(scsi_debug_every_nth))) {
2768 scsi_debug_cmnd_count = 0;
2769 if (scsi_debug_every_nth < -1)
2770 scsi_debug_every_nth = -1;
2771 if (SCSI_DEBUG_OPT_TIMEOUT & scsi_debug_opts)
2772 return 0; /* ignore command causing timeout */
2773 else if (SCSI_DEBUG_OPT_RECOVERED_ERR & scsi_debug_opts)
2774 inj_recovered = 1; /* to reads and writes below */
2775 else if (SCSI_DEBUG_OPT_TRANSPORT_ERR & scsi_debug_opts)
2776 inj_transport = 1; /* to reads and writes below */
2777 }
2778
2779 if (devip->wlun) {
2780 switch (*cmd) {
2781 case INQUIRY:
2782 case REQUEST_SENSE:
2783 case TEST_UNIT_READY:
2784 case REPORT_LUNS:
2785 break; /* only allowable wlun commands */
2786 default:
2787 if (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts)
2788 printk(KERN_INFO "scsi_debug: Opcode: 0x%x "
2789 "not supported for wlun\n", *cmd);
2790 mk_sense_buffer(devip, ILLEGAL_REQUEST,
2791 INVALID_OPCODE, 0);
2792 errsts = check_condition_result;
2793 return schedule_resp(SCpnt, devip, done, errsts,
2794 0);
2795 }
2796 }
2797
2798 switch (*cmd) {
2799 case INQUIRY: /* mandatory, ignore unit attention */
2800 delay_override = 1;
2801 errsts = resp_inquiry(SCpnt, target, devip);
2802 break;
2803 case REQUEST_SENSE: /* mandatory, ignore unit attention */
2804 delay_override = 1;
2805 errsts = resp_requests(SCpnt, devip);
2806 break;
2807 case REZERO_UNIT: /* actually this is REWIND for SSC */
2808 case START_STOP:
2809 errsts = resp_start_stop(SCpnt, devip);
2810 break;
2811 case ALLOW_MEDIUM_REMOVAL:
2812 errsts = check_readiness(SCpnt, 1, devip);
2813 if (errsts)
2814 break;
2815 if (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts)
2816 printk(KERN_INFO "scsi_debug: Medium removal %s\n",
2817 cmd[4] ? "inhibited" : "enabled");
2818 break;
2819 case SEND_DIAGNOSTIC: /* mandatory */
2820 errsts = check_readiness(SCpnt, 1, devip);
2821 break;
2822 case TEST_UNIT_READY: /* mandatory */
2823 delay_override = 1;
2824 errsts = check_readiness(SCpnt, 0, devip);
2825 break;
2826 case RESERVE:
2827 errsts = check_readiness(SCpnt, 1, devip);
2828 break;
2829 case RESERVE_10:
2830 errsts = check_readiness(SCpnt, 1, devip);
2831 break;
2832 case RELEASE:
2833 errsts = check_readiness(SCpnt, 1, devip);
2834 break;
2835 case RELEASE_10:
2836 errsts = check_readiness(SCpnt, 1, devip);
2837 break;
2838 case READ_CAPACITY:
2839 errsts = resp_readcap(SCpnt, devip);
2840 break;
2841 case SERVICE_ACTION_IN:
2842 if (SAI_READ_CAPACITY_16 != cmd[1]) {
2843 mk_sense_buffer(devip, ILLEGAL_REQUEST,
2844 INVALID_OPCODE, 0);
2845 errsts = check_condition_result;
2846 break;
2847 }
2848 errsts = resp_readcap16(SCpnt, devip);
2849 break;
2850 case MAINTENANCE_IN:
2851 if (MI_REPORT_TARGET_PGS != cmd[1]) {
2852 mk_sense_buffer(devip, ILLEGAL_REQUEST,
2853 INVALID_OPCODE, 0);
2854 errsts = check_condition_result;
2855 break;
2856 }
2857 errsts = resp_report_tgtpgs(SCpnt, devip);
2858 break;
2859 case READ_16:
2860 case READ_12:
2861 case READ_10:
2862 case READ_6:
2863 errsts = check_readiness(SCpnt, 0, devip);
2864 if (errsts)
2865 break;
2866 if (scsi_debug_fake_rw)
2867 break;
2868 get_data_transfer_info(cmd, &lba, &num);
2869 errsts = resp_read(SCpnt, lba, num, devip);
2870 if (inj_recovered && (0 == errsts)) {
2871 mk_sense_buffer(devip, RECOVERED_ERROR,
2872 THRESHOLD_EXCEEDED, 0);
2873 errsts = check_condition_result;
2874 } else if (inj_transport && (0 == errsts)) {
2875 mk_sense_buffer(devip, ABORTED_COMMAND,
2876 TRANSPORT_PROBLEM, ACK_NAK_TO);
2877 errsts = check_condition_result;
2878 }
2879 break;
2880 case REPORT_LUNS: /* mandatory, ignore unit attention */
2881 delay_override = 1;
2882 errsts = resp_report_luns(SCpnt, devip);
2883 break;
2884 case VERIFY: /* 10 byte SBC-2 command */
2885 errsts = check_readiness(SCpnt, 0, devip);
2886 break;
2887 case WRITE_16:
2888 case WRITE_12:
2889 case WRITE_10:
2890 case WRITE_6:
2891 errsts = check_readiness(SCpnt, 0, devip);
2892 if (errsts)
2893 break;
2894 if (scsi_debug_fake_rw)
2895 break;
2896 get_data_transfer_info(cmd, &lba, &num);
2897 errsts = resp_write(SCpnt, lba, num, devip);
2898 if (inj_recovered && (0 == errsts)) {
2899 mk_sense_buffer(devip, RECOVERED_ERROR,
2900 THRESHOLD_EXCEEDED, 0);
2901 errsts = check_condition_result;
2902 }
2903 break;
2904 case MODE_SENSE:
2905 case MODE_SENSE_10:
2906 errsts = resp_mode_sense(SCpnt, target, devip);
2907 break;
2908 case MODE_SELECT:
2909 errsts = resp_mode_select(SCpnt, 1, devip);
2910 break;
2911 case MODE_SELECT_10:
2912 errsts = resp_mode_select(SCpnt, 0, devip);
2913 break;
2914 case LOG_SENSE:
2915 errsts = resp_log_sense(SCpnt, devip);
2916 break;
2917 case SYNCHRONIZE_CACHE:
2918 delay_override = 1;
2919 errsts = check_readiness(SCpnt, 0, devip);
2920 break;
2921 case WRITE_BUFFER:
2922 errsts = check_readiness(SCpnt, 1, devip);
2923 break;
2924 case XDWRITEREAD_10:
2925 if (!scsi_bidi_cmnd(SCpnt)) {
2926 mk_sense_buffer(devip, ILLEGAL_REQUEST,
2927 INVALID_FIELD_IN_CDB, 0);
2928 errsts = check_condition_result;
2929 break;
2930 }
2931
2932 errsts = check_readiness(SCpnt, 0, devip);
2933 if (errsts)
2934 break;
2935 if (scsi_debug_fake_rw)
2936 break;
2937 get_data_transfer_info(cmd, &lba, &num);
2938 errsts = resp_read(SCpnt, lba, num, devip);
2939 if (errsts)
2940 break;
2941 errsts = resp_write(SCpnt, lba, num, devip);
2942 if (errsts)
2943 break;
2944 errsts = resp_xdwriteread(SCpnt, lba, num, devip);
2945 break;
2946 default:
2947 if (SCSI_DEBUG_OPT_NOISE & scsi_debug_opts)
2948 printk(KERN_INFO "scsi_debug: Opcode: 0x%x not "
2949 "supported\n", *cmd);
2950 errsts = check_readiness(SCpnt, 1, devip);
2951 if (errsts)
2952 break; /* Unit attention takes precedence */
2953 mk_sense_buffer(devip, ILLEGAL_REQUEST, INVALID_OPCODE, 0);
2954 errsts = check_condition_result;
2955 break;
2956 }
2957 return schedule_resp(SCpnt, devip, done, errsts,
2958 (delay_override ? 0 : scsi_debug_delay));
2959}
2960
3002static struct scsi_host_template sdebug_driver_template = { 2961static struct scsi_host_template sdebug_driver_template = {
3003 .proc_info = scsi_debug_proc_info, 2962 .proc_info = scsi_debug_proc_info,
3004 .proc_name = sdebug_proc_name, 2963 .proc_name = sdebug_proc_name,