diff options
| author | <jgarzik@pretzel.yyz.us> | 2005-06-04 00:40:40 -0400 |
|---|---|---|
| committer | Jeff Garzik <jgarzik@pobox.com> | 2005-06-04 00:40:40 -0400 |
| commit | ae20ea8525a80a863f70d332cf47b71bd9f54c1f (patch) | |
| tree | 9d3cedeb65db521a8436b545bd91641549a18d24 /drivers/scsi/ide-scsi.c | |
| parent | f497ba735fc9ff4e35a19641143708b3be1c7061 (diff) | |
| parent | 8be3de3fd8469154a2b3e18a4712032dac5b4a53 (diff) | |
Automatic merge of /spare/repo/linux-2.6/.git branch HEAD
Diffstat (limited to 'drivers/scsi/ide-scsi.c')
| -rw-r--r-- | drivers/scsi/ide-scsi.c | 86 |
1 files changed, 50 insertions, 36 deletions
diff --git a/drivers/scsi/ide-scsi.c b/drivers/scsi/ide-scsi.c index 2e2486b035dd..83f062ed9082 100644 --- a/drivers/scsi/ide-scsi.c +++ b/drivers/scsi/ide-scsi.c | |||
| @@ -179,8 +179,18 @@ static void idescsi_input_buffers (ide_drive_t *drive, idescsi_pc_t *pc, unsigne | |||
| 179 | return; | 179 | return; |
| 180 | } | 180 | } |
| 181 | count = min(pc->sg->length - pc->b_count, bcount); | 181 | count = min(pc->sg->length - pc->b_count, bcount); |
| 182 | buf = page_address(pc->sg->page) + pc->sg->offset; | 182 | if (PageHighMem(pc->sg->page)) { |
| 183 | drive->hwif->atapi_input_bytes(drive, buf + pc->b_count, count); | 183 | unsigned long flags; |
| 184 | |||
| 185 | local_irq_save(flags); | ||
| 186 | buf = kmap_atomic(pc->sg->page, KM_IRQ0) + pc->sg->offset; | ||
| 187 | drive->hwif->atapi_input_bytes(drive, buf + pc->b_count, count); | ||
| 188 | kunmap_atomic(buf - pc->sg->offset, KM_IRQ0); | ||
| 189 | local_irq_restore(flags); | ||
| 190 | } else { | ||
| 191 | buf = page_address(pc->sg->page) + pc->sg->offset; | ||
| 192 | drive->hwif->atapi_input_bytes(drive, buf + pc->b_count, count); | ||
| 193 | } | ||
| 184 | bcount -= count; pc->b_count += count; | 194 | bcount -= count; pc->b_count += count; |
| 185 | if (pc->b_count == pc->sg->length) { | 195 | if (pc->b_count == pc->sg->length) { |
| 186 | pc->sg++; | 196 | pc->sg++; |
| @@ -201,8 +211,18 @@ static void idescsi_output_buffers (ide_drive_t *drive, idescsi_pc_t *pc, unsign | |||
| 201 | return; | 211 | return; |
| 202 | } | 212 | } |
| 203 | count = min(pc->sg->length - pc->b_count, bcount); | 213 | count = min(pc->sg->length - pc->b_count, bcount); |
| 204 | buf = page_address(pc->sg->page) + pc->sg->offset; | 214 | if (PageHighMem(pc->sg->page)) { |
| 205 | drive->hwif->atapi_output_bytes(drive, buf + pc->b_count, count); | 215 | unsigned long flags; |
| 216 | |||
| 217 | local_irq_save(flags); | ||
| 218 | buf = kmap_atomic(pc->sg->page, KM_IRQ0) + pc->sg->offset; | ||
| 219 | drive->hwif->atapi_output_bytes(drive, buf + pc->b_count, count); | ||
| 220 | kunmap_atomic(buf - pc->sg->offset, KM_IRQ0); | ||
| 221 | local_irq_restore(flags); | ||
| 222 | } else { | ||
| 223 | buf = page_address(pc->sg->page) + pc->sg->offset; | ||
| 224 | drive->hwif->atapi_output_bytes(drive, buf + pc->b_count, count); | ||
| 225 | } | ||
| 206 | bcount -= count; pc->b_count += count; | 226 | bcount -= count; pc->b_count += count; |
| 207 | if (pc->b_count == pc->sg->length) { | 227 | if (pc->b_count == pc->sg->length) { |
| 208 | pc->sg++; | 228 | pc->sg++; |
| @@ -713,7 +733,6 @@ static void idescsi_add_settings(ide_drive_t *drive) | |||
| 713 | */ | 733 | */ |
| 714 | static void idescsi_setup (ide_drive_t *drive, idescsi_scsi_t *scsi) | 734 | static void idescsi_setup (ide_drive_t *drive, idescsi_scsi_t *scsi) |
| 715 | { | 735 | { |
| 716 | DRIVER(drive)->busy++; | ||
| 717 | if (drive->id && (drive->id->config & 0x0060) == 0x20) | 736 | if (drive->id && (drive->id->config & 0x0060) == 0x20) |
| 718 | set_bit (IDESCSI_DRQ_INTERRUPT, &scsi->flags); | 737 | set_bit (IDESCSI_DRQ_INTERRUPT, &scsi->flags); |
| 719 | set_bit(IDESCSI_TRANSFORM, &scsi->transform); | 738 | set_bit(IDESCSI_TRANSFORM, &scsi->transform); |
| @@ -722,17 +741,16 @@ static void idescsi_setup (ide_drive_t *drive, idescsi_scsi_t *scsi) | |||
| 722 | set_bit(IDESCSI_LOG_CMD, &scsi->log); | 741 | set_bit(IDESCSI_LOG_CMD, &scsi->log); |
| 723 | #endif /* IDESCSI_DEBUG_LOG */ | 742 | #endif /* IDESCSI_DEBUG_LOG */ |
| 724 | idescsi_add_settings(drive); | 743 | idescsi_add_settings(drive); |
| 725 | DRIVER(drive)->busy--; | ||
| 726 | } | 744 | } |
| 727 | 745 | ||
| 728 | static int idescsi_cleanup (ide_drive_t *drive) | 746 | static int ide_scsi_remove(struct device *dev) |
| 729 | { | 747 | { |
| 748 | ide_drive_t *drive = to_ide_device(dev); | ||
| 730 | struct Scsi_Host *scsihost = drive->driver_data; | 749 | struct Scsi_Host *scsihost = drive->driver_data; |
| 731 | struct ide_scsi_obj *scsi = scsihost_to_idescsi(scsihost); | 750 | struct ide_scsi_obj *scsi = scsihost_to_idescsi(scsihost); |
| 732 | struct gendisk *g = scsi->disk; | 751 | struct gendisk *g = scsi->disk; |
| 733 | 752 | ||
| 734 | if (ide_unregister_subdriver(drive)) | 753 | ide_unregister_subdriver(drive, scsi->driver); |
| 735 | return 1; | ||
| 736 | 754 | ||
| 737 | ide_unregister_region(g); | 755 | ide_unregister_region(g); |
| 738 | 756 | ||
| @@ -746,7 +764,7 @@ static int idescsi_cleanup (ide_drive_t *drive) | |||
| 746 | return 0; | 764 | return 0; |
| 747 | } | 765 | } |
| 748 | 766 | ||
| 749 | static int idescsi_attach(ide_drive_t *drive); | 767 | static int ide_scsi_probe(struct device *); |
| 750 | 768 | ||
| 751 | #ifdef CONFIG_PROC_FS | 769 | #ifdef CONFIG_PROC_FS |
| 752 | static ide_proc_entry_t idescsi_proc[] = { | 770 | static ide_proc_entry_t idescsi_proc[] = { |
| @@ -757,24 +775,22 @@ static ide_proc_entry_t idescsi_proc[] = { | |||
| 757 | # define idescsi_proc NULL | 775 | # define idescsi_proc NULL |
| 758 | #endif | 776 | #endif |
| 759 | 777 | ||
| 760 | /* | ||
| 761 | * IDE subdriver functions, registered with ide.c | ||
| 762 | */ | ||
| 763 | static ide_driver_t idescsi_driver = { | 778 | static ide_driver_t idescsi_driver = { |
| 764 | .owner = THIS_MODULE, | 779 | .owner = THIS_MODULE, |
| 765 | .name = "ide-scsi", | 780 | .gen_driver = { |
| 781 | .name = "ide-scsi", | ||
| 782 | .bus = &ide_bus_type, | ||
| 783 | .probe = ide_scsi_probe, | ||
| 784 | .remove = ide_scsi_remove, | ||
| 785 | }, | ||
| 766 | .version = IDESCSI_VERSION, | 786 | .version = IDESCSI_VERSION, |
| 767 | .media = ide_scsi, | 787 | .media = ide_scsi, |
| 768 | .busy = 0, | ||
| 769 | .supports_dsc_overlap = 0, | 788 | .supports_dsc_overlap = 0, |
| 770 | .proc = idescsi_proc, | 789 | .proc = idescsi_proc, |
| 771 | .attach = idescsi_attach, | ||
| 772 | .cleanup = idescsi_cleanup, | ||
| 773 | .do_request = idescsi_do_request, | 790 | .do_request = idescsi_do_request, |
| 774 | .end_request = idescsi_end_request, | 791 | .end_request = idescsi_end_request, |
| 775 | .error = idescsi_atapi_error, | 792 | .error = idescsi_atapi_error, |
| 776 | .abort = idescsi_atapi_abort, | 793 | .abort = idescsi_atapi_abort, |
| 777 | .drives = LIST_HEAD_INIT(idescsi_driver.drives), | ||
| 778 | }; | 794 | }; |
| 779 | 795 | ||
| 780 | static int idescsi_ide_open(struct inode *inode, struct file *filp) | 796 | static int idescsi_ide_open(struct inode *inode, struct file *filp) |
| @@ -821,8 +837,6 @@ static struct block_device_operations idescsi_ops = { | |||
| 821 | .ioctl = idescsi_ide_ioctl, | 837 | .ioctl = idescsi_ide_ioctl, |
| 822 | }; | 838 | }; |
| 823 | 839 | ||
| 824 | static int idescsi_attach(ide_drive_t *drive); | ||
| 825 | |||
| 826 | static int idescsi_slave_configure(struct scsi_device * sdp) | 840 | static int idescsi_slave_configure(struct scsi_device * sdp) |
| 827 | { | 841 | { |
| 828 | /* Configure detected device */ | 842 | /* Configure detected device */ |
| @@ -1095,8 +1109,9 @@ static struct scsi_host_template idescsi_template = { | |||
| 1095 | .proc_name = "ide-scsi", | 1109 | .proc_name = "ide-scsi", |
| 1096 | }; | 1110 | }; |
| 1097 | 1111 | ||
| 1098 | static int idescsi_attach(ide_drive_t *drive) | 1112 | static int ide_scsi_probe(struct device *dev) |
| 1099 | { | 1113 | { |
| 1114 | ide_drive_t *drive = to_ide_device(dev); | ||
| 1100 | idescsi_scsi_t *idescsi; | 1115 | idescsi_scsi_t *idescsi; |
| 1101 | struct Scsi_Host *host; | 1116 | struct Scsi_Host *host; |
| 1102 | struct gendisk *g; | 1117 | struct gendisk *g; |
| @@ -1112,7 +1127,7 @@ static int idescsi_attach(ide_drive_t *drive) | |||
| 1112 | !drive->present || | 1127 | !drive->present || |
| 1113 | drive->media == ide_disk || | 1128 | drive->media == ide_disk || |
| 1114 | !(host = scsi_host_alloc(&idescsi_template,sizeof(idescsi_scsi_t)))) | 1129 | !(host = scsi_host_alloc(&idescsi_template,sizeof(idescsi_scsi_t)))) |
| 1115 | return 1; | 1130 | return -ENODEV; |
| 1116 | 1131 | ||
| 1117 | g = alloc_disk(1 << PARTN_BITS); | 1132 | g = alloc_disk(1 << PARTN_BITS); |
| 1118 | if (!g) | 1133 | if (!g) |
| @@ -1138,20 +1153,19 @@ static int idescsi_attach(ide_drive_t *drive) | |||
| 1138 | idescsi->host = host; | 1153 | idescsi->host = host; |
| 1139 | idescsi->disk = g; | 1154 | idescsi->disk = g; |
| 1140 | g->private_data = &idescsi->driver; | 1155 | g->private_data = &idescsi->driver; |
| 1141 | err = ide_register_subdriver(drive, &idescsi_driver); | 1156 | ide_register_subdriver(drive, &idescsi_driver); |
| 1157 | err = 0; | ||
| 1158 | idescsi_setup(drive, idescsi); | ||
| 1159 | g->fops = &idescsi_ops; | ||
| 1160 | ide_register_region(g); | ||
| 1161 | err = scsi_add_host(host, &drive->gendev); | ||
| 1142 | if (!err) { | 1162 | if (!err) { |
| 1143 | idescsi_setup (drive, idescsi); | 1163 | scsi_scan_host(host); |
| 1144 | g->fops = &idescsi_ops; | 1164 | return 0; |
| 1145 | ide_register_region(g); | ||
| 1146 | err = scsi_add_host(host, &drive->gendev); | ||
| 1147 | if (!err) { | ||
| 1148 | scsi_scan_host(host); | ||
| 1149 | return 0; | ||
| 1150 | } | ||
| 1151 | /* fall through on error */ | ||
| 1152 | ide_unregister_region(g); | ||
| 1153 | ide_unregister_subdriver(drive); | ||
| 1154 | } | 1165 | } |
| 1166 | /* fall through on error */ | ||
| 1167 | ide_unregister_region(g); | ||
| 1168 | ide_unregister_subdriver(drive, &idescsi_driver); | ||
| 1155 | 1169 | ||
| 1156 | put_disk(g); | 1170 | put_disk(g); |
| 1157 | out_host_put: | 1171 | out_host_put: |
| @@ -1161,12 +1175,12 @@ out_host_put: | |||
| 1161 | 1175 | ||
| 1162 | static int __init init_idescsi_module(void) | 1176 | static int __init init_idescsi_module(void) |
| 1163 | { | 1177 | { |
| 1164 | return ide_register_driver(&idescsi_driver); | 1178 | return driver_register(&idescsi_driver.gen_driver); |
| 1165 | } | 1179 | } |
| 1166 | 1180 | ||
| 1167 | static void __exit exit_idescsi_module(void) | 1181 | static void __exit exit_idescsi_module(void) |
| 1168 | { | 1182 | { |
| 1169 | ide_unregister_driver(&idescsi_driver); | 1183 | driver_unregister(&idescsi_driver.gen_driver); |
| 1170 | } | 1184 | } |
| 1171 | 1185 | ||
| 1172 | module_init(init_idescsi_module); | 1186 | module_init(init_idescsi_module); |
