[disk] Put the device structure right in the disk structure
[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 WV_M_DISK_H_
22 #  define WV_M_DISK_H_
23
24 /**
25  * @file
26  *
27  * Disk device specifics.
28  */
29
30 typedef enum WV_DISK_MEDIA_TYPE {
31     WvDiskMediaTypeFloppy,
32     WvDiskMediaTypeHard,
33     WvDiskMediaTypeOptical,
34     WvDiskMediaTypes
35   } WV_E_DISK_MEDIA_TYPE, * WV_EP_DISK_MEDIA_TYPE;
36
37 typedef char WV_A_DISK_BOOT_SECT[512];
38 typedef WV_A_DISK_BOOT_SECT * WV_AP_DISK_BOOT_SECT;
39
40 extern winvblock__bool WvDiskIsRemovable[WvDiskMediaTypes];
41 extern PWCHAR WvDiskCompatIds[WvDiskMediaTypes];
42
43 typedef enum WV_DISK_IO_MODE {
44     WvDiskIoModeRead,
45     WvDiskIoModeWrite,
46     WvDiskIoModes
47   } WV_E_DISK_IO_MODE, * WV_EP_DISK_IO_MODE;
48
49 /* Forward declaration. */
50 typedef struct WV_DISK_T WV_S_DISK_T, * WV_SP_DISK_T;
51
52 /**
53  * I/O Request.
54  *
55  * @v dev_ptr           Points to the disk's device structure.
56  * @v mode              Read / write mode.
57  * @v start_sector      First sector for request.
58  * @v sector_count      Number of sectors to work with.
59  * @v buffer            Buffer to read / write sectors to / from.
60  * @v irp               Interrupt request packet for this request.
61  */
62 typedef NTSTATUS STDCALL WV_F_DISK_IO(
63     IN WV_SP_DEV_T,
64     IN WV_E_DISK_IO_MODE,
65     IN LONGLONG,
66     IN winvblock__uint32,
67     IN winvblock__uint8_ptr,
68     IN PIRP
69   );
70 typedef WV_F_DISK_IO * WV_FP_DISK_IO;
71
72 /**
73  * Maximum transfer length response routine.
74  *
75  * @v disk_ptr        The disk being queried.
76  * @ret UINT32        The maximum transfer length.
77  */
78 typedef winvblock__uint32 WV_F_DISK_MAX_XFER_LEN(IN WV_SP_DISK_T);
79 typedef WV_F_DISK_MAX_XFER_LEN * WV_FP_DISK_MAX_XFER_LEN;
80
81 /**
82  * Disk initialization routine.
83  *
84  * @v disk_ptr        The disk device being initialized.
85  * @ret BOOLEAN       FALSE if initialization failed, otherwise TRUE
86  */
87 typedef winvblock__bool STDCALL WV_F_DISK_INIT(IN WV_SP_DISK_T);
88 typedef WV_F_DISK_INIT * WV_FP_DISK_INIT;
89
90 /**
91  * Disk close routine.
92  *
93  * @v disk_ptr        The disk device being closed.
94  */
95 typedef void STDCALL WV_F_DISK_CLOSE(IN WV_SP_DISK_T);
96 typedef WV_F_DISK_CLOSE * WV_FP_DISK_CLOSE;
97
98 typedef struct WV_DISK_OPS {
99     WV_FP_DISK_IO Io;
100     WV_FP_DISK_MAX_XFER_LEN MaxXferLen;
101     WV_FP_DISK_INIT Init;
102     WV_FP_DISK_CLOSE Close;
103   } WV_S_DISK_OPS, * WV_SP_DISK_OPS;
104
105 struct WV_DISK_T {
106     WV_S_DEV_T Dev[1];
107     KEVENT SearchEvent;
108     KSPIN_LOCK SpinLock;
109     winvblock__bool BootDrive;
110     winvblock__bool Unmount;
111     WV_E_DISK_MEDIA_TYPE Media;
112     WV_S_DISK_OPS disk_ops;
113     ULONGLONG LBADiskSize;
114     ULONGLONG Cylinders;
115     winvblock__uint32 Heads;
116     winvblock__uint32 Sectors;
117     winvblock__uint32 SectorSize;
118     winvblock__uint32 SpecialFileCount;
119     WV_FP_DEV_FREE prev_free;
120     LIST_ENTRY tracking;
121     winvblock__any_ptr ext;
122   };
123
124 /* Yield a pointer to the disk. */
125 #define disk__get_ptr(dev_ptr) ((WV_SP_DISK_T) dev_ptr->ext)
126
127 /* An MBR C/H/S address and ways to access its components. */
128 typedef winvblock__uint8 chs[3];
129
130 #define     chs_head(chs) chs[0]
131 #define   chs_sector(chs) (chs[1] & 0x3F)
132 #define chs_cyl_high(chs) (((winvblock__uint16) (chs[1] & 0xC0)) << 2)
133 #define  chs_cyl_low(chs) ((winvblock__uint16) chs[2])
134 #define chs_cylinder(chs) (chs_cyl_high(chs) | chs_cyl_low(chs))
135
136 #ifdef _MSC_VER
137 #  pragma pack(1)
138 #endif
139
140 /* An MBR. */
141 winvblock__def_struct (mbr) {
142     winvblock__uint8 code[440];
143     winvblock__uint32 disk_sig;
144     winvblock__uint16 pad;
145     struct {
146         winvblock__uint8 status;
147         chs chs_start;
148         winvblock__uint8 type;
149         chs chs_end;
150         winvblock__uint32 lba_start;
151         winvblock__uint32 lba_count;
152       } partition[4] __attribute__((packed));
153     winvblock__uint16 mbr_sig;
154   } __attribute__((__packed__));
155
156 #ifdef _MSC_VER
157 #  pragma pack()
158 #endif
159
160 extern WV_F_DISK_IO disk__io;
161 extern WV_F_DISK_MAX_XFER_LEN disk__max_xfer_len;
162
163 /**
164  * Attempt to guess a disk's geometry.
165  *
166  * @v boot_sect_ptr     The MBR or VBR with possible geometry clues.
167  * @v disk_ptr          The disk to set the geometry for.
168  */
169 extern winvblock__lib_func void disk__guess_geometry(
170     IN WV_AP_DISK_BOOT_SECT,
171     IN OUT WV_SP_DISK_T disk_ptr
172   );
173
174 /**
175  * Create a new disk.
176  *
177  * @ret disk_ptr        The address of a new disk, or NULL for failure.
178  *
179  * This function should not be confused with a PDO creation routine, which is
180  * actually implemented for each device type.  This routine will allocate a
181  * WV_S_DISK_T, track it in a global list, as well as populate the disk
182  * with default values.
183  */
184 extern winvblock__lib_func WV_SP_DISK_T disk__create(void);
185
186 extern NTSTATUS disk__module_init(void);
187
188 #endif  /* WV_M_DISK_H_ */