1 | /*␊ |
2 | * Copyright (c) 2009 netkas. All rights reserved.␊ |
3 | * Redistribution and use in binary form for direct or indirect commercial purposes, with or without␊ |
4 | * modification, is stricktly forbidden.␊ |
5 | * Redistributions in binary form for non-commercial purposes must reproduce the above license notice,␊ |
6 | * this list of conditions and the following disclaimer in the documentation and/or other materials␊ |
7 | * provided with the distribution.␊ |
8 | * Neither the names of EFI V1-V10 copyright owner nor the names of its contributors may be used␊ |
9 | * to endorse or promote products derived direct or indirect from this software.␊ |
10 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” AND ANY EXPRESS␊ |
11 | * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY␊ |
12 | * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR␊ |
13 | * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL␊ |
14 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,␊ |
15 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER␊ |
16 | * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT␊ |
17 | * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.␊ |
18 | */␊ |
19 | ␊ |
20 | #include "libsaio.h"␊ |
21 | #include "mindrvr.h"␊ |
22 | ␊ |
23 | #define CDB_SIZE_T 12 ␊ |
24 | uint8_t cdb[CDB_SIZE_T];␊ |
25 | ␊ |
26 | uint32_t cd_drives[32][4];␊ |
27 | uint32_t cd_count = 0;␊ |
28 | ␊ |
29 | uint8_t cd_bad[10] = {0,0,0,0,0,0,0,0,0,0};␊ |
30 | ␊ |
31 | uint32_t pci_count = 0;␊ |
32 | uint32_t pci_devs[ 768 ];␊ |
33 | uint32_t curdrive = 0;␊ |
34 | #define CACHE_BLKN 4␊ |
35 | unsigned char * cache_2k;␊ |
36 | unsigned int cache_blk;␊ |
37 | ␊ |
38 | static void DriveReset(uint32_t dev)␊ |
39 | {␊ |
40 | ␉if (dev > cd_count)␊ |
41 | ␉{␊ |
42 | ␉␉printf("device %d doesnt exist, max is %d\n", dev, cd_count);␊ |
43 | ␉␉return;␊ |
44 | ␉}␊ |
45 | ␉reg_reset(cd_drives[dev][2]);␊ |
46 | }␊ |
47 | ␊ |
48 | static int SelectDrive(uint32_t dev)␊ |
49 | {␊ |
50 | ␉if(cd_bad[dev] == 1) return 1;␊ |
51 | ␉if(curdrive == dev) return 0;␊ |
52 | ␉if (dev > cd_count)␊ |
53 | ␉{␊ |
54 | ␉␉printf("device %d doesnt exist, max is %d\n", dev, cd_count);␊ |
55 | ␉␉return 1;␊ |
56 | ␉}␊ |
57 | ␉pio_set_iobase_addr(cd_drives[dev][0], cd_drives[dev][1], cd_drives[dev][3]);␊ |
58 | //␉reg_config();␊ |
59 | ␉reg_config_info[0]=0;␊ |
60 | ␉reg_config_info[1]=0;␊ |
61 | ␉reg_config_info[cd_drives[dev][2]]=REG_CONFIG_TYPE_ATAPI;␊ |
62 | ␉curdrive = dev;␊ |
63 | //␉DriveReset(dev);␊ |
64 | ␉return 0;␊ |
65 | }␊ |
66 | ␊ |
67 | static int cdcheck (int dev, char * buffer)␊ |
68 | {␊ |
69 | uint32_t result, try, wait_time;␊ |
70 | ␊ |
71 | if(SelectDrive(dev))␊ |
72 | {␊ |
73 | ␉printf("Select drive returned 1, thats bad\n");␊ |
74 | ␉return -1;␊ |
75 | };␊ |
76 | ␊ |
77 | ␊ |
78 | for (try=0; try<10; ++try)␊ |
79 | {␊ |
80 | ␉memset( cdb, 0, sizeof( cdb ) );␊ |
81 | cdb[0] = 0xa8;␊ |
82 | cdb[1] = 0x00;␊ |
83 | cdb[2] = 0x00;␊ |
84 | cdb[3] = 0x00;␊ |
85 | cdb[4] = 0x00;␊ |
86 | cdb[5] = 0x00;␊ |
87 | cdb[6] = 0x00;␊ |
88 | cdb[7] = 0x00;␊ |
89 | cdb[8] = 0x00;␊ |
90 | cdb[9] = 0x01;␊ |
91 | cdb[10] = 0x00;␊ |
92 | ␉cdb[11] = 0x00;␊ |
93 | ␉result = reg_packet(cd_drives[dev][2], sizeof(cdb), (unsigned char*) cdb, 0, 2048, cache_2k);␊ |
94 | ␉if(!result)␊ |
95 | ␉{␊ |
96 | ␉␉return 0;␊ |
97 | ␉}␊ |
98 | ␉wait_time = time18() + 20;␊ |
99 | ␉while(time18() < wait_time);␊ |
100 | }␊ |
101 | return -1;␊ |
102 | }␊ |
103 | ␊ |
104 | ␊ |
105 | static void AddDrive(uint32_t base1, uint32_t base2, uint32_t bmbase)␊ |
106 | {␊ |
107 | ␉uint32_t res,i;␊ |
108 | ␉pio_set_iobase_addr(base1, base2, bmbase);␊ |
109 | ␉res=reg_config();␊ |
110 | ␉if(res>0)␊ |
111 | ␉{␊ |
112 | ␉␉printf( "AddDrive: Found %d devices, base1 is %x, base2 is %x, dev 0 is %d, dev 1 is %d.\n",␊ |
113 | ␉ res, base1, base2, ␊ |
114 | ␉␉␉reg_config_info[0] ,␊ |
115 | ␉ reg_config_info[1] );␊ |
116 | ␉␉if(reg_config_info[0] == REG_CONFIG_TYPE_ATAPI) ␊ |
117 | ␉␉{␊ |
118 | ␉␉␉i=++cd_count;␊ |
119 | ␉␉␉cd_drives[i][0] = base1;␊ |
120 | ␉␉␉cd_drives[i][1] = base2;␊ |
121 | ␉␉␉cd_drives[i][2] = 0; //master␊ |
122 | ␉␉␉cd_drives[i][3] = bmbase;␊ |
123 | ␉␉␉printf("added master device %d\n", i);␊ |
124 | ␉␉␉reg_reset(0);␊ |
125 | ␉␉}␊ |
126 | ␉␉if(reg_config_info[1] == REG_CONFIG_TYPE_ATAPI) ␊ |
127 | ␉␉{␊ |
128 | ␉␉␉i=++cd_count;␊ |
129 | ␉␉␉cd_drives[i][0] = base1;␊ |
130 | ␉␉␉cd_drives[i][1] = base2;␊ |
131 | ␉␉␉cd_drives[i][2] = 1; //slave␊ |
132 | ␉␉␉cd_drives[i][3] = bmbase;␉␊ |
133 | ␉␉␉printf("added slave device %d\n", i);␊ |
134 | ␉␉␉reg_reset(1);␊ |
135 | ␉␉}␊ |
136 | ␉}␊ |
137 | ␉␊ |
138 | }␊ |
139 | ␊ |
140 | int setup_cdread(void)␊ |
141 | {␊ |
142 | ␉int res;␊ |
143 | ␉int trylegacy = 0;␊ |
144 | ␉uint16_t i;␊ |
145 | ␉unsigned int pcidev=0;␊ |
146 | unsigned int index=0;␊ |
147 | unsigned int vendid=0;␊ |
148 | unsigned int devid=0;␊ |
149 | ␉unsigned int cmdBase=0;␊ |
150 | ␉unsigned int ctrlBase=0;␊ |
151 | ␉unsigned int classid=0;␊ |
152 | ␉unsigned int bmideBase=0;␊ |
153 | ␉if(cd_count>0) return cd_count;␊ |
154 | ␊ |
155 | ␉for(i=0; i<0x05ff;i++)␊ |
156 | ␉{␊ |
157 | ␉␉vendid = GetPciDword( i, 0x00) & 0xffff;␊ |
158 | ␉␉devid = (GetPciDword( i, 0x00) >>16) & 0xffff; ␊ |
159 | ␉␉if((vendid != 0xffff) && (vendid != 0x0000) && (devid != 0x2825) && (devid != 0x2921) && (devid != 0x2926) && (devid != 0x3a06) && (devid != 0x3a26))// && (vendid != 0x1283) && (vendid != 0x197b)) // dont need jmicron and ite␊ |
160 | ␉␉{␉␊ |
161 | //␉␉␉devid = (GetPciDword( i, 0x00) >>16) & 0xffff; ␊ |
162 | ␉␉␉classid = (GetPciDword( i, 0x08) >>16) & 0xffff;␊ |
163 | ␉␉␉if(classid == 0x0101)␊ |
164 | ␉␉␉{␊ |
165 | ␉␉␉␉printf("device %x, vendid %x, devid %x, classid %x\n", i, vendid, devid, classid);␊ |
166 | ␉␉␉␉cmdBase = GetPciDword(i, 0x10) & 0xfffe;␊ |
167 | ␉␉␉␉ctrlBase = GetPciDword(i, 0x14) & 0xfffe;␊ |
168 | ␉␉␉␉bmideBase = GetPciDword(i, 0x20) & 0xffff;␊ |
169 | ␉␉␉␉if(cmdBase && ctrlBase)AddDrive(cmdBase, ctrlBase, bmideBase); //no need in bmidebase?␊ |
170 | ␉␉␉␉if(cmdBase == 0 && ctrlBase == 0) trylegacy=1;␊ |
171 | ␉␉␉␉printf("pri port cmdbase - %x, ctrlbase - %x, bmideBase - %x\n", cmdBase, ctrlBase, bmideBase);␊ |
172 | ␉␉␉␉cmdBase = GetPciDword(i, 0x10+8) & 0xfffe;␊ |
173 | ␉␉␉␉ctrlBase = GetPciDword(i, 0x14+8) & 0xfffe;␊ |
174 | ␉␉␉␉if(cmdBase && ctrlBase)AddDrive(cmdBase, ctrlBase, bmideBase);␊ |
175 | ␉␉␉␉printf("sec port cmdbase - %x, ctrlbase - %x, bmideBase - %x\n", cmdBase, ctrlBase, bmideBase);␊ |
176 | ␉␉␉}␊ |
177 | ␉␉}␊ |
178 | ␉}␊ |
179 | ␉if(trylegacy)␊ |
180 | ␉{␊ |
181 | ␉␉␉AddDrive(0x1f0, 0x3f4, 0x00);␊ |
182 | ␉␉␉AddDrive(0x170, 0x374, 0x00);␊ |
183 | ␉}␊ |
184 | ␉if(cd_count == 0) return 0;␊ |
185 | //␉AddDrive(0xa000, 0x9c00, 0x00); //ich9r pri␊ |
186 | //␉AddDrive(0x9880, 0x9800, 0x00); //ich9r sec␊ |
187 | //␉AddDrive(0xd600, 0xd700, 0x00);␊ |
188 | //␉AddDrive(0xd800, 0xd900, 0x00);␊ |
189 | ␉cache_2k = malloc(2048*CACHE_BLKN);␊ |
190 | ␉cache_blk = 0xFFFF0000;␊ |
191 | ␉for(i=1; i<=cd_count;i++)␊ |
192 | ␉␉if(cdcheck(i, cache_2k))␊ |
193 | ␉␉{␊ |
194 | ␉␉␉printf("no inserted cd found in drive %d\n",i);␊ |
195 | ␉␉␉cd_bad[i]=1;␊ |
196 | ␉␉}␊ |
197 | ␉printf("cd setup done\n");␊ |
198 | ␉return cd_count;␊ |
199 | }␊ |
200 | ␊ |
201 | int cdread (int dev, unsigned int secno, char * buffer)␊ |
202 | {␊ |
203 | uint32_t result, try, wait_time, olddrive;␊ |
204 | ␊ |
205 | olddrive=curdrive; //saving curdrive until its overwrited in SelectDrive␊ |
206 | ␊ |
207 | if(SelectDrive(dev))␊ |
208 | {␊ |
209 | ␉printf("Select drive returned 1, thats bad\n");␊ |
210 | ␉return -1;␊ |
211 | };␊ |
212 | ␊ |
213 | if(secno >= cache_blk && secno < (cache_blk + CACHE_BLKN) && olddrive == dev)␊ |
214 | {␊ |
215 | ␉bcopy(cache_2k + (secno - cache_blk) * 2048, buffer, 2048);␊ |
216 | ␉return 0;␊ |
217 | }␊ |
218 | for (try=0; try<10; ++try)␊ |
219 | {␊ |
220 | ␉memset( cdb, 0, sizeof( cdb ) );␊ |
221 | ␉cdb[0] = 0xa8;␊ |
222 | ␉cdb[1] = 0x00;␊ |
223 | ␉cdb[2] = (OSSwapBigToHostInt32(secno) & 0xFF); //4␊ |
224 | ␉cdb[3] = (OSSwapBigToHostInt32(secno) & 0xFF00) >> 8; //3␊ |
225 | ␉cdb[4] = (OSSwapBigToHostInt32(secno) & 0xFF0000) >> 16; //2␊ |
226 | ␉cdb[5] = (OSSwapBigToHostInt32(secno) & 0xFF000000) >> 24; //1␊ |
227 | ␉cdb[6] = 0x00;␊ |
228 | ␉cdb[7] = 0x00;␊ |
229 | ␉cdb[8] = 0x00;␊ |
230 | ␉cdb[9] = CACHE_BLKN;␊ |
231 | ␉cdb[10] = 0x00;␊ |
232 | ␉cdb[11] = 0x00;␊ |
233 | ␊ |
234 | ␉result = reg_packet(cd_drives[dev][2], sizeof(cdb), (unsigned char*) cdb, 0, 2048*CACHE_BLKN, cache_2k);␊ |
235 | ␉if(!result)␊ |
236 | ␉{␊ |
237 | ␉␉bcopy(cache_2k, buffer, 2048);␊ |
238 | ␉␉cache_blk=secno;␊ |
239 | ␉␉return 0;␊ |
240 | ␉}␊ |
241 | ␉//␉DriveReset(dev);␊ |
242 | ␉wait_time = time18() + 50;␊ |
243 | ␉while(time18() < wait_time);␊ |
244 | }␊ |
245 | return -1;␊ |
246 | }␊ |
247 | ␊ |
248 | void ejectcd(uint32_t dev, uint32_t dir)␊ |
249 | {␊ |
250 | ␉SelectDrive(dev);␊ |
251 | ␉memset( cdb, 0, sizeof( cdb ) );␊ |
252 | ␊ |
253 | ␉cdb[0] = 0x1b;␊ |
254 | ␉cdb[1] = 0x00;␊ |
255 | ␉cdb[2] = 0x00;␊ |
256 | ␉cdb[3] = 0x00;␊ |
257 | ␉cdb[4] = dir ? 2 :3;␊ |
258 | ␉cdb[5] = 0x00;␊ |
259 | ␉cdb[6] = 0x00;␊ |
260 | ␉cdb[7] = 0x00;␊ |
261 | ␉cdb[8] = 0x00;␊ |
262 | ␉cdb[9] = 0x00;␊ |
263 | ␉cdb[10] = 0x00;␊ |
264 | ␉cdb[11] = 0x00;␊ |
265 | ␊ |
266 | ␉reg_packet(cd_drives[dev][2], sizeof(cdb), (unsigned char*) cdb, 0, 2048,␉kLoadAddr);␊ |
267 | //␉DriveReset(dev);␊ |
268 | }␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀␀ |