diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2009-06-12 12:29:42 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2009-06-12 12:29:42 -0400 |
commit | d614aec4752f8c61b2e7cb77806b6bd59aa50836 (patch) | |
tree | 3b0cfb3085c43415931dbf18666d582fb8ae3c75 /drivers/ide/ide-tape.c | |
parent | db8e7f10ed67933ca272f4030eb7057b7f13de07 (diff) | |
parent | ad7c52d0988a8965989dc06d630c52a5bde849d5 (diff) |
Merge branch 'for-2.6.31' of git://git.kernel.org/pub/scm/linux/kernel/git/bart/ide-2.6
* 'for-2.6.31' of git://git.kernel.org/pub/scm/linux/kernel/git/bart/ide-2.6: (29 commits)
ide: re-implement ide_pci_init_one() on top of ide_pci_init_two()
ide: unexport ide_find_dma_mode()
ide: fix PowerMac bootup oops
ide: skip probe if there are no devices on the port (v2)
sl82c105: add printk() logging facility
ide-tape: fix proc warning
ide: add IDE_DFLAG_NIEN_QUIRK device flag
ide: respect quirk_drives[] list on all controllers
hpt366: enable all quirks for devices on quirk_drives[] list
hpt366: sync quirk_drives[] list with pdc202xx_{new,old}.c
ide: remove superfluous SELECT_MASK() call from do_rw_taskfile()
ide: remove superfluous SELECT_MASK() call from ide_driveid_update()
icside: remove superfluous ->maskproc method
ide-tape: fix IDE_AFLAG_* atomic accesses
ide-tape: change IDE_AFLAG_IGNORE_DSC non-atomically
pdc202xx_old: kill resetproc() method
pdc202xx_old: don't call pdc202xx_reset() on IRQ timeout
pdc202xx_old: use ide_dma_test_irq()
ide: preserve Host Protected Area by default (v2)
ide-gd: implement block device ->set_capacity method (v2)
...
Diffstat (limited to 'drivers/ide/ide-tape.c')
-rw-r--r-- | drivers/ide/ide-tape.c | 90 |
1 files changed, 46 insertions, 44 deletions
diff --git a/drivers/ide/ide-tape.c b/drivers/ide/ide-tape.c index d9764f0bc82f..4b447a8a49d4 100644 --- a/drivers/ide/ide-tape.c +++ b/drivers/ide/ide-tape.c | |||
@@ -240,18 +240,27 @@ static struct class *idetape_sysfs_class; | |||
240 | 240 | ||
241 | static void ide_tape_release(struct device *); | 241 | static void ide_tape_release(struct device *); |
242 | 242 | ||
243 | static struct ide_tape_obj *ide_tape_get(struct gendisk *disk) | 243 | static struct ide_tape_obj *idetape_devs[MAX_HWIFS * MAX_DRIVES]; |
244 | |||
245 | static struct ide_tape_obj *ide_tape_get(struct gendisk *disk, bool cdev, | ||
246 | unsigned int i) | ||
244 | { | 247 | { |
245 | struct ide_tape_obj *tape = NULL; | 248 | struct ide_tape_obj *tape = NULL; |
246 | 249 | ||
247 | mutex_lock(&idetape_ref_mutex); | 250 | mutex_lock(&idetape_ref_mutex); |
248 | tape = ide_drv_g(disk, ide_tape_obj); | 251 | |
252 | if (cdev) | ||
253 | tape = idetape_devs[i]; | ||
254 | else | ||
255 | tape = ide_drv_g(disk, ide_tape_obj); | ||
256 | |||
249 | if (tape) { | 257 | if (tape) { |
250 | if (ide_device_get(tape->drive)) | 258 | if (ide_device_get(tape->drive)) |
251 | tape = NULL; | 259 | tape = NULL; |
252 | else | 260 | else |
253 | get_device(&tape->dev); | 261 | get_device(&tape->dev); |
254 | } | 262 | } |
263 | |||
255 | mutex_unlock(&idetape_ref_mutex); | 264 | mutex_unlock(&idetape_ref_mutex); |
256 | return tape; | 265 | return tape; |
257 | } | 266 | } |
@@ -267,24 +276,6 @@ static void ide_tape_put(struct ide_tape_obj *tape) | |||
267 | } | 276 | } |
268 | 277 | ||
269 | /* | 278 | /* |
270 | * The variables below are used for the character device interface. Additional | ||
271 | * state variables are defined in our ide_drive_t structure. | ||
272 | */ | ||
273 | static struct ide_tape_obj *idetape_devs[MAX_HWIFS * MAX_DRIVES]; | ||
274 | |||
275 | static struct ide_tape_obj *ide_tape_chrdev_get(unsigned int i) | ||
276 | { | ||
277 | struct ide_tape_obj *tape = NULL; | ||
278 | |||
279 | mutex_lock(&idetape_ref_mutex); | ||
280 | tape = idetape_devs[i]; | ||
281 | if (tape) | ||
282 | get_device(&tape->dev); | ||
283 | mutex_unlock(&idetape_ref_mutex); | ||
284 | return tape; | ||
285 | } | ||
286 | |||
287 | /* | ||
288 | * called on each failed packet command retry to analyze the request sense. We | 279 | * called on each failed packet command retry to analyze the request sense. We |
289 | * currently do not utilize this information. | 280 | * currently do not utilize this information. |
290 | */ | 281 | */ |
@@ -397,7 +388,8 @@ static int ide_tape_callback(ide_drive_t *drive, int dsc) | |||
397 | if (readpos[0] & 0x4) { | 388 | if (readpos[0] & 0x4) { |
398 | printk(KERN_INFO "ide-tape: Block location is unknown" | 389 | printk(KERN_INFO "ide-tape: Block location is unknown" |
399 | "to the tape\n"); | 390 | "to the tape\n"); |
400 | clear_bit(IDE_AFLAG_ADDRESS_VALID, &drive->atapi_flags); | 391 | clear_bit(ilog2(IDE_AFLAG_ADDRESS_VALID), |
392 | &drive->atapi_flags); | ||
401 | uptodate = 0; | 393 | uptodate = 0; |
402 | err = IDE_DRV_ERROR_GENERAL; | 394 | err = IDE_DRV_ERROR_GENERAL; |
403 | } else { | 395 | } else { |
@@ -406,7 +398,8 @@ static int ide_tape_callback(ide_drive_t *drive, int dsc) | |||
406 | 398 | ||
407 | tape->partition = readpos[1]; | 399 | tape->partition = readpos[1]; |
408 | tape->first_frame = be32_to_cpup((__be32 *)&readpos[4]); | 400 | tape->first_frame = be32_to_cpup((__be32 *)&readpos[4]); |
409 | set_bit(IDE_AFLAG_ADDRESS_VALID, &drive->atapi_flags); | 401 | set_bit(ilog2(IDE_AFLAG_ADDRESS_VALID), |
402 | &drive->atapi_flags); | ||
410 | } | 403 | } |
411 | } | 404 | } |
412 | 405 | ||
@@ -656,15 +649,15 @@ static ide_startstop_t idetape_do_request(ide_drive_t *drive, | |||
656 | 649 | ||
657 | if ((drive->dev_flags & IDE_DFLAG_DSC_OVERLAP) == 0 && | 650 | if ((drive->dev_flags & IDE_DFLAG_DSC_OVERLAP) == 0 && |
658 | (rq->cmd[13] & REQ_IDETAPE_PC2) == 0) | 651 | (rq->cmd[13] & REQ_IDETAPE_PC2) == 0) |
659 | set_bit(IDE_AFLAG_IGNORE_DSC, &drive->atapi_flags); | 652 | drive->atapi_flags |= IDE_AFLAG_IGNORE_DSC; |
660 | 653 | ||
661 | if (drive->dev_flags & IDE_DFLAG_POST_RESET) { | 654 | if (drive->dev_flags & IDE_DFLAG_POST_RESET) { |
662 | set_bit(IDE_AFLAG_IGNORE_DSC, &drive->atapi_flags); | 655 | drive->atapi_flags |= IDE_AFLAG_IGNORE_DSC; |
663 | drive->dev_flags &= ~IDE_DFLAG_POST_RESET; | 656 | drive->dev_flags &= ~IDE_DFLAG_POST_RESET; |
664 | } | 657 | } |
665 | 658 | ||
666 | if (!test_and_clear_bit(IDE_AFLAG_IGNORE_DSC, &drive->atapi_flags) && | 659 | if (!(drive->atapi_flags & IDE_AFLAG_IGNORE_DSC) && |
667 | (stat & ATA_DSC) == 0) { | 660 | !(stat & ATA_DSC)) { |
668 | if (postponed_rq == NULL) { | 661 | if (postponed_rq == NULL) { |
669 | tape->dsc_polling_start = jiffies; | 662 | tape->dsc_polling_start = jiffies; |
670 | tape->dsc_poll_freq = tape->best_dsc_rw_freq; | 663 | tape->dsc_poll_freq = tape->best_dsc_rw_freq; |
@@ -684,7 +677,9 @@ static ide_startstop_t idetape_do_request(ide_drive_t *drive, | |||
684 | tape->dsc_poll_freq = IDETAPE_DSC_MA_SLOW; | 677 | tape->dsc_poll_freq = IDETAPE_DSC_MA_SLOW; |
685 | idetape_postpone_request(drive); | 678 | idetape_postpone_request(drive); |
686 | return ide_stopped; | 679 | return ide_stopped; |
687 | } | 680 | } else |
681 | drive->atapi_flags &= ~IDE_AFLAG_IGNORE_DSC; | ||
682 | |||
688 | if (rq->cmd[13] & REQ_IDETAPE_READ) { | 683 | if (rq->cmd[13] & REQ_IDETAPE_READ) { |
689 | pc = &tape->queued_pc; | 684 | pc = &tape->queued_pc; |
690 | ide_tape_create_rw_cmd(tape, pc, rq, READ_6); | 685 | ide_tape_create_rw_cmd(tape, pc, rq, READ_6); |
@@ -744,7 +739,7 @@ static int idetape_wait_ready(ide_drive_t *drive, unsigned long timeout) | |||
744 | int load_attempted = 0; | 739 | int load_attempted = 0; |
745 | 740 | ||
746 | /* Wait for the tape to become ready */ | 741 | /* Wait for the tape to become ready */ |
747 | set_bit(IDE_AFLAG_MEDIUM_PRESENT, &drive->atapi_flags); | 742 | set_bit(ilog2(IDE_AFLAG_MEDIUM_PRESENT), &drive->atapi_flags); |
748 | timeout += jiffies; | 743 | timeout += jiffies; |
749 | while (time_before(jiffies, timeout)) { | 744 | while (time_before(jiffies, timeout)) { |
750 | if (ide_do_test_unit_ready(drive, disk) == 0) | 745 | if (ide_do_test_unit_ready(drive, disk) == 0) |
@@ -820,7 +815,7 @@ static void __ide_tape_discard_merge_buffer(ide_drive_t *drive) | |||
820 | if (tape->chrdev_dir != IDETAPE_DIR_READ) | 815 | if (tape->chrdev_dir != IDETAPE_DIR_READ) |
821 | return; | 816 | return; |
822 | 817 | ||
823 | clear_bit(IDE_AFLAG_FILEMARK, &drive->atapi_flags); | 818 | clear_bit(ilog2(IDE_AFLAG_FILEMARK), &drive->atapi_flags); |
824 | tape->valid = 0; | 819 | tape->valid = 0; |
825 | if (tape->buf != NULL) { | 820 | if (tape->buf != NULL) { |
826 | kfree(tape->buf); | 821 | kfree(tape->buf); |
@@ -1113,7 +1108,8 @@ static int idetape_space_over_filemarks(ide_drive_t *drive, short mt_op, | |||
1113 | 1108 | ||
1114 | if (tape->chrdev_dir == IDETAPE_DIR_READ) { | 1109 | if (tape->chrdev_dir == IDETAPE_DIR_READ) { |
1115 | tape->valid = 0; | 1110 | tape->valid = 0; |
1116 | if (test_and_clear_bit(IDE_AFLAG_FILEMARK, &drive->atapi_flags)) | 1111 | if (test_and_clear_bit(ilog2(IDE_AFLAG_FILEMARK), |
1112 | &drive->atapi_flags)) | ||
1117 | ++count; | 1113 | ++count; |
1118 | ide_tape_discard_merge_buffer(drive, 0); | 1114 | ide_tape_discard_merge_buffer(drive, 0); |
1119 | } | 1115 | } |
@@ -1168,7 +1164,7 @@ static ssize_t idetape_chrdev_read(struct file *file, char __user *buf, | |||
1168 | debug_log(DBG_CHRDEV, "Enter %s, count %Zd\n", __func__, count); | 1164 | debug_log(DBG_CHRDEV, "Enter %s, count %Zd\n", __func__, count); |
1169 | 1165 | ||
1170 | if (tape->chrdev_dir != IDETAPE_DIR_READ) { | 1166 | if (tape->chrdev_dir != IDETAPE_DIR_READ) { |
1171 | if (test_bit(IDE_AFLAG_DETECT_BS, &drive->atapi_flags)) | 1167 | if (test_bit(ilog2(IDE_AFLAG_DETECT_BS), &drive->atapi_flags)) |
1172 | if (count > tape->blk_size && | 1168 | if (count > tape->blk_size && |
1173 | (count % tape->blk_size) == 0) | 1169 | (count % tape->blk_size) == 0) |
1174 | tape->user_bs_factor = count / tape->blk_size; | 1170 | tape->user_bs_factor = count / tape->blk_size; |
@@ -1184,7 +1180,8 @@ static ssize_t idetape_chrdev_read(struct file *file, char __user *buf, | |||
1184 | /* refill if staging buffer is empty */ | 1180 | /* refill if staging buffer is empty */ |
1185 | if (!tape->valid) { | 1181 | if (!tape->valid) { |
1186 | /* If we are at a filemark, nothing more to read */ | 1182 | /* If we are at a filemark, nothing more to read */ |
1187 | if (test_bit(IDE_AFLAG_FILEMARK, &drive->atapi_flags)) | 1183 | if (test_bit(ilog2(IDE_AFLAG_FILEMARK), |
1184 | &drive->atapi_flags)) | ||
1188 | break; | 1185 | break; |
1189 | /* read */ | 1186 | /* read */ |
1190 | if (idetape_queue_rw_tail(drive, REQ_IDETAPE_READ, | 1187 | if (idetape_queue_rw_tail(drive, REQ_IDETAPE_READ, |
@@ -1202,7 +1199,7 @@ static ssize_t idetape_chrdev_read(struct file *file, char __user *buf, | |||
1202 | done += todo; | 1199 | done += todo; |
1203 | } | 1200 | } |
1204 | 1201 | ||
1205 | if (!done && test_bit(IDE_AFLAG_FILEMARK, &drive->atapi_flags)) { | 1202 | if (!done && test_bit(ilog2(IDE_AFLAG_FILEMARK), &drive->atapi_flags)) { |
1206 | debug_log(DBG_SENSE, "%s: spacing over filemark\n", tape->name); | 1203 | debug_log(DBG_SENSE, "%s: spacing over filemark\n", tape->name); |
1207 | 1204 | ||
1208 | idetape_space_over_filemarks(drive, MTFSF, 1); | 1205 | idetape_space_over_filemarks(drive, MTFSF, 1); |
@@ -1336,7 +1333,8 @@ static int idetape_mtioctop(ide_drive_t *drive, short mt_op, int mt_count) | |||
1336 | ide_tape_discard_merge_buffer(drive, 0); | 1333 | ide_tape_discard_merge_buffer(drive, 0); |
1337 | retval = ide_do_start_stop(drive, disk, !IDETAPE_LU_LOAD_MASK); | 1334 | retval = ide_do_start_stop(drive, disk, !IDETAPE_LU_LOAD_MASK); |
1338 | if (!retval) | 1335 | if (!retval) |
1339 | clear_bit(IDE_AFLAG_MEDIUM_PRESENT, &drive->atapi_flags); | 1336 | clear_bit(ilog2(IDE_AFLAG_MEDIUM_PRESENT), |
1337 | &drive->atapi_flags); | ||
1340 | return retval; | 1338 | return retval; |
1341 | case MTNOP: | 1339 | case MTNOP: |
1342 | ide_tape_discard_merge_buffer(drive, 0); | 1340 | ide_tape_discard_merge_buffer(drive, 0); |
@@ -1358,9 +1356,11 @@ static int idetape_mtioctop(ide_drive_t *drive, short mt_op, int mt_count) | |||
1358 | mt_count % tape->blk_size) | 1356 | mt_count % tape->blk_size) |
1359 | return -EIO; | 1357 | return -EIO; |
1360 | tape->user_bs_factor = mt_count / tape->blk_size; | 1358 | tape->user_bs_factor = mt_count / tape->blk_size; |
1361 | clear_bit(IDE_AFLAG_DETECT_BS, &drive->atapi_flags); | 1359 | clear_bit(ilog2(IDE_AFLAG_DETECT_BS), |
1360 | &drive->atapi_flags); | ||
1362 | } else | 1361 | } else |
1363 | set_bit(IDE_AFLAG_DETECT_BS, &drive->atapi_flags); | 1362 | set_bit(ilog2(IDE_AFLAG_DETECT_BS), |
1363 | &drive->atapi_flags); | ||
1364 | return 0; | 1364 | return 0; |
1365 | case MTSEEK: | 1365 | case MTSEEK: |
1366 | ide_tape_discard_merge_buffer(drive, 0); | 1366 | ide_tape_discard_merge_buffer(drive, 0); |
@@ -1486,7 +1486,7 @@ static int idetape_chrdev_open(struct inode *inode, struct file *filp) | |||
1486 | return -ENXIO; | 1486 | return -ENXIO; |
1487 | 1487 | ||
1488 | lock_kernel(); | 1488 | lock_kernel(); |
1489 | tape = ide_tape_chrdev_get(i); | 1489 | tape = ide_tape_get(NULL, true, i); |
1490 | if (!tape) { | 1490 | if (!tape) { |
1491 | unlock_kernel(); | 1491 | unlock_kernel(); |
1492 | return -ENXIO; | 1492 | return -ENXIO; |
@@ -1505,20 +1505,20 @@ static int idetape_chrdev_open(struct inode *inode, struct file *filp) | |||
1505 | 1505 | ||
1506 | filp->private_data = tape; | 1506 | filp->private_data = tape; |
1507 | 1507 | ||
1508 | if (test_and_set_bit(IDE_AFLAG_BUSY, &drive->atapi_flags)) { | 1508 | if (test_and_set_bit(ilog2(IDE_AFLAG_BUSY), &drive->atapi_flags)) { |
1509 | retval = -EBUSY; | 1509 | retval = -EBUSY; |
1510 | goto out_put_tape; | 1510 | goto out_put_tape; |
1511 | } | 1511 | } |
1512 | 1512 | ||
1513 | retval = idetape_wait_ready(drive, 60 * HZ); | 1513 | retval = idetape_wait_ready(drive, 60 * HZ); |
1514 | if (retval) { | 1514 | if (retval) { |
1515 | clear_bit(IDE_AFLAG_BUSY, &drive->atapi_flags); | 1515 | clear_bit(ilog2(IDE_AFLAG_BUSY), &drive->atapi_flags); |
1516 | printk(KERN_ERR "ide-tape: %s: drive not ready\n", tape->name); | 1516 | printk(KERN_ERR "ide-tape: %s: drive not ready\n", tape->name); |
1517 | goto out_put_tape; | 1517 | goto out_put_tape; |
1518 | } | 1518 | } |
1519 | 1519 | ||
1520 | idetape_read_position(drive); | 1520 | idetape_read_position(drive); |
1521 | if (!test_bit(IDE_AFLAG_ADDRESS_VALID, &drive->atapi_flags)) | 1521 | if (!test_bit(ilog2(IDE_AFLAG_ADDRESS_VALID), &drive->atapi_flags)) |
1522 | (void)idetape_rewind_tape(drive); | 1522 | (void)idetape_rewind_tape(drive); |
1523 | 1523 | ||
1524 | /* Read block size and write protect status from drive. */ | 1524 | /* Read block size and write protect status from drive. */ |
@@ -1534,7 +1534,7 @@ static int idetape_chrdev_open(struct inode *inode, struct file *filp) | |||
1534 | if (tape->write_prot) { | 1534 | if (tape->write_prot) { |
1535 | if ((filp->f_flags & O_ACCMODE) == O_WRONLY || | 1535 | if ((filp->f_flags & O_ACCMODE) == O_WRONLY || |
1536 | (filp->f_flags & O_ACCMODE) == O_RDWR) { | 1536 | (filp->f_flags & O_ACCMODE) == O_RDWR) { |
1537 | clear_bit(IDE_AFLAG_BUSY, &drive->atapi_flags); | 1537 | clear_bit(ilog2(IDE_AFLAG_BUSY), &drive->atapi_flags); |
1538 | retval = -EROFS; | 1538 | retval = -EROFS; |
1539 | goto out_put_tape; | 1539 | goto out_put_tape; |
1540 | } | 1540 | } |
@@ -1591,15 +1591,17 @@ static int idetape_chrdev_release(struct inode *inode, struct file *filp) | |||
1591 | ide_tape_discard_merge_buffer(drive, 1); | 1591 | ide_tape_discard_merge_buffer(drive, 1); |
1592 | } | 1592 | } |
1593 | 1593 | ||
1594 | if (minor < 128 && test_bit(IDE_AFLAG_MEDIUM_PRESENT, &drive->atapi_flags)) | 1594 | if (minor < 128 && test_bit(ilog2(IDE_AFLAG_MEDIUM_PRESENT), |
1595 | &drive->atapi_flags)) | ||
1595 | (void) idetape_rewind_tape(drive); | 1596 | (void) idetape_rewind_tape(drive); |
1597 | |||
1596 | if (tape->chrdev_dir == IDETAPE_DIR_NONE) { | 1598 | if (tape->chrdev_dir == IDETAPE_DIR_NONE) { |
1597 | if (tape->door_locked == DOOR_LOCKED) { | 1599 | if (tape->door_locked == DOOR_LOCKED) { |
1598 | if (!ide_set_media_lock(drive, tape->disk, 0)) | 1600 | if (!ide_set_media_lock(drive, tape->disk, 0)) |
1599 | tape->door_locked = DOOR_UNLOCKED; | 1601 | tape->door_locked = DOOR_UNLOCKED; |
1600 | } | 1602 | } |
1601 | } | 1603 | } |
1602 | clear_bit(IDE_AFLAG_BUSY, &drive->atapi_flags); | 1604 | clear_bit(ilog2(IDE_AFLAG_BUSY), &drive->atapi_flags); |
1603 | ide_tape_put(tape); | 1605 | ide_tape_put(tape); |
1604 | unlock_kernel(); | 1606 | unlock_kernel(); |
1605 | return 0; | 1607 | return 0; |
@@ -1905,7 +1907,7 @@ static const struct file_operations idetape_fops = { | |||
1905 | 1907 | ||
1906 | static int idetape_open(struct block_device *bdev, fmode_t mode) | 1908 | static int idetape_open(struct block_device *bdev, fmode_t mode) |
1907 | { | 1909 | { |
1908 | struct ide_tape_obj *tape = ide_tape_get(bdev->bd_disk); | 1910 | struct ide_tape_obj *tape = ide_tape_get(bdev->bd_disk, false, 0); |
1909 | 1911 | ||
1910 | if (!tape) | 1912 | if (!tape) |
1911 | return -ENXIO; | 1913 | return -ENXIO; |