This source file includes following definitions.
- scsicam_bios_param
- partsize
- setsize
1
2
3
4
5
6
7
8
9
10
11
12
13 #ifdef MODULE
14
15
16
17
18 #define _SCSI_SYMS_VER_
19 #include <linux/autoconf.h>
20 #include <linux/module.h>
21 #include <linux/version.h>
22 #else
23 #define MOD_INC_USE_COUNT
24 #define MOD_DEC_USE_COUNT
25 #endif
26
27 #include <linux/fs.h>
28 #include <linux/genhd.h>
29 #include <linux/kernel.h>
30 #include "../block/blk.h"
31 #include "scsi.h"
32 #include "hosts.h"
33 #include "sd.h"
34
35 static int partsize(struct buffer_head *bh, unsigned long capacity,
36 unsigned int *cyls, unsigned int *hds, unsigned int *secs);
37 static int setsize(unsigned long capacity,unsigned int *cyls,unsigned int *hds,
38 unsigned int *secs);
39
40
41
42
43
44
45
46
47
48
49
50
51 int scsicam_bios_param (Disk *disk,
52 int dev,
53 int *ip ) {
54 struct buffer_head *bh;
55 int ret_code;
56 int size = disk->capacity;
57
58 if (!(bh = bread(dev & ~0xf,0,1024)))
59 return -1;
60
61 #ifdef DEBUG
62 printk ("scsicam_bios_param : trying existing mapping\n");
63 #endif
64 ret_code = partsize (bh, (unsigned long) size, (unsigned int *) ip + 2,
65 (unsigned int *) ip + 0, (unsigned int *) ip + 1);
66 brelse (bh);
67
68 if (ret_code == -1) {
69 #ifdef DEBUG
70 printk ("scsicam_bios_param : trying optimal mapping\n");
71 #endif
72 ret_code = setsize ((unsigned long) size, (unsigned int *) ip + 2,
73 (unsigned int *) ip + 0, (unsigned int *) ip + 1);
74 }
75
76 return ret_code;
77 }
78
79
80
81
82
83
84
85
86
87
88
89
90 static int partsize(struct buffer_head *bh, unsigned long capacity,
91 unsigned int *cyls, unsigned int *hds, unsigned int *secs) {
92 struct partition *p, *largest = NULL;
93 int i, largest_cyl;
94 int cyl, end_head, end_cyl, end_sector;
95 unsigned int logical_end, physical_end;
96
97
98 if (*(unsigned short *) (bh->b_data+510) == 0xAA55) {
99 for (largest_cyl = -1, p = (struct partition *)
100 (0x1BE + bh->b_data), i = 0; i < 4; ++i, ++p) {
101 if (!p->sys_ind)
102 continue;
103 #ifdef DEBUG
104 printk ("scsicam_bios_param : partition %d has system \n",
105 i);
106 #endif
107 cyl = p->cyl + ((p->sector & 0xc0) << 2);
108 if (cyl > largest_cyl) {
109 largest_cyl = cyl;
110 largest = p;
111 }
112 }
113 }
114
115 if (largest) {
116 end_cyl = largest->end_cyl + ((largest->end_sector & 0xc0) << 2);
117 end_head = largest->end_head;
118 end_sector = largest->end_sector & 0x3f;
119 #ifdef DEBUG
120 printk ("scsicam_bios_param : end at h = %d, c = %d, s = %d\n",
121 end_head, end_cyl, end_sector);
122 #endif
123
124 physical_end = end_cyl * (end_head + 1) * end_sector +
125 end_head * end_sector + end_sector;
126
127
128 logical_end = largest->start_sect + largest->nr_sects;
129
130 if (logical_end == physical_end) {
131 *secs = end_sector;
132 *hds = end_head + 1;
133 *cyls = capacity / ((end_head + 1) * end_sector);
134 return 0;
135 }
136 #ifdef DEBUG
137 printk ("scsicam_bios_param : logical (%u) != physical (%u)\n",
138 logical_end, physical_end);
139 #endif
140 }
141 return -1;
142 }
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178 static int setsize(unsigned long capacity,unsigned int *cyls,unsigned int *hds,
179 unsigned int *secs) {
180 unsigned int rv = 0;
181 unsigned long heads, sectors, cylinders, temp;
182
183 cylinders = 1024L;
184 sectors = 62L;
185
186 temp = cylinders * sectors;
187 heads = capacity / temp;
188 if (capacity % temp) {
189 heads++;
190 temp = cylinders * heads;
191 sectors = capacity / temp;
192
193 if (capacity % temp) {
194 sectors++;
195 temp = heads * sectors;
196 cylinders = capacity / temp;
197 }
198 }
199 if (cylinders == 0) rv=(unsigned)-1;
200
201 *cyls = (unsigned int) cylinders;
202 *secs = (unsigned int) sectors;
203 *hds = (unsigned int) heads;
204 return(rv);
205 }