Chameleon

Chameleon Svn Source Tree

Root/branches/prasys/i386/libsaio/cddrvr.c

  • Property svn:executable set to *
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
24uint8_t cdb[CDB_SIZE_T];
25
26uint32_t cd_drives[32][4];
27uint32_t cd_count = 0;
28
29uint8_t cd_bad[10] = {0,0,0,0,0,0,0,0,0,0};
30
31uint32_t pci_count = 0;
32uint32_t pci_devs[ 768 ];
33uint32_t curdrive = 0;
34#define CACHE_BLKN 4
35unsigned char * cache_2k;
36unsigned int cache_blk;
37
38static void DriveReset(uint32_t dev)
39{
40if (dev > cd_count)
41{
42printf("device %d doesnt exist, max is %d\n", dev, cd_count);
43return;
44}
45reg_reset(cd_drives[dev][2]);
46}
47
48static int SelectDrive(uint32_t dev)
49{
50if(cd_bad[dev] == 1) return 1;
51if(curdrive == dev) return 0;
52if (dev > cd_count)
53{
54printf("device %d doesnt exist, max is %d\n", dev, cd_count);
55return 1;
56}
57pio_set_iobase_addr(cd_drives[dev][0], cd_drives[dev][1], cd_drives[dev][3]);
58//reg_config();
59reg_config_info[0]=0;
60reg_config_info[1]=0;
61reg_config_info[cd_drives[dev][2]]=REG_CONFIG_TYPE_ATAPI;
62curdrive = dev;
63//DriveReset(dev);
64return 0;
65}
66
67static int cdcheck (int dev, char * buffer)
68{
69uint32_t result, try, wait_time;
70
71if(SelectDrive(dev))
72{
73printf("Select drive returned 1, thats bad\n");
74return -1;
75};
76
77
78for (try=0; try<10; ++try)
79 {
80memset( 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;
92cdb[11] = 0x00;
93result = reg_packet(cd_drives[dev][2], sizeof(cdb), (unsigned char*) cdb, 0, 2048, cache_2k);
94if(!result)
95{
96return 0;
97}
98wait_time = time18() + 20;
99while(time18() < wait_time);
100 }
101return -1;
102}
103
104
105static void AddDrive(uint32_t base1, uint32_t base2, uint32_t bmbase)
106{
107uint32_t res,i;
108pio_set_iobase_addr(base1, base2, bmbase);
109res=reg_config();
110if(res>0)
111{
112printf( "AddDrive: Found %d devices, base1 is %x, base2 is %x, dev 0 is %d, dev 1 is %d.\n",
113 res, base1, base2,
114reg_config_info[0] ,
115 reg_config_info[1] );
116if(reg_config_info[0] == REG_CONFIG_TYPE_ATAPI)
117{
118i=++cd_count;
119cd_drives[i][0] = base1;
120cd_drives[i][1] = base2;
121cd_drives[i][2] = 0; //master
122cd_drives[i][3] = bmbase;
123printf("added master device %d\n", i);
124reg_reset(0);
125}
126if(reg_config_info[1] == REG_CONFIG_TYPE_ATAPI)
127{
128i=++cd_count;
129cd_drives[i][0] = base1;
130cd_drives[i][1] = base2;
131cd_drives[i][2] = 1; //slave
132cd_drives[i][3] = bmbase;
133printf("added slave device %d\n", i);
134reg_reset(1);
135}
136}
137
138}
139
140int setup_cdread(void)
141{
142int res;
143int trylegacy = 0;
144uint16_t i;
145unsigned int pcidev=0;
146 unsigned int index=0;
147 unsigned int vendid=0;
148 unsigned int devid=0;
149unsigned int cmdBase=0;
150unsigned int ctrlBase=0;
151unsigned int classid=0;
152unsigned int bmideBase=0;
153if(cd_count>0) return cd_count;
154
155for(i=0; i<0x05ff;i++)
156{
157vendid = GetPciDword( i, 0x00) & 0xffff;
158devid = (GetPciDword( i, 0x00) >>16) & 0xffff;
159if((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;
162classid = (GetPciDword( i, 0x08) >>16) & 0xffff;
163if(classid == 0x0101)
164{
165printf("device %x, vendid %x, devid %x, classid %x\n", i, vendid, devid, classid);
166cmdBase = GetPciDword(i, 0x10) & 0xfffe;
167ctrlBase = GetPciDword(i, 0x14) & 0xfffe;
168bmideBase = GetPciDword(i, 0x20) & 0xffff;
169if(cmdBase && ctrlBase)AddDrive(cmdBase, ctrlBase, bmideBase); //no need in bmidebase?
170if(cmdBase == 0 && ctrlBase == 0) trylegacy=1;
171printf("pri port cmdbase - %x, ctrlbase - %x, bmideBase - %x\n", cmdBase, ctrlBase, bmideBase);
172cmdBase = GetPciDword(i, 0x10+8) & 0xfffe;
173ctrlBase = GetPciDword(i, 0x14+8) & 0xfffe;
174if(cmdBase && ctrlBase)AddDrive(cmdBase, ctrlBase, bmideBase);
175printf("sec port cmdbase - %x, ctrlbase - %x, bmideBase - %x\n", cmdBase, ctrlBase, bmideBase);
176}
177}
178}
179if(trylegacy)
180{
181AddDrive(0x1f0, 0x3f4, 0x00);
182AddDrive(0x170, 0x374, 0x00);
183}
184if(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);
189cache_2k = malloc(2048*CACHE_BLKN);
190cache_blk = 0xFFFF0000;
191for(i=1; i<=cd_count;i++)
192if(cdcheck(i, cache_2k))
193{
194printf("no inserted cd found in drive %d\n",i);
195cd_bad[i]=1;
196}
197printf("cd setup done\n");
198return cd_count;
199}
200
201int cdread (int dev, unsigned int secno, char * buffer)
202{
203uint32_t result, try, wait_time, olddrive;
204
205olddrive=curdrive; //saving curdrive until its overwrited in SelectDrive
206
207if(SelectDrive(dev))
208{
209printf("Select drive returned 1, thats bad\n");
210return -1;
211};
212
213if(secno >= cache_blk && secno < (cache_blk + CACHE_BLKN) && olddrive == dev)
214{
215bcopy(cache_2k + (secno - cache_blk) * 2048, buffer, 2048);
216return 0;
217}
218for (try=0; try<10; ++try)
219 {
220memset( cdb, 0, sizeof( cdb ) );
221cdb[0] = 0xa8;
222cdb[1] = 0x00;
223cdb[2] = (OSSwapBigToHostInt32(secno) & 0xFF); //4
224cdb[3] = (OSSwapBigToHostInt32(secno) & 0xFF00) >> 8; //3
225cdb[4] = (OSSwapBigToHostInt32(secno) & 0xFF0000) >> 16; //2
226cdb[5] = (OSSwapBigToHostInt32(secno) & 0xFF000000) >> 24; //1
227cdb[6] = 0x00;
228cdb[7] = 0x00;
229cdb[8] = 0x00;
230cdb[9] = CACHE_BLKN;
231cdb[10] = 0x00;
232cdb[11] = 0x00;
233
234result = reg_packet(cd_drives[dev][2], sizeof(cdb), (unsigned char*) cdb, 0, 2048*CACHE_BLKN, cache_2k);
235if(!result)
236{
237bcopy(cache_2k, buffer, 2048);
238cache_blk=secno;
239return 0;
240}
241//DriveReset(dev);
242wait_time = time18() + 50;
243while(time18() < wait_time);
244 }
245return -1;
246}
247
248void ejectcd(uint32_t dev, uint32_t dir)
249{
250SelectDrive(dev);
251memset( cdb, 0, sizeof( cdb ) );
252
253cdb[0] = 0x1b;
254cdb[1] = 0x00;
255cdb[2] = 0x00;
256cdb[3] = 0x00;
257cdb[4] = dir ? 2 :3;
258cdb[5] = 0x00;
259cdb[6] = 0x00;
260cdb[7] = 0x00;
261cdb[8] = 0x00;
262cdb[9] = 0x00;
263cdb[10] = 0x00;
264cdb[11] = 0x00;
265
266reg_packet(cd_drives[dev][2], sizeof(cdb), (unsigned char*) cdb, 0, 2048,kLoadAddr);
267//DriveReset(dev);
268}

Archive Download this file

Revision: 51