1/* 2 * lowlevel.c 3 * 4 * PURPOSE 5 * Low Level Device Routines for the UDF filesystem 6 * 7 * CONTACTS 8 * E-mail regarding any portion of the Linux UDF file system should be 9 * directed to the development team mailing list (run by majordomo): 10 * linux_udf@hpesjro.fc.hp.com 11 * 12 * COPYRIGHT 13 * This file is distributed under the terms of the GNU General Public 14 * License (GPL). Copies of the GPL can be obtained from: 15 * ftp://prep.ai.mit.edu/pub/gnu/GPL 16 * Each contributing author retains all rights to their own work. 17 * 18 * (C) 1999-2001 Ben Fennema 19 * 20 * HISTORY 21 * 22 * 03/26/99 blf Created. 23 */ 24 25#include "udfdecl.h" 26 27#include <linux/blkdev.h> 28#include <linux/cdrom.h> 29#include <asm/uaccess.h> 30#include <scsi/scsi.h> 31 32typedef struct scsi_device Scsi_Device; 33typedef struct scsi_cmnd Scsi_Cmnd; 34 35#include <scsi/scsi_ioctl.h> 36 37#include <linux/udf_fs.h> 38#include "udf_sb.h" 39 40unsigned int 41udf_get_last_session(struct super_block *sb) 42{ 43 struct cdrom_multisession ms_info; 44 unsigned int vol_desc_start; 45 struct block_device *bdev = sb->s_bdev; 46 int i; 47 48 vol_desc_start=0; 49 ms_info.addr_format=CDROM_LBA; 50 i = ioctl_by_bdev(bdev, CDROMMULTISESSION, (unsigned long) &ms_info); 51 52#define WE_OBEY_THE_WRITTEN_STANDARDS 1 53 54 if (i == 0) 55 { 56 udf_debug("XA disk: %s, vol_desc_start=%d\n", 57 (ms_info.xa_flag ? "yes" : "no"), ms_info.addr.lba); 58#if WE_OBEY_THE_WRITTEN_STANDARDS 59 if (ms_info.xa_flag) /* necessary for a valid ms_info.addr */ 60#endif 61 vol_desc_start = ms_info.addr.lba; 62 } 63 else 64 { 65 udf_debug("CDROMMULTISESSION not supported: rc=%d\n", i); 66 } 67 return vol_desc_start; 68} 69 70unsigned long 71udf_get_last_block(struct super_block *sb) 72{ 73 struct block_device *bdev = sb->s_bdev; 74 int ret; 75 unsigned long lblock = 0; 76 77 ret = ioctl_by_bdev(bdev, CDROM_LAST_WRITTEN, (unsigned long) &lblock); 78 79 if (ret) /* Hard Disk */ 80 { 81 ret = ioctl_by_bdev(bdev, BLKGETSIZE, (unsigned long) &lblock); 82 83 if (!ret && lblock != 0x7FFFFFFF) 84 lblock = ((512 * lblock) / sb->s_blocksize); 85 } 86 87 if (!ret && lblock) 88 return lblock - 1; 89 else 90 return 0; 91} 92