0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011 #ifndef _LINUX_CDROM_H
0012 #define _LINUX_CDROM_H
0013
0014 #include <linux/fs.h> /* not really needed, later.. */
0015 #include <linux/list.h>
0016 #include <scsi/scsi_common.h>
0017 #include <uapi/linux/cdrom.h>
0018
0019 struct packet_command
0020 {
0021 unsigned char cmd[CDROM_PACKET_SIZE];
0022 unsigned char *buffer;
0023 unsigned int buflen;
0024 int stat;
0025 struct scsi_sense_hdr *sshdr;
0026 unsigned char data_direction;
0027 int quiet;
0028 int timeout;
0029 void *reserved[1];
0030 };
0031
0032
0033
0034
0035 #define CDDA_OLD 0
0036 #define CDDA_BPC_SINGLE 1
0037 #define CDDA_BPC_FULL 2
0038
0039
0040 struct cdrom_device_info {
0041 const struct cdrom_device_ops *ops;
0042 struct list_head list;
0043 struct gendisk *disk;
0044 void *handle;
0045
0046 int mask;
0047 int speed;
0048 int capacity;
0049
0050 unsigned int options : 30;
0051 unsigned mc_flags : 2;
0052 unsigned int vfs_events;
0053 unsigned int ioctl_events;
0054 int use_count;
0055 char name[20];
0056
0057 __u8 sanyo_slot : 2;
0058 __u8 keeplocked : 1;
0059 __u8 reserved : 5;
0060 int cdda_method;
0061 __u8 last_sense;
0062 __u8 media_written;
0063 unsigned short mmc3_profile;
0064 int for_data;
0065 int (*exit)(struct cdrom_device_info *);
0066 int mrw_mode_page;
0067 __s64 last_media_change_ms;
0068 };
0069
0070 struct cdrom_device_ops {
0071
0072 int (*open) (struct cdrom_device_info *, int);
0073 void (*release) (struct cdrom_device_info *);
0074 int (*drive_status) (struct cdrom_device_info *, int);
0075 unsigned int (*check_events) (struct cdrom_device_info *cdi,
0076 unsigned int clearing, int slot);
0077 int (*tray_move) (struct cdrom_device_info *, int);
0078 int (*lock_door) (struct cdrom_device_info *, int);
0079 int (*select_speed) (struct cdrom_device_info *, int);
0080 int (*get_last_session) (struct cdrom_device_info *,
0081 struct cdrom_multisession *);
0082 int (*get_mcn) (struct cdrom_device_info *,
0083 struct cdrom_mcn *);
0084
0085 int (*reset) (struct cdrom_device_info *);
0086
0087 int (*audio_ioctl) (struct cdrom_device_info *,unsigned int, void *);
0088
0089
0090 int (*generic_packet) (struct cdrom_device_info *,
0091 struct packet_command *);
0092 int (*read_cdda_bpc)(struct cdrom_device_info *cdi, void __user *ubuf,
0093 u32 lba, u32 nframes, u8 *last_sense);
0094
0095 const int capability;
0096 };
0097
0098 int cdrom_multisession(struct cdrom_device_info *cdi,
0099 struct cdrom_multisession *info);
0100 int cdrom_read_tocentry(struct cdrom_device_info *cdi,
0101 struct cdrom_tocentry *entry);
0102
0103
0104 extern int cdrom_open(struct cdrom_device_info *cdi, struct block_device *bdev,
0105 fmode_t mode);
0106 extern void cdrom_release(struct cdrom_device_info *cdi, fmode_t mode);
0107 extern int cdrom_ioctl(struct cdrom_device_info *cdi, struct block_device *bdev,
0108 fmode_t mode, unsigned int cmd, unsigned long arg);
0109 extern unsigned int cdrom_check_events(struct cdrom_device_info *cdi,
0110 unsigned int clearing);
0111
0112 extern int register_cdrom(struct gendisk *disk, struct cdrom_device_info *cdi);
0113 extern void unregister_cdrom(struct cdrom_device_info *cdi);
0114
0115 typedef struct {
0116 int data;
0117 int audio;
0118 int cdi;
0119 int xa;
0120 long error;
0121 } tracktype;
0122
0123 extern int cdrom_get_last_written(struct cdrom_device_info *cdi, long *last_written);
0124 extern int cdrom_number_of_slots(struct cdrom_device_info *cdi);
0125 extern int cdrom_mode_select(struct cdrom_device_info *cdi,
0126 struct packet_command *cgc);
0127 extern int cdrom_mode_sense(struct cdrom_device_info *cdi,
0128 struct packet_command *cgc,
0129 int page_code, int page_control);
0130 extern void init_cdrom_command(struct packet_command *cgc,
0131 void *buffer, int len, int type);
0132 extern int cdrom_dummy_generic_packet(struct cdrom_device_info *cdi,
0133 struct packet_command *cgc);
0134
0135
0136 #define CDROM_MAX_SLOTS 256
0137
0138 struct cdrom_mechstat_header {
0139 #if defined(__BIG_ENDIAN_BITFIELD)
0140 __u8 fault : 1;
0141 __u8 changer_state : 2;
0142 __u8 curslot : 5;
0143 __u8 mech_state : 3;
0144 __u8 door_open : 1;
0145 __u8 reserved1 : 4;
0146 #elif defined(__LITTLE_ENDIAN_BITFIELD)
0147 __u8 curslot : 5;
0148 __u8 changer_state : 2;
0149 __u8 fault : 1;
0150 __u8 reserved1 : 4;
0151 __u8 door_open : 1;
0152 __u8 mech_state : 3;
0153 #endif
0154 __u8 curlba[3];
0155 __u8 nslots;
0156 __u16 slot_tablelen;
0157 };
0158
0159 struct cdrom_slot {
0160 #if defined(__BIG_ENDIAN_BITFIELD)
0161 __u8 disc_present : 1;
0162 __u8 reserved1 : 6;
0163 __u8 change : 1;
0164 #elif defined(__LITTLE_ENDIAN_BITFIELD)
0165 __u8 change : 1;
0166 __u8 reserved1 : 6;
0167 __u8 disc_present : 1;
0168 #endif
0169 __u8 reserved2[3];
0170 };
0171
0172 struct cdrom_changer_info {
0173 struct cdrom_mechstat_header hdr;
0174 struct cdrom_slot slots[CDROM_MAX_SLOTS];
0175 };
0176
0177 typedef enum {
0178 mechtype_caddy = 0,
0179 mechtype_tray = 1,
0180 mechtype_popup = 2,
0181 mechtype_individual_changer = 4,
0182 mechtype_cartridge_changer = 5
0183 } mechtype_t;
0184
0185 typedef struct {
0186 #if defined(__BIG_ENDIAN_BITFIELD)
0187 __u8 ps : 1;
0188 __u8 reserved1 : 1;
0189 __u8 page_code : 6;
0190 __u8 page_length;
0191 __u8 reserved2 : 1;
0192 __u8 bufe : 1;
0193 __u8 ls_v : 1;
0194 __u8 test_write : 1;
0195 __u8 write_type : 4;
0196 __u8 multi_session : 2;
0197 __u8 fp : 1;
0198 __u8 copy : 1;
0199 __u8 track_mode : 4;
0200 __u8 reserved3 : 4;
0201 __u8 data_block_type : 4;
0202 #elif defined(__LITTLE_ENDIAN_BITFIELD)
0203 __u8 page_code : 6;
0204 __u8 reserved1 : 1;
0205 __u8 ps : 1;
0206 __u8 page_length;
0207 __u8 write_type : 4;
0208 __u8 test_write : 1;
0209 __u8 ls_v : 1;
0210 __u8 bufe : 1;
0211 __u8 reserved2 : 1;
0212 __u8 track_mode : 4;
0213 __u8 copy : 1;
0214 __u8 fp : 1;
0215 __u8 multi_session : 2;
0216 __u8 data_block_type : 4;
0217 __u8 reserved3 : 4;
0218 #endif
0219 __u8 link_size;
0220 __u8 reserved4;
0221 #if defined(__BIG_ENDIAN_BITFIELD)
0222 __u8 reserved5 : 2;
0223 __u8 app_code : 6;
0224 #elif defined(__LITTLE_ENDIAN_BITFIELD)
0225 __u8 app_code : 6;
0226 __u8 reserved5 : 2;
0227 #endif
0228 __u8 session_format;
0229 __u8 reserved6;
0230 __be32 packet_size;
0231 __u16 audio_pause;
0232 __u8 mcn[16];
0233 __u8 isrc[16];
0234 __u8 subhdr0;
0235 __u8 subhdr1;
0236 __u8 subhdr2;
0237 __u8 subhdr3;
0238 } __attribute__((packed)) write_param_page;
0239
0240 struct modesel_head
0241 {
0242 __u8 reserved1;
0243 __u8 medium;
0244 __u8 reserved2;
0245 __u8 block_desc_length;
0246 __u8 density;
0247 __u8 number_of_blocks_hi;
0248 __u8 number_of_blocks_med;
0249 __u8 number_of_blocks_lo;
0250 __u8 reserved3;
0251 __u8 block_length_hi;
0252 __u8 block_length_med;
0253 __u8 block_length_lo;
0254 };
0255
0256 typedef struct {
0257 __u16 report_key_length;
0258 __u8 reserved1;
0259 __u8 reserved2;
0260 #if defined(__BIG_ENDIAN_BITFIELD)
0261 __u8 type_code : 2;
0262 __u8 vra : 3;
0263 __u8 ucca : 3;
0264 #elif defined(__LITTLE_ENDIAN_BITFIELD)
0265 __u8 ucca : 3;
0266 __u8 vra : 3;
0267 __u8 type_code : 2;
0268 #endif
0269 __u8 region_mask;
0270 __u8 rpc_scheme;
0271 __u8 reserved3;
0272 } rpc_state_t;
0273
0274 struct event_header {
0275 __be16 data_len;
0276 #if defined(__BIG_ENDIAN_BITFIELD)
0277 __u8 nea : 1;
0278 __u8 reserved1 : 4;
0279 __u8 notification_class : 3;
0280 #elif defined(__LITTLE_ENDIAN_BITFIELD)
0281 __u8 notification_class : 3;
0282 __u8 reserved1 : 4;
0283 __u8 nea : 1;
0284 #endif
0285 __u8 supp_event_class;
0286 };
0287
0288 struct media_event_desc {
0289 #if defined(__BIG_ENDIAN_BITFIELD)
0290 __u8 reserved1 : 4;
0291 __u8 media_event_code : 4;
0292 __u8 reserved2 : 6;
0293 __u8 media_present : 1;
0294 __u8 door_open : 1;
0295 #elif defined(__LITTLE_ENDIAN_BITFIELD)
0296 __u8 media_event_code : 4;
0297 __u8 reserved1 : 4;
0298 __u8 door_open : 1;
0299 __u8 media_present : 1;
0300 __u8 reserved2 : 6;
0301 #endif
0302 __u8 start_slot;
0303 __u8 end_slot;
0304 };
0305
0306 extern int cdrom_get_media_event(struct cdrom_device_info *cdi, struct media_event_desc *med);
0307
0308 static inline void lba_to_msf(int lba, u8 *m, u8 *s, u8 *f)
0309 {
0310 lba += CD_MSF_OFFSET;
0311 lba &= 0xffffff;
0312 *m = lba / (CD_SECS * CD_FRAMES);
0313 lba %= (CD_SECS * CD_FRAMES);
0314 *s = lba / CD_FRAMES;
0315 *f = lba % CD_FRAMES;
0316 }
0317
0318 static inline int msf_to_lba(u8 m, u8 s, u8 f)
0319 {
0320 return (((m * CD_SECS) + s) * CD_FRAMES + f) - CD_MSF_OFFSET;
0321 }
0322 #endif