1 /////////////////////////////////////////////////////////////////////////
2 // $Id: cdrom_amigaos.cc,v 1.14 2008/01/26 22:24:00 sshwarts Exp $
3 /////////////////////////////////////////////////////////////////////////
5 // Copyright (C) 2000 MandrakeSoft S.A.
9 // 75002 Paris - France
10 // http://www.linux-mandrake.com/
11 // http://www.mandrakesoft.com/
13 // This library is free software; you can redistribute it and/or
14 // modify it under the terms of the GNU Lesser General Public
15 // License as published by the Free Software Foundation; either
16 // version 2 of the License, or (at your option) any later version.
18 // This library is distributed in the hope that it will be useful,
19 // but WITHOUT ANY WARRANTY; without even the implied warranty of
20 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
21 // Lesser General Public License for more details.
23 // You should have received a copy of the GNU Lesser General Public
24 // License along with this library; if not, write to the Free Software
25 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
28 // These are the low-level CDROM functions which are called
29 // from 'harddrv.cc'. They effect the OS specific functionality
30 // needed by the CDROM emulation in 'harddrv.cc'. Mostly, just
31 // ioctl() calls and such. Should be fairly easy to add support
32 // for your OS if it is not supported yet.
36 #include "scsi_commands.h"
39 #include <exec/types.h>
40 #include <exec/memory.h>
41 #include <devices/trackdisk.h>
42 #include <devices/scsidisk.h>
44 #include <proto/dos.h>
45 #include <proto/exec.h>
46 #include <clib/alib_protos.h>
49 #define LOG_THIS /* no SMF tricks here, not needed */
51 #define BX_CD_FRAMESIZE 2048
52 #define CD_FRAMESIZE 2048
54 #define MAX_DATA_LEN 252
57 char amiga_cd_device
[256];
59 struct MsgPort
*CDMP
; /* Pointer for message port */
60 struct IOExtTD
*CDIO
; /* Pointer for IORequest */
83 unsigned char sensebuf
[SENSELEN
];
85 int DoSCSI (UBYTE
* data
, int datasize
, UBYTE
* cmd
, int cmdsize
, UBYTE flags
);
87 cdrom_interface::cdrom_interface(char *dev
)
91 sscanf(dev
, "%s%s", amiga_cd_device
, buf
);
92 amiga_cd_unit
= atoi(buf
);
94 CDMP
= CreateMsgPort();
96 CDIO
= (struct IOExtTD
*)CreateIORequest(CDMP
, sizeof(struct IOExtTD
));
98 cd_error
= OpenDevice(amiga_cd_device
, amiga_cd_unit
, (struct IORequest
*)CDIO
, 0);
100 BX_PANIC(("CD_Open: could not open device %s unit %d\n", amiga_cd_device
, amiga_cd_unit
));
105 cdrom_interface::~cdrom_interface(void)
108 CloseDevice((struct IORequest
*)CDIO
);
111 DeleteIORequest((struct IORequest
*)CDIO
);
119 cdrom_interface::insert_cdrom(char *dev
)
122 Bit8u buf
[2*BX_CD_FRAMESIZE
];
125 memset(cdb
,0,sizeof(cdb
));
127 cdb
[0] = SCSI_DA_START_STOP_UNIT
;
130 DoSCSI(0, 0,cdb
,sizeof(cdb
),SCSIF_READ
);
132 /*Check if there's a valid media present in the drive*/
133 CDIO
->iotd_Req
.io_Data
= buf
;
134 CDIO
->iotd_Req
.io_Command
= CMD_READ
;
135 CDIO
->iotd_Req
.io_Length
= BX_CD_FRAMESIZE
;
136 CDIO
->iotd_Req
.io_Offset
= BX_CD_FRAMESIZE
;
138 for(i
= 0; i
< 200; i
++) /*it takes a while for the cdrom to validate*/
140 DoIO((struct IORequest
*)CDIO
);
141 if (CDIO
->iotd_Req
.io_Error
== 0)
146 if (CDIO
->iotd_Req
.io_Error
!= 0)
154 cdrom_interface::eject_cdrom()
158 memset(cdb
,0,sizeof(cdb
));
160 cdb
[0] = SCSI_DA_START_STOP_UNIT
;
163 DoSCSI(0, 0,cdb
,sizeof(cdb
),SCSIF_READ
);
168 cdrom_interface::read_toc(Bit8u
* buf
, int* length
, bx_bool msf
, int start_track
, int format
)
177 memset(cdb
,0,sizeof(cdb
));
179 cdb
[0] = SCSI_CD_READ_TOC
;
186 cdb
[6] = start_track
;
187 cdb
[7] = sizeof(TOC
)>>8;
188 cdb
[8] = sizeof(TOC
)&0xFF;
190 DoSCSI((UBYTE
*)buf
, sizeof(TOC
), cdb
, sizeof(cdb
), SCSIF_READ
);
192 *length
= toc
->length
+ 4;
199 cdrom_interface::capacity()
204 memset(cdb
,0,sizeof(cdb
));
205 cdb
[0] = SCSI_DA_READ_CAPACITY
;
209 if ((err
= DoSCSI((UBYTE
*)&cap
, sizeof(cap
),
211 (SCSIF_READ
| SCSIF_AUTOSENSE
))) == 0)
214 BX_PANIC (("Couldn't get media capacity"));
218 cdrom_interface::read_block(Bit8u
* buf
, int lba
, int blocksize
)
220 CDIO
->iotd_Req
.io_Data
= buf
;
221 CDIO
->iotd_Req
.io_Command
= CMD_READ
;
222 CDIO
->iotd_Req
.io_Length
= BX_CD_FRAMESIZE
;
223 CDIO
->iotd_Req
.io_Offset
= lba
* BX_CD_FRAMESIZE
;
224 DoIO((struct IORequest
*)CDIO
);
226 if (CDIO
->iotd_Req
.io_Error
!= 0) {
227 BX_PANIC(("Error %d reading CD data sector: %ld", CDIO
->iotd_Req
.io_Error
, lba
));
234 cdrom_interface::start_cdrom()
236 // Spin up the cdrom drive.
239 BX_INFO(("start_cdrom: your OS is not supported yet."));
240 return 0; // OS not supported yet, return 0 always.
246 int DoSCSI(UBYTE
*data
, int datasize
, Bit8u
*cmd
,int cmdsize
, UBYTE direction
)
250 CDIO
->iotd_Req
.io_Command
= HD_SCSICMD
;
251 CDIO
->iotd_Req
.io_Data
= &scmd
;
252 CDIO
->iotd_Req
.io_Length
= sizeof(scmd
);
254 scmd
.scsi_Data
= (UWORD
*)data
;
255 scmd
.scsi_Length
= datasize
;
256 scmd
.scsi_SenseActual
= 0;
257 scmd
.scsi_SenseData
= sensebuf
;
258 scmd
.scsi_SenseLength
= SENSELEN
;
259 scmd
.scsi_Command
= cmd
;
260 scmd
.scsi_CmdLength
= cmdsize
;
261 scmd
.scsi_Flags
= SCSIF_AUTOSENSE
| direction
;
263 DoIO((struct IORequest
*)CDIO
);
265 if (CDIO
->iotd_Req
.io_Error
!= 0) {
266 BX_PANIC(("DoSCSI: error %d", CDIO
->iotd_Req
.io_Error
));
269 return CDIO
->iotd_Req
.io_Error
;
272 void cdrom_interface::seek(int lba
)
274 unsigned char buffer
[BX_CD_FRAMESIZE
];
276 read_block(buffer
, lba
, BX_CD_FRAMESIZE
);