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 kdev_t dev,
53 int *ip ) {
54
55 struct buffer_head *bh;
56 int ret_code;
57 int size = disk->capacity;
58
59 if (!(bh = bread(MKDEV(MAJOR(dev), MINOR(dev)&~0xf), 0, 1024)))
60 return -1;
61
62 #ifdef DEBUG
63 printk ("scsicam_bios_param : trying existing mapping\n");
64 #endif
65 ret_code = partsize (bh, (unsigned long) size, (unsigned int *) ip + 2,
66 (unsigned int *) ip + 0, (unsigned int *) ip + 1);
67 brelse (bh);
68
69 if (ret_code == -1) {
70 #ifdef DEBUG
71 printk ("scsicam_bios_param : trying optimal mapping\n");
72 #endif
73 ret_code = setsize ((unsigned long) size, (unsigned int *) ip + 2,
74 (unsigned int *) ip + 0, (unsigned int *) ip + 1);
75 }
76
77 return ret_code;
78 }
79
80
81
82
83
84
85
86
87
88
89
90
91 static int partsize(struct buffer_head *bh, unsigned long capacity,
92 unsigned int *cyls, unsigned int *hds, unsigned int *secs) {
93 struct partition *p, *largest = NULL;
94 int i, largest_cyl;
95 int cyl, end_head, end_cyl, end_sector;
96 unsigned int logical_end, physical_end;
97
98
99 if (*(unsigned short *) (bh->b_data+510) == 0xAA55) {
100 for (largest_cyl = -1, p = (struct partition *)
101 (0x1BE + bh->b_data), i = 0; i < 4; ++i, ++p) {
102 if (!p->sys_ind)
103 continue;
104 #ifdef DEBUG
105 printk ("scsicam_bios_param : partition %d has system \n",
106 i);
107 #endif
108 cyl = p->cyl + ((p->sector & 0xc0) << 2);
109 if (cyl > largest_cyl) {
110 largest_cyl = cyl;
111 largest = p;
112 }
113 }
114 }
115
116 if (largest) {
117 end_cyl = largest->end_cyl + ((largest->end_sector & 0xc0) << 2);
118 end_head = largest->end_head;
119 end_sector = largest->end_sector & 0x3f;
120 #ifdef DEBUG
121 printk ("scsicam_bios_param : end at h = %d, c = %d, s = %d\n",
122 end_head, end_cyl, end_sector);
123 #endif
124
125 physical_end = end_cyl * (end_head + 1) * end_sector +
126 end_head * end_sector + end_sector;
127
128
129 logical_end = largest->start_sect + largest->nr_sects;
130
131 if (logical_end == physical_end) {
132 *secs = end_sector;
133 *hds = end_head + 1;
134 *cyls = capacity / ((end_head + 1) * end_sector);
135 return 0;
136 }
137 #ifdef DEBUG
138 printk ("scsicam_bios_param : logical (%u) != physical (%u)\n",
139 logical_end, physical_end);
140 #endif
141 }
142 return -1;
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
179 static int setsize(unsigned long capacity,unsigned int *cyls,unsigned int *hds,
180 unsigned int *secs) {
181 unsigned int rv = 0;
182 unsigned long heads, sectors, cylinders, temp;
183
184 cylinders = 1024L;
185 sectors = 62L;
186
187 temp = cylinders * sectors;
188 heads = capacity / temp;
189 if (capacity % temp) {
190 heads++;
191 temp = cylinders * heads;
192 sectors = capacity / temp;
193
194 if (capacity % temp) {
195 sectors++;
196 temp = heads * sectors;
197 cylinders = capacity / temp;
198 }
199 }
200 if (cylinders == 0) rv=(unsigned)-1;
201
202 *cyls = (unsigned int) cylinders;
203 *secs = (unsigned int) sectors;
204 *hds = (unsigned int) heads;
205 return(rv);
206 }