diff options
| -rw-r--r-- | drivers/scsi/sr.c | 49 | ||||
| -rw-r--r-- | drivers/scsi/sr_ioctl.c | 62 |
2 files changed, 37 insertions, 74 deletions
diff --git a/drivers/scsi/sr.c b/drivers/scsi/sr.c index 8cbe6e004187..39fc5b0fbc18 100644 --- a/drivers/scsi/sr.c +++ b/drivers/scsi/sr.c | |||
| @@ -50,10 +50,10 @@ | |||
| 50 | #include <scsi/scsi_dbg.h> | 50 | #include <scsi/scsi_dbg.h> |
| 51 | #include <scsi/scsi_device.h> | 51 | #include <scsi/scsi_device.h> |
| 52 | #include <scsi/scsi_driver.h> | 52 | #include <scsi/scsi_driver.h> |
| 53 | #include <scsi/scsi_cmnd.h> | ||
| 53 | #include <scsi/scsi_eh.h> | 54 | #include <scsi/scsi_eh.h> |
| 54 | #include <scsi/scsi_host.h> | 55 | #include <scsi/scsi_host.h> |
| 55 | #include <scsi/scsi_ioctl.h> /* For the door lock/unlock commands */ | 56 | #include <scsi/scsi_ioctl.h> /* For the door lock/unlock commands */ |
| 56 | #include <scsi/scsi_request.h> | ||
| 57 | 57 | ||
| 58 | #include "scsi_logging.h" | 58 | #include "scsi_logging.h" |
| 59 | #include "sr.h" | 59 | #include "sr.h" |
| @@ -658,39 +658,27 @@ static void get_sectorsize(struct scsi_cd *cd) | |||
| 658 | unsigned char *buffer; | 658 | unsigned char *buffer; |
| 659 | int the_result, retries = 3; | 659 | int the_result, retries = 3; |
| 660 | int sector_size; | 660 | int sector_size; |
| 661 | struct scsi_request *SRpnt = NULL; | ||
| 662 | request_queue_t *queue; | 661 | request_queue_t *queue; |
| 663 | 662 | ||
| 664 | buffer = kmalloc(512, GFP_KERNEL | GFP_DMA); | 663 | buffer = kmalloc(512, GFP_KERNEL | GFP_DMA); |
| 665 | if (!buffer) | 664 | if (!buffer) |
| 666 | goto Enomem; | 665 | goto Enomem; |
| 667 | SRpnt = scsi_allocate_request(cd->device, GFP_KERNEL); | ||
| 668 | if (!SRpnt) | ||
| 669 | goto Enomem; | ||
| 670 | 666 | ||
| 671 | do { | 667 | do { |
| 672 | cmd[0] = READ_CAPACITY; | 668 | cmd[0] = READ_CAPACITY; |
| 673 | memset((void *) &cmd[1], 0, 9); | 669 | memset((void *) &cmd[1], 0, 9); |
| 674 | /* Mark as really busy */ | ||
| 675 | SRpnt->sr_request->rq_status = RQ_SCSI_BUSY; | ||
| 676 | SRpnt->sr_cmd_len = 0; | ||
| 677 | |||
| 678 | memset(buffer, 0, 8); | 670 | memset(buffer, 0, 8); |
| 679 | 671 | ||
| 680 | /* Do the command and wait.. */ | 672 | /* Do the command and wait.. */ |
| 681 | SRpnt->sr_data_direction = DMA_FROM_DEVICE; | 673 | the_result = scsi_execute_req(cd->device, cmd, DMA_FROM_DEVICE, |
| 682 | scsi_wait_req(SRpnt, (void *) cmd, (void *) buffer, | 674 | buffer, 8, NULL, SR_TIMEOUT, |
| 683 | 8, SR_TIMEOUT, MAX_RETRIES); | 675 | MAX_RETRIES); |
| 684 | 676 | ||
| 685 | the_result = SRpnt->sr_result; | ||
| 686 | retries--; | 677 | retries--; |
| 687 | 678 | ||
| 688 | } while (the_result && retries); | 679 | } while (the_result && retries); |
| 689 | 680 | ||
| 690 | 681 | ||
| 691 | scsi_release_request(SRpnt); | ||
| 692 | SRpnt = NULL; | ||
| 693 | |||
| 694 | if (the_result) { | 682 | if (the_result) { |
| 695 | cd->capacity = 0x1fffff; | 683 | cd->capacity = 0x1fffff; |
| 696 | sector_size = 2048; /* A guess, just in case */ | 684 | sector_size = 2048; /* A guess, just in case */ |
| @@ -750,8 +738,6 @@ Enomem: | |||
| 750 | cd->capacity = 0x1fffff; | 738 | cd->capacity = 0x1fffff; |
| 751 | sector_size = 2048; /* A guess, just in case */ | 739 | sector_size = 2048; /* A guess, just in case */ |
| 752 | cd->needs_sector_size = 1; | 740 | cd->needs_sector_size = 1; |
| 753 | if (SRpnt) | ||
| 754 | scsi_release_request(SRpnt); | ||
| 755 | goto out; | 741 | goto out; |
| 756 | } | 742 | } |
| 757 | 743 | ||
| @@ -759,8 +745,8 @@ static void get_capabilities(struct scsi_cd *cd) | |||
| 759 | { | 745 | { |
| 760 | unsigned char *buffer; | 746 | unsigned char *buffer; |
| 761 | struct scsi_mode_data data; | 747 | struct scsi_mode_data data; |
| 762 | struct scsi_request *SRpnt; | ||
| 763 | unsigned char cmd[MAX_COMMAND_SIZE]; | 748 | unsigned char cmd[MAX_COMMAND_SIZE]; |
| 749 | struct scsi_sense_hdr sshdr; | ||
| 764 | unsigned int the_result; | 750 | unsigned int the_result; |
| 765 | int retries, rc, n; | 751 | int retries, rc, n; |
| 766 | 752 | ||
| @@ -776,19 +762,11 @@ static void get_capabilities(struct scsi_cd *cd) | |||
| 776 | "" | 762 | "" |
| 777 | }; | 763 | }; |
| 778 | 764 | ||
| 779 | /* allocate a request for the TEST_UNIT_READY */ | ||
| 780 | SRpnt = scsi_allocate_request(cd->device, GFP_KERNEL); | ||
| 781 | if (!SRpnt) { | ||
| 782 | printk(KERN_WARNING "(get_capabilities:) Request allocation " | ||
| 783 | "failure.\n"); | ||
| 784 | return; | ||
| 785 | } | ||
| 786 | 765 | ||
| 787 | /* allocate transfer buffer */ | 766 | /* allocate transfer buffer */ |
| 788 | buffer = kmalloc(512, GFP_KERNEL | GFP_DMA); | 767 | buffer = kmalloc(512, GFP_KERNEL | GFP_DMA); |
| 789 | if (!buffer) { | 768 | if (!buffer) { |
| 790 | printk(KERN_ERR "sr: out of memory.\n"); | 769 | printk(KERN_ERR "sr: out of memory.\n"); |
| 791 | scsi_release_request(SRpnt); | ||
| 792 | return; | 770 | return; |
| 793 | } | 771 | } |
| 794 | 772 | ||
| @@ -800,20 +778,15 @@ static void get_capabilities(struct scsi_cd *cd) | |||
| 800 | memset((void *)cmd, 0, MAX_COMMAND_SIZE); | 778 | memset((void *)cmd, 0, MAX_COMMAND_SIZE); |
| 801 | cmd[0] = TEST_UNIT_READY; | 779 | cmd[0] = TEST_UNIT_READY; |
| 802 | 780 | ||
| 803 | SRpnt->sr_cmd_len = 0; | 781 | the_result = scsi_execute_req (cd->device, cmd, DMA_NONE, NULL, |
| 804 | SRpnt->sr_sense_buffer[0] = 0; | 782 | 0, &sshdr, SR_TIMEOUT, |
| 805 | SRpnt->sr_sense_buffer[2] = 0; | 783 | MAX_RETRIES); |
| 806 | SRpnt->sr_data_direction = DMA_NONE; | ||
| 807 | |||
| 808 | scsi_wait_req (SRpnt, (void *) cmd, buffer, | ||
| 809 | 0, SR_TIMEOUT, MAX_RETRIES); | ||
| 810 | 784 | ||
| 811 | the_result = SRpnt->sr_result; | ||
| 812 | retries++; | 785 | retries++; |
| 813 | } while (retries < 5 && | 786 | } while (retries < 5 && |
| 814 | (!scsi_status_is_good(the_result) || | 787 | (!scsi_status_is_good(the_result) || |
| 815 | ((driver_byte(the_result) & DRIVER_SENSE) && | 788 | (scsi_sense_valid(&sshdr) && |
| 816 | SRpnt->sr_sense_buffer[2] == UNIT_ATTENTION))); | 789 | sshdr.sense_key == UNIT_ATTENTION))); |
| 817 | 790 | ||
| 818 | /* ask for mode page 0x2a */ | 791 | /* ask for mode page 0x2a */ |
| 819 | rc = scsi_mode_sense(cd->device, 0, 0x2a, buffer, 128, | 792 | rc = scsi_mode_sense(cd->device, 0, 0x2a, buffer, 128, |
| @@ -825,7 +798,6 @@ static void get_capabilities(struct scsi_cd *cd) | |||
| 825 | cd->cdi.mask |= (CDC_CD_R | CDC_CD_RW | CDC_DVD_R | | 798 | cd->cdi.mask |= (CDC_CD_R | CDC_CD_RW | CDC_DVD_R | |
| 826 | CDC_DVD | CDC_DVD_RAM | | 799 | CDC_DVD | CDC_DVD_RAM | |
| 827 | CDC_SELECT_DISC | CDC_SELECT_SPEED); | 800 | CDC_SELECT_DISC | CDC_SELECT_SPEED); |
| 828 | scsi_release_request(SRpnt); | ||
| 829 | kfree(buffer); | 801 | kfree(buffer); |
| 830 | printk("%s: scsi-1 drive\n", cd->cdi.name); | 802 | printk("%s: scsi-1 drive\n", cd->cdi.name); |
| 831 | return; | 803 | return; |
| @@ -885,7 +857,6 @@ static void get_capabilities(struct scsi_cd *cd) | |||
| 885 | cd->device->writeable = 1; | 857 | cd->device->writeable = 1; |
| 886 | } | 858 | } |
| 887 | 859 | ||
| 888 | scsi_release_request(SRpnt); | ||
| 889 | kfree(buffer); | 860 | kfree(buffer); |
| 890 | } | 861 | } |
| 891 | 862 | ||
diff --git a/drivers/scsi/sr_ioctl.c b/drivers/scsi/sr_ioctl.c index 82d68fdb1548..6e45ac3c43c5 100644 --- a/drivers/scsi/sr_ioctl.c +++ b/drivers/scsi/sr_ioctl.c | |||
| @@ -17,7 +17,7 @@ | |||
| 17 | #include <scsi/scsi_eh.h> | 17 | #include <scsi/scsi_eh.h> |
| 18 | #include <scsi/scsi_host.h> | 18 | #include <scsi/scsi_host.h> |
| 19 | #include <scsi/scsi_ioctl.h> | 19 | #include <scsi/scsi_ioctl.h> |
| 20 | #include <scsi/scsi_request.h> | 20 | #include <scsi/scsi_cmnd.h> |
| 21 | 21 | ||
| 22 | #include "sr.h" | 22 | #include "sr.h" |
| 23 | 23 | ||
| @@ -84,41 +84,37 @@ static int sr_fake_playtrkind(struct cdrom_device_info *cdi, struct cdrom_ti *ti | |||
| 84 | 84 | ||
| 85 | int sr_do_ioctl(Scsi_CD *cd, struct packet_command *cgc) | 85 | int sr_do_ioctl(Scsi_CD *cd, struct packet_command *cgc) |
| 86 | { | 86 | { |
| 87 | struct scsi_request *SRpnt; | ||
| 88 | struct scsi_device *SDev; | 87 | struct scsi_device *SDev; |
| 89 | struct request *req; | 88 | struct scsi_sense_hdr sshdr; |
| 90 | int result, err = 0, retries = 0; | 89 | int result, err = 0, retries = 0; |
| 90 | struct request_sense *sense = cgc->sense; | ||
| 91 | 91 | ||
| 92 | SDev = cd->device; | 92 | SDev = cd->device; |
| 93 | SRpnt = scsi_allocate_request(SDev, GFP_KERNEL); | 93 | |
| 94 | if (!SRpnt) { | 94 | if (!sense) { |
| 95 | printk(KERN_ERR "Unable to allocate SCSI request in sr_do_ioctl"); | 95 | sense = kmalloc(sizeof(*sense), GFP_KERNEL); |
| 96 | err = -ENOMEM; | 96 | if (!sense) { |
| 97 | goto out; | 97 | err = -ENOMEM; |
| 98 | } | 98 | goto out; |
| 99 | SRpnt->sr_data_direction = cgc->data_direction; | 99 | } |
| 100 | } | ||
| 100 | 101 | ||
| 101 | retry: | 102 | retry: |
| 102 | if (!scsi_block_when_processing_errors(SDev)) { | 103 | if (!scsi_block_when_processing_errors(SDev)) { |
| 103 | err = -ENODEV; | 104 | err = -ENODEV; |
| 104 | goto out_free; | 105 | goto out; |
| 105 | } | 106 | } |
| 106 | 107 | ||
| 107 | scsi_wait_req(SRpnt, cgc->cmd, cgc->buffer, cgc->buflen, | 108 | memset(sense, 0, sizeof(*sense)); |
| 108 | cgc->timeout, IOCTL_RETRIES); | 109 | result = scsi_execute(SDev, cgc->cmd, cgc->data_direction, |
| 109 | 110 | cgc->buffer, cgc->buflen, (char *)sense, | |
| 110 | req = SRpnt->sr_request; | 111 | cgc->timeout, IOCTL_RETRIES, 0); |
| 111 | if (SRpnt->sr_buffer && req->buffer && SRpnt->sr_buffer != req->buffer) { | ||
| 112 | memcpy(req->buffer, SRpnt->sr_buffer, SRpnt->sr_bufflen); | ||
| 113 | kfree(SRpnt->sr_buffer); | ||
| 114 | SRpnt->sr_buffer = req->buffer; | ||
| 115 | } | ||
| 116 | 112 | ||
| 117 | result = SRpnt->sr_result; | 113 | scsi_normalize_sense((char *)sense, sizeof(*sense), &sshdr); |
| 118 | 114 | ||
| 119 | /* Minimal error checking. Ignore cases we know about, and report the rest. */ | 115 | /* Minimal error checking. Ignore cases we know about, and report the rest. */ |
| 120 | if (driver_byte(result) != 0) { | 116 | if (driver_byte(result) != 0) { |
| 121 | switch (SRpnt->sr_sense_buffer[2] & 0xf) { | 117 | switch (sshdr.sense_key) { |
| 122 | case UNIT_ATTENTION: | 118 | case UNIT_ATTENTION: |
| 123 | SDev->changed = 1; | 119 | SDev->changed = 1; |
| 124 | if (!cgc->quiet) | 120 | if (!cgc->quiet) |
| @@ -128,8 +124,8 @@ int sr_do_ioctl(Scsi_CD *cd, struct packet_command *cgc) | |||
| 128 | err = -ENOMEDIUM; | 124 | err = -ENOMEDIUM; |
| 129 | break; | 125 | break; |
| 130 | case NOT_READY: /* This happens if there is no disc in drive */ | 126 | case NOT_READY: /* This happens if there is no disc in drive */ |
| 131 | if (SRpnt->sr_sense_buffer[12] == 0x04 && | 127 | if (sshdr.asc == 0x04 && |
| 132 | SRpnt->sr_sense_buffer[13] == 0x01) { | 128 | sshdr.ascq == 0x01) { |
| 133 | /* sense: Logical unit is in process of becoming ready */ | 129 | /* sense: Logical unit is in process of becoming ready */ |
| 134 | if (!cgc->quiet) | 130 | if (!cgc->quiet) |
| 135 | printk(KERN_INFO "%s: CDROM not ready yet.\n", cd->cdi.name); | 131 | printk(KERN_INFO "%s: CDROM not ready yet.\n", cd->cdi.name); |
| @@ -146,37 +142,33 @@ int sr_do_ioctl(Scsi_CD *cd, struct packet_command *cgc) | |||
| 146 | if (!cgc->quiet) | 142 | if (!cgc->quiet) |
| 147 | printk(KERN_INFO "%s: CDROM not ready. Make sure there is a disc in the drive.\n", cd->cdi.name); | 143 | printk(KERN_INFO "%s: CDROM not ready. Make sure there is a disc in the drive.\n", cd->cdi.name); |
| 148 | #ifdef DEBUG | 144 | #ifdef DEBUG |
| 149 | scsi_print_req_sense("sr", SRpnt); | 145 | scsi_print_sense_hdr("sr", &sshdr); |
| 150 | #endif | 146 | #endif |
| 151 | err = -ENOMEDIUM; | 147 | err = -ENOMEDIUM; |
| 152 | break; | 148 | break; |
| 153 | case ILLEGAL_REQUEST: | 149 | case ILLEGAL_REQUEST: |
| 154 | err = -EIO; | 150 | err = -EIO; |
| 155 | if (SRpnt->sr_sense_buffer[12] == 0x20 && | 151 | if (sshdr.asc == 0x20 && |
| 156 | SRpnt->sr_sense_buffer[13] == 0x00) | 152 | sshdr.ascq == 0x00) |
| 157 | /* sense: Invalid command operation code */ | 153 | /* sense: Invalid command operation code */ |
| 158 | err = -EDRIVE_CANT_DO_THIS; | 154 | err = -EDRIVE_CANT_DO_THIS; |
| 159 | #ifdef DEBUG | 155 | #ifdef DEBUG |
| 160 | __scsi_print_command(cgc->cmd); | 156 | __scsi_print_command(cgc->cmd); |
| 161 | scsi_print_req_sense("sr", SRpnt); | 157 | scsi_print_sense_hdr("sr", &sshdr); |
| 162 | #endif | 158 | #endif |
| 163 | break; | 159 | break; |
| 164 | default: | 160 | default: |
| 165 | printk(KERN_ERR "%s: CDROM (ioctl) error, command: ", cd->cdi.name); | 161 | printk(KERN_ERR "%s: CDROM (ioctl) error, command: ", cd->cdi.name); |
| 166 | __scsi_print_command(cgc->cmd); | 162 | __scsi_print_command(cgc->cmd); |
| 167 | scsi_print_req_sense("sr", SRpnt); | 163 | scsi_print_sense_hdr("sr", &sshdr); |
| 168 | err = -EIO; | 164 | err = -EIO; |
| 169 | } | 165 | } |
| 170 | } | 166 | } |
| 171 | 167 | ||
| 172 | if (cgc->sense) | ||
| 173 | memcpy(cgc->sense, SRpnt->sr_sense_buffer, sizeof(*cgc->sense)); | ||
| 174 | |||
| 175 | /* Wake up a process waiting for device */ | 168 | /* Wake up a process waiting for device */ |
| 176 | out_free: | ||
| 177 | scsi_release_request(SRpnt); | ||
| 178 | SRpnt = NULL; | ||
| 179 | out: | 169 | out: |
| 170 | if (!cgc->sense) | ||
| 171 | kfree(sense); | ||
| 180 | cgc->stat = err; | 172 | cgc->stat = err; |
| 181 | return err; | 173 | return err; |
| 182 | } | 174 | } |
