aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/ide/ide-atapi.c15
-rw-r--r--drivers/ide/ide-floppy.c32
-rw-r--r--drivers/ide/ide-tape.c41
-rw-r--r--include/linux/ide.h6
4 files changed, 36 insertions, 58 deletions
diff --git a/drivers/ide/ide-atapi.c b/drivers/ide/ide-atapi.c
index f82ddfb9a44e..c647a40c0d33 100644
--- a/drivers/ide/ide-atapi.c
+++ b/drivers/ide/ide-atapi.c
@@ -162,6 +162,21 @@ int ide_queue_pc_tail(ide_drive_t *drive, struct gendisk *disk,
162} 162}
163EXPORT_SYMBOL_GPL(ide_queue_pc_tail); 163EXPORT_SYMBOL_GPL(ide_queue_pc_tail);
164 164
165int ide_set_media_lock(ide_drive_t *drive, struct gendisk *disk, int on)
166{
167 struct ide_atapi_pc pc;
168
169 if (drive->atapi_flags & IDE_AFLAG_NO_DOORLOCK)
170 return 0;
171
172 ide_init_pc(&pc);
173 pc.c[0] = ALLOW_MEDIUM_REMOVAL;
174 pc.c[4] = on;
175
176 return ide_queue_pc_tail(drive, disk, &pc);
177}
178EXPORT_SYMBOL_GPL(ide_set_media_lock);
179
165/* TODO: unify the code thus making some arguments go away */ 180/* TODO: unify the code thus making some arguments go away */
166ide_startstop_t ide_pc_intr(ide_drive_t *drive, struct ide_atapi_pc *pc, 181ide_startstop_t ide_pc_intr(ide_drive_t *drive, struct ide_atapi_pc *pc,
167 ide_handler_t *handler, unsigned int timeout, ide_expiry_t *expiry, 182 ide_handler_t *handler, unsigned int timeout, ide_expiry_t *expiry,
diff --git a/drivers/ide/ide-floppy.c b/drivers/ide/ide-floppy.c
index ca12a230d9a6..f39cf404b030 100644
--- a/drivers/ide/ide-floppy.c
+++ b/drivers/ide/ide-floppy.c
@@ -325,15 +325,6 @@ static ide_startstop_t idefloppy_issue_pc(ide_drive_t *drive,
325 IDEFLOPPY_WAIT_CMD, NULL); 325 IDEFLOPPY_WAIT_CMD, NULL);
326} 326}
327 327
328static void idefloppy_create_prevent_cmd(struct ide_atapi_pc *pc, int prevent)
329{
330 debug_log("creating prevent removal command, prevent = %d\n", prevent);
331
332 ide_init_pc(pc);
333 pc->c[0] = GPCMD_PREVENT_ALLOW_MEDIUM_REMOVAL;
334 pc->c[4] = prevent;
335}
336
337void ide_floppy_create_read_capacity_cmd(struct ide_atapi_pc *pc) 328void ide_floppy_create_read_capacity_cmd(struct ide_atapi_pc *pc)
338{ 329{
339 ide_init_pc(pc); 330 ide_init_pc(pc);
@@ -712,6 +703,8 @@ static void idefloppy_setup(ide_drive_t *drive, idefloppy_floppy_t *floppy)
712 if (strncmp((char *)&id[ATA_ID_PROD], "IOMEGA Clik!", 11) == 0) { 703 if (strncmp((char *)&id[ATA_ID_PROD], "IOMEGA Clik!", 11) == 0) {
713 blk_queue_max_sectors(drive->queue, 64); 704 blk_queue_max_sectors(drive->queue, 64);
714 drive->atapi_flags |= IDE_AFLAG_CLIK_DRIVE; 705 drive->atapi_flags |= IDE_AFLAG_CLIK_DRIVE;
706 /* IOMEGA Clik! drives do not support lock/unlock commands */
707 drive->atapi_flags |= IDE_AFLAG_NO_DOORLOCK;
715 } 708 }
716 709
717 (void) ide_floppy_get_capacity(drive); 710 (void) ide_floppy_get_capacity(drive);
@@ -782,18 +775,6 @@ static ide_driver_t idefloppy_driver = {
782#endif 775#endif
783}; 776};
784 777
785static void ide_floppy_set_media_lock(ide_drive_t *drive, int on)
786{
787 struct ide_floppy_obj *floppy = drive->driver_data;
788 struct ide_atapi_pc pc;
789
790 /* IOMEGA Clik! drives do not support lock/unlock commands */
791 if ((drive->atapi_flags & IDE_AFLAG_CLIK_DRIVE) == 0) {
792 idefloppy_create_prevent_cmd(&pc, on);
793 (void)ide_queue_pc_tail(drive, floppy->disk, &pc);
794 }
795}
796
797static int idefloppy_open(struct inode *inode, struct file *filp) 778static int idefloppy_open(struct inode *inode, struct file *filp)
798{ 779{
799 struct gendisk *disk = inode->i_bdev->bd_disk; 780 struct gendisk *disk = inode->i_bdev->bd_disk;
@@ -842,7 +823,7 @@ static int idefloppy_open(struct inode *inode, struct file *filp)
842 } 823 }
843 824
844 drive->atapi_flags |= IDE_AFLAG_MEDIA_CHANGED; 825 drive->atapi_flags |= IDE_AFLAG_MEDIA_CHANGED;
845 ide_floppy_set_media_lock(drive, 1); 826 ide_set_media_lock(drive, disk, 1);
846 check_disk_change(inode->i_bdev); 827 check_disk_change(inode->i_bdev);
847 } else if (drive->atapi_flags & IDE_AFLAG_FORMAT_IN_PROGRESS) { 828 } else if (drive->atapi_flags & IDE_AFLAG_FORMAT_IN_PROGRESS) {
848 ret = -EBUSY; 829 ret = -EBUSY;
@@ -865,7 +846,7 @@ static int idefloppy_release(struct inode *inode, struct file *filp)
865 debug_log("Reached %s\n", __func__); 846 debug_log("Reached %s\n", __func__);
866 847
867 if (floppy->openers == 1) { 848 if (floppy->openers == 1) {
868 ide_floppy_set_media_lock(drive, 0); 849 ide_set_media_lock(drive, disk, 0);
869 drive->atapi_flags &= ~IDE_AFLAG_FORMAT_IN_PROGRESS; 850 drive->atapi_flags &= ~IDE_AFLAG_FORMAT_IN_PROGRESS;
870 } 851 }
871 852
@@ -891,16 +872,17 @@ static int ide_floppy_lockdoor(ide_drive_t *drive, struct ide_atapi_pc *pc,
891 unsigned long arg, unsigned int cmd) 872 unsigned long arg, unsigned int cmd)
892{ 873{
893 idefloppy_floppy_t *floppy = drive->driver_data; 874 idefloppy_floppy_t *floppy = drive->driver_data;
875 struct gendisk *disk = floppy->disk;
894 int prevent = (arg && cmd != CDROMEJECT) ? 1 : 0; 876 int prevent = (arg && cmd != CDROMEJECT) ? 1 : 0;
895 877
896 if (floppy->openers > 1) 878 if (floppy->openers > 1)
897 return -EBUSY; 879 return -EBUSY;
898 880
899 ide_floppy_set_media_lock(drive, prevent); 881 ide_set_media_lock(drive, disk, prevent);
900 882
901 if (cmd == CDROMEJECT) { 883 if (cmd == CDROMEJECT) {
902 idefloppy_create_start_stop_cmd(pc, 2); 884 idefloppy_create_start_stop_cmd(pc, 2);
903 (void)ide_queue_pc_tail(drive, floppy->disk, pc); 885 (void)ide_queue_pc_tail(drive, disk, pc);
904 } 886 }
905 887
906 return 0; 888 return 0;
diff --git a/drivers/ide/ide-tape.c b/drivers/ide/ide-tape.c
index 88cb94554267..b7f3eebc0d15 100644
--- a/drivers/ide/ide-tape.c
+++ b/drivers/ide/ide-tape.c
@@ -1214,32 +1214,6 @@ static void idetape_create_locate_cmd(ide_drive_t *drive,
1214 pc->flags |= PC_FLAG_WAIT_FOR_DSC; 1214 pc->flags |= PC_FLAG_WAIT_FOR_DSC;
1215} 1215}
1216 1216
1217static int idetape_create_prevent_cmd(ide_drive_t *drive,
1218 struct ide_atapi_pc *pc, int prevent)
1219{
1220 idetape_tape_t *tape = drive->driver_data;
1221
1222 /* device supports locking according to capabilities page */
1223 if (!(tape->caps[6] & 0x01))
1224 return 0;
1225
1226 ide_init_pc(pc);
1227 pc->c[0] = ALLOW_MEDIUM_REMOVAL;
1228 pc->c[4] = prevent;
1229 return 1;
1230}
1231
1232static int ide_tape_set_media_lock(ide_drive_t *drive, int on)
1233{
1234 struct ide_tape_obj *tape = drive->driver_data;
1235 struct ide_atapi_pc pc;
1236
1237 if (!idetape_create_prevent_cmd(drive, &pc, on))
1238 return 0;
1239
1240 return ide_queue_pc_tail(drive, tape->disk, &pc);
1241}
1242
1243static void __ide_tape_discard_merge_buffer(ide_drive_t *drive) 1217static void __ide_tape_discard_merge_buffer(ide_drive_t *drive)
1244{ 1218{
1245 idetape_tape_t *tape = drive->driver_data; 1219 idetape_tape_t *tape = drive->driver_data;
@@ -1872,7 +1846,7 @@ static int idetape_mtioctop(ide_drive_t *drive, short mt_op, int mt_count)
1872 * attempting to eject. 1846 * attempting to eject.
1873 */ 1847 */
1874 if (tape->door_locked) { 1848 if (tape->door_locked) {
1875 if (!ide_tape_set_media_lock(drive, 0)) 1849 if (!ide_set_media_lock(drive, disk, 0))
1876 tape->door_locked = DOOR_UNLOCKED; 1850 tape->door_locked = DOOR_UNLOCKED;
1877 } 1851 }
1878 ide_tape_discard_merge_buffer(drive, 0); 1852 ide_tape_discard_merge_buffer(drive, 0);
@@ -1917,13 +1891,13 @@ static int idetape_mtioctop(ide_drive_t *drive, short mt_op, int mt_count)
1917 case MTFSR: 1891 case MTFSR:
1918 case MTBSR: 1892 case MTBSR:
1919 case MTLOCK: 1893 case MTLOCK:
1920 retval = ide_tape_set_media_lock(drive, 1); 1894 retval = ide_set_media_lock(drive, disk, 1);
1921 if (retval) 1895 if (retval)
1922 return retval; 1896 return retval;
1923 tape->door_locked = DOOR_EXPLICITLY_LOCKED; 1897 tape->door_locked = DOOR_EXPLICITLY_LOCKED;
1924 return 0; 1898 return 0;
1925 case MTUNLOCK: 1899 case MTUNLOCK:
1926 retval = ide_tape_set_media_lock(drive, 0); 1900 retval = ide_set_media_lock(drive, disk, 0);
1927 if (retval) 1901 if (retval)
1928 return retval; 1902 return retval;
1929 tape->door_locked = DOOR_UNLOCKED; 1903 tape->door_locked = DOOR_UNLOCKED;
@@ -2087,7 +2061,7 @@ static int idetape_chrdev_open(struct inode *inode, struct file *filp)
2087 2061
2088 /* Lock the tape drive door so user can't eject. */ 2062 /* Lock the tape drive door so user can't eject. */
2089 if (tape->chrdev_dir == IDETAPE_DIR_NONE) { 2063 if (tape->chrdev_dir == IDETAPE_DIR_NONE) {
2090 if (!ide_tape_set_media_lock(drive, 1)) { 2064 if (!ide_set_media_lock(drive, tape->disk, 1)) {
2091 if (tape->door_locked != DOOR_EXPLICITLY_LOCKED) 2065 if (tape->door_locked != DOOR_EXPLICITLY_LOCKED)
2092 tape->door_locked = DOOR_LOCKED; 2066 tape->door_locked = DOOR_LOCKED;
2093 } 2067 }
@@ -2140,7 +2114,7 @@ static int idetape_chrdev_release(struct inode *inode, struct file *filp)
2140 (void) idetape_rewind_tape(drive); 2114 (void) idetape_rewind_tape(drive);
2141 if (tape->chrdev_dir == IDETAPE_DIR_NONE) { 2115 if (tape->chrdev_dir == IDETAPE_DIR_NONE) {
2142 if (tape->door_locked == DOOR_LOCKED) { 2116 if (tape->door_locked == DOOR_LOCKED) {
2143 if (!ide_tape_set_media_lock(drive, 0)) 2117 if (!ide_set_media_lock(drive, tape->disk, 0))
2144 tape->door_locked = DOOR_UNLOCKED; 2118 tape->door_locked = DOOR_UNLOCKED;
2145 } 2119 }
2146 } 2120 }
@@ -2218,6 +2192,11 @@ static void idetape_get_mode_sense_results(ide_drive_t *drive)
2218 } 2192 }
2219 2193
2220 memcpy(&tape->caps, caps, 20); 2194 memcpy(&tape->caps, caps, 20);
2195
2196 /* device lacks locking support according to capabilities page */
2197 if ((caps[6] & 1) == 0)
2198 drive->atapi_flags |= IDE_AFLAG_NO_DOORLOCK;
2199
2221 if (caps[7] & 0x02) 2200 if (caps[7] & 0x02)
2222 tape->blk_size = 512; 2201 tape->blk_size = 512;
2223 else if (caps[7] & 0x04) 2202 else if (caps[7] & 0x04)
diff --git a/include/linux/ide.h b/include/linux/ide.h
index cc41a885688a..ac067a3c1be3 100644
--- a/include/linux/ide.h
+++ b/include/linux/ide.h
@@ -317,10 +317,10 @@ struct ide_acpi_hwif_link;
317enum { 317enum {
318 IDE_AFLAG_DRQ_INTERRUPT = (1 << 0), 318 IDE_AFLAG_DRQ_INTERRUPT = (1 << 0),
319 IDE_AFLAG_MEDIA_CHANGED = (1 << 1), 319 IDE_AFLAG_MEDIA_CHANGED = (1 << 1),
320
321 /* ide-cd */
322 /* Drive cannot lock the door. */ 320 /* Drive cannot lock the door. */
323 IDE_AFLAG_NO_DOORLOCK = (1 << 2), 321 IDE_AFLAG_NO_DOORLOCK = (1 << 2),
322
323 /* ide-cd */
324 /* Drive cannot eject the disc. */ 324 /* Drive cannot eject the disc. */
325 IDE_AFLAG_NO_EJECT = (1 << 3), 325 IDE_AFLAG_NO_EJECT = (1 << 3),
326 /* Drive is a pre ATAPI 1.2 drive. */ 326 /* Drive is a pre ATAPI 1.2 drive. */
@@ -1142,6 +1142,8 @@ void ide_queue_pc_head(ide_drive_t *, struct gendisk *, struct ide_atapi_pc *,
1142 struct request *); 1142 struct request *);
1143int ide_queue_pc_tail(ide_drive_t *, struct gendisk *, struct ide_atapi_pc *); 1143int ide_queue_pc_tail(ide_drive_t *, struct gendisk *, struct ide_atapi_pc *);
1144 1144
1145int ide_set_media_lock(ide_drive_t *, struct gendisk *, int);
1146
1145ide_startstop_t ide_pc_intr(ide_drive_t *drive, struct ide_atapi_pc *pc, 1147ide_startstop_t ide_pc_intr(ide_drive_t *drive, struct ide_atapi_pc *pc,
1146 ide_handler_t *handler, unsigned int timeout, ide_expiry_t *expiry, 1148 ide_handler_t *handler, unsigned int timeout, ide_expiry_t *expiry,
1147 void (*update_buffers)(ide_drive_t *, struct ide_atapi_pc *), 1149 void (*update_buffers)(ide_drive_t *, struct ide_atapi_pc *),