1 /* 2 * lowlevel.c 3 * 4 * PURPOSE 5 * Low Level Device Routines for the UDF filesystem 6 * 7 * COPYRIGHT 8 * This file is distributed under the terms of the GNU General Public 9 * License (GPL). Copies of the GPL can be obtained from: 10 * ftp://prep.ai.mit.edu/pub/gnu/GPL 11 * Each contributing author retains all rights to their own work. 12 * 13 * (C) 1999-2001 Ben Fennema 14 * 15 * HISTORY 16 * 17 * 03/26/99 blf Created. 18 */ 19 20 #include "udfdecl.h" 21 22 #include <linux/blkdev.h> 23 #include <linux/cdrom.h> 24 #include <asm/uaccess.h> 25 26 #include <linux/udf_fs.h> 27 #include "udf_sb.h" 28 29 unsigned int udf_get_last_session(struct super_block *sb) 30 { 31 struct cdrom_multisession ms_info; 32 unsigned int vol_desc_start; 33 struct block_device *bdev = sb->s_bdev; 34 int i; 35 36 vol_desc_start = 0; 37 ms_info.addr_format = CDROM_LBA; 38 i = ioctl_by_bdev(bdev, CDROMMULTISESSION, (unsigned long)&ms_info); 39 40 #define WE_OBEY_THE_WRITTEN_STANDARDS 1 41 42 if (i == 0) { 43 udf_debug("XA disk: %s, vol_desc_start=%d\n", 44 (ms_info.xa_flag ? "yes" : "no"), ms_info.addr.lba); 45 #if WE_OBEY_THE_WRITTEN_STANDARDS 46 if (ms_info.xa_flag) /* necessary for a valid ms_info.addr */ 47 #endif 48 vol_desc_start = ms_info.addr.lba; 49 } else { 50 udf_debug("CDROMMULTISESSION not supported: rc=%d\n", i); 51 } 52 return vol_desc_start; 53 } 54 55 unsigned long udf_get_last_block(struct super_block *sb) 56 { 57 struct block_device *bdev = sb->s_bdev; 58 unsigned long lblock = 0; 59 60 if (ioctl_by_bdev(bdev, CDROM_LAST_WRITTEN, (unsigned long) &lblock)) 61 lblock = bdev->bd_inode->i_size >> sb->s_blocksize_bits; 62 63 if (lblock) 64 return lblock - 1; 65 else 66 return 0; 67 } 68