xref: /openbmc/linux/include/linux/cdrom.h (revision 05bdb996)
1b2441318SGreg Kroah-Hartman /* SPDX-License-Identifier: GPL-2.0 */
21da177e4SLinus Torvalds /*
31da177e4SLinus Torvalds  * -- <linux/cdrom.h>
41da177e4SLinus Torvalds  * General header file for linux CD-ROM drivers
51da177e4SLinus Torvalds  * Copyright (C) 1992         David Giller, rafetmad@oxy.edu
696de0e25SJan Engelhardt  *               1994, 1995   Eberhard Mönkeberg, emoenke@gwdg.de
71da177e4SLinus Torvalds  *               1996         David van Leeuwen, david@tm.tno.nl
81da177e4SLinus Torvalds  *               1997, 1998   Erik Andersen, andersee@debian.org
91da177e4SLinus Torvalds  *               1998-2002    Jens Axboe, axboe@suse.de
101da177e4SLinus Torvalds  */
111da177e4SLinus Torvalds #ifndef	_LINUX_CDROM_H
121da177e4SLinus Torvalds #define	_LINUX_CDROM_H
131da177e4SLinus Torvalds 
141da177e4SLinus Torvalds #include <linux/fs.h>		/* not really needed, later.. */
157fd097d4SAkinobu Mita #include <linux/list.h>
16*05bdb996SChristoph Hellwig #include <linux/blkdev.h>
17e7d0748dSKees Cook #include <scsi/scsi_common.h>
18607ca46eSDavid Howells #include <uapi/linux/cdrom.h>
191da177e4SLinus Torvalds 
201da177e4SLinus Torvalds struct packet_command
211da177e4SLinus Torvalds {
221da177e4SLinus Torvalds 	unsigned char 		cmd[CDROM_PACKET_SIZE];
231da177e4SLinus Torvalds 	unsigned char 		*buffer;
241da177e4SLinus Torvalds 	unsigned int 		buflen;
251da177e4SLinus Torvalds 	int			stat;
26e7d0748dSKees Cook 	struct scsi_sense_hdr	*sshdr;
271da177e4SLinus Torvalds 	unsigned char		data_direction;
281da177e4SLinus Torvalds 	int			quiet;
291da177e4SLinus Torvalds 	int			timeout;
301da177e4SLinus Torvalds 	void			*reserved[1];
311da177e4SLinus Torvalds };
321da177e4SLinus Torvalds 
331da177e4SLinus Torvalds /*
341da177e4SLinus Torvalds  * _OLD will use PIO transfer on atapi devices, _BPC_* will use DMA
351da177e4SLinus Torvalds  */
361da177e4SLinus Torvalds #define CDDA_OLD		0	/* old style */
371da177e4SLinus Torvalds #define CDDA_BPC_SINGLE		1	/* single frame block pc */
381da177e4SLinus Torvalds #define CDDA_BPC_FULL		2	/* multi frame block pc */
391da177e4SLinus Torvalds 
401da177e4SLinus Torvalds /* Uniform cdrom data structures for cdrom.c */
411da177e4SLinus Torvalds struct cdrom_device_info {
42853fe1bfSKees Cook 	const struct cdrom_device_ops *ops; /* link to device_ops */
437fd097d4SAkinobu Mita 	struct list_head list;		/* linked list of all device_info */
441da177e4SLinus Torvalds 	struct gendisk *disk;		/* matching block layer disk */
451da177e4SLinus Torvalds 	void *handle;		        /* driver-dependent data */
461da177e4SLinus Torvalds /* specifications */
471da177e4SLinus Torvalds 	int mask;                       /* mask of capability: disables them */
481da177e4SLinus Torvalds 	int speed;			/* maximum speed for reading data */
491da177e4SLinus Torvalds 	int capacity;			/* number of discs in jukebox */
501da177e4SLinus Torvalds /* device-related storage */
510cba01dbSRandy Dunlap 	unsigned int options	: 30;	/* options flags */
521da177e4SLinus Torvalds 	unsigned mc_flags	: 2;	/* media change buffer flags */
532d921729STejun Heo 	unsigned int vfs_events;	/* cached events for vfs path */
542d921729STejun Heo 	unsigned int ioctl_events;	/* cached events for ioctl path */
551da177e4SLinus Torvalds     	int use_count;                  /* number of times device opened */
561da177e4SLinus Torvalds     	char name[20];                  /* name of the device type */
571da177e4SLinus Torvalds /* per-device flags */
581da177e4SLinus Torvalds         __u8 sanyo_slot		: 2;	/* Sanyo 3 CD changer support */
59cdccaa94SPaolo Bonzini         __u8 keeplocked		: 1;	/* CDROM_LOCKDOOR status */
60cdccaa94SPaolo Bonzini         __u8 reserved		: 5;	/* not used yet */
611da177e4SLinus Torvalds 	int cdda_method;		/* see flags */
621da177e4SLinus Torvalds 	__u8 last_sense;
631da177e4SLinus Torvalds 	__u8 media_written;		/* dirty flag, DVD+RW bookkeeping */
641da177e4SLinus Torvalds 	unsigned short mmc3_profile;	/* current MMC3 profile */
651da177e4SLinus Torvalds 	int (*exit)(struct cdrom_device_info *);
661da177e4SLinus Torvalds 	int mrw_mode_page;
678cdf433eSChristoph Hellwig 	bool opened_for_data;
6867f1e027SLukas Prediger 	__s64 last_media_change_ms;
691da177e4SLinus Torvalds };
701da177e4SLinus Torvalds 
711da177e4SLinus Torvalds struct cdrom_device_ops {
721da177e4SLinus Torvalds /* routines */
731da177e4SLinus Torvalds 	int (*open) (struct cdrom_device_info *, int);
741da177e4SLinus Torvalds 	void (*release) (struct cdrom_device_info *);
751da177e4SLinus Torvalds 	int (*drive_status) (struct cdrom_device_info *, int);
762d921729STejun Heo 	unsigned int (*check_events) (struct cdrom_device_info *cdi,
772d921729STejun Heo 				      unsigned int clearing, int slot);
781da177e4SLinus Torvalds 	int (*tray_move) (struct cdrom_device_info *, int);
791da177e4SLinus Torvalds 	int (*lock_door) (struct cdrom_device_info *, int);
801da177e4SLinus Torvalds 	int (*select_speed) (struct cdrom_device_info *, int);
811da177e4SLinus Torvalds 	int (*get_last_session) (struct cdrom_device_info *,
821da177e4SLinus Torvalds 				 struct cdrom_multisession *);
831da177e4SLinus Torvalds 	int (*get_mcn) (struct cdrom_device_info *,
841da177e4SLinus Torvalds 			struct cdrom_mcn *);
851da177e4SLinus Torvalds 	/* hard reset device */
861da177e4SLinus Torvalds 	int (*reset) (struct cdrom_device_info *);
871da177e4SLinus Torvalds 	/* play stuff */
881da177e4SLinus Torvalds 	int (*audio_ioctl) (struct cdrom_device_info *,unsigned int, void *);
896a2900b6SChristoph Hellwig 
901da177e4SLinus Torvalds 	/* handle uniform packets for scsi type devices (scsi,atapi) */
911da177e4SLinus Torvalds 	int (*generic_packet) (struct cdrom_device_info *,
921da177e4SLinus Torvalds 			       struct packet_command *);
93ba51bdafSChristoph Hellwig 	int (*read_cdda_bpc)(struct cdrom_device_info *cdi, void __user *ubuf,
94ba51bdafSChristoph Hellwig 			       u32 lba, u32 nframes, u8 *last_sense);
95ba51bdafSChristoph Hellwig /* driver specifications */
96ba51bdafSChristoph Hellwig 	const int capability;   /* capability flags */
971da177e4SLinus Torvalds };
981da177e4SLinus Torvalds 
99eaf8e3e4SChristoph Hellwig int cdrom_multisession(struct cdrom_device_info *cdi,
100eaf8e3e4SChristoph Hellwig 		struct cdrom_multisession *info);
1014c3cfcceSChristoph Hellwig int cdrom_read_tocentry(struct cdrom_device_info *cdi,
1024c3cfcceSChristoph Hellwig 		struct cdrom_tocentry *entry);
1034c3cfcceSChristoph Hellwig 
1041da177e4SLinus Torvalds /* the general block_device operations structure: */
105*05bdb996SChristoph Hellwig int cdrom_open(struct cdrom_device_info *cdi, blk_mode_t mode);
1067ae24fceSChristoph Hellwig void cdrom_release(struct cdrom_device_info *cdi);
107473399b5SChristoph Hellwig int cdrom_ioctl(struct cdrom_device_info *cdi, struct block_device *bdev,
108473399b5SChristoph Hellwig 		unsigned int cmd, unsigned long arg);
1092d921729STejun Heo extern unsigned int cdrom_check_events(struct cdrom_device_info *cdi,
1102d921729STejun Heo 				       unsigned int clearing);
1111da177e4SLinus Torvalds 
112a711d91cSChristoph Hellwig extern int register_cdrom(struct gendisk *disk, struct cdrom_device_info *cdi);
1130a0c4114SAkinobu Mita extern void unregister_cdrom(struct cdrom_device_info *cdi);
1141da177e4SLinus Torvalds 
1151da177e4SLinus Torvalds typedef struct {
1161da177e4SLinus Torvalds     int data;
1171da177e4SLinus Torvalds     int audio;
1181da177e4SLinus Torvalds     int cdi;
1191da177e4SLinus Torvalds     int xa;
1201da177e4SLinus Torvalds     long error;
1211da177e4SLinus Torvalds } tracktype;
1221da177e4SLinus Torvalds 
1231da177e4SLinus Torvalds extern int cdrom_get_last_written(struct cdrom_device_info *cdi, long *last_written);
1241da177e4SLinus Torvalds extern int cdrom_number_of_slots(struct cdrom_device_info *cdi);
1251da177e4SLinus Torvalds extern int cdrom_mode_select(struct cdrom_device_info *cdi,
1261da177e4SLinus Torvalds 			     struct packet_command *cgc);
1271da177e4SLinus Torvalds extern int cdrom_mode_sense(struct cdrom_device_info *cdi,
1281da177e4SLinus Torvalds 			    struct packet_command *cgc,
1291da177e4SLinus Torvalds 			    int page_code, int page_control);
1301da177e4SLinus Torvalds extern void init_cdrom_command(struct packet_command *cgc,
1311da177e4SLinus Torvalds 			       void *buffer, int len, int type);
132853fe1bfSKees Cook extern int cdrom_dummy_generic_packet(struct cdrom_device_info *cdi,
133853fe1bfSKees Cook 				      struct packet_command *cgc);
1341da177e4SLinus Torvalds 
1351da177e4SLinus Torvalds /* The SCSI spec says there could be 256 slots. */
1361da177e4SLinus Torvalds #define CDROM_MAX_SLOTS	256
1371da177e4SLinus Torvalds 
1381da177e4SLinus Torvalds struct cdrom_mechstat_header {
1391da177e4SLinus Torvalds #if defined(__BIG_ENDIAN_BITFIELD)
1401da177e4SLinus Torvalds 	__u8 fault         : 1;
1411da177e4SLinus Torvalds 	__u8 changer_state : 2;
1421da177e4SLinus Torvalds 	__u8 curslot       : 5;
1431da177e4SLinus Torvalds 	__u8 mech_state    : 3;
1441da177e4SLinus Torvalds 	__u8 door_open     : 1;
1451da177e4SLinus Torvalds 	__u8 reserved1     : 4;
1461da177e4SLinus Torvalds #elif defined(__LITTLE_ENDIAN_BITFIELD)
1471da177e4SLinus Torvalds 	__u8 curslot       : 5;
1481da177e4SLinus Torvalds 	__u8 changer_state : 2;
1491da177e4SLinus Torvalds 	__u8 fault         : 1;
1501da177e4SLinus Torvalds 	__u8 reserved1     : 4;
1511da177e4SLinus Torvalds 	__u8 door_open     : 1;
1521da177e4SLinus Torvalds 	__u8 mech_state    : 3;
1531da177e4SLinus Torvalds #endif
1541da177e4SLinus Torvalds 	__u8     curlba[3];
1551da177e4SLinus Torvalds 	__u8     nslots;
1561da177e4SLinus Torvalds 	__u16 slot_tablelen;
1571da177e4SLinus Torvalds };
1581da177e4SLinus Torvalds 
1591da177e4SLinus Torvalds struct cdrom_slot {
1601da177e4SLinus Torvalds #if defined(__BIG_ENDIAN_BITFIELD)
1611da177e4SLinus Torvalds 	__u8 disc_present : 1;
1621da177e4SLinus Torvalds 	__u8 reserved1    : 6;
1631da177e4SLinus Torvalds 	__u8 change       : 1;
1641da177e4SLinus Torvalds #elif defined(__LITTLE_ENDIAN_BITFIELD)
1651da177e4SLinus Torvalds 	__u8 change       : 1;
1661da177e4SLinus Torvalds 	__u8 reserved1    : 6;
1671da177e4SLinus Torvalds 	__u8 disc_present : 1;
1681da177e4SLinus Torvalds #endif
1691da177e4SLinus Torvalds 	__u8 reserved2[3];
1701da177e4SLinus Torvalds };
1711da177e4SLinus Torvalds 
1721da177e4SLinus Torvalds struct cdrom_changer_info {
1731da177e4SLinus Torvalds 	struct cdrom_mechstat_header hdr;
1741da177e4SLinus Torvalds 	struct cdrom_slot slots[CDROM_MAX_SLOTS];
1751da177e4SLinus Torvalds };
1761da177e4SLinus Torvalds 
1771da177e4SLinus Torvalds typedef enum {
1781da177e4SLinus Torvalds 	mechtype_caddy = 0,
1791da177e4SLinus Torvalds 	mechtype_tray  = 1,
1801da177e4SLinus Torvalds 	mechtype_popup = 2,
1811da177e4SLinus Torvalds 	mechtype_individual_changer = 4,
1821da177e4SLinus Torvalds 	mechtype_cartridge_changer  = 5
1831da177e4SLinus Torvalds } mechtype_t;
1841da177e4SLinus Torvalds 
1851da177e4SLinus Torvalds typedef struct {
1861da177e4SLinus Torvalds #if defined(__BIG_ENDIAN_BITFIELD)
1871da177e4SLinus Torvalds 	__u8 ps			: 1;
1881da177e4SLinus Torvalds 	__u8 reserved1		: 1;
1891da177e4SLinus Torvalds 	__u8 page_code		: 6;
1901da177e4SLinus Torvalds         __u8 page_length;
1911da177e4SLinus Torvalds 	__u8 reserved2		: 1;
1921da177e4SLinus Torvalds 	__u8 bufe		: 1;
1931da177e4SLinus Torvalds 	__u8 ls_v		: 1;
1941da177e4SLinus Torvalds 	__u8 test_write		: 1;
1951da177e4SLinus Torvalds         __u8 write_type		: 4;
1961da177e4SLinus Torvalds 	__u8 multi_session	: 2; /* or border, DVD */
1971da177e4SLinus Torvalds 	__u8 fp			: 1;
1981da177e4SLinus Torvalds 	__u8 copy		: 1;
1991da177e4SLinus Torvalds 	__u8 track_mode		: 4;
2001da177e4SLinus Torvalds 	__u8 reserved3		: 4;
2011da177e4SLinus Torvalds 	__u8 data_block_type	: 4;
2021da177e4SLinus Torvalds #elif defined(__LITTLE_ENDIAN_BITFIELD)
2031da177e4SLinus Torvalds 	__u8 page_code		: 6;
2041da177e4SLinus Torvalds 	__u8 reserved1		: 1;
2051da177e4SLinus Torvalds 	__u8 ps			: 1;
2061da177e4SLinus Torvalds         __u8 page_length;
2071da177e4SLinus Torvalds         __u8 write_type		: 4;
2081da177e4SLinus Torvalds 	__u8 test_write		: 1;
2091da177e4SLinus Torvalds 	__u8 ls_v		: 1;
2101da177e4SLinus Torvalds 	__u8 bufe		: 1;
2111da177e4SLinus Torvalds 	__u8 reserved2		: 1;
2121da177e4SLinus Torvalds 	__u8 track_mode		: 4;
2131da177e4SLinus Torvalds 	__u8 copy		: 1;
2141da177e4SLinus Torvalds 	__u8 fp			: 1;
2151da177e4SLinus Torvalds 	__u8 multi_session	: 2; /* or border, DVD */
2161da177e4SLinus Torvalds 	__u8 data_block_type	: 4;
2171da177e4SLinus Torvalds 	__u8 reserved3		: 4;
2181da177e4SLinus Torvalds #endif
2191da177e4SLinus Torvalds 	__u8 link_size;
2201da177e4SLinus Torvalds 	__u8 reserved4;
2211da177e4SLinus Torvalds #if defined(__BIG_ENDIAN_BITFIELD)
2221da177e4SLinus Torvalds 	__u8 reserved5		: 2;
2231da177e4SLinus Torvalds 	__u8 app_code		: 6;
2241da177e4SLinus Torvalds #elif defined(__LITTLE_ENDIAN_BITFIELD)
2251da177e4SLinus Torvalds 	__u8 app_code		: 6;
2261da177e4SLinus Torvalds 	__u8 reserved5		: 2;
2271da177e4SLinus Torvalds #endif
2281da177e4SLinus Torvalds 	__u8 session_format;
2291da177e4SLinus Torvalds 	__u8 reserved6;
23056052d52SAlexey Dobriyan 	__be32 packet_size;
2311da177e4SLinus Torvalds 	__u16 audio_pause;
2321da177e4SLinus Torvalds 	__u8 mcn[16];
2331da177e4SLinus Torvalds 	__u8 isrc[16];
2341da177e4SLinus Torvalds 	__u8 subhdr0;
2351da177e4SLinus Torvalds 	__u8 subhdr1;
2361da177e4SLinus Torvalds 	__u8 subhdr2;
2371da177e4SLinus Torvalds 	__u8 subhdr3;
2381da177e4SLinus Torvalds } __attribute__((packed)) write_param_page;
2391da177e4SLinus Torvalds 
2401da177e4SLinus Torvalds struct modesel_head
2411da177e4SLinus Torvalds {
2421da177e4SLinus Torvalds 	__u8	reserved1;
2431da177e4SLinus Torvalds 	__u8	medium;
2441da177e4SLinus Torvalds 	__u8	reserved2;
2451da177e4SLinus Torvalds 	__u8	block_desc_length;
2461da177e4SLinus Torvalds 	__u8	density;
2471da177e4SLinus Torvalds 	__u8	number_of_blocks_hi;
2481da177e4SLinus Torvalds 	__u8	number_of_blocks_med;
2491da177e4SLinus Torvalds 	__u8	number_of_blocks_lo;
2501da177e4SLinus Torvalds 	__u8	reserved3;
2511da177e4SLinus Torvalds 	__u8	block_length_hi;
2521da177e4SLinus Torvalds 	__u8	block_length_med;
2531da177e4SLinus Torvalds 	__u8	block_length_lo;
2541da177e4SLinus Torvalds };
2551da177e4SLinus Torvalds 
2561da177e4SLinus Torvalds typedef struct {
2571da177e4SLinus Torvalds 	__u16 report_key_length;
2581da177e4SLinus Torvalds 	__u8 reserved1;
2591da177e4SLinus Torvalds 	__u8 reserved2;
2601da177e4SLinus Torvalds #if defined(__BIG_ENDIAN_BITFIELD)
2611da177e4SLinus Torvalds 	__u8 type_code			: 2;
2621da177e4SLinus Torvalds 	__u8 vra			: 3;
2631da177e4SLinus Torvalds 	__u8 ucca			: 3;
2641da177e4SLinus Torvalds #elif defined(__LITTLE_ENDIAN_BITFIELD)
2651da177e4SLinus Torvalds 	__u8 ucca			: 3;
2661da177e4SLinus Torvalds 	__u8 vra			: 3;
2671da177e4SLinus Torvalds 	__u8 type_code			: 2;
2681da177e4SLinus Torvalds #endif
2691da177e4SLinus Torvalds 	__u8 region_mask;
2701da177e4SLinus Torvalds 	__u8 rpc_scheme;
2711da177e4SLinus Torvalds 	__u8 reserved3;
2721da177e4SLinus Torvalds } rpc_state_t;
2731da177e4SLinus Torvalds 
2741da177e4SLinus Torvalds struct event_header {
27556052d52SAlexey Dobriyan 	__be16 data_len;
2761da177e4SLinus Torvalds #if defined(__BIG_ENDIAN_BITFIELD)
2771da177e4SLinus Torvalds 	__u8 nea		: 1;
2781da177e4SLinus Torvalds 	__u8 reserved1		: 4;
2791da177e4SLinus Torvalds 	__u8 notification_class	: 3;
2801da177e4SLinus Torvalds #elif defined(__LITTLE_ENDIAN_BITFIELD)
2811da177e4SLinus Torvalds 	__u8 notification_class	: 3;
2821da177e4SLinus Torvalds 	__u8 reserved1		: 4;
2831da177e4SLinus Torvalds 	__u8 nea		: 1;
2841da177e4SLinus Torvalds #endif
2851da177e4SLinus Torvalds 	__u8 supp_event_class;
2861da177e4SLinus Torvalds };
2871da177e4SLinus Torvalds 
2881da177e4SLinus Torvalds struct media_event_desc {
2891da177e4SLinus Torvalds #if defined(__BIG_ENDIAN_BITFIELD)
2901da177e4SLinus Torvalds 	__u8 reserved1		: 4;
2911da177e4SLinus Torvalds 	__u8 media_event_code	: 4;
2921da177e4SLinus Torvalds 	__u8 reserved2		: 6;
2931da177e4SLinus Torvalds 	__u8 media_present	: 1;
2941da177e4SLinus Torvalds 	__u8 door_open		: 1;
2951da177e4SLinus Torvalds #elif defined(__LITTLE_ENDIAN_BITFIELD)
2961da177e4SLinus Torvalds 	__u8 media_event_code	: 4;
2971da177e4SLinus Torvalds 	__u8 reserved1		: 4;
2981da177e4SLinus Torvalds 	__u8 door_open		: 1;
2991da177e4SLinus Torvalds 	__u8 media_present	: 1;
3001da177e4SLinus Torvalds 	__u8 reserved2		: 6;
3011da177e4SLinus Torvalds #endif
3021da177e4SLinus Torvalds 	__u8 start_slot;
3031da177e4SLinus Torvalds 	__u8 end_slot;
3041da177e4SLinus Torvalds };
3051da177e4SLinus Torvalds 
3061da177e4SLinus Torvalds extern int cdrom_get_media_event(struct cdrom_device_info *cdi, struct media_event_desc *med);
3071da177e4SLinus Torvalds 
lba_to_msf(int lba,u8 * m,u8 * s,u8 * f)308a1bb9457SBartlomiej Zolnierkiewicz static inline void lba_to_msf(int lba, u8 *m, u8 *s, u8 *f)
309a1bb9457SBartlomiej Zolnierkiewicz {
310a1bb9457SBartlomiej Zolnierkiewicz 	lba += CD_MSF_OFFSET;
311a1bb9457SBartlomiej Zolnierkiewicz 	lba &= 0xffffff;  /* negative lbas use only 24 bits */
312a1bb9457SBartlomiej Zolnierkiewicz 	*m = lba / (CD_SECS * CD_FRAMES);
313a1bb9457SBartlomiej Zolnierkiewicz 	lba %= (CD_SECS * CD_FRAMES);
314a1bb9457SBartlomiej Zolnierkiewicz 	*s = lba / CD_FRAMES;
315a1bb9457SBartlomiej Zolnierkiewicz 	*f = lba % CD_FRAMES;
316a1bb9457SBartlomiej Zolnierkiewicz }
317a1bb9457SBartlomiej Zolnierkiewicz 
msf_to_lba(u8 m,u8 s,u8 f)318a1bb9457SBartlomiej Zolnierkiewicz static inline int msf_to_lba(u8 m, u8 s, u8 f)
319a1bb9457SBartlomiej Zolnierkiewicz {
320a1bb9457SBartlomiej Zolnierkiewicz 	return (((m * CD_SECS) + s) * CD_FRAMES + f) - CD_MSF_OFFSET;
321a1bb9457SBartlomiej Zolnierkiewicz }
3221da177e4SLinus Torvalds #endif  /* _LINUX_CDROM_H */
323