| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 1 | /* | 
 | 2 |  * Copyright (C) 2000 Jens Axboe <axboe@suse.de> | 
 | 3 |  * Copyright (C) 2001-2004 Peter Osterlund <petero2@telia.com> | 
 | 4 |  * | 
 | 5 |  * May be copied or modified under the terms of the GNU General Public | 
 | 6 |  * License.  See linux/COPYING for more information. | 
 | 7 |  * | 
 | 8 |  * Packet writing layer for ATAPI and SCSI CD-R, CD-RW, DVD-R, and | 
 | 9 |  * DVD-RW devices. | 
 | 10 |  * | 
 | 11 |  */ | 
 | 12 | #ifndef __PKTCDVD_H | 
 | 13 | #define __PKTCDVD_H | 
 | 14 |  | 
 | 15 | #include <linux/types.h> | 
 | 16 |  | 
 | 17 | /* | 
 | 18 |  * 1 for normal debug messages, 2 is very verbose. 0 to turn it off. | 
 | 19 |  */ | 
 | 20 | #define PACKET_DEBUG		1 | 
 | 21 |  | 
 | 22 | #define	MAX_WRITERS		8 | 
 | 23 |  | 
 | 24 | #define PKT_RB_POOL_SIZE	512 | 
 | 25 |  | 
 | 26 | /* | 
 | 27 |  * How long we should hold a non-full packet before starting data gathering. | 
 | 28 |  */ | 
 | 29 | #define PACKET_WAIT_TIME	(HZ * 5 / 1000) | 
 | 30 |  | 
 | 31 | /* | 
 | 32 |  * use drive write caching -- we need deferred error handling to be | 
 | 33 |  * able to sucessfully recover with this option (drive will return good | 
 | 34 |  * status as soon as the cdb is validated). | 
 | 35 |  */ | 
 | 36 | #if defined(CONFIG_CDROM_PKTCDVD_WCACHE) | 
 | 37 | #define USE_WCACHING		1 | 
 | 38 | #else | 
 | 39 | #define USE_WCACHING		0 | 
 | 40 | #endif | 
 | 41 |  | 
 | 42 | /* | 
 | 43 |  * No user-servicable parts beyond this point -> | 
 | 44 |  */ | 
 | 45 |  | 
 | 46 | /* | 
 | 47 |  * device types | 
 | 48 |  */ | 
 | 49 | #define PACKET_CDR		1 | 
 | 50 | #define	PACKET_CDRW		2 | 
 | 51 | #define PACKET_DVDR		3 | 
 | 52 | #define PACKET_DVDRW		4 | 
 | 53 |  | 
 | 54 | /* | 
 | 55 |  * flags | 
 | 56 |  */ | 
 | 57 | #define PACKET_WRITABLE		1	/* pd is writable */ | 
 | 58 | #define PACKET_NWA_VALID	2	/* next writable address valid */ | 
 | 59 | #define PACKET_LRA_VALID	3	/* last recorded address valid */ | 
 | 60 | #define PACKET_MERGE_SEGS	4	/* perform segment merging to keep */ | 
 | 61 | 					/* underlying cdrom device happy */ | 
 | 62 |  | 
 | 63 | /* | 
 | 64 |  * Disc status -- from READ_DISC_INFO | 
 | 65 |  */ | 
 | 66 | #define PACKET_DISC_EMPTY	0 | 
 | 67 | #define PACKET_DISC_INCOMPLETE	1 | 
 | 68 | #define PACKET_DISC_COMPLETE	2 | 
 | 69 | #define PACKET_DISC_OTHER	3 | 
 | 70 |  | 
 | 71 | /* | 
 | 72 |  * write type, and corresponding data block type | 
 | 73 |  */ | 
 | 74 | #define PACKET_MODE1		1 | 
 | 75 | #define PACKET_MODE2		2 | 
 | 76 | #define PACKET_BLOCK_MODE1	8 | 
 | 77 | #define PACKET_BLOCK_MODE2	10 | 
 | 78 |  | 
 | 79 | /* | 
 | 80 |  * Last session/border status | 
 | 81 |  */ | 
 | 82 | #define PACKET_SESSION_EMPTY		0 | 
 | 83 | #define PACKET_SESSION_INCOMPLETE	1 | 
 | 84 | #define PACKET_SESSION_RESERVED		2 | 
 | 85 | #define PACKET_SESSION_COMPLETE		3 | 
 | 86 |  | 
 | 87 | #define PACKET_MCN			"4a656e734178626f65323030300000" | 
 | 88 |  | 
 | 89 | #undef PACKET_USE_LS | 
 | 90 |  | 
 | 91 | #define PKT_CTRL_CMD_SETUP	0 | 
 | 92 | #define PKT_CTRL_CMD_TEARDOWN	1 | 
 | 93 | #define PKT_CTRL_CMD_STATUS	2 | 
 | 94 |  | 
 | 95 | struct pkt_ctrl_command { | 
 | 96 | 	__u32 command;				/* in: Setup, teardown, status */ | 
 | 97 | 	__u32 dev_index;			/* in/out: Device index */ | 
 | 98 | 	__u32 dev;				/* in/out: Device nr for cdrw device */ | 
 | 99 | 	__u32 pkt_dev;				/* in/out: Device nr for packet device */ | 
 | 100 | 	__u32 num_devices;			/* out: Largest device index + 1 */ | 
 | 101 | 	__u32 padding;				/* Not used */ | 
 | 102 | }; | 
 | 103 |  | 
 | 104 | /* | 
 | 105 |  * packet ioctls | 
 | 106 |  */ | 
 | 107 | #define PACKET_IOCTL_MAGIC	('X') | 
 | 108 | #define PACKET_CTRL_CMD		_IOWR(PACKET_IOCTL_MAGIC, 1, struct pkt_ctrl_command) | 
 | 109 |  | 
 | 110 | #ifdef __KERNEL__ | 
 | 111 | #include <linux/blkdev.h> | 
 | 112 | #include <linux/completion.h> | 
 | 113 | #include <linux/cdrom.h> | 
| Thomas Maier | 3269485 | 2006-12-08 02:36:12 -0800 | [diff] [blame] | 114 | #include <linux/kobject.h> | 
 | 115 | #include <linux/sysfs.h> | 
| Thomas Maier | 0a0fc96 | 2006-12-08 02:36:11 -0800 | [diff] [blame] | 116 |  | 
 | 117 | /* default bio write queue congestion marks */ | 
 | 118 | #define PKT_WRITE_CONGESTION_ON    10000 | 
 | 119 | #define PKT_WRITE_CONGESTION_OFF   9000 | 
 | 120 |  | 
 | 121 |  | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 122 | struct packet_settings | 
 | 123 | { | 
| Phillip Susi | a460ad6 | 2006-02-04 23:27:44 -0800 | [diff] [blame] | 124 | 	__u32			size;		/* packet size in (512 byte) sectors */ | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 125 | 	__u8			fp;		/* fixed packets */ | 
 | 126 | 	__u8			link_loss;	/* the rest is specified | 
 | 127 | 						 * as per Mt Fuji */ | 
 | 128 | 	__u8			write_type; | 
 | 129 | 	__u8			track_mode; | 
 | 130 | 	__u8			block_mode; | 
 | 131 | }; | 
 | 132 |  | 
 | 133 | /* | 
 | 134 |  * Very crude stats for now | 
 | 135 |  */ | 
 | 136 | struct packet_stats | 
 | 137 | { | 
 | 138 | 	unsigned long		pkt_started; | 
 | 139 | 	unsigned long		pkt_ended; | 
 | 140 | 	unsigned long		secs_w; | 
 | 141 | 	unsigned long		secs_rg; | 
 | 142 | 	unsigned long		secs_r; | 
 | 143 | }; | 
 | 144 |  | 
 | 145 | struct packet_cdrw | 
 | 146 | { | 
 | 147 | 	struct list_head	pkt_free_list; | 
 | 148 | 	struct list_head	pkt_active_list; | 
 | 149 | 	spinlock_t		active_list_lock; /* Serialize access to pkt_active_list */ | 
 | 150 | 	struct task_struct	*thread; | 
 | 151 | 	atomic_t		pending_bios; | 
 | 152 | }; | 
 | 153 |  | 
 | 154 | /* | 
 | 155 |  * Switch to high speed reading after reading this many kilobytes | 
 | 156 |  * with no interspersed writes. | 
 | 157 |  */ | 
 | 158 | #define HI_SPEED_SWITCH 512 | 
 | 159 |  | 
 | 160 | struct packet_iosched | 
 | 161 | { | 
 | 162 | 	atomic_t		attention;	/* Set to non-zero when queue processing is needed */ | 
 | 163 | 	int			writing;	/* Non-zero when writing, zero when reading */ | 
 | 164 | 	spinlock_t		lock;		/* Protecting read/write queue manipulations */ | 
 | 165 | 	struct bio		*read_queue; | 
 | 166 | 	struct bio		*read_queue_tail; | 
 | 167 | 	struct bio		*write_queue; | 
 | 168 | 	struct bio		*write_queue_tail; | 
| Peter Osterlund | 46c271b | 2005-06-23 00:10:02 -0700 | [diff] [blame] | 169 | 	sector_t		last_write;	/* The sector where the last write ended */ | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 170 | 	int			successive_reads; | 
 | 171 | }; | 
 | 172 |  | 
 | 173 | /* | 
 | 174 |  * 32 buffers of 2048 bytes | 
 | 175 |  */ | 
| Peter Osterlund | 610827d | 2005-09-13 01:25:29 -0700 | [diff] [blame] | 176 | #if (PAGE_SIZE % CD_FRAMESIZE) != 0 | 
 | 177 | #error "PAGE_SIZE must be a multiple of CD_FRAMESIZE" | 
 | 178 | #endif | 
| Phillip Susi | 5c55ac9 | 2006-02-04 23:27:48 -0800 | [diff] [blame] | 179 | #define PACKET_MAX_SIZE		128 | 
| Peter Osterlund | e1bc89b | 2006-02-04 23:27:47 -0800 | [diff] [blame] | 180 | #define FRAMES_PER_PAGE		(PAGE_SIZE / CD_FRAMESIZE) | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 181 | #define PACKET_MAX_SECTORS	(PACKET_MAX_SIZE * CD_FRAMESIZE >> 9) | 
 | 182 |  | 
 | 183 | enum packet_data_state { | 
 | 184 | 	PACKET_IDLE_STATE,			/* Not used at the moment */ | 
 | 185 | 	PACKET_WAITING_STATE,			/* Waiting for more bios to arrive, so */ | 
 | 186 | 						/* we don't have to do as much */ | 
 | 187 | 						/* data gathering */ | 
 | 188 | 	PACKET_READ_WAIT_STATE,			/* Waiting for reads to fill in holes */ | 
 | 189 | 	PACKET_WRITE_WAIT_STATE,		/* Waiting for the write to complete */ | 
 | 190 | 	PACKET_RECOVERY_STATE,			/* Recover after read/write errors */ | 
 | 191 | 	PACKET_FINISHED_STATE,			/* After write has finished */ | 
 | 192 |  | 
 | 193 | 	PACKET_NUM_STATES			/* Number of possible states */ | 
 | 194 | }; | 
 | 195 |  | 
 | 196 | /* | 
 | 197 |  * Information needed for writing a single packet | 
 | 198 |  */ | 
 | 199 | struct pktcdvd_device; | 
 | 200 |  | 
 | 201 | struct packet_data | 
 | 202 | { | 
 | 203 | 	struct list_head	list; | 
 | 204 |  | 
 | 205 | 	spinlock_t		lock;		/* Lock protecting state transitions and */ | 
 | 206 | 						/* orig_bios list */ | 
 | 207 |  | 
 | 208 | 	struct bio		*orig_bios;	/* Original bios passed to pkt_make_request */ | 
 | 209 | 	struct bio		*orig_bios_tail;/* that will be handled by this packet */ | 
 | 210 | 	int			write_size;	/* Total size of all bios in the orig_bios */ | 
 | 211 | 						/* list, measured in number of frames */ | 
 | 212 |  | 
 | 213 | 	struct bio		*w_bio;		/* The bio we will send to the real CD */ | 
 | 214 | 						/* device once we have all data for the */ | 
 | 215 | 						/* packet we are going to write */ | 
 | 216 | 	sector_t		sector;		/* First sector in this packet */ | 
 | 217 | 	int			frames;		/* Number of frames in this packet */ | 
 | 218 |  | 
 | 219 | 	enum packet_data_state	state;		/* Current state */ | 
 | 220 | 	atomic_t		run_sm;		/* Incremented whenever the state */ | 
 | 221 | 						/* machine needs to be run */ | 
 | 222 | 	long			sleep_time;	/* Set this to non-zero to make the state */ | 
 | 223 | 						/* machine run after this many jiffies. */ | 
 | 224 |  | 
 | 225 | 	atomic_t		io_wait;	/* Number of pending IO operations */ | 
 | 226 | 	atomic_t		io_errors;	/* Number of read/write errors during IO */ | 
 | 227 |  | 
 | 228 | 	struct bio		*r_bios[PACKET_MAX_SIZE]; /* bios to use during data gathering */ | 
| Peter Osterlund | e1bc89b | 2006-02-04 23:27:47 -0800 | [diff] [blame] | 229 | 	struct page		*pages[PACKET_MAX_SIZE / FRAMES_PER_PAGE]; | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 230 |  | 
 | 231 | 	int			cache_valid;	/* If non-zero, the data for the zone defined */ | 
 | 232 | 						/* by the sector variable is completely cached */ | 
 | 233 | 						/* in the pages[] vector. */ | 
 | 234 |  | 
 | 235 | 	int			id;		/* ID number for debugging */ | 
 | 236 | 	struct pktcdvd_device	*pd; | 
 | 237 | }; | 
 | 238 |  | 
 | 239 | struct pkt_rb_node { | 
 | 240 | 	struct rb_node		rb_node; | 
 | 241 | 	struct bio		*bio; | 
 | 242 | }; | 
 | 243 |  | 
 | 244 | struct packet_stacked_data | 
 | 245 | { | 
 | 246 | 	struct bio		*bio;		/* Original read request bio */ | 
 | 247 | 	struct pktcdvd_device	*pd; | 
 | 248 | }; | 
 | 249 | #define PSD_POOL_SIZE		64 | 
 | 250 |  | 
| Thomas Maier | 3269485 | 2006-12-08 02:36:12 -0800 | [diff] [blame] | 251 | struct pktcdvd_kobj | 
 | 252 | { | 
 | 253 | 	struct kobject		kobj; | 
 | 254 | 	struct pktcdvd_device	*pd; | 
 | 255 | }; | 
 | 256 | #define to_pktcdvdkobj(_k) \ | 
 | 257 |   ((struct pktcdvd_kobj*)container_of(_k,struct pktcdvd_kobj,kobj)) | 
 | 258 |  | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 259 | struct pktcdvd_device | 
 | 260 | { | 
 | 261 | 	struct block_device	*bdev;		/* dev attached */ | 
 | 262 | 	dev_t			pkt_dev;	/* our dev */ | 
 | 263 | 	char			name[20]; | 
 | 264 | 	struct packet_settings	settings; | 
 | 265 | 	struct packet_stats	stats; | 
 | 266 | 	int			refcnt;		/* Open count */ | 
 | 267 | 	int			write_speed;	/* current write speed, kB/s */ | 
 | 268 | 	int			read_speed;	/* current read speed, kB/s */ | 
 | 269 | 	unsigned long		offset;		/* start offset */ | 
 | 270 | 	__u8			mode_offset;	/* 0 / 8 */ | 
 | 271 | 	__u8			type; | 
 | 272 | 	unsigned long		flags; | 
 | 273 | 	__u16			mmc3_profile; | 
 | 274 | 	__u32			nwa;		/* next writable address */ | 
 | 275 | 	__u32			lra;		/* last recorded address */ | 
 | 276 | 	struct packet_cdrw	cdrw; | 
 | 277 | 	wait_queue_head_t	wqueue; | 
 | 278 |  | 
 | 279 | 	spinlock_t		lock;		/* Serialize access to bio_queue */ | 
 | 280 | 	struct rb_root		bio_queue;	/* Work queue of bios we need to handle */ | 
 | 281 | 	int			bio_queue_size;	/* Number of nodes in bio_queue */ | 
 | 282 | 	sector_t		current_sector;	/* Keep track of where the elevator is */ | 
 | 283 | 	atomic_t		scan_queue;	/* Set to non-zero when pkt_handle_queue */ | 
 | 284 | 						/* needs to be run. */ | 
 | 285 | 	mempool_t		*rb_pool;	/* mempool for pkt_rb_node allocations */ | 
 | 286 |  | 
 | 287 | 	struct packet_iosched   iosched; | 
 | 288 | 	struct gendisk		*disk; | 
| Thomas Maier | 0a0fc96 | 2006-12-08 02:36:11 -0800 | [diff] [blame] | 289 |  | 
 | 290 | 	int			write_congestion_off; | 
 | 291 | 	int			write_congestion_on; | 
| Thomas Maier | 3269485 | 2006-12-08 02:36:12 -0800 | [diff] [blame] | 292 |  | 
 | 293 | 	struct class_device	*clsdev;	/* sysfs pktcdvd[0-7] class dev */ | 
 | 294 | 	struct pktcdvd_kobj	*kobj_stat;	/* sysfs pktcdvd[0-7]/stat/     */ | 
 | 295 | 	struct pktcdvd_kobj	*kobj_wqueue;	/* sysfs pktcdvd[0-7]/write_queue/ */ | 
 | 296 |  | 
 | 297 | 	struct dentry		*dfs_d_root;	/* debugfs: devname directory */ | 
 | 298 | 	struct dentry		*dfs_f_info;	/* debugfs: info file */ | 
| Linus Torvalds | 1da177e | 2005-04-16 15:20:36 -0700 | [diff] [blame] | 299 | }; | 
 | 300 |  | 
 | 301 | #endif /* __KERNEL__ */ | 
 | 302 |  | 
 | 303 | #endif /* __PKTCDVD_H */ |