1 /***************************************************************************
2  *                                                                         *
3  *    LIBDSK: General floppy and diskimage access library                  *
4  *    Copyright (C) 2001  John Elliott <seasip.webmaster@gmail.com>            *
5  *                                                                         *
6  *    This library is free software; you can redistribute it and/or        *
7  *    modify it under the terms of the GNU Library General Public          *
8  *    License as published by the Free Software Foundation; either         *
9  *    version 2 of the License, or (at your option) any later version.     *
10  *                                                                         *
11  *    This library is distributed in the hope that it will be useful,      *
12  *    but WITHOUT ANY WARRANTY; without even the implied warranty of       *
13  *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU    *
14  *    Library General Public License for more details.                     *
15  *                                                                         *
16  *    You should have received a copy of the GNU Library General Public    *
17  *    License along with this library; if not, write to the Free           *
18  *    Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,      *
19  *    MA 02111-1307, USA                                                   *
20  *                                                                         *
21  ***************************************************************************/
22 
23 typedef struct dsk_option
24 {
25 	struct dsk_option *do_next;
26 	int do_value;
27 	char do_name[1];
28 } DSK_OPTION;
29 
30 /* Moved here from libdsk.h; there's no need for it to be public */
31 typedef struct dsk_driver
32 {
33         struct drv_class     *dr_class;
34         struct compress_data *dr_compress;      /* Compressed? */
35 	struct remote_data   *dr_remote;	/* Remote, if any */
36 	struct dsk_option    *dr_options;	/* Optional properties, if any */
37 	char *dr_comment;	/* Comment, if any */
38 /*        int dr_forcehead;     Force drive to use head 0 or head 1
39  *        			Moved to Linux floppy driver; it's the only one
40  *        			that supports it. */
41 	int dr_dirty;		/* Has this device been written to?
42 				 * Set to 1 by writes and formats */
43 	unsigned dr_retry_count; /* Number of times to retry if error */
44 } DSK_DRIVER;
45 
46 
47 
48 /* Functions a driver must provide. If you are implementing a driver,
49  * create instances of these functions and have pointers to them (see
50  * eg. drvposix.c) */
51 
52 typedef struct drv_class
53 {
54 	/* Variables */
55 	size_t	dc_selfsize;	/* Size of the DSK_DRIVER subclass to be
56 				 * malloced and zeroed before we enter
57 				 * dc_open */
58 	char   *dc_drvname;	/* Short driver name, as used by eg. the
59 				 * -itype and -otype arguments in DSKTRANS. */
60 	char   *dc_description;	/* Human-readable description of driver */
61 
62 	/* Functions: */
63 
64 	/* Open an existing disc image. Return DSK_ERR_OK if successful.
65 	 * Return DSK_ERR_NOTME if the image cannot be handled by this driver.
66 	 * Return other errors only if you want to stop other drivers having
67 	 * a go. */
68 	dsk_err_t (*dc_open )(DSK_DRIVER *self, const char *filename);
69 	/* Create a new disc image. Return DSK_ERR_OK if successful, any
70 	 * other errors if failed. For floppy drives, does the same as
71 	 * dc_open */
72 	dsk_err_t (*dc_creat)(DSK_DRIVER *self, const char *filename);
73 	/* Close disc image / drive */
74 	dsk_err_t (*dc_close)(DSK_DRIVER *self);
75 
76 	/* Read a physical sector */
77 	dsk_err_t (*dc_read)(DSK_DRIVER *self, const DSK_GEOMETRY *geom,
78 			      void *buf, dsk_pcyl_t cylinder,
79 			      dsk_phead_t head, dsk_psect_t sector);
80 	/* Write a physical sector */
81 	dsk_err_t (*dc_write)(DSK_DRIVER *self, const DSK_GEOMETRY *geom,
82 			      const void *buf, dsk_pcyl_t cylinder,
83 			      dsk_phead_t head, dsk_psect_t sector);
84 
85 	/* Format a track */
86 	dsk_err_t (*dc_format)(DSK_DRIVER *self, DSK_GEOMETRY *geom,
87                                 dsk_pcyl_t cylinder, dsk_phead_t head,
88                                 const DSK_FORMAT *format, unsigned char filler);
89 	/* Get geometry. Only provide this function if your disc image
90 	 * does not allow a program to set its own disc geometry; if it
91 	 * /does/, then use the DSK_GEOMETRY argument passed to the other
92 	 * functions (drvlinux.c is a good example here).
93 	 * The two drivers which do this are the Windows NT one, because
94 	 * Windows NT uses an arbitrary geometry which can't be overridden;
95 	 * and the MYZ80 one, which has a single fixed geometry.
96 	 * Return DSK_ERR_NOTME to fall back to the default geometry
97 	 * probe; other values indicate immediate success or failure. */
98 	dsk_err_t (*dc_getgeom)(DSK_DRIVER *self, DSK_GEOMETRY *geom);
99 
100 	/* Read the ID of a random sector on a certain track/head, and
101 	 * put it in "result". This function is primarily used to test for
102 	 * discs in CPC format (which have oddly-numbered physical sectors);
103 	 * drivers such as NT and POSIX can't implement it, and so don't. */
104 	dsk_err_t (*dc_secid)(DSK_DRIVER *self, const DSK_GEOMETRY *geom,
105                                 dsk_pcyl_t cylinder, dsk_phead_t head,
106                                 DSK_FORMAT *result);
107 	/* Seek to a track */
108 	dsk_err_t (*dc_xseek)(DSK_DRIVER *self, const DSK_GEOMETRY *geom,
109 				dsk_pcyl_t cylinder, dsk_phead_t head);
110 	/* Get drive status */
111 	dsk_err_t (*dc_status)(DSK_DRIVER *self, const DSK_GEOMETRY *geom,
112 				dsk_phead_t head, unsigned char *result);
113 	/* Read a sector whose ID doesn't match its location on disc */
114 	dsk_err_t (*dc_xread)(DSK_DRIVER *self, const DSK_GEOMETRY *geom,
115 			      void *buf,
116 			      dsk_pcyl_t cylinder, dsk_phead_t head,
117 			      dsk_pcyl_t cyl_expected, dsk_phead_t head_expected,
118 			      dsk_psect_t sector, size_t sector_len,
119 			      int *deleted);
120 	/* Write a sector whose ID doesn't match its location on disc */
121 	dsk_err_t (*dc_xwrite)(DSK_DRIVER *self, const DSK_GEOMETRY *geom,
122 			      const void *buf,
123 			      dsk_pcyl_t cylinder, dsk_phead_t head,
124 			      dsk_pcyl_t cyl_expected, dsk_phead_t head_expected,
125 			      dsk_psect_t sector, size_t sector_len,
126 			      int deleted);
127 	/* Read a track (8272 READ TRACK command) */
128 	dsk_err_t (*dc_tread)(DSK_DRIVER *self, const DSK_GEOMETRY *geom,
129 			      void *buf, dsk_pcyl_t cylinder,
130 			      dsk_phead_t head);
131 	/* Read a track: Version where the sector ID doesn't necessarily
132 	 * match */
133 	dsk_err_t (*dc_xtread)(DSK_DRIVER *self, const DSK_GEOMETRY *geom,
134 			      void *buf, dsk_pcyl_t cylinder,
135 			      dsk_phead_t head, dsk_pcyl_t cyl_expected,
136 			      dsk_phead_t head_expected);
137 
138 	/* List driver-specific options */
139 	dsk_err_t (*dc_option_enum)(DSK_DRIVER *self, int idx, char **optname);
140 
141 	/* Set a driver-specific option */
142 	dsk_err_t (*dc_option_set)(DSK_DRIVER *self, const char *optname, int value);
143 	/* Get a driver-specific option */
144 	dsk_err_t (*dc_option_get)(DSK_DRIVER *self, const char *optname, int *value);
145 	/* Read headers for an entire track at once */
146 	dsk_err_t (*dc_trackids)(DSK_DRIVER *self, const DSK_GEOMETRY *geom,
147                                 dsk_pcyl_t cylinder, dsk_phead_t head,
148                                 dsk_psect_t *count, DSK_FORMAT **result);
149 
150 	/* Read raw track, including sector headers */
151 	dsk_err_t (*dc_rtread)(DSK_DRIVER *self, const DSK_GEOMETRY *geom,
152 			void *buf, dsk_pcyl_t cylinder,  dsk_phead_t head,
153 			int reserved, size_t *bufsize);
154 } DRV_CLASS;
155 
156