include upstream ip1000a driver version 2.09f
[linux-2.4.git] / fs / udf / lowlevel.c
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
32 typedef struct scsi_device Scsi_Device;
33 typedef 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
40 unsigned int 
41 udf_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
70 unsigned long
71 udf_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 }