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 <linux/uaccess.h> 25 26 #include "udf_sb.h" 27 28 unsigned int udf_get_last_session(struct super_block *sb) 29 { 30 struct cdrom_multisession ms_info; 31 unsigned int vol_desc_start; 32 struct block_device *bdev = sb->s_bdev; 33 int i; 34 35 vol_desc_start = 0; 36 ms_info.addr_format = CDROM_LBA; 37 i = ioctl_by_bdev(bdev, CDROMMULTISESSION, (unsigned long)&ms_info); 38 39 if (i == 0) { 40 udf_debug("XA disk: %s, vol_desc_start=%d\n", 41 ms_info.xa_flag ? "yes" : "no", ms_info.addr.lba); 42 if (ms_info.xa_flag) /* necessary for a valid ms_info.addr */ 43 vol_desc_start = ms_info.addr.lba; 44 } else { 45 udf_debug("CDROMMULTISESSION not supported: rc=%d\n", i); 46 } 47 return vol_desc_start; 48 } 49 50 unsigned long udf_get_last_block(struct super_block *sb) 51 { 52 struct block_device *bdev = sb->s_bdev; 53 unsigned long lblock = 0; 54 55 /* 56 * ioctl failed or returned obviously bogus value? 57 * Try using the device size... 58 */ 59 if (ioctl_by_bdev(bdev, CDROM_LAST_WRITTEN, (unsigned long) &lblock) || 60 lblock == 0) 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