diff options
Diffstat (limited to 'drivers/scsi/scsi_scan.c')
-rw-r--r-- | drivers/scsi/scsi_scan.c | 33 |
1 files changed, 25 insertions, 8 deletions
diff --git a/drivers/scsi/scsi_scan.c b/drivers/scsi/scsi_scan.c index b8f0cab57813..8160c00d1092 100644 --- a/drivers/scsi/scsi_scan.c +++ b/drivers/scsi/scsi_scan.c | |||
@@ -133,12 +133,10 @@ struct async_scan_data { | |||
133 | /** | 133 | /** |
134 | * scsi_complete_async_scans - Wait for asynchronous scans to complete | 134 | * scsi_complete_async_scans - Wait for asynchronous scans to complete |
135 | * | 135 | * |
136 | * Asynchronous scans add themselves to the scanning_hosts list. Once | 136 | * When this function returns, any host which started scanning before |
137 | * that list is empty, we know that the scans are complete. Rather than | 137 | * this function was called will have finished its scan. Hosts which |
138 | * waking up periodically to check the state of the list, we pretend to be | 138 | * started scanning after this function was called may or may not have |
139 | * a scanning task by adding ourselves at the end of the list and going to | 139 | * finished. |
140 | * sleep. When the task before us wakes us up, we take ourselves off the | ||
141 | * list and return. | ||
142 | */ | 140 | */ |
143 | int scsi_complete_async_scans(void) | 141 | int scsi_complete_async_scans(void) |
144 | { | 142 | { |
@@ -171,6 +169,11 @@ int scsi_complete_async_scans(void) | |||
171 | 169 | ||
172 | spin_lock(&async_scan_lock); | 170 | spin_lock(&async_scan_lock); |
173 | list_del(&data->list); | 171 | list_del(&data->list); |
172 | if (!list_empty(&scanning_hosts)) { | ||
173 | struct async_scan_data *next = list_entry(scanning_hosts.next, | ||
174 | struct async_scan_data, list); | ||
175 | complete(&next->prev_finished); | ||
176 | } | ||
174 | done: | 177 | done: |
175 | spin_unlock(&async_scan_lock); | 178 | spin_unlock(&async_scan_lock); |
176 | 179 | ||
@@ -739,6 +742,14 @@ static int scsi_add_lun(struct scsi_device *sdev, unsigned char *inq_result, | |||
739 | sdev->no_uld_attach = 1; | 742 | sdev->no_uld_attach = 1; |
740 | 743 | ||
741 | switch (sdev->type = (inq_result[0] & 0x1f)) { | 744 | switch (sdev->type = (inq_result[0] & 0x1f)) { |
745 | case TYPE_RBC: | ||
746 | /* RBC devices can return SCSI-3 compliance and yet | ||
747 | * still not support REPORT LUNS, so make them act as | ||
748 | * BLIST_NOREPORTLUN unless BLIST_REPORTLUN2 is | ||
749 | * specifically set */ | ||
750 | if ((*bflags & BLIST_REPORTLUN2) == 0) | ||
751 | *bflags |= BLIST_NOREPORTLUN; | ||
752 | /* fall through */ | ||
742 | case TYPE_TAPE: | 753 | case TYPE_TAPE: |
743 | case TYPE_DISK: | 754 | case TYPE_DISK: |
744 | case TYPE_PRINTER: | 755 | case TYPE_PRINTER: |
@@ -749,11 +760,17 @@ static int scsi_add_lun(struct scsi_device *sdev, unsigned char *inq_result, | |||
749 | case TYPE_ENCLOSURE: | 760 | case TYPE_ENCLOSURE: |
750 | case TYPE_COMM: | 761 | case TYPE_COMM: |
751 | case TYPE_RAID: | 762 | case TYPE_RAID: |
752 | case TYPE_RBC: | ||
753 | sdev->writeable = 1; | 763 | sdev->writeable = 1; |
754 | break; | 764 | break; |
755 | case TYPE_WORM: | ||
756 | case TYPE_ROM: | 765 | case TYPE_ROM: |
766 | /* MMC devices can return SCSI-3 compliance and yet | ||
767 | * still not support REPORT LUNS, so make them act as | ||
768 | * BLIST_NOREPORTLUN unless BLIST_REPORTLUN2 is | ||
769 | * specifically set */ | ||
770 | if ((*bflags & BLIST_REPORTLUN2) == 0) | ||
771 | *bflags |= BLIST_NOREPORTLUN; | ||
772 | /* fall through */ | ||
773 | case TYPE_WORM: | ||
757 | sdev->writeable = 0; | 774 | sdev->writeable = 0; |
758 | break; | 775 | break; |
759 | default: | 776 | default: |