9fbde5a243fcfc949d4516a0ae0fa38b8a35c933
[people/sha0/winvblock.git] / src / include / disk.h
1 /**
2  * Copyright (C) 2009-2010, Shao Miller <shao.miller@yrdsb.edu.on.ca>.
3  * Copyright 2006-2008, V.
4  * For WinAoE contact information, see http://winaoe.org/
5  *
6  * This file is part of WinVBlock, derived from WinAoE.
7  *
8  * WinVBlock is free software: you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation, either version 3 of the License, or
11  * (at your option) any later version.
12  *
13  * WinVBlock is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with WinVBlock.  If not, see <http://www.gnu.org/licenses/>.
20  */
21 #ifndef _disk_h
22 #  define _disk_h
23
24 /**
25  * @file
26  *
27  * Disk device specifics.
28  */
29
30 enum _disk__media
31 {
32   disk__media_floppy,
33   disk__media_hard,
34   disk__media_optical,
35   disk__media_count
36 };
37 winvblock__def_enum ( disk__media );
38
39 typedef char disk__boot_sect_ptr[512];
40
41 extern winvblock__bool disk__removable[disk__media_count];
42 extern PWCHAR disk__compat_ids[disk__media_count];
43
44 enum _disk__io_mode
45 {
46   disk__io_mode_read,
47   disk__io_mode_write
48 };
49 winvblock__def_enum ( disk__io_mode );
50
51 /* Forward declaration */
52 winvblock__def_struct ( disk__type );
53
54 /**
55  * I/O Request
56  *
57  * @v dev_ptr           Points to the disk's device structure
58  * @v mode              Read / write mode
59  * @v start_sector      First sector for request
60  * @v sector_count      Number of sectors to work with
61  * @v buffer            Buffer to read / write sectors to / from
62  * @v irp               Interrupt request packet for this request
63  */
64 #  define disk__io_decl( x ) \
65 \
66 NTSTATUS STDCALL \
67 x ( \
68   IN struct device__type * dev_ptr, \
69   IN disk__io_mode mode, \
70   IN LONGLONG start_sector, \
71   IN winvblock__uint32 sector_count, \
72   IN winvblock__uint8_ptr buffer, \
73   IN PIRP irp \
74  )
75 /*
76  * Function pointer for a disk I/O routine.
77  * 'indent' mangles this, so it looks weird
78  */
79 typedef disk__io_decl (
80    ( *disk__io_routine )
81  );
82
83 /**
84  * Maximum transfer length response routine
85  *
86  * @v disk_ptr        The disk being queried
87  */
88 #  define disk__max_xfer_len_decl( x ) \
89 \
90 winvblock__uint32 \
91 x ( \
92   IN disk__type_ptr disk_ptr \
93  )
94 /*
95  * Function pointer for a maximum transfer length response routine.
96  * 'indent' mangles this, so it looks weird
97  */
98 typedef disk__max_xfer_len_decl (
99    ( *disk__max_xfer_len_routine )
100  );
101
102 /**
103  * Disk initialization routine
104  *
105  * @v disk_ptr        The disk device being initialized
106  */
107 #  define disk__init_decl( x ) \
108 \
109 winvblock__bool STDCALL \
110 x ( \
111   IN disk__type_ptr disk_ptr \
112  )
113 /*
114  * Function pointer for a disk initialization routine.
115  * 'indent' mangles this, so it looks weird
116  */
117 typedef disk__init_decl (
118    ( *disk__init_routine )
119  );
120
121 /**
122  * Disk close routine
123  *
124  * @v disk_ptr        The disk device being closed
125  */
126 #  define disk__close_decl( x ) \
127 \
128 void STDCALL \
129 x ( \
130   IN disk__type_ptr disk_ptr \
131  )
132 /*
133  * Function pointer for a disk close routine.
134  * 'indent' mangles this, so it looks weird
135  */
136 typedef disk__close_decl (
137    ( *disk__close_routine )
138  );
139
140 winvblock__def_struct ( disk__ops )
141 {
142   disk__io_routine io;
143   disk__max_xfer_len_routine max_xfer_len;
144   disk__init_routine init;
145   disk__close_routine close;
146 };
147
148 struct _disk__type
149 {
150   struct device__type * device;
151   KEVENT SearchEvent;
152   KSPIN_LOCK SpinLock;
153   winvblock__bool BootDrive;
154   winvblock__bool Unmount;
155   winvblock__uint32 DiskNumber;
156   disk__media media;
157   disk__ops disk_ops;
158   ULONGLONG LBADiskSize;
159   ULONGLONG Cylinders;
160   winvblock__uint32 Heads;
161   winvblock__uint32 Sectors;
162   winvblock__uint32 SectorSize;
163   winvblock__uint32 SpecialFileCount;
164   device__free_func * prev_free;
165   LIST_ENTRY tracking;
166   winvblock__any_ptr ext;
167 };
168
169 /*
170  * Yield a pointer to the disk
171  */
172 #  define disk__get_ptr( dev_ptr ) ( ( disk__type_ptr ) dev_ptr->ext )
173
174 /* An MBR C/H/S address and ways to access its components */
175 typedef winvblock__uint8 chs[3];
176
177 #  define     chs_head( chs ) chs[0]
178 #  define   chs_sector( chs ) ( chs[1] & 0x3F )
179 #  define chs_cyl_high( chs ) ( ( ( winvblock__uint16 ) ( chs[1] & 0xC0 ) ) << 2 )
180 #  define  chs_cyl_low( chs ) ( ( winvblock__uint16 ) chs[2] )
181 #  define chs_cylinder( chs ) ( chs_cyl_high ( chs ) | chs_cyl_low ( chs ) )
182
183 #  ifdef _MSC_VER
184 #    pragma pack(1)
185 #  endif
186
187 /* An MBR */
188 winvblock__def_struct ( mbr )
189 {
190   winvblock__uint8 code[440];
191   winvblock__uint32 disk_sig;
192   winvblock__uint16 pad;
193   struct
194   {
195     winvblock__uint8 status;
196     chs chs_start;
197     winvblock__uint8 type;
198     chs chs_end;
199     winvblock__uint32 lba_start;
200     winvblock__uint32 lba_count;
201   } partition[4] __attribute__ ( ( packed ) );
202   winvblock__uint16 mbr_sig;
203 } __attribute__ ( ( __packed__ ) );
204
205 #  ifdef _MSC_VER
206 #    pragma pack()
207 #  endif
208
209 extern disk__io_decl (
210   disk__io
211  );
212 extern disk__max_xfer_len_decl (
213   disk__max_xfer_len
214  );
215
216 /**
217  * Attempt to guess a disk's geometry
218  *
219  * @v boot_sect_ptr     The MBR or VBR with possible geometry clues
220  * @v disk_ptr          The disk to set the geometry for
221  */
222 extern winvblock__lib_func void disk__guess_geometry (
223   IN disk__boot_sect_ptr boot_sect_ptr,
224   IN OUT disk__type_ptr disk_ptr
225  );
226
227 /**
228  * Create a new disk
229  *
230  * @ret disk_ptr        The address of a new disk, or NULL for failure
231  *
232  * This function should not be confused with a PDO creation routine, which is
233  * actually implemented for each device type.  This routine will allocate a
234  * disk__type, track it in a global list, as well as populate the disk
235  * with default values.
236  */
237 extern winvblock__lib_func disk__type_ptr disk__create (
238   void
239  );
240
241 /**
242  * Initialize the global, disk-common environment
243  *
244  * @ret ntstatus        STATUS_SUCCESS or the NTSTATUS for a failure
245  */
246 extern NTSTATUS disk__init (
247   void
248  );
249
250 #endif                          /* _disk_h */