1 /* *********************************************************************
2 * Broadcom Common Firmware Environment (CFE)
4 * Generic IDE disk driver File: dev_ide_common.c
6 * This is a simple driver for IDE hard disks. The mechanics
7 * of talking to the I/O ports are abstracted sufficiently to make
8 * this driver usable for various bus interfaces.
10 * Author: Mitch Lichtenberg (mpl@broadcom.com)
12 *********************************************************************
14 * Copyright 2000,2001,2002,2003
15 * Broadcom Corporation. All rights reserved.
17 * This software is furnished under license and may be used and
18 * copied only in accordance with the following terms and
19 * conditions. Subject to these conditions, you may download,
20 * copy, install, use, modify and distribute modified or unmodified
21 * copies of this software in source and/or binary form. No title
22 * or ownership is transferred hereby.
24 * 1) Any source code used, modified or distributed must reproduce
25 * and retain this copyright notice and list of conditions
26 * as they appear in the source file.
28 * 2) No right is granted to use any trade name, trademark, or
29 * logo of Broadcom Corporation. The "Broadcom Corporation"
30 * name may not be used to endorse or promote products derived
31 * from this software without the prior written permission of
32 * Broadcom Corporation.
34 * 3) THIS SOFTWARE IS PROVIDED "AS-IS" AND ANY EXPRESS OR
35 * IMPLIED WARRANTIES, INCLUDING BUT NOT LIMITED TO, ANY IMPLIED
36 * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
37 * PURPOSE, OR NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT
38 * SHALL BROADCOM BE LIABLE FOR ANY DAMAGES WHATSOEVER, AND IN
39 * PARTICULAR, BROADCOM SHALL NOT BE LIABLE FOR DIRECT, INDIRECT,
40 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
41 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
42 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
43 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
44 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
45 * TORT (INCLUDING NEGLIGENCE OR OTHERWISE), EVEN IF ADVISED OF
46 * THE POSSIBILITY OF SUCH DAMAGE.
47 ********************************************************************* */
50 #include "lib_types.h"
51 #include "lib_malloc.h"
52 #include "lib_printf.h"
53 #include "lib_string.h"
54 #include "cfe_timer.h"
56 #include "cfe_device.h"
57 #include "cfe_ioctl.h"
58 #include "cfe_error.h"
60 #include "dev_ide_common.h"
64 /* *********************************************************************
66 ********************************************************************* */
71 #define IDE_WRITEREG8(ide,reg,val) IDEDISP_WRITEREG8(ide->idecommon_dispatch,reg,val)
72 #define IDE_WRITEREG16(ide,reg,val) IDEDISP_WRITEREG8(ide->idecommon_dispatch,reg,val)
73 #define IDE_WRITEBUF(ide,reg,buf,len) IDEDISP_WRITEBUF(ide->idecommon_dispatch,reg,buf,len)
74 #define IDE_READREG8(ide,reg) IDEDISP_READREG8(ide->idecommon_dispatch,reg)
75 #define IDE_READREG16(ide,reg) IDEDISP_READREG16(ide->idecommon_dispatch,reg)
76 #define IDE_READBUF(ide,reg,buf,len) IDEDISP_READBUF(ide->idecommon_dispatch,reg,buf,len)
78 #define GETWORD_LE(buf,wordidx) (((unsigned int) (buf)[(wordidx)*2]) + \
79 (((unsigned int) (buf)[(wordidx)*2+1]) << 8))
84 static void idecommon_testdrq(idecommon_t
*ide
);
86 /* *********************************************************************
87 * idecommon_sectorshift(size)
89 * Given a sector size, return log2(size). We cheat; this is
90 * only needed for 2048 and 512-byte sectors.
91 * Explicitly using shifts and masks in sector number calculations
92 * helps on 32-bit-only platforms, since we probably won't need
100 ********************************************************************* */
102 #define idecommon_sectorshift(size) (((size)==2048)?11:9)
104 /* *********************************************************************
105 * idecommon_waitnotbusy(ide)
107 * Wait for an IDE device to report "not busy"
110 * ide - IDE interface
113 * 0 if ok, else -1 if timeout
114 ********************************************************************* */
116 static int idecommon_waitnotbusy(idecommon_t
*ide
)
121 TIMER_SET(timer
,10*CFE_HZ
);
123 while (!TIMER_EXPIRED(timer
)) {
124 status
= IDE_READREG8(ide
,IDE_REG_STATUS
);
125 if (!(status
& IDE_STS_BSY
) && (status
& IDE_STS_DRQ
)) {
126 idecommon_testdrq(ide
);
129 if ((status
& (IDE_STS_BSY
| IDE_STS_DRQ
)) == 0) return 0;
134 xprintf("Device did not become unbusy\n");
140 /* *********************************************************************
141 * idecommon_waitbusy(idx)
143 * Wait for an IDE disk to start processing a command, or at
144 * least long enough to indicate that it is doing so.
145 * The code below looks suspiciously like a timing loop.
146 * unfortunately, that's what it is, determined empirically
147 * for certain ATA flash cards. Without this many reads to the
148 * ALTSTAT register, the PCMCIA controller deasserts the
149 * card detect pins briefly. Anyone have any clues?
152 * ide - IDE interface
156 ********************************************************************* */
158 static void idecommon_waitbusy(idecommon_t
*ide
)
162 for (idx
= 0; idx
< 10; idx
++) {
163 IDE_READREG8(ide
,IDE_REG_ALTSTAT
);
164 IDE_READREG8(ide
,IDE_REG_ALTSTAT
);
165 IDE_READREG8(ide
,IDE_REG_ALTSTAT
);
166 IDE_READREG8(ide
,IDE_REG_ALTSTAT
);
171 /* *********************************************************************
172 * idecommon_wait_drq(ide)
174 * Wait for the BUSY bit to be clear and the DRQ bit to be set.
175 * This is usually the indication that it's time to transfer data.
178 * ide - IDE interface
180 * -1 if timeout occured
181 ********************************************************************* */
183 static int idecommon_wait_drq(idecommon_t
*ide
)
188 TIMER_SET(timer
,10*CFE_HZ
);
190 while (!TIMER_EXPIRED(timer
)) {
192 status
= IDE_READREG8(ide
,IDE_REG_STATUS
);
193 if (!(status
& IDE_STS_BSY
) && (status
& IDE_STS_ERR
)) {
194 xprintf("Drive status: %02X error %02X\n",status
,
195 IDE_READREG8(ide
,IDE_REG_ERROR
));
198 if (!(status
& IDE_STS_BSY
) && (status
& IDE_STS_DRQ
)) return 0;
202 xprintf("Timeout waiting for disk\n");
208 /* *********************************************************************
209 * idecommon_testdrq(ide)
211 * Debug routine. Check the DRQ bit. If it's set, it is not
212 * supposed to be, so transfer data until it clears and report
213 * how much we had to transfer.
216 * ide - IDE interface
220 ********************************************************************* */
223 static void idecommon_testdrq(idecommon_t
*ide
)
229 status
= IDE_READREG8(ide
,IDE_REG_STATUS
);
230 if (status
& IDE_STS_DRQ
) {
231 xprintf("Error: DRQ should be zero\n");
233 while (status
& IDE_STS_DRQ
) {
234 data
= IDE_READREG16(ide
,IDE_REG_DATA
);
236 status
= IDE_READREG8(ide
,IDE_REG_STATUS
);
238 xprintf("Had to read data %d times to clear DRQ\n",idx
);
242 #define idecommon_testdrq(ide)
246 /* *********************************************************************
247 * idecommon_dumpregs(ide)
249 * Dump out the IDE registers. (debug routine)
256 ********************************************************************* */
258 static void idecommon_dumpregs(idecommon_t
*ide
)
263 /* *********************************************************************
264 * idecommon_reset(ide)
266 * Reset the IDE interface.
269 * ide - IDE interface
272 * 0 if ok, else -1 if a timeout occured
273 ********************************************************************* */
275 static int idecommon_reset(idecommon_t
*ide
)
280 /* *********************************************************************
281 * idecommon_identify(ide,buffer)
283 * Execute an IDENTIFY command to get information about the disk.
286 * ide - IDE interface
287 * buffer - pointer to 512 byte buffer
292 ********************************************************************* */
294 int idecommon_identify(idecommon_t
*ide
,unsigned char *buffer
)
297 /* Device Select Protocol; see ATAPI-4 sect 9.6 */
299 if (idecommon_waitnotbusy(ide
) < 0) return -1;
300 IDE_WRITEREG8(ide
,IDE_REG_DRVHD
,(ide
->idecommon_unit
<<4)|0);
301 if (idecommon_waitnotbusy(ide
) < 0) return -1;
303 /* Set device registers */
305 IDE_WRITEREG8(ide
,IDE_REG_CYLLSB
,0);
306 IDE_WRITEREG8(ide
,IDE_REG_CYLMSB
,0);
307 IDE_WRITEREG8(ide
,IDE_REG_SECNUM
,1);
308 IDE_WRITEREG8(ide
,IDE_REG_SECCNT
,1);
310 idecommon_testdrq(ide
);
312 /* Issue command, then read ALT STATUS (9.7) */
314 if (ide
->idecommon_atapi
) {
315 IDE_WRITEREG8(ide
,IDE_REG_COMMAND
,IDE_CMD_ATAPI_IDENTIFY
);
318 IDE_WRITEREG8(ide
,IDE_REG_COMMAND
,IDE_CMD_DRIVE_INFO
);
321 IDE_READREG8(ide
,IDE_REG_ALTSTAT
);
322 idecommon_waitbusy(ide
); /* should not be necessary */
324 /* Wait BSY=0 && DRQ=1, then read buffer, see sect 9.7 */
326 if (idecommon_wait_drq(ide
) < 0) return -1;
327 IDE_READBUF(ide
,IDE_REG_DATA
,buffer
,DISK_SECTORSIZE
);
329 idecommon_testdrq(ide
);
334 /* *********************************************************************
335 * idecommon_packet(ide,packet,pktlen,databuf,datalen)
337 * Process an IDE "packet" command, for ATAPI devices
340 * ide - IDE interface
341 * packet,pktlen - command packet
342 * databuf,datalen - data buffer
347 ********************************************************************* */
349 static int idecommon_packet(idecommon_t
*ide
,
350 uint8_t *packet
,int pktlen
,
351 uint8_t *databuf
,int datalen
)
356 * Not valid on non-ATAPI disks
359 if (!ide
->idecommon_atapi
) return -1;
362 * Set up the standard IDE registers for an ATAPI PACKET command
365 /* Device Select Protocol */
366 if (idecommon_waitnotbusy(ide
) < 0) return -1;
367 IDE_WRITEREG8(ide
,IDE_REG_DRVHD
,(ide
->idecommon_unit
<<4));
368 if (idecommon_waitnotbusy(ide
) < 0) return -1;
370 /* Device Registers */
371 IDE_WRITEREG8(ide
,IDE_REG_BCLSB
,(datalen
& 0xFF));
372 IDE_WRITEREG8(ide
,IDE_REG_BCMSB
,((datalen
>> 8) & 0xFF));
373 IDE_WRITEREG8(ide
,IDE_REG_SECNUM
,0);
374 IDE_WRITEREG8(ide
,IDE_REG_SECCNT
,0);
375 IDE_WRITEREG8(ide
,IDE_REG_COMMAND
,IDE_CMD_ATAPI_PACKET
);
378 * Wait for the DRQ bit to indicate that we should send
382 if (idecommon_wait_drq(ide
) < 0) return -1;
384 status
= IDE_READREG8(ide
,IDE_REG_IR
);
387 * Send the packet to the device
390 IDE_WRITEBUF(ide
,IDE_REG_DATA
,packet
,pktlen
);
393 * Wait for BSY to be cleared and DRQ to be set.
396 if (idecommon_wait_drq(ide
) < 0) return -1;
397 status
= IDE_READREG8(ide
,IDE_REG_ALTSTAT
);
398 if (idecommon_wait_drq(ide
) < 0) return -1;
399 status
= IDE_READREG8(ide
,IDE_REG_IR
);
403 * Transfer data, if necessary. The direction will depend
404 * on what the drive says. If this is a non-data command,
405 * passing databuf == NULL can avoid all this.
409 status
= IDE_READREG8(ide
,IDE_REG_IR
);
410 if (status
& IDE_IR_CD
) {
411 xprintf("Error: Command/data should be zero\n");
414 if (status
& IDE_IR_IO
) { /* from device (READ) */
415 IDE_READBUF(ide
,IDE_REG_DATA
,databuf
,datalen
);
417 else { /* to device (WRITE) */
418 IDE_WRITEBUF(ide
,IDE_REG_DATA
,databuf
,datalen
);
424 idecommon_testdrq(ide
);
431 /* *********************************************************************
432 * idecommon_request_sense(ide)
434 * Request sense data. This also clears a UNIT_ATTENTION condition
437 * ide - IDE interface
442 ********************************************************************* */
443 static int idecommon_request_sense(idecommon_t
*ide
)
446 uint8_t sensedata
[32];
450 numbytes
= sizeof(sensedata
);
452 cdb
[0] = CDB_CMD_REQSENSE
;
456 cdb
[4] = sizeof(sensedata
);
465 memset(sensedata
,0,sizeof(sensedata
));
467 res
= idecommon_packet(ide
,cdb
,sizeof(cdb
),sensedata
,numbytes
);
470 idecommon_testdrq(ide
);
476 /* *********************************************************************
477 * idecommon_read_atapi(ide,lba,numsec,buffer)
479 * Read sector(s) from the device. This version is for ATAPI devs.
482 * ide - IDE interface
483 * lba - logical block address
484 * numsec - number of sectors
485 * buffer - buffer address
490 ********************************************************************* */
492 static int idecommon_read_atapi(idecommon_t
*ide
,uint64_t lba
,
493 int numsec
,unsigned char *buffer
)
500 numbytes
= numsec
<< idecommon_sectorshift(ide
->idecommon_sectorsize
);
502 cdb
[0] = CDB_CMD_READ
;
504 cdb
[2] = ((lba
>> 24) & 0xFF);
505 cdb
[3] = ((lba
>> 16) & 0xFF);
506 cdb
[4] = ((lba
>> 8) & 0xFF);
507 cdb
[5] = ((lba
>> 0) & 0xFF);
509 cdb
[7] = ((numsec
>> 8) & 0xFF);
510 cdb
[8] = ((numsec
>> 0) & 0xFF);
515 for (idx
= 0; idx
< 4; idx
++) {
516 res
= idecommon_packet(ide
,cdb
,sizeof(cdb
),buffer
,numbytes
);
518 idecommon_request_sense(ide
);
528 /* *********************************************************************
529 * idecommon_write_atapi(ide,lba,numsec,buffer)
531 * Write sector(s) to the device. This version is for ATAPI disks
534 * ide - IDE interface
535 * lba - logical block address
536 * numsec - number of sectors
537 * buffer - buffer address
542 ********************************************************************* */
544 static int idecommon_write_atapi(idecommon_t
*ide
,uint64_t lba
,
545 int numsec
,unsigned char *buffer
)
551 numbytes
= numsec
<< idecommon_sectorshift(ide
->idecommon_sectorsize
);
553 cdb
[0] = CDB_CMD_WRITE
;
555 cdb
[2] = ((lba
>> 24) & 0xFF);
556 cdb
[3] = ((lba
>> 16) & 0xFF);
557 cdb
[4] = ((lba
>> 8) & 0xFF);
558 cdb
[5] = ((lba
>> 0) & 0xFF);
560 cdb
[7] = ((numsec
>> 8) & 0xFF);
561 cdb
[8] = ((numsec
>> 0) & 0xFF);
566 res
= idecommon_packet(ide
,cdb
,sizeof(cdb
),buffer
,numbytes
);
572 /* *********************************************************************
573 * idecommon_read_lba(ide,lba,numsec,buffer)
575 * Read sector(s) from the device.
578 * ide - IDE interface
579 * lba - logical block address
580 * numsec - number of sectors
581 * buffer - buffer address
586 ********************************************************************* */
588 static int idecommon_read_lba(idecommon_t
*ide
,uint64_t lba
,int numsec
,unsigned char *buffer
)
593 if (idecommon_waitnotbusy(ide
) < 0) return -1;
594 IDE_WRITEREG8(ide
,IDE_REG_DRVHD
,(ide
->idecommon_unit
<<4) | ((lba
>> 24) & 0x0F) | 0x40);
595 if (idecommon_waitnotbusy(ide
) < 0) return -1;
597 IDE_WRITEREG8(ide
,IDE_REG_CYLMSB
,((lba
>> 16) & 0xFF));
598 IDE_WRITEREG8(ide
,IDE_REG_CYLLSB
,((lba
>> 8) & 0xFF));
599 IDE_WRITEREG8(ide
,IDE_REG_SECNUM
,(lba
& 0xFF));
600 IDE_WRITEREG8(ide
,IDE_REG_SECCNT
,numsec
);
602 idecommon_testdrq(ide
);
604 IDE_WRITEREG8(ide
,IDE_REG_COMMAND
,IDE_CMD_READ
);
606 idecommon_waitbusy(ide
);
607 if (idecommon_wait_drq(ide
) < 0) return -1;
611 for (secidx
= 0; secidx
< numsec
; secidx
++) {
612 IDE_READBUF(ide
,IDE_REG_DATA
,ptr
,ide
->idecommon_sectorsize
);
613 ptr
+= ide
->idecommon_sectorsize
;
616 idecommon_testdrq(ide
);
622 /* *********************************************************************
623 * idecommon_write_lba(ide,lba,numsec,buffer)
625 * Write sector(s) from the device.
628 * ide - IDE interface
629 * lba - logical block address
630 * numsec - number of sectors
631 * buffer - buffer address
636 ********************************************************************* */
638 static int idecommon_write_lba(idecommon_t
*ide
,uint64_t lba
,int numsec
,unsigned char *buffer
)
643 if (idecommon_waitnotbusy(ide
) < 0) return -1;
644 IDE_WRITEREG8(ide
,IDE_REG_DRVHD
,(ide
->idecommon_unit
<<4) | ((lba
>> 24) & 0x0F) | 0x40);
645 if (idecommon_waitnotbusy(ide
) < 0) return -1;
647 IDE_WRITEREG8(ide
,IDE_REG_CYLMSB
,((lba
>> 16) & 0xFF));
648 IDE_WRITEREG8(ide
,IDE_REG_CYLLSB
,((lba
>> 8) & 0xFF));
649 IDE_WRITEREG8(ide
,IDE_REG_SECNUM
,(lba
& 0xFF));
650 IDE_WRITEREG8(ide
,IDE_REG_SECCNT
,numsec
);
652 IDE_WRITEREG8(ide
,IDE_REG_COMMAND
,IDE_CMD_WRITE
);
654 if (idecommon_wait_drq(ide
) < 0) return -1;
658 for (secidx
= 0; secidx
< numsec
; secidx
++) {
659 IDE_WRITEBUF(ide
,IDE_REG_DATA
,ptr
,ide
->idecommon_sectorsize
);
660 ptr
+= ide
->idecommon_sectorsize
;
663 idecommon_testdrq(ide
);
669 /* *********************************************************************
670 * idecommon_diagnostic(ide)
672 * run the device diagnostics on the IDE device. This also
673 * helps us determine if it's an IDE or ATAPI disk, since the
674 * diagnostic will leave a signature in the registers.
677 * softc - IDE interface
682 ********************************************************************* */
684 static int idecommon_diagnostic(idecommon_t
*softc
)
686 if (idecommon_waitnotbusy(softc
) < 0) return -1;
687 IDE_WRITEREG8(softc
,IDE_REG_DRVHD
,(softc
->idecommon_unit
<<4));
688 if (idecommon_waitnotbusy(softc
) < 0) return -1;
690 IDE_WRITEREG8(softc
,IDE_REG_COMMAND
,IDE_CMD_DIAGNOSTIC
);
691 if (idecommon_waitnotbusy(softc
) < 0) return -1;
694 idecommon_dumpregs(softc
);
700 /* *********************************************************************
701 * idecommon_getmodel(buffer,model)
703 * Get the ASCII model name out of an IDE identify buffer. some
704 * byte swapping is involved here. The trailing blanks are trimmed.
707 * buffer - 512-byte buffer from IDENTIFY command
708 * model - 41-byte string (max) for model name
712 ********************************************************************* */
714 static void idecommon_getmodel(uint8_t *buffer
,char *model
)
719 for (idx
= 0; idx
< 20; idx
++) {
720 w
= GETWORD_LE(buffer
,27+idx
);
721 model
[idx
*2] = w
>> 8;
722 model
[idx
*2+1] = w
& 0xFF;
724 for (idx
= 39; idx
> 0; idx
--) {
725 if (model
[idx
] != ' ') {
733 /* *********************************************************************
734 * idecommon_devprobe(softc)
736 * Probe the IDE device, to determine if it's actually present
737 * or not. If present, determine if it's IDE or ATAPI and
738 * get the device size. Init our internal structures so we know
739 * how to talk to the device.
742 * softc - IDE structure
743 * noisy - display stuff as we probe
746 * 0 if ok, else error code
747 ********************************************************************* */
749 int idecommon_devprobe(idecommon_t
*softc
,int noisy
)
753 unsigned char buffer
[DISK_SECTORSIZE
];
754 unsigned char model
[41];
764 res
= idecommon_reset(softc
);
765 if (res
< 0) return -1;
768 * Run diagnostic to get the signature.
771 res
= idecommon_diagnostic(softc
);
772 if (res
< 0) return res
;
779 if ((IDE_READREG8(softc
,IDE_REG_CYLLSB
) == ATAPI_SIG_LSB
) &&
780 (IDE_READREG8(softc
,IDE_REG_CYLMSB
) == ATAPI_SIG_MSB
)) {
785 if (atapi
) xprintf("ATAPI: ");
786 else xprintf("IDE: ");
790 * Do tha appropriate IDENTIFY command to get device information
793 softc
->idecommon_atapi
= atapi
;
794 res
= idecommon_identify(softc
,buffer
);
795 if (res
< 0) return -1;
798 * Using that information, determine our device type
802 devtype
= IDE_DEVTYPE_DISK
;
806 w
= GETWORD_LE(buffer
,0);
807 switch ((w
>> 8) & 31) {
809 devtype
= IDE_DEVTYPE_CDROM
;
813 devtype
= IDE_DEVTYPE_ATAPIDISK
;
820 * Say nice things about the device.
823 idecommon_getmodel(buffer
,(char *)model
);
824 if (noisy
) xprintf("%s, \"%s\"",typename
,model
);
828 if (!softc
->idecommon_atapi
) {
829 ttlsect
= (GETWORD_LE(buffer
,57) + (GETWORD_LE(buffer
,58) << 16));
830 if (noisy
) xprintf(", Sectors: %llu (%lld MB)",ttlsect
,
831 (uint64_t) (ttlsect
/2048));
837 if (noisy
) xprintf("\n");
840 * Initialize internal structure info, especially pointers to the
841 * read/write routines and the sector size.
844 softc
->idecommon_ttlsect
= ttlsect
;
845 idecommon_init(softc
,devtype
);
850 /* *********************************************************************
851 * idecommon_open(ctx)
853 * Process the CFE OPEN call for this device. For IDE disks,
854 * the device is reset and identified, and the geometry is
858 * ctx - device context
861 * 0 if ok, else error code
862 ********************************************************************* */
865 int idecommon_open(cfe_devctx_t
*ctx
)
867 idecommon_t
*softc
= ctx
->dev_softc
;
870 if (softc
->idecommon_deferprobe
) {
871 res
= idecommon_devprobe(softc
,0);
872 if (res
< 0) return res
;
878 /* *********************************************************************
879 * idecommon_read(ctx,buffer)
881 * Process a CFE READ command for the IDE device. This is
882 * more complex than it looks, since CFE offsets are byte offsets
883 * and we may need to read partial sectors.
886 * ctx - device context
887 * buffer - buffer descriptor
890 * number of bytes read, or <0 if an error occured
891 ********************************************************************* */
893 int idecommon_read(cfe_devctx_t
*ctx
,iocb_buffer_t
*buffer
)
895 idecommon_t
*softc
= ctx
->dev_softc
;
903 unsigned char sector
[MAX_SECTORSIZE
];
906 sectorshift
= idecommon_sectorshift(softc
->idecommon_sectorsize
);
908 bptr
= buffer
->buf_ptr
;
909 blen
= buffer
->buf_length
;
910 offset
= buffer
->buf_offset
;
911 numsec
= (blen
+ softc
->idecommon_sectorsize
- 1) >> sectorshift
;
913 if (offset
& (softc
->idecommon_sectorsize
-1)) {
914 lba
= (offset
>> sectorshift
);
915 res
= (*softc
->idecommon_readfunc
)(softc
,lba
,1,sector
);
916 if (res
< 0) goto out
;
917 amtcopy
= softc
->idecommon_sectorsize
- (offset
& (softc
->idecommon_sectorsize
-1));
918 if (amtcopy
> blen
) amtcopy
= blen
;
919 memcpy(bptr
,§or
[offset
& (softc
->idecommon_sectorsize
-1)],amtcopy
);
925 while (blen
>= softc
->idecommon_sectorsize
) {
926 lba
= (offset
>> sectorshift
);
927 amtcopy
= softc
->idecommon_sectorsize
;
928 res
= (*softc
->idecommon_readfunc
)(softc
,lba
,1,bptr
);
929 if (res
< 0) goto out
;
936 lba
= (offset
>> sectorshift
);
937 res
= (*softc
->idecommon_readfunc
)(softc
,lba
,1,sector
);
938 if (res
< 0) goto out
;
940 memcpy(bptr
,sector
,amtcopy
);
947 buffer
->buf_retlen
= bptr
- buffer
->buf_ptr
;
952 /* *********************************************************************
953 * idecommon_inpstat(ctx,inpstat)
955 * Test input status for the IDE disk. Disks are always ready
959 * ctx - device context
960 * inpstat - input status structure
964 ********************************************************************* */
966 int idecommon_inpstat(cfe_devctx_t
*ctx
,iocb_inpstat_t
*inpstat
)
968 /* idecommon_t *softc = ctx->dev_softc; */
970 inpstat
->inp_status
= 1;
974 /* *********************************************************************
975 * idecommon_write(ctx,buffer)
977 * Process a CFE WRITE command for the IDE device. If the write
978 * involves partial sectors, the affected sectors are read first
979 * and the changes are merged in.
982 * ctx - device context
983 * buffer - buffer descriptor
986 * number of bytes write, or <0 if an error occured
987 ********************************************************************* */
989 int idecommon_write(cfe_devctx_t
*ctx
,iocb_buffer_t
*buffer
)
991 idecommon_t
*softc
= ctx
->dev_softc
;
999 unsigned char sector
[MAX_SECTORSIZE
];
1002 sectorshift
= (softc
->idecommon_sectorsize
== 2048) ? 11 : 9;
1004 bptr
= buffer
->buf_ptr
;
1005 blen
= buffer
->buf_length
;
1006 offset
= buffer
->buf_offset
;
1007 numsec
= (blen
+ softc
->idecommon_sectorsize
- 1) >> sectorshift
;
1009 if (offset
& (softc
->idecommon_sectorsize
-1)) {
1010 lba
= (offset
>> sectorshift
);
1011 res
= (*softc
->idecommon_readfunc
)(softc
,lba
,1,sector
);
1012 if (res
< 0) goto out
;
1013 amtcopy
= softc
->idecommon_sectorsize
- (offset
& (softc
->idecommon_sectorsize
-1));
1014 if (amtcopy
> blen
) amtcopy
= blen
;
1015 memcpy(§or
[offset
& (softc
->idecommon_sectorsize
-1)],bptr
,amtcopy
);
1016 res
= (*softc
->idecommon_writefunc
)(softc
,lba
,1,sector
);
1017 if (res
< 0) goto out
;
1023 while (blen
>= softc
->idecommon_sectorsize
) {
1024 amtcopy
= softc
->idecommon_sectorsize
;
1025 lba
= (offset
>> sectorshift
);
1026 res
= (*softc
->idecommon_writefunc
)(softc
,lba
,1,bptr
);
1027 if (res
< 0) goto out
;
1034 lba
= (offset
>> sectorshift
);
1035 res
= (*softc
->idecommon_readfunc
)(softc
,lba
,1,sector
);
1036 if (res
< 0) goto out
;
1038 memcpy(sector
,bptr
,amtcopy
);
1039 res
= (*softc
->idecommon_writefunc
)(softc
,lba
,1,sector
);
1040 if (res
< 0) goto out
;
1047 buffer
->buf_retlen
= bptr
- buffer
->buf_ptr
;
1053 /* *********************************************************************
1054 * idecommon_ioctl(ctx,buffer)
1056 * Process device I/O control requests for the IDE device.
1059 * ctx - device context
1060 * buffer - buffer descriptor
1065 ********************************************************************* */
1067 int idecommon_ioctl(cfe_devctx_t
*ctx
,iocb_buffer_t
*buffer
)
1069 idecommon_t
*softc
= ctx
->dev_softc
;
1070 unsigned int *info
= (unsigned int *) buffer
->buf_ptr
;
1071 unsigned long long *linfo
= (unsigned long long *) buffer
->buf_ptr
;
1072 blockdev_info_t
*devinfo
;
1074 switch ((int)buffer
->buf_ioctlcmd
) {
1075 case IOCTL_BLOCK_GETBLOCKSIZE
:
1076 *info
= softc
->idecommon_sectorsize
;
1078 case IOCTL_BLOCK_GETTOTALBLOCKS
:
1079 *linfo
= softc
->idecommon_ttlsect
;
1081 case IOCTL_BLOCK_GETDEVTYPE
:
1082 devinfo
= (blockdev_info_t
*) buffer
->buf_ptr
;
1083 devinfo
->blkdev_totalblocks
= softc
->idecommon_ttlsect
;
1084 devinfo
->blkdev_blocksize
= softc
->idecommon_sectorsize
;
1085 devinfo
->blkdev_devtype
= (softc
->idecommon_devtype
== IDE_DEVTYPE_CDROM
) ?
1086 BLOCK_DEVTYPE_CDROM
: BLOCK_DEVTYPE_DISK
;
1095 /* *********************************************************************
1096 * idecommon_close(ctx)
1098 * Close the I/O device.
1101 * ctx - device context
1104 * 0 if ok, else error code
1105 ********************************************************************* */
1107 int idecommon_close(cfe_devctx_t
*ctx
)
1109 /* idecommon_t *softc = ctx->dev_softc; */
1115 /* *********************************************************************
1116 * idecommon_init(ide,devtype)
1118 * Set up internal values based on the device type
1121 * ide - IDE interface
1122 * devtype - device type
1126 ********************************************************************* */
1128 void idecommon_init(idecommon_t
*ide
,int devtype
)
1131 ide
->idecommon_devtype
= devtype
;
1133 switch (ide
->idecommon_devtype
) {
1134 case IDE_DEVTYPE_DISK
:
1135 ide
->idecommon_atapi
= FALSE
;
1136 ide
->idecommon_sectorsize
= DISK_SECTORSIZE
;
1138 case IDE_DEVTYPE_CDROM
:
1139 ide
->idecommon_atapi
= TRUE
;
1140 ide
->idecommon_sectorsize
= CDROM_SECTORSIZE
;
1142 case IDE_DEVTYPE_ATAPIDISK
:
1143 ide
->idecommon_atapi
= TRUE
;
1144 ide
->idecommon_sectorsize
= DISK_SECTORSIZE
;
1147 ide
->idecommon_atapi
= FALSE
;
1148 ide
->idecommon_sectorsize
= DISK_SECTORSIZE
;
1152 if (ide
->idecommon_atapi
) {
1153 ide
->idecommon_readfunc
= idecommon_read_atapi
;
1154 ide
->idecommon_writefunc
= idecommon_write_atapi
;
1157 ide
->idecommon_readfunc
= idecommon_read_lba
;
1158 ide
->idecommon_writefunc
= idecommon_write_lba
;
1162 /* *********************************************************************
1163 * idecommon_attach(devdisp)
1165 * Set up a cfe_devdisp structure that points at the idecommon
1169 * devdisp - cfe_devdisp_t structure
1173 ********************************************************************* */
1174 void idecommon_attach(cfe_devdisp_t
*disp
)
1176 disp
->dev_open
= idecommon_open
;
1177 disp
->dev_read
= idecommon_read
;
1178 disp
->dev_inpstat
= idecommon_inpstat
;
1179 disp
->dev_write
= idecommon_write
;
1180 disp
->dev_ioctl
= idecommon_ioctl
;
1181 disp
->dev_close
= idecommon_close
;
1182 disp
->dev_poll
= NULL
;
1183 disp
->dev_reset
= NULL
;